From 7028cbe09c688437910a25623098762bf0fa592d Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 28 Mar 2016 22:28:34 +1000 Subject: Move Irrlicht to src/others. --- .../irrlicht-1.8.1/source/Irrlicht/BuiltInFont.h | 1075 ++ .../source/Irrlicht/C3DSMeshFileLoader.cpp | 1396 +++ .../source/Irrlicht/C3DSMeshFileLoader.h | 166 + .../source/Irrlicht/CAnimatedMeshHalfLife.cpp | 1695 +++ .../source/Irrlicht/CAnimatedMeshHalfLife.h | 630 + .../source/Irrlicht/CAnimatedMeshMD2.cpp | 457 + .../source/Irrlicht/CAnimatedMeshMD2.h | 154 + .../source/Irrlicht/CAnimatedMeshMD3.cpp | 468 + .../source/Irrlicht/CAnimatedMeshMD3.h | 135 + .../source/Irrlicht/CAnimatedMeshSceneNode.cpp | 1132 ++ .../source/Irrlicht/CAnimatedMeshSceneNode.h | 227 + .../source/Irrlicht/CAttributeImpl.h | 2071 ++++ .../irrlicht-1.8.1/source/Irrlicht/CAttributes.cpp | 1665 +++ .../irrlicht-1.8.1/source/Irrlicht/CAttributes.h | 712 ++ .../source/Irrlicht/CB3DMeshFileLoader.cpp | 1105 ++ .../source/Irrlicht/CB3DMeshFileLoader.h | 140 + .../source/Irrlicht/CBSPMeshFileLoader.cpp | 107 + .../source/Irrlicht/CBSPMeshFileLoader.h | 52 + .../source/Irrlicht/CBillboardSceneNode.cpp | 294 + .../source/Irrlicht/CBillboardSceneNode.h | 99 + src/others/irrlicht-1.8.1/source/Irrlicht/CBlit.h | 1273 ++ .../source/Irrlicht/CBoneSceneNode.cpp | 129 + .../source/Irrlicht/CBoneSceneNode.h | 79 + .../Irrlicht/CBurningShader_Raster_Reference.cpp | 1143 ++ .../irrlicht-1.8.1/source/Irrlicht/CCSMLoader.cpp | 872 ++ .../irrlicht-1.8.1/source/Irrlicht/CCSMLoader.h | 82 + .../source/Irrlicht/CCameraSceneNode.cpp | 385 + .../source/Irrlicht/CCameraSceneNode.h | 172 + .../source/Irrlicht/CCgMaterialRenderer.cpp | 361 + .../source/Irrlicht/CCgMaterialRenderer.h | 176 + .../source/Irrlicht/CColladaFileLoader.cpp | 2957 +++++ .../source/Irrlicht/CColladaFileLoader.h | 389 + .../source/Irrlicht/CColladaMeshWriter.cpp | 2245 ++++ .../source/Irrlicht/CColladaMeshWriter.h | 271 + .../source/Irrlicht/CColorConverter.cpp | 705 ++ .../source/Irrlicht/CColorConverter.h | 92 + .../source/Irrlicht/CCubeSceneNode.cpp | 235 + .../source/Irrlicht/CCubeSceneNode.h | 93 + .../irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.cpp | 2455 ++++ .../irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.h | 341 + .../source/Irrlicht/CD3D8MaterialRenderer.h | 581 + .../source/Irrlicht/CD3D8NormalMapRenderer.cpp | 248 + .../source/Irrlicht/CD3D8NormalMapRenderer.h | 56 + .../source/Irrlicht/CD3D8ParallaxMapRenderer.cpp | 318 + .../source/Irrlicht/CD3D8ParallaxMapRenderer.h | 62 + .../Irrlicht/CD3D8ShaderMaterialRenderer.cpp | 332 + .../source/Irrlicht/CD3D8ShaderMaterialRenderer.h | 82 + .../source/Irrlicht/CD3D8Texture.cpp | 659 ++ .../irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.h | 120 + .../source/Irrlicht/CD3D9CgMaterialRenderer.cpp | 222 + .../source/Irrlicht/CD3D9CgMaterialRenderer.h | 83 + .../irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.cpp | 3633 ++++++ .../irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.h | 496 + .../source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp | 428 + .../source/Irrlicht/CD3D9HLSLMaterialRenderer.h | 85 + .../source/Irrlicht/CD3D9MaterialRenderer.h | 615 + .../source/Irrlicht/CD3D9NormalMapRenderer.cpp | 306 + .../source/Irrlicht/CD3D9NormalMapRenderer.h | 56 + .../source/Irrlicht/CD3D9ParallaxMapRenderer.cpp | 410 + .../source/Irrlicht/CD3D9ParallaxMapRenderer.h | 63 + .../Irrlicht/CD3D9ShaderMaterialRenderer.cpp | 540 + .../source/Irrlicht/CD3D9ShaderMaterialRenderer.h | 102 + .../source/Irrlicht/CD3D9Texture.cpp | 699 ++ .../irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.h | 130 + .../irrlicht-1.8.1/source/Irrlicht/CDMFLoader.cpp | 436 + .../irrlicht-1.8.1/source/Irrlicht/CDMFLoader.h | 91 + .../source/Irrlicht/CDefaultGUIElementFactory.cpp | 164 + .../source/Irrlicht/CDefaultGUIElementFactory.d | 2 + .../source/Irrlicht/CDefaultGUIElementFactory.h | 70 + .../Irrlicht/CDefaultSceneNodeAnimatorFactory.cpp | 162 + .../Irrlicht/CDefaultSceneNodeAnimatorFactory.h | 75 + .../source/Irrlicht/CDefaultSceneNodeFactory.cpp | 179 + .../source/Irrlicht/CDefaultSceneNodeFactory.h | 80 + .../source/Irrlicht/CDepthBuffer.cpp | 176 + .../irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.h | 94 + .../Irrlicht/CDummyTransformationSceneNode.cpp | 105 + .../Irrlicht/CDummyTransformationSceneNode.h | 62 + .../source/Irrlicht/CEmptySceneNode.cpp | 70 + .../source/Irrlicht/CEmptySceneNode.h | 46 + .../irrlicht-1.8.1/source/Irrlicht/CFPSCounter.cpp | 76 + .../irrlicht-1.8.1/source/Irrlicht/CFPSCounter.h | 54 + .../irrlicht-1.8.1/source/Irrlicht/CFileList.cpp | 165 + .../irrlicht-1.8.1/source/Irrlicht/CFileList.h | 138 + .../irrlicht-1.8.1/source/Irrlicht/CFileSystem.cpp | 1078 ++ .../irrlicht-1.8.1/source/Irrlicht/CFileSystem.h | 173 + .../irrlicht-1.8.1/source/Irrlicht/CGUIButton.cpp | 531 + .../irrlicht-1.8.1/source/Irrlicht/CGUIButton.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIButton.h | 143 + .../source/Irrlicht/CGUICheckBox.cpp | 205 + .../irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.h | 55 + .../source/Irrlicht/CGUIColorSelectDialog.cpp | 483 + .../source/Irrlicht/CGUIColorSelectDialog.d | 2 + .../source/Irrlicht/CGUIColorSelectDialog.h | 74 + .../source/Irrlicht/CGUIComboBox.cpp | 523 + .../irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.h | 117 + .../source/Irrlicht/CGUIContextMenu.cpp | 869 ++ .../source/Irrlicht/CGUIContextMenu.d | 2 + .../source/Irrlicht/CGUIContextMenu.h | 174 + .../irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.cpp | 1555 +++ .../irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.h | 182 + .../source/Irrlicht/CGUIEnvironment.cpp | 1658 +++ .../source/Irrlicht/CGUIEnvironment.d | 2 + .../source/Irrlicht/CGUIEnvironment.h | 323 + .../source/Irrlicht/CGUIFileOpenDialog.cpp | 446 + .../source/Irrlicht/CGUIFileOpenDialog.d | 2 + .../source/Irrlicht/CGUIFileOpenDialog.h | 84 + .../irrlicht-1.8.1/source/Irrlicht/CGUIFont.cpp | 589 + .../irrlicht-1.8.1/source/Irrlicht/CGUIFont.d | 1 + .../irrlicht-1.8.1/source/Irrlicht/CGUIFont.h | 118 + .../irrlicht-1.8.1/source/Irrlicht/CGUIImage.cpp | 164 + .../irrlicht-1.8.1/source/Irrlicht/CGUIImage.d | 1 + .../irrlicht-1.8.1/source/Irrlicht/CGUIImage.h | 75 + .../source/Irrlicht/CGUIImageList.cpp | 93 + .../irrlicht-1.8.1/source/Irrlicht/CGUIImageList.d | 26 + .../irrlicht-1.8.1/source/Irrlicht/CGUIImageList.h | 68 + .../source/Irrlicht/CGUIInOutFader.cpp | 179 + .../source/Irrlicht/CGUIInOutFader.d | 2 + .../source/Irrlicht/CGUIInOutFader.h | 75 + .../irrlicht-1.8.1/source/Irrlicht/CGUIListBox.cpp | 910 ++ .../irrlicht-1.8.1/source/Irrlicht/CGUIListBox.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIListBox.h | 190 + .../irrlicht-1.8.1/source/Irrlicht/CGUIMenu.cpp | 294 + .../irrlicht-1.8.1/source/Irrlicht/CGUIMenu.d | 1 + .../irrlicht-1.8.1/source/Irrlicht/CGUIMenu.h | 52 + .../source/Irrlicht/CGUIMeshViewer.cpp | 171 + .../source/Irrlicht/CGUIMeshViewer.d | 2 + .../source/Irrlicht/CGUIMeshViewer.h | 61 + .../source/Irrlicht/CGUIMessageBox.cpp | 463 + .../source/Irrlicht/CGUIMessageBox.d | 2 + .../source/Irrlicht/CGUIMessageBox.h | 64 + .../source/Irrlicht/CGUIModalScreen.cpp | 235 + .../source/Irrlicht/CGUIModalScreen.d | 2 + .../source/Irrlicht/CGUIModalScreen.h | 70 + .../source/Irrlicht/CGUIScrollBar.cpp | 569 + .../irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.h | 113 + .../irrlicht-1.8.1/source/Irrlicht/CGUISkin.cpp | 1019 ++ .../irrlicht-1.8.1/source/Irrlicht/CGUISkin.d | 1 + .../irrlicht-1.8.1/source/Irrlicht/CGUISkin.h | 249 + .../irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.cpp | 327 + .../irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.h | 108 + .../source/Irrlicht/CGUISpriteBank.cpp | 250 + .../source/Irrlicht/CGUISpriteBank.d | 2 + .../source/Irrlicht/CGUISpriteBank.h | 84 + .../source/Irrlicht/CGUIStaticText.cpp | 630 + .../source/Irrlicht/CGUIStaticText.d | 2 + .../source/Irrlicht/CGUIStaticText.h | 145 + .../source/Irrlicht/CGUITabControl.cpp | 1042 ++ .../source/Irrlicht/CGUITabControl.d | 2 + .../source/Irrlicht/CGUITabControl.h | 202 + .../irrlicht-1.8.1/source/Irrlicht/CGUITable.cpp | 1256 ++ .../irrlicht-1.8.1/source/Irrlicht/CGUITable.d | 1 + .../irrlicht-1.8.1/source/Irrlicht/CGUITable.h | 224 + .../irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.cpp | 176 + .../irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.h | 52 + .../source/Irrlicht/CGUITreeView.cpp | 1101 ++ .../irrlicht-1.8.1/source/Irrlicht/CGUITreeView.d | 19 + .../irrlicht-1.8.1/source/Irrlicht/CGUITreeView.h | 331 + .../irrlicht-1.8.1/source/Irrlicht/CGUIWindow.cpp | 404 + .../irrlicht-1.8.1/source/Irrlicht/CGUIWindow.d | 2 + .../irrlicht-1.8.1/source/Irrlicht/CGUIWindow.h | 99 + .../source/Irrlicht/CGeometryCreator.cpp | 892 ++ .../source/Irrlicht/CGeometryCreator.h | 65 + .../irrlicht-1.8.1/source/Irrlicht/CImage.cpp | 462 + src/others/irrlicht-1.8.1/source/Irrlicht/CImage.h | 127 + .../source/Irrlicht/CImageLoaderBMP.cpp | 372 + .../source/Irrlicht/CImageLoaderBMP.h | 100 + .../source/Irrlicht/CImageLoaderDDS.cpp | 712 ++ .../source/Irrlicht/CImageLoaderDDS.h | 296 + .../source/Irrlicht/CImageLoaderJPG.cpp | 306 + .../source/Irrlicht/CImageLoaderJPG.h | 116 + .../source/Irrlicht/CImageLoaderPCX.cpp | 231 + .../source/Irrlicht/CImageLoaderPCX.h | 82 + .../source/Irrlicht/CImageLoaderPNG.cpp | 290 + .../source/Irrlicht/CImageLoaderPNG.h | 45 + .../source/Irrlicht/CImageLoaderPPM.cpp | 277 + .../source/Irrlicht/CImageLoaderPPM.h | 55 + .../source/Irrlicht/CImageLoaderPSD.cpp | 375 + .../source/Irrlicht/CImageLoaderPSD.h | 72 + .../source/Irrlicht/CImageLoaderRGB.cpp | 654 ++ .../source/Irrlicht/CImageLoaderRGB.h | 165 + .../source/Irrlicht/CImageLoaderTGA.cpp | 239 + .../source/Irrlicht/CImageLoaderTGA.h | 82 + .../source/Irrlicht/CImageLoaderWAL.cpp | 285 + .../source/Irrlicht/CImageLoaderWAL.h | 100 + .../source/Irrlicht/CImageWriterBMP.cpp | 140 + .../source/Irrlicht/CImageWriterBMP.h | 37 + .../source/Irrlicht/CImageWriterJPG.cpp | 229 + .../source/Irrlicht/CImageWriterJPG.h | 37 + .../source/Irrlicht/CImageWriterPCX.cpp | 162 + .../source/Irrlicht/CImageWriterPCX.h | 37 + .../source/Irrlicht/CImageWriterPNG.cpp | 222 + .../source/Irrlicht/CImageWriterPNG.h | 37 + .../source/Irrlicht/CImageWriterPPM.cpp | 105 + .../source/Irrlicht/CImageWriterPPM.h | 37 + .../source/Irrlicht/CImageWriterPSD.cpp | 46 + .../source/Irrlicht/CImageWriterPSD.h | 37 + .../source/Irrlicht/CImageWriterTGA.cpp | 147 + .../source/Irrlicht/CImageWriterTGA.h | 37 + .../source/Irrlicht/CIrrDeviceConsole.cpp | 477 + .../source/Irrlicht/CIrrDeviceConsole.h | 330 + .../source/Irrlicht/CIrrDeviceFB.cpp | 405 + .../irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.h | 207 + .../source/Irrlicht/CIrrDeviceLinux.cpp | 2303 ++++ .../source/Irrlicht/CIrrDeviceLinux.h | 452 + .../source/Irrlicht/CIrrDeviceSDL.cpp | 973 ++ .../irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.h | 235 + .../source/Irrlicht/CIrrDeviceStub.cpp | 429 + .../source/Irrlicht/CIrrDeviceStub.h | 186 + .../source/Irrlicht/CIrrDeviceWin32.cpp | 2068 ++++ .../source/Irrlicht/CIrrDeviceWin32.h | 420 + .../source/Irrlicht/CIrrDeviceWinCE.cpp | 868 ++ .../source/Irrlicht/CIrrDeviceWinCE.h | 296 + .../source/Irrlicht/CIrrMeshFileLoader.cpp | 554 + .../source/Irrlicht/CIrrMeshFileLoader.h | 90 + .../source/Irrlicht/CIrrMeshWriter.cpp | 315 + .../source/Irrlicht/CIrrMeshWriter.h | 63 + .../source/Irrlicht/CLMTSMeshFileLoader.cpp | 373 + .../source/Irrlicht/CLMTSMeshFileLoader.h | 109 + .../source/Irrlicht/CLWOMeshFileLoader.cpp | 2114 ++++ .../source/Irrlicht/CLWOMeshFileLoader.h | 87 + .../source/Irrlicht/CLightSceneNode.cpp | 275 + .../source/Irrlicht/CLightSceneNode.h | 108 + .../source/Irrlicht/CLimitReadFile.cpp | 127 + .../source/Irrlicht/CLimitReadFile.h | 62 + .../irrlicht-1.8.1/source/Irrlicht/CLogger.cpp | 102 + .../irrlicht-1.8.1/source/Irrlicht/CLogger.h | 56 + .../source/Irrlicht/CMD2MeshFileLoader.cpp | 364 + .../source/Irrlicht/CMD2MeshFileLoader.h | 45 + .../source/Irrlicht/CMD3MeshFileLoader.cpp | 53 + .../source/Irrlicht/CMD3MeshFileLoader.h | 49 + .../source/Irrlicht/CMS3DMeshFileLoader.cpp | 818 ++ .../source/Irrlicht/CMS3DMeshFileLoader.h | 49 + .../irrlicht-1.8.1/source/Irrlicht/CMY3DHelper.h | 447 + .../source/Irrlicht/CMY3DMeshFileLoader.cpp | 882 ++ .../source/Irrlicht/CMY3DMeshFileLoader.h | 131 + .../irrlicht-1.8.1/source/Irrlicht/CMemoryFile.cpp | 122 + .../irrlicht-1.8.1/source/Irrlicht/CMemoryFile.h | 62 + .../irrlicht-1.8.1/source/Irrlicht/CMeshCache.cpp | 178 + .../irrlicht-1.8.1/source/Irrlicht/CMeshCache.h | 123 + .../source/Irrlicht/CMeshManipulator.cpp | 1820 +++ .../source/Irrlicht/CMeshManipulator.h | 95 + .../source/Irrlicht/CMeshSceneNode.cpp | 447 + .../source/Irrlicht/CMeshSceneNode.h | 103 + .../source/Irrlicht/CMetaTriangleSelector.cpp | 188 + .../source/Irrlicht/CMetaTriangleSelector.h | 76 + .../source/Irrlicht/CMountPointReader.cpp | 175 + .../source/Irrlicht/CMountPointReader.h | 89 + .../irrlicht-1.8.1/source/Irrlicht/CNPKReader.cpp | 277 + .../irrlicht-1.8.1/source/Irrlicht/CNPKReader.h | 128 + .../irrlicht-1.8.1/source/Irrlicht/CNullDriver.cpp | 2448 ++++ .../irrlicht-1.8.1/source/Irrlicht/CNullDriver.h | 849 ++ .../source/Irrlicht/COBJMeshFileLoader.cpp | 931 ++ .../source/Irrlicht/COBJMeshFileLoader.h | 122 + .../source/Irrlicht/COBJMeshWriter.cpp | 243 + .../source/Irrlicht/COBJMeshWriter.h | 58 + .../irrlicht-1.8.1/source/Irrlicht/COCTLoader.cpp | 336 + .../irrlicht-1.8.1/source/Irrlicht/COCTLoader.h | 141 + .../irrlicht-1.8.1/source/Irrlicht/COSOperator.cpp | 212 + .../irrlicht-1.8.1/source/Irrlicht/COSOperator.h | 60 + .../source/Irrlicht/COctreeSceneNode.cpp | 636 + .../source/Irrlicht/COctreeSceneNode.h | 115 + .../source/Irrlicht/COctreeTriangleSelector.cpp | 265 + .../source/Irrlicht/COctreeTriangleSelector.h | 80 + .../source/Irrlicht/COgreMeshFileLoader.cpp | 1592 +++ .../source/Irrlicht/COgreMeshFileLoader.h | 269 + .../source/Irrlicht/COpenGLCgMaterialRenderer.cpp | 244 + .../source/Irrlicht/COpenGLCgMaterialRenderer.h | 99 + .../source/Irrlicht/COpenGLDriver.cpp | 4830 ++++++++ .../irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.h | 613 + .../source/Irrlicht/COpenGLExtensionHandler.cpp | 804 ++ .../source/Irrlicht/COpenGLExtensionHandler.h | 2586 +++++ .../source/Irrlicht/COpenGLMaterialRenderer.h | 756 ++ .../source/Irrlicht/COpenGLNormalMapRenderer.cpp | 291 + .../source/Irrlicht/COpenGLNormalMapRenderer.h | 49 + .../source/Irrlicht/COpenGLParallaxMapRenderer.cpp | 354 + .../source/Irrlicht/COpenGLParallaxMapRenderer.h | 55 + .../source/Irrlicht/COpenGLSLMaterialRenderer.cpp | 693 ++ .../source/Irrlicht/COpenGLSLMaterialRenderer.h | 141 + .../Irrlicht/COpenGLShaderMaterialRenderer.cpp | 339 + .../Irrlicht/COpenGLShaderMaterialRenderer.h | 97 + .../source/Irrlicht/COpenGLTexture.cpp | 963 ++ .../source/Irrlicht/COpenGLTexture.h | 205 + .../source/Irrlicht/CPLYMeshFileLoader.cpp | 817 ++ .../source/Irrlicht/CPLYMeshFileLoader.h | 148 + .../source/Irrlicht/CPLYMeshWriter.cpp | 183 + .../source/Irrlicht/CPLYMeshWriter.h | 35 + .../irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp | 196 + .../irrlicht-1.8.1/source/Irrlicht/CPakReader.h | 125 + .../CParticleAnimatedMeshSceneNodeEmitter.cpp | 200 + .../CParticleAnimatedMeshSceneNodeEmitter.h | 161 + .../Irrlicht/CParticleAttractionAffector.cpp | 84 + .../source/Irrlicht/CParticleAttractionAffector.h | 87 + .../source/Irrlicht/CParticleBoxEmitter.cpp | 188 + .../source/Irrlicht/CParticleBoxEmitter.h | 133 + .../source/Irrlicht/CParticleCylinderEmitter.cpp | 187 + .../source/Irrlicht/CParticleCylinderEmitter.h | 164 + .../source/Irrlicht/CParticleFadeOutAffector.cpp | 70 + .../source/Irrlicht/CParticleFadeOutAffector.h | 63 + .../source/Irrlicht/CParticleGravityAffector.cpp | 64 + .../source/Irrlicht/CParticleGravityAffector.h | 64 + .../source/Irrlicht/CParticleMeshEmitter.cpp | 190 + .../source/Irrlicht/CParticleMeshEmitter.h | 160 + .../source/Irrlicht/CParticlePointEmitter.cpp | 147 + .../source/Irrlicht/CParticlePointEmitter.h | 123 + .../source/Irrlicht/CParticleRingEmitter.cpp | 177 + .../source/Irrlicht/CParticleRingEmitter.h | 148 + .../source/Irrlicht/CParticleRotationAffector.cpp | 67 + .../source/Irrlicht/CParticleRotationAffector.h | 56 + .../source/Irrlicht/CParticleScaleAffector.cpp | 53 + .../source/Irrlicht/CParticleScaleAffector.h | 44 + .../source/Irrlicht/CParticleSphereEmitter.cpp | 175 + .../source/Irrlicht/CParticleSphereEmitter.h | 141 + .../source/Irrlicht/CParticleSystemSceneNode.cpp | 721 ++ .../source/Irrlicht/CParticleSystemSceneNode.h | 239 + .../source/Irrlicht/CQ3LevelMesh.cpp | 2082 ++++ .../irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.h | 491 + .../source/Irrlicht/CQuake3ShaderSceneNode.cpp | 1376 +++ .../source/Irrlicht/CQuake3ShaderSceneNode.h | 118 + .../irrlicht-1.8.1/source/Irrlicht/CReadFile.cpp | 114 + .../irrlicht-1.8.1/source/Irrlicht/CReadFile.h | 64 + .../source/Irrlicht/CSMFMeshFileLoader.cpp | 232 + .../source/Irrlicht/CSMFMeshFileLoader.h | 67 + .../source/Irrlicht/CSTLMeshFileLoader.cpp | 253 + .../source/Irrlicht/CSTLMeshFileLoader.h | 49 + .../source/Irrlicht/CSTLMeshWriter.cpp | 187 + .../source/Irrlicht/CSTLMeshWriter.h | 55 + .../source/Irrlicht/CSceneCollisionManager.cpp | 960 ++ .../source/Irrlicht/CSceneCollisionManager.h | 158 + .../source/Irrlicht/CSceneLoaderIrr.cpp | 284 + .../source/Irrlicht/CSceneLoaderIrr.h | 82 + .../source/Irrlicht/CSceneManager.cpp | 2522 ++++ .../irrlicht-1.8.1/source/Irrlicht/CSceneManager.h | 659 ++ .../Irrlicht/CSceneNodeAnimatorCameraFPS.cpp | 355 + .../source/Irrlicht/CSceneNodeAnimatorCameraFPS.h | 123 + .../Irrlicht/CSceneNodeAnimatorCameraMaya.cpp | 317 + .../source/Irrlicht/CSceneNodeAnimatorCameraMaya.h | 116 + .../CSceneNodeAnimatorCollisionResponse.cpp | 303 + .../Irrlicht/CSceneNodeAnimatorCollisionResponse.h | 157 + .../source/Irrlicht/CSceneNodeAnimatorDelete.cpp | 51 + .../source/Irrlicht/CSceneNodeAnimatorDelete.h | 46 + .../Irrlicht/CSceneNodeAnimatorFlyCircle.cpp | 100 + .../source/Irrlicht/CSceneNodeAnimatorFlyCircle.h | 64 + .../Irrlicht/CSceneNodeAnimatorFlyStraight.cpp | 112 + .../Irrlicht/CSceneNodeAnimatorFlyStraight.h | 60 + .../Irrlicht/CSceneNodeAnimatorFollowSpline.cpp | 161 + .../Irrlicht/CSceneNodeAnimatorFollowSpline.h | 63 + .../source/Irrlicht/CSceneNodeAnimatorRotation.cpp | 73 + .../source/Irrlicht/CSceneNodeAnimatorRotation.h | 49 + .../source/Irrlicht/CSceneNodeAnimatorTexture.cpp | 140 + .../source/Irrlicht/CSceneNodeAnimatorTexture.h | 59 + .../source/Irrlicht/CShadowVolumeSceneNode.cpp | 419 + .../source/Irrlicht/CShadowVolumeSceneNode.h | 87 + .../source/Irrlicht/CSkinnedMesh.cpp | 1471 +++ .../irrlicht-1.8.1/source/Irrlicht/CSkinnedMesh.h | 215 + .../source/Irrlicht/CSkyBoxSceneNode.cpp | 263 + .../source/Irrlicht/CSkyBoxSceneNode.h | 62 + .../source/Irrlicht/CSkyDomeSceneNode.cpp | 264 + .../source/Irrlicht/CSkyDomeSceneNode.h | 50 + .../source/Irrlicht/CSoftware2MaterialRenderer.h | 118 + .../source/Irrlicht/CSoftwareDriver.cpp | 973 ++ .../source/Irrlicht/CSoftwareDriver.h | 180 + .../source/Irrlicht/CSoftwareDriver2.cpp | 2723 +++++ .../source/Irrlicht/CSoftwareDriver2.h | 290 + .../source/Irrlicht/CSoftwareTexture.cpp | 151 + .../source/Irrlicht/CSoftwareTexture.h | 76 + .../source/Irrlicht/CSoftwareTexture2.cpp | 156 + .../source/Irrlicht/CSoftwareTexture2.h | 141 + .../source/Irrlicht/CSphereSceneNode.cpp | 199 + .../source/Irrlicht/CSphereSceneNode.h | 96 + .../irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp | 300 + .../irrlicht-1.8.1/source/Irrlicht/CTRFlatWire.cpp | 281 + .../irrlicht-1.8.1/source/Irrlicht/CTRGouraud.cpp | 358 + .../irrlicht-1.8.1/source/Irrlicht/CTRGouraud2.cpp | 645 ++ .../source/Irrlicht/CTRGouraudAlpha2.cpp | 657 ++ .../source/Irrlicht/CTRGouraudAlphaNoZ2.cpp | 654 ++ .../source/Irrlicht/CTRGouraudWire.cpp | 326 + .../source/Irrlicht/CTRNormalMap.cpp | 848 ++ .../source/Irrlicht/CTRStencilShadow.cpp | 930 ++ .../source/Irrlicht/CTRTextureBlend.cpp | 2385 ++++ .../source/Irrlicht/CTRTextureDetailMap2.cpp | 659 ++ .../source/Irrlicht/CTRTextureFlat.cpp | 339 + .../source/Irrlicht/CTRTextureFlatWire.cpp | 313 + .../source/Irrlicht/CTRTextureGouraud.cpp | 468 + .../source/Irrlicht/CTRTextureGouraud.h | 85 + .../source/Irrlicht/CTRTextureGouraud2.cpp | 674 ++ .../source/Irrlicht/CTRTextureGouraudAdd.cpp | 419 + .../source/Irrlicht/CTRTextureGouraudAdd2.cpp | 680 ++ .../source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp | 645 ++ .../source/Irrlicht/CTRTextureGouraudAlpha.cpp | 744 ++ .../source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp | 745 ++ .../source/Irrlicht/CTRTextureGouraudNoZ.cpp | 367 + .../source/Irrlicht/CTRTextureGouraudNoZ2.cpp | 647 ++ .../Irrlicht/CTRTextureGouraudVertexAlpha2.cpp | 690 ++ .../source/Irrlicht/CTRTextureGouraudWire.cpp | 364 + .../source/Irrlicht/CTRTextureLightMap2_Add.cpp | 672 ++ .../source/Irrlicht/CTRTextureLightMap2_M1.cpp | 644 ++ .../source/Irrlicht/CTRTextureLightMap2_M2.cpp | 644 ++ .../source/Irrlicht/CTRTextureLightMap2_M4.cpp | 1154 ++ .../Irrlicht/CTRTextureLightMapGouraud2_M4.cpp | 690 ++ .../source/Irrlicht/CTRTextureWire2.cpp | 298 + .../irrlicht-1.8.1/source/Irrlicht/CTarReader.cpp | 258 + .../irrlicht-1.8.1/source/Irrlicht/CTarReader.h | 133 + .../source/Irrlicht/CTerrainSceneNode.cpp | 1502 +++ .../source/Irrlicht/CTerrainSceneNode.h | 330 + .../source/Irrlicht/CTerrainTriangleSelector.cpp | 234 + .../source/Irrlicht/CTerrainTriangleSelector.h | 100 + .../source/Irrlicht/CTextSceneNode.cpp | 471 + .../source/Irrlicht/CTextSceneNode.h | 160 + src/others/irrlicht-1.8.1/source/Irrlicht/CTimer.h | 108 + .../source/Irrlicht/CTriangleBBSelector.cpp | 80 + .../source/Irrlicht/CTriangleBBSelector.h | 43 + .../source/Irrlicht/CTriangleSelector.cpp | 298 + .../source/Irrlicht/CTriangleSelector.h | 92 + .../source/Irrlicht/CVideoModeList.cpp | 132 + .../source/Irrlicht/CVideoModeList.h | 79 + .../source/Irrlicht/CVolumeLightSceneNode.cpp | 202 + .../source/Irrlicht/CVolumeLightSceneNode.h | 93 + .../irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp | 263 + .../irrlicht-1.8.1/source/Irrlicht/CWADReader.h | 177 + .../source/Irrlicht/CWaterSurfaceSceneNode.cpp | 137 + .../source/Irrlicht/CWaterSurfaceSceneNode.h | 61 + .../irrlicht-1.8.1/source/Irrlicht/CWriteFile.cpp | 123 + .../irrlicht-1.8.1/source/Irrlicht/CWriteFile.h | 58 + .../irrlicht-1.8.1/source/Irrlicht/CXMLReader.cpp | 70 + .../irrlicht-1.8.1/source/Irrlicht/CXMLReader.h | 26 + .../source/Irrlicht/CXMLReaderImpl.h | 821 ++ .../irrlicht-1.8.1/source/Irrlicht/CXMLWriter.cpp | 257 + .../irrlicht-1.8.1/source/Irrlicht/CXMLWriter.h | 76 + .../source/Irrlicht/CXMeshFileLoader.cpp | 2423 ++++ .../source/Irrlicht/CXMeshFileLoader.h | 198 + .../irrlicht-1.8.1/source/Irrlicht/CZBuffer.cpp | 109 + .../irrlicht-1.8.1/source/Irrlicht/CZBuffer.h | 52 + .../irrlicht-1.8.1/source/Irrlicht/CZipReader.cpp | 839 ++ .../irrlicht-1.8.1/source/Irrlicht/CZipReader.h | 227 + .../irrlicht-1.8.1/source/Irrlicht/IAttribute.h | 107 + .../source/Irrlicht/IBurningShader.cpp | 120 + .../source/Irrlicht/IBurningShader.h | 201 + .../irrlicht-1.8.1/source/Irrlicht/IDepthBuffer.h | 82 + .../source/Irrlicht/IImagePresenter.h | 36 + .../source/Irrlicht/ISceneNodeAnimatorFinishing.h | 36 + .../source/Irrlicht/ITriangleRenderer.h | 68 + .../irrlicht-1.8.1/source/Irrlicht/IZBuffer.h | 47 + .../source/Irrlicht/Irrlicht-gcc.cbp | 1323 +++ .../irrlicht-1.8.1/source/Irrlicht/Irrlicht.aps | Bin 0 -> 61604 bytes .../irrlicht-1.8.1/source/Irrlicht/Irrlicht.cpp | 154 + .../irrlicht-1.8.1/source/Irrlicht/Irrlicht.dev | 6630 +++++++++++ .../irrlicht-1.8.1/source/Irrlicht/Irrlicht.rc | Bin 0 -> 4598 bytes .../source/Irrlicht/Irrlicht10.0.sln | 50 + .../source/Irrlicht/Irrlicht10.0.vcxproj | 1555 +++ .../source/Irrlicht/Irrlicht10.0.vcxproj.filters | 2247 ++++ .../source/Irrlicht/Irrlicht11.0.sln | 50 + .../source/Irrlicht/Irrlicht11.0.vcxproj | 1563 +++ .../source/Irrlicht/Irrlicht11.0.vcxproj.filters | 2247 ++++ .../irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.sln | 29 + .../source/Irrlicht/Irrlicht8.0.vcproj | 3512 ++++++ .../irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.sln | 32 + .../source/Irrlicht/Irrlicht9.0.vcproj | 3656 ++++++ .../source/Irrlicht/Irrlicht_mobile6.sln | 22 + .../source/Irrlicht/Irrlicht_mobile6.vcproj | 3085 +++++ .../source/Irrlicht/Irrlicht_xbox.sln | 30 + .../source/Irrlicht/Irrlicht_xbox.vcproj | 1987 ++++ .../source/Irrlicht/MacOSX/._MainMenu.nib | Bin 0 -> 82 bytes .../source/Irrlicht/MacOSX/AppDelegate.h | 24 + .../source/Irrlicht/MacOSX/AppDelegate.mm | 79 + .../source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h | 251 + .../source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm | 1889 +++ .../source/Irrlicht/MacOSX/DemoApp-Info.plist | 24 + .../source/Irrlicht/MacOSX/Irrlicht-Info.plist | 20 + .../MacOSX/MacOSX.xcodeproj/project.pbxproj | 7232 ++++++++++++ .../source/Irrlicht/MacOSX/MacOSX_Prefix.pch | 5 + .../Irrlicht/MacOSX/MainMenu.nib/classes.nib | 4 + .../source/Irrlicht/MacOSX/MainMenu.nib/info.nib | 17 + .../Irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib | Bin 0 -> 13030 bytes .../source/Irrlicht/MacOSX/OSXClipboard.h | 15 + .../source/Irrlicht/MacOSX/OSXClipboard.mm | 36 + .../source/Irrlicht/MacOSX/irrFramework-Info.plist | 20 + src/others/irrlicht-1.8.1/source/Irrlicht/Makefile | 203 + src/others/irrlicht-1.8.1/source/Irrlicht/Octree.h | 388 + .../irrlicht-1.8.1/source/Irrlicht/S2DVertex.h | 30 + .../irrlicht-1.8.1/source/Irrlicht/S4DVertex.h | 693 ++ .../irrlicht-1.8.1/source/Irrlicht/SConstruct | 102 + .../Irrlicht/SoftwareDriver2_compile_config.h | 104 + .../source/Irrlicht/SoftwareDriver2_helper.h | 1042 ++ .../source/Irrlicht/aesGladman/Readme.txt | 25 + .../source/Irrlicht/aesGladman/aes.h | 137 + .../source/Irrlicht/aesGladman/aescrypt.cpp | 303 + .../source/Irrlicht/aesGladman/aeskey.cpp | 455 + .../source/Irrlicht/aesGladman/aesopt.h | 955 ++ .../source/Irrlicht/aesGladman/aestab.cpp | 223 + .../source/Irrlicht/aesGladman/fileenc.cpp | 140 + .../source/Irrlicht/aesGladman/fileenc.h | 114 + .../source/Irrlicht/aesGladman/hmac.cpp | 142 + .../source/Irrlicht/aesGladman/hmac.h | 95 + .../source/Irrlicht/aesGladman/prng.cpp | 146 + .../source/Irrlicht/aesGladman/prng.h | 74 + .../source/Irrlicht/aesGladman/pwd2key.cpp | 186 + .../source/Irrlicht/aesGladman/pwd2key.h | 50 + .../source/Irrlicht/aesGladman/sha1.cpp | 237 + .../source/Irrlicht/aesGladman/sha1.h | 68 + .../source/Irrlicht/aesGladman/sha2.cpp | 626 + .../source/Irrlicht/aesGladman/sha2.h | 160 + .../irrlicht-1.8.1/source/Irrlicht/builtInFont.bmp | Bin 0 -> 8266 bytes .../irrlicht-1.8.1/source/Irrlicht/bzip2/CHANGES | 327 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/LICENSE | 42 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile | 217 + .../source/Irrlicht/bzip2/Makefile-libbz2_so | 59 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/README | 215 + .../Irrlicht/bzip2/README.COMPILATION.PROBLEMS | 58 + .../source/Irrlicht/bzip2/README.XML.STUFF | 45 + .../source/Irrlicht/bzip2/blocksort.c | 1094 ++ .../source/Irrlicht/bzip2/bz-common.xsl | 39 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bz-fo.xsl | 276 + .../source/Irrlicht/bzip2/bz-html.xsl | 20 + .../source/Irrlicht/bzip2/bzcompress.c | 672 ++ .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff | 76 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff.1 | 47 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep | 75 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep.1 | 56 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzip.css | 74 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1 | 454 + .../source/Irrlicht/bzip2/bzip2.1.preformatted | 399 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.c | 2034 ++++ .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.txt | 391 + .../source/Irrlicht/bzip2/bzip2recover.c | 514 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.c | 1580 +++ .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.h | 285 + .../source/Irrlicht/bzip2/bzlib_private.h | 509 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore | 61 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore.1 | 152 + .../source/Irrlicht/bzip2/crctable.c | 104 + .../source/Irrlicht/bzip2/decompress.c | 646 ++ .../irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.c | 175 + .../source/Irrlicht/bzip2/dlltest.dsp | 93 + .../source/Irrlicht/bzip2/entities.xml | 9 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/format.pl | 68 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/huffman.c | 205 + .../source/Irrlicht/bzip2/libbz2.def | 27 + .../source/Irrlicht/bzip2/libbz2.dsp | 130 + .../source/Irrlicht/bzip2/makefile.msc | 63 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/mk251.c | 31 + .../source/Irrlicht/bzip2/randtable.c | 84 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/spewG.c | 54 + .../source/Irrlicht/bzip2/unzcrash.c | 141 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/words0 | 9 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/words1 | 4 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/words2 | 5 + .../irrlicht-1.8.1/source/Irrlicht/bzip2/words3 | 30 + .../source/Irrlicht/bzip2/xmlproc.sh | 114 + .../irrlicht-1.8.1/source/Irrlicht/dmfsupport.h | 732 ++ src/others/irrlicht-1.8.1/source/Irrlicht/glext.h | 11488 +++++++++++++++++++ src/others/irrlicht-1.8.1/source/Irrlicht/glxext.h | 993 ++ .../irrlicht-1.8.1/source/Irrlicht/irrXML.cpp | 180 + .../irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.c | 999 ++ .../irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.h | 231 + .../irrlicht-1.8.1/source/Irrlicht/lzma/Types.h | 254 + src/others/irrlicht-1.8.1/source/Irrlicht/os.cpp | 347 + src/others/irrlicht-1.8.1/source/Irrlicht/os.h | 131 + .../irrlicht-1.8.1/source/Irrlicht/resource.h | 14 + .../irrlicht-1.8.1/source/Irrlicht/source.txt | 40 + src/others/irrlicht-1.8.1/source/Irrlicht/wglext.h | 929 ++ 566 files changed, 240099 insertions(+) create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/BuiltInFont.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAttributeImpl.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CB3DMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CB3DMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBlit.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CBurningShader_Raster_Reference.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8MaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9MaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultGUIElementFactory.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultGUIElementFactory.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultGUIElementFactory.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultSceneNodeAnimatorFactory.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultSceneNodeAnimatorFactory.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultSceneNodeFactory.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultSceneNodeFactory.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.d create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImage.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImage.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DHelper.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COgreMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COgreMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkinnedMesh.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkinnedMesh.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftware2MaterialRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlatWire.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlpha2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudWire.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRNormalMap.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRStencilShadow.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureBlend.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureDetailMap2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlat.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlpha.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudWire.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_Add.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M1.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureWire2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainTriangleSelector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainTriangleSelector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTimer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CVideoModeList.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CVideoModeList.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReaderImpl.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/IAttribute.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/IDepthBuffer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/IImagePresenter.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/ISceneNodeAnimatorFinishing.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/ITriangleRenderer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/IZBuffer.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht-gcc.cbp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.aps create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.dev create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.rc create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.sln create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj.filters create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.sln create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj.filters create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.sln create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.vcproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.sln create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.vcproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.sln create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.vcproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.sln create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.vcproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/._MainMenu.nib create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.mm create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/DemoApp-Info.plist create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/Irrlicht-Info.plist create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX_Prefix.pch create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/classes.nib create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/info.nib create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.mm create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/irrFramework-Info.plist create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Makefile create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/Octree.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/S2DVertex.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/S4DVertex.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/SConstruct create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_compile_config.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/Readme.txt create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aes.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aescrypt.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aeskey.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aesopt.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aestab.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/builtInFont.bmp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/CHANGES create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/LICENSE create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile-libbz2_so create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.COMPILATION.PROBLEMS create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.XML.STUFF create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/blocksort.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-common.xsl create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-fo.xsl create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-html.xsl create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzcompress.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff.1 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep.1 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip.css create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1.preformatted create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.txt create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2recover.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib_private.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore.1 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/crctable.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/decompress.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.dsp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/entities.xml create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/format.pl create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/huffman.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.def create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.dsp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/makefile.msc create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/mk251.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/randtable.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/spewG.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/unzcrash.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words0 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words1 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words2 create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words3 create mode 100755 src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/xmlproc.sh create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/dmfsupport.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/glext.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/glxext.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/irrXML.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.c create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/lzma/Types.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/os.cpp create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/os.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/resource.h create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/source.txt create mode 100644 src/others/irrlicht-1.8.1/source/Irrlicht/wglext.h (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht') diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/BuiltInFont.h b/src/others/irrlicht-1.8.1/source/Irrlicht/BuiltInFont.h new file mode 100644 index 0000000..da7a931 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/BuiltInFont.h @@ -0,0 +1,1075 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __BUILD_IN_FONT_H_INCLUDED__ +#define __BUILD_IN_FONT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +// header file generated by Bin2H, copyright 2002 by N.Gebhardt. +// Bin2H is Freeware. Download it freely from www.code3d.com. +// for the source bitmap, see builtInFont.bmp + +namespace irr +{ +namespace gui +{ +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ +u8 BuiltInFontData[] = +{ + 0x42, 0x4d, 0x4a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x63, 0x0b, + 0x00, 0x00, 0x63, 0x0b, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, + 0x18, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x22, 0x44, 0x42, 0x04, + 0x44, 0x44, 0x02, 0x04, 0x44, 0x44, 0x40, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x04, + 0x40, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x40, 0x40, 0x22, 0x20, 0x00, 0x02, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x04, + 0x40, 0x02, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, + 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x42, 0x24, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x24, 0x42, + 0x22, 0x24, 0x42, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x42, 0x44, 0x22, 0x44, + 0x42, 0x22, 0x22, 0x44, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x24, + 0x42, 0x44, 0x22, 0x22, 0x44, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x42, 0x24, 0x42, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x44, 0x42, 0x24, 0x42, + 0x44, 0x22, 0x22, 0x24, 0x42, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x44, 0x22, 0x24, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, + 0x44, 0x44, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, + 0x42, 0x44, 0x42, 0x24, 0x44, 0x44, 0x22, 0x24, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x42, 0x22, 0x44, 0x22, 0x44, 0x22, 0x24, + 0x42, 0x24, 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x24, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x42, 0x22, 0x44, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x44, 0x44, 0x24, 0x42, 0x44, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x42, 0x22, 0x42, 0x22, + 0x44, 0x44, 0x24, 0x42, 0x24, 0x42, 0x22, 0x22, + 0x44, 0x22, 0x44, 0x24, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x44, 0x44, 0x24, 0x22, 0x24, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x24, 0x44, 0x44, 0x44, 0x22, 0x44, + 0x42, 0x44, 0x42, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x44, 0x44, 0x22, 0x44, 0x22, 0x44, 0x22, 0x24, + 0x42, 0x24, 0x42, 0x24, 0x42, 0x44, 0x22, 0x44, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x42, 0x44, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x42, 0x22, 0x24, 0x42, 0x24, 0x42, 0x44, + 0x22, 0x44, 0x22, 0x22, 0x44, 0x42, 0x24, 0x42, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x24, 0x42, + 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, 0x24, 0x24, + 0x44, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, + 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x21, 0x22, 0x12, 0x22, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x44, 0x22, 0x24, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, + 0x42, 0x22, 0x42, 0x42, 0x22, 0x44, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x44, 0x42, + 0x22, 0x24, 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x22, 0x24, 0x42, 0x22, + 0x24, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, 0x24, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, + 0x42, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x44, 0x22, 0x42, 0x44, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x42, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x24, 0x24, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x42, 0x42, 0x22, 0x44, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, + 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x42, 0x24, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x44, 0x44, 0x44, + 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x32, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x44, 0x22, 0x22, + 0x44, 0x42, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, + 0x42, 0x22, 0x24, 0x44, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x22, 0x44, 0x22, 0x44, 0x44, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, 0x22, 0x44, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x24, 0x22, 0x44, 0x22, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x44, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x24, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x44, + 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x42, 0x24, 0x22, 0x22, 0x42, 0x42, 0x24, 0x24, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x24, 0x22, 0x44, 0x42, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x22, 0x44, 0x22, 0x24, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x42, 0x22, 0x44, 0x24, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x42, 0x24, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, + 0x22, 0x44, 0x42, 0x22, 0x42, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x42, 0x24, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x42, 0x24, 0x42, + 0x22, 0x42, 0x42, 0x24, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x22, 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x32, 0x24, 0x24, 0x23, 0x24, 0x24, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, + 0x42, 0x22, 0x23, 0x22, 0x24, 0x22, 0x32, 0x24, + 0x22, 0x23, 0x24, 0x24, 0x22, 0x32, 0x22, 0x42, + 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x24, 0x22, 0x42, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x24, 0x44, 0x42, 0x24, 0x44, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, + 0x44, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x24, 0x44, 0x44, 0x22, 0x44, 0x44, + 0x42, 0x24, 0x44, 0x44, 0x22, 0x44, 0x44, 0x42, + 0x24, 0x44, 0x44, 0x22, 0x44, 0x44, 0x22, 0x22, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, 0x22, + 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x44, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x24, 0x22, + 0x22, 0x42, 0x42, 0x22, 0x22, 0x44, 0x44, 0x42, + 0x24, 0x22, 0x22, 0x24, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x24, 0x44, 0x42, 0x24, 0x44, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x24, 0x44, + 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x42, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x22, 0x24, 0x44, 0x42, 0x24, 0x44, + 0x42, 0x24, 0x44, 0x42, 0x24, 0x44, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x22, 0x44, 0x42, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x24, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x42, 0x23, 0x22, 0x42, + 0x22, 0x32, 0x24, 0x24, 0x23, 0x24, 0x24, 0x22, + 0x32, 0x24, 0x22, 0x23, 0x22, 0x22, 0x22, 0x22, + 0x32, 0x22, 0x22, 0x32, 0x42, 0x22, 0x32, 0x24, + 0x22, 0x32, 0x24, 0x22, 0x34, 0x22, 0x42, 0x32, + 0x23, 0x24, 0x23, 0x42, 0x23, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x32, 0x24, 0x24, 0x23, 0x24, 0x22, + 0x22, 0x32, 0x22, 0x42, 0x23, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x12, 0x21, 0x22, 0x22, 0x12, 0x21, 0x22, + 0x12, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x21, 0x22, 0x21, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x42, 0x42, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x42, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x44, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x44, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x24, 0x22, 0x24, 0x24, 0x42, 0x22, 0x42, 0x44, + 0x22, 0x24, 0x24, 0x42, 0x22, 0x42, 0x22, 0x44, + 0x44, 0x42, 0x24, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x42, 0x22, 0x42, 0x42, 0x24, + 0x44, 0x42, 0x24, 0x22, 0x42, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x42, + 0x42, 0x22, 0x22, 0x42, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x42, 0x22, 0x24, + 0x24, 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x42, + 0x42, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x42, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, + 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x24, 0x22, 0x24, 0x24, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, + 0x22, 0x44, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x42, 0x24, 0x24, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x44, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x32, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x22, 0x22, 0x32, + 0x22, 0x23, 0x22, 0x32, 0x22, 0x23, 0x22, 0x32, + 0x23, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x32, 0x22, 0x32, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x23, 0x24, + 0x22, 0x22, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, + 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, + 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, + 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, + 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, + 0x21, 0x22, 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, + 0x12, 0x21, 0x22, 0x12, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x44, 0x22, + 0x24, 0x44, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x24, 0x22, 0x22, 0x42, 0x42, 0x24, 0x44, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, + 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, + 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, + 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, + 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, + 0x22, 0x32, 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, + 0x23, 0x22, 0x32, 0x23, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x12, 0x22, + 0x22, 0x12, 0x22, 0x21, 0x22, 0x12, 0x21, 0x22, + 0x22, 0x12, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x12, 0x21, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x44, 0x22, 0x42, 0x22, 0x24, + 0x44, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x42, 0x22, 0x44, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x44, 0x42, 0x24, 0x22, 0x24, 0x42, 0x22, 0x24, + 0x22, 0x24, 0x42, 0x22, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x24, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x24, 0x22, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x42, 0x22, 0x42, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x42, 0x24, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x24, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x42, 0x22, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x42, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x42, 0x22, 0x42, 0x22, 0x42, 0x42, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, 0x22, 0x24, + 0x44, 0x22, 0x44, 0x22, 0x24, 0x22, 0x42, 0x24, + 0x24, 0x22, 0x42, 0x24, 0x44, 0x42, 0x22, 0x44, + 0x22, 0x22, 0x44, 0x22, 0x24, 0x44, 0x22, 0x22, + 0x44, 0x42, 0x24, 0x42, 0x22, 0x44, 0x22, 0x44, + 0x22, 0x42, 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, + 0x42, 0x24, 0x24, 0x22, 0x42, 0x42, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x32, 0x23, 0x22, 0x32, + 0x22, 0x23, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x22, 0x32, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x32, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, + 0x22, 0x12, 0x22, 0x12, 0x22, 0x12, 0x22, 0x21, + 0x22, 0x22, 0x21, 0x22, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x44, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x44, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x44, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x22, 0x44, 0x44, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, + 0x44, 0x42, 0x22, 0x24, 0x42, 0x22, 0x44, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x24, 0x22, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x44, 0x22, 0x24, 0x24, 0x24, + 0x22, 0x44, 0x44, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x22, 0x42, 0x22, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x42, 0x22, + 0x44, 0x42, 0x22, 0x24, 0x42, 0x22, 0x44, 0x42, + 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x22, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x24, + 0x22, 0x22, 0x42, 0x42, 0x22, 0x22, 0x24, 0x22, + 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, 0x42, + 0x22, 0x44, 0x44, 0x22, 0x22, 0x44, 0x22, 0x44, + 0x44, 0x42, 0x24, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x22, 0x24, 0x22, 0x42, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x22, 0x44, 0x44, 0x22, + 0x44, 0x22, 0x42, 0x22, 0x44, 0x22, 0x24, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x22, 0x23, 0x22, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0x22, + 0x32, 0x22, 0x22, 0x32, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, + 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x12, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x21, 0x22, 0x12, 0x22, + 0x21, 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x12, 0x22, + 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, 0x44, + 0x42, 0x22, 0x24, 0x44, 0x22, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x44, 0x22, 0x42, 0x22, 0x22, 0x24, + 0x44, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x44, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x44, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x44, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, + 0x44, 0x42, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x42, 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x24, 0x22, 0x42, 0x24, 0x22, 0x44, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x42, 0x22, 0x42, 0x22, 0x24, 0x24, + 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x24, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x24, 0x22, 0x24, 0x44, + 0x22, 0x24, 0x22, 0x22, 0x24, 0x22, 0x24, 0x22, + 0x42, 0x24, 0x22, 0x24, 0x24, 0x22, 0x24, 0x44, + 0x42, 0x22, 0x42, 0x22, 0x22, 0x24, 0x22, 0x24, + 0x22, 0x44, 0x42, 0x22, 0x44, 0x42, 0x22, 0x42, + 0x22, 0x22, 0x24, 0x44, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x42, 0x22, 0x24, 0x22, 0x22, 0x42, + 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, + 0x22, 0x42, 0x22, 0x24, 0x22, 0x42, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x24, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x24, 0x22, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x24, 0x42, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x44, 0x22, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x42, 0x22, 0x24, 0x44, + 0x42, 0x22, 0x24, 0x44, 0x22, 0x24, 0x44, 0x42, + 0x22, 0x44, 0x44, 0x22, 0x44, 0x44, 0x22, 0x24, + 0x44, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, 0x22, 0x44, + 0x22, 0x24, 0x42, 0x24, 0x42, 0x24, 0x22, 0x24, + 0x44, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x32, 0x23, 0x22, 0x22, 0x32, 0x22, + 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, + 0x22, 0x23, 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x32, 0x22, 0x22, 0x32, 0x23, 0x22, + 0x22, 0x32, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x12, 0x21, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x21, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x12, 0x22, 0x22, 0x12, 0x21, 0x22, 0x21, 0x22, + 0x21, 0x22, 0x21, 0x22, 0x22, 0x12, 0x21, 0x22, + 0x21, 0x22, 0x12, 0x22, 0x12, 0x22, 0x22, 0x12, + 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, + 0x22, 0x22, 0x12, 0x22, 0x21, 0x22, 0x22, 0x21, + 0x22, 0x22, 0x12, 0x22, 0x22, 0x12, 0x22, 0x22, + 0x12, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x24, 0x24, 0x22, 0x24, 0x44, 0x22, 0x22, 0x44, + 0x22, 0x24, 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x22, 0x24, 0x42, 0x22, + 0x24, 0x22, 0x44, 0x44, 0x22, 0x24, 0x42, 0x22, + 0x22, 0x42, 0x22, 0x44, 0x22, 0x22, 0x44, 0x22, + 0x22, 0x42, 0x22, 0x24, 0x42, 0x22, 0x24, 0x42, + 0x22, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x44, 0x44, 0x42, 0x22, 0x44, 0x22, 0x42, 0x44, + 0x22, 0x42, 0x42, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, + 0x44, 0x44, 0x22, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x24, 0x24, 0x22, 0x22, 0x42, 0x22, 0x24, 0x22, + 0x22, 0x42, 0x44, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x24, 0x44, 0x22, 0x22, 0x24, + 0x42, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x24, 0x42, 0x22, 0x22, 0x24, 0x22, + 0x42, 0x42, 0x22, 0x22, 0x42, 0x24, 0x22, 0x42, + 0x22, 0x42, 0x22, 0x42, 0x24, 0x22, 0x22, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x24, 0x24, 0x22, 0x24, 0x42, 0x22, 0x22, 0x42, + 0x22, 0x24, 0x22, 0x22, 0x22, 0x24, 0x22, 0x22, + 0x42, 0x22, 0x22, 0x22, 0x42, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x22, 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, + 0x24, 0x42, 0x22, 0x44, 0x22, 0x24, 0x44, 0x22, + 0x22, 0x42, 0x22, 0x24, 0x42, 0x22, 0x24, 0x44, + 0x22, 0x42, 0x22, 0x22, 0x42, 0x24, 0x24, 0x22, + 0x44, 0x44, 0x42, 0x24, 0x44, 0x22, 0x44, 0x24, + 0x22, 0x42, 0x42, 0x22, 0x42, 0x24, 0x22, 0x22, + 0x42, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x44, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, 0x22, + 0x24, 0x42, 0x22, 0x42, 0x22, 0x24, 0x22, 0x22, + 0x22, 0x24, 0x22, 0x42, 0x24, 0x22, 0x42, 0x24, + 0x22, 0x22, 0x22, 0x22, 0x42, 0x24, 0x24, 0x22, + 0x24, 0x24, 0x22, 0x22, 0x42, 0x22, 0x44, 0x22, + 0x22, 0x24, 0x22, 0x22, 0x42, 0x22, 0x42, 0x24, + 0x22, 0x24, 0x42, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x24, 0x22, 0x24, 0x42, 0x22, + 0x24, 0x22, 0x24, 0x42, 0x22, 0x24, 0x42, 0x22, + 0x22, 0x42, 0x22, 0x44, 0x42, 0x22, 0x44, 0x22, + 0x24, 0x44, 0x22, 0x24, 0x42, 0x22, 0x24, 0x42, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x31, 0x23, 0x22, 0x32, 0x22, 0x23, + 0x22, 0x22, 0x22, 0x32, 0x22, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x22, 0x32, 0x22, 0x32, + 0x22, 0x32, 0x22, 0x32, 0x22, 0x23, 0x22, 0x32, + 0x22, 0x32, 0x23, 0x22, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x32, 0x22, 0x22, + 0x32, 0x22, 0x23, 0x22, 0x22, 0x23, 0x22, 0x22, + 0x23, 0x22 +}; + + u32 BuiltInFontDataSize = sizeof(BuiltInFontData); + +#else // !defined(_IRR_COMPILE_WITH_BMP_LOADER_) + + // built-in font cannot be loaded if there is no BMP loader + + u8* BuiltInFontData=0; + + u32 BuiltInFontDataSize = 0; + +#endif +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.cpp new file mode 100644 index 0000000..65d3117 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.cpp @@ -0,0 +1,1396 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_3DS_LOADER_ + +#include "C3DSMeshFileLoader.h" +#include "os.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "IVideoDriver.h" +#include "IMeshManipulator.h" + +#ifdef _DEBUG +#define _IRR_DEBUG_3DS_LOADER_ +#endif + +namespace irr +{ +namespace scene +{ + + +namespace +{ +enum e3DSChunk +{ + // Primary chunk + C3DS_MAIN3DS = 0x4D4D, + + // Main Chunks + C3DS_EDIT3DS = 0x3D3D, + C3DS_KEYF3DS = 0xB000, + C3DS_VERSION = 0x0002, + C3DS_MESHVERSION = 0x3D3E, + + // sub chunks of C3DS_EDIT3DS + C3DS_EDIT_MATERIAL = 0xAFFF, + C3DS_EDIT_OBJECT = 0x4000, + + // sub chunks of C3DS_EDIT_MATERIAL + C3DS_MATNAME = 0xA000, + C3DS_MATAMBIENT = 0xA010, + C3DS_MATDIFFUSE = 0xA020, + C3DS_MATSPECULAR = 0xA030, + C3DS_MATSHININESS = 0xA040, + C3DS_MATSHIN2PCT = 0xA041, + C3DS_TRANSPARENCY = 0xA050, + C3DS_TRANSPARENCY_FALLOFF = 0xA052, + C3DS_REFL_BLUR = 0xA053, + C3DS_TWO_SIDE = 0xA081, + C3DS_WIRE = 0xA085, + C3DS_SHADING = 0xA100, + C3DS_MATTEXMAP = 0xA200, + C3DS_MATSPECMAP = 0xA204, + C3DS_MATOPACMAP = 0xA210, + C3DS_MATREFLMAP = 0xA220, + C3DS_MATBUMPMAP = 0xA230, + C3DS_MATMAPFILE = 0xA300, + C3DS_MAT_TEXTILING = 0xA351, + C3DS_MAT_USCALE = 0xA354, + C3DS_MAT_VSCALE = 0xA356, + C3DS_MAT_UOFFSET = 0xA358, + C3DS_MAT_VOFFSET = 0xA35A, + + // subs of C3DS_EDIT_OBJECT + C3DS_OBJTRIMESH = 0x4100, + + // subs of C3DS_OBJTRIMESH + C3DS_TRIVERT = 0x4110, + C3DS_POINTFLAGARRAY= 0x4111, + C3DS_TRIFACE = 0x4120, + C3DS_TRIFACEMAT = 0x4130, + C3DS_TRIUV = 0x4140, + C3DS_TRISMOOTH = 0x4150, + C3DS_TRIMATRIX = 0x4160, + C3DS_MESHCOLOR = 0x4165, + C3DS_DIRECT_LIGHT = 0x4600, + C3DS_DL_INNER_RANGE= 0x4659, + C3DS_DL_OUTER_RANGE= 0x465A, + C3DS_DL_MULTIPLIER = 0x465B, + C3DS_CAMERA = 0x4700, + C3DS_CAM_SEE_CONE = 0x4710, + C3DS_CAM_RANGES = 0x4720, + + // subs of C3DS_KEYF3DS + C3DS_KF_HDR = 0xB00A, + C3DS_AMBIENT_TAG = 0xB001, + C3DS_OBJECT_TAG = 0xB002, + C3DS_CAMERA_TAG = 0xB003, + C3DS_TARGET_TAG = 0xB004, + C3DS_LIGHTNODE_TAG = 0xB005, + C3DS_KF_SEG = 0xB008, + C3DS_KF_CURTIME = 0xB009, + C3DS_KF_NODE_HDR = 0xB010, + C3DS_PIVOTPOINT = 0xB013, + C3DS_BOUNDBOX = 0xB014, + C3DS_MORPH_SMOOTH = 0xB015, + C3DS_POS_TRACK_TAG = 0xB020, + C3DS_ROT_TRACK_TAG = 0xB021, + C3DS_SCL_TRACK_TAG = 0xB022, + C3DS_NODE_ID = 0xB030, + + // Viewport definitions + C3DS_VIEWPORT_LAYOUT = 0x7001, + C3DS_VIEWPORT_DATA = 0x7011, + C3DS_VIEWPORT_DATA_3 = 0x7012, + C3DS_VIEWPORT_SIZE = 0x7020, + + // different color chunk types + C3DS_COL_RGB = 0x0010, + C3DS_COL_TRU = 0x0011, + C3DS_COL_LIN_24 = 0x0012, + C3DS_COL_LIN_F = 0x0013, + + // percentage chunk types + C3DS_PERCENTAGE_I = 0x0030, + C3DS_PERCENTAGE_F = 0x0031, + + C3DS_CHUNK_MAX = 0xFFFF +}; +} + + +//! Constructor +C3DSMeshFileLoader::C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs) +: SceneManager(smgr), FileSystem(fs), Vertices(0), Indices(0), SmoothingGroups(0), TCoords(0), + CountVertices(0), CountFaces(0), CountTCoords(0), Mesh(0) +{ + + #ifdef _DEBUG + setDebugName("C3DSMeshFileLoader"); + #endif + + if (FileSystem) + FileSystem->grab(); +} + + +//! destructor +C3DSMeshFileLoader::~C3DSMeshFileLoader() +{ + cleanUp(); + + if (FileSystem) + FileSystem->drop(); + + if (Mesh) + Mesh->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool C3DSMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "3ds" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* C3DSMeshFileLoader::createMesh(io::IReadFile* file) +{ + ChunkData data; + + readChunkData(file, data); + + if (data.header.id != C3DS_MAIN3DS ) + return 0; + + CurrentMaterial.clear(); + Materials.clear(); + MeshBufferNames.clear(); + cleanUp(); + + if (Mesh) + Mesh->drop(); + + Mesh = new SMesh(); + + if (readChunk(file, &data)) + { + // success + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + SMeshBuffer* mb = ((SMeshBuffer*)Mesh->getMeshBuffer(i)); + // drop empty buffers + if (mb->getIndexCount() == 0 || mb->getVertexCount() == 0) + { + Mesh->MeshBuffers.erase(i--); + mb->drop(); + } + else + { + if (mb->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID) + { + SMesh tmp; + tmp.addMeshBuffer(mb); + mb->drop(); + IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp); + Mesh->MeshBuffers[i]=tangentMesh->getMeshBuffer(0); + // we need to grab because we replace the buffer manually. + Mesh->MeshBuffers[i]->grab(); + // clean up intermediate mesh struct + tangentMesh->drop(); + } + Mesh->MeshBuffers[i]->recalculateBoundingBox(); + } + } + + Mesh->recalculateBoundingBox(); + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + return am; + } + + Mesh->drop(); + Mesh = 0; + + return 0; +} + + +bool C3DSMeshFileLoader::readPercentageChunk(io::IReadFile* file, + ChunkData* chunk, f32& percentage) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load percentage chunk.", ELL_DEBUG); +#endif + + ChunkData data; + readChunkData(file, data); + + short intpercentage; + float fpercentage; + + switch(data.header.id) + { + case C3DS_PERCENTAGE_I: + { + // read short + file->read(&intpercentage, 2); +#ifdef __BIG_ENDIAN__ + intpercentage = os::Byteswap::byteswap(intpercentage); +#endif + percentage=intpercentage/100.0f; + data.read += 2; + } + break; + case C3DS_PERCENTAGE_F: + { + // read float + file->read(&fpercentage, sizeof(float)); + data.read += sizeof(float); +#ifdef __BIG_ENDIAN__ + percentage = os::Byteswap::byteswap(fpercentage); +#else + percentage = (f32)fpercentage; +#endif + } + break; + default: + { + // unknown percentage chunk + os::Printer::log("Unknown percentage chunk in 3Ds file.", ELL_WARNING); + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + } + + chunk->read += data.read; + + return true; +} + +bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk, + video::SColor& out) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load color chunk.", ELL_DEBUG); +#endif + ChunkData data; + readChunkData(file, data); + + u8 c[3]; + f32 cf[3]; + + switch(data.header.id) + { + case C3DS_COL_TRU: + case C3DS_COL_LIN_24: + { + // read 8 bit data + file->read(c, sizeof(c)); + out.set(255, c[0], c[1], c[2]); + data.read += sizeof(c); + } + break; + case C3DS_COL_RGB: + case C3DS_COL_LIN_F: + { + // read float data + file->read(cf, sizeof(cf)); +#ifdef __BIG_ENDIAN__ + cf[0] = os::Byteswap::byteswap(cf[0]); + cf[1] = os::Byteswap::byteswap(cf[1]); + cf[2] = os::Byteswap::byteswap(cf[2]); +#endif + out.set(255, (s32)(cf[0]*255.0f), (s32)(cf[1]*255.0f), (s32)(cf[2]*255.0f)); + data.read += sizeof(cf); + } + break; + default: + { + // unknown color chunk size + os::Printer::log("Unknown size of color chunk in 3Ds file.", ELL_WARNING); + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + } + + chunk->read += data.read; + + return true; +} + + +bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load material chunk.", ELL_DEBUG); +#endif + u16 matSection=0; + + while(parent->read < parent->header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_MATNAME: + { + c8* c = new c8[data.header.length - data.read]; + file->read(c, data.header.length - data.read); + + if (strlen(c)) + CurrentMaterial.Name = c; + + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_MATAMBIENT: + readColorChunk(file, &data, CurrentMaterial.Material.AmbientColor); + break; + case C3DS_MATDIFFUSE: + readColorChunk(file, &data, CurrentMaterial.Material.DiffuseColor); + break; + case C3DS_MATSPECULAR: + readColorChunk(file, &data, CurrentMaterial.Material.SpecularColor); + break; + case C3DS_MATSHININESS: + readPercentageChunk(file, &data, CurrentMaterial.Material.Shininess); + CurrentMaterial.Material.Shininess = (1.f-CurrentMaterial.Material.Shininess)*128.f; + break; + case C3DS_TRANSPARENCY: + { + f32 percentage; + readPercentageChunk(file, &data, percentage); + if (percentage>0.0f) + { + CurrentMaterial.Material.MaterialTypeParam=percentage; + CurrentMaterial.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + else + { + CurrentMaterial.Material.MaterialType=video::EMT_SOLID; + } + } + break; + case C3DS_WIRE: + CurrentMaterial.Material.Wireframe=true; + break; + case C3DS_TWO_SIDE: + CurrentMaterial.Material.BackfaceCulling=false; + break; + case C3DS_SHADING: + { + s16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + switch (flags) + { + case 0: + CurrentMaterial.Material.Wireframe=true; + break; + case 1: + CurrentMaterial.Material.Wireframe=false; + CurrentMaterial.Material.GouraudShading=false; + break; + case 2: + CurrentMaterial.Material.Wireframe=false; + CurrentMaterial.Material.GouraudShading=true; + break; + default: + // phong and metal missing + break; + } + data.read += data.header.length - data.read; + } + break; + case C3DS_MATTEXMAP: + case C3DS_MATSPECMAP: + case C3DS_MATOPACMAP: + case C3DS_MATREFLMAP: + case C3DS_MATBUMPMAP: + { + matSection=data.header.id; + // Should contain a percentage chunk, but does + // not always have it + s16 testval; + const long pos = file->getPos(); + file->read(&testval, 2); +#ifdef __BIG_ENDIAN__ + testval = os::Byteswap::byteswap(testval); +#endif + file->seek(pos, false); + if ((testval == C3DS_PERCENTAGE_I) || + (testval == C3DS_PERCENTAGE_F)) + switch (matSection) + { + case C3DS_MATTEXMAP: + readPercentageChunk(file, &data, CurrentMaterial.Strength[0]); + break; + case C3DS_MATSPECMAP: + readPercentageChunk(file, &data, CurrentMaterial.Strength[1]); + break; + case C3DS_MATOPACMAP: + readPercentageChunk(file, &data, CurrentMaterial.Strength[2]); + break; + case C3DS_MATBUMPMAP: + readPercentageChunk(file, &data, CurrentMaterial.Strength[4]); + break; + } + } + break; + case C3DS_MATMAPFILE: + { + // read texture file name + c8* c = new c8[data.header.length - data.read]; + file->read(c, data.header.length - data.read); + switch (matSection) + { + case C3DS_MATTEXMAP: + CurrentMaterial.Filename[0] = c; + break; + case C3DS_MATSPECMAP: + CurrentMaterial.Filename[1] = c; + break; + case C3DS_MATOPACMAP: + CurrentMaterial.Filename[2] = c; + break; + case C3DS_MATREFLMAP: + CurrentMaterial.Filename[3] = c; + break; + case C3DS_MATBUMPMAP: + CurrentMaterial.Filename[4] = c; + break; + } + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_MAT_TEXTILING: + { + s16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 2; + } + break; + case C3DS_MAT_USCALE: + case C3DS_MAT_VSCALE: + case C3DS_MAT_UOFFSET: + case C3DS_MAT_VOFFSET: + { + f32 value; + file->read(&value, 4); +#ifdef __BIG_ENDIAN__ + value = os::Byteswap::byteswap(value); +#endif + u32 i=0; + if (matSection != C3DS_MATTEXMAP) + i=1; + u32 j=0,k=0; + if (data.header.id == C3DS_MAT_VSCALE) + { + j=1; + k=1; + } + else if (data.header.id == C3DS_MAT_UOFFSET) + { + j=2; + k=0; + } + else if (data.header.id == C3DS_MAT_VOFFSET) + { + j=2; + k=1; + } + CurrentMaterial.Material.getTextureMatrix(i)(j,k)=value; + + data.read += 4; + } + break; + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + } + + Materials.push_back(CurrentMaterial); + CurrentMaterial.clear(); + + return true; +} + + + +bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data, + IMeshBuffer* mb, const core::vector3df& pivot) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load track chunk.", ELL_DEBUG); +#endif + u16 flags; + u32 flags2; + // Track flags + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + // Num keys + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + file->read(&flags2, 4); +#ifdef __BIG_ENDIAN__ + flags2 = os::Byteswap::byteswap(flags2); +#endif + // TCB flags + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 20; + + f32 angle=0.0f; + if (data.header.id== C3DS_ROT_TRACK_TAG) + { + // Angle + file->read(&angle, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + angle = os::Byteswap::byteswap(angle); +#endif + data.read += sizeof(f32); + } + core::vector3df vec; + file->read(&vec.X, sizeof(f32)); + file->read(&vec.Y, sizeof(f32)); + file->read(&vec.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + vec.X = os::Byteswap::byteswap(vec.X); + vec.Y = os::Byteswap::byteswap(vec.Y); + vec.Z = os::Byteswap::byteswap(vec.Z); +#endif + data.read += 12; + vec-=pivot; + + // apply transformation to mesh buffer + if (false)//mb) + { + video::S3DVertex *vertices=(video::S3DVertex*)mb->getVertices(); + if (data.header.id==C3DS_POS_TRACK_TAG) + { + for (u32 i=0; igetVertexCount(); ++i) + vertices[i].Pos+=vec; + } + else if (data.header.id==C3DS_ROT_TRACK_TAG) + { + //TODO + } + else if (data.header.id==C3DS_SCL_TRACK_TAG) + { + //TODO + } + } + // skip further frames + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + return true; +} + + +bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load frame chunk.", ELL_DEBUG); +#endif + ChunkData data; + + //KF_HDR is always at the beginning + readChunkData(file, data); + if (data.header.id != C3DS_KF_HDR) + return false; + else + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load keyframe header.", ELL_DEBUG); +#endif + u16 version; + file->read(&version, 2); +#ifdef __BIG_ENDIAN__ + version = os::Byteswap::byteswap(version); +#endif + core::stringc name; + readString(file, data, name); + u32 flags; + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + + data.read += 4; + parent->read += data.read; + } + data.read=0; + + IMeshBuffer* mb=0; + core::vector3df pivot,bboxCenter; + while(parent->read < parent->header.length) + { + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_OBJECT_TAG: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load object tag.", ELL_DEBUG); +#endif + mb=0; + pivot.set(0.0f, 0.0f, 0.0f); + } + break; + case C3DS_KF_SEG: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load keyframe segment.", ELL_DEBUG); +#endif + u32 flags; + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 8; + } + break; + case C3DS_KF_NODE_HDR: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load keyframe node header.", ELL_DEBUG); +#endif + s16 flags; + c8* c = new c8[data.header.length - data.read-6]; + file->read(c, data.header.length - data.read-6); + + // search mesh buffer to apply these transformations to + for (u32 i=0; igetMeshBuffer(i); + break; + } + } + + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += data.header.length - data.read; + delete [] c; + } + break; + case C3DS_KF_CURTIME: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load keyframe current time.", ELL_DEBUG); +#endif + u32 flags; + file->read(&flags, 4); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 4; + } + break; + case C3DS_NODE_ID: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load node ID.", ELL_DEBUG); +#endif + u16 flags; + file->read(&flags, 2); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + data.read += 2; + } + break; + case C3DS_PIVOTPOINT: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load pivot point.", ELL_DEBUG); +#endif + file->read(&pivot.X, sizeof(f32)); + file->read(&pivot.Y, sizeof(f32)); + file->read(&pivot.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + pivot.X = os::Byteswap::byteswap(pivot.X); + pivot.Y = os::Byteswap::byteswap(pivot.Y); + pivot.Z = os::Byteswap::byteswap(pivot.Z); +#endif + data.read += 12; + } + break; + case C3DS_BOUNDBOX: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load bounding box.", ELL_DEBUG); +#endif + core::aabbox3df bbox; + // abuse bboxCenter as temporary variable + file->read(&bboxCenter.X, sizeof(f32)); + file->read(&bboxCenter.Y, sizeof(f32)); + file->read(&bboxCenter.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X); + bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y); + bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z); +#endif + bbox.reset(bboxCenter); + file->read(&bboxCenter.X, sizeof(f32)); + file->read(&bboxCenter.Y, sizeof(f32)); + file->read(&bboxCenter.Z, sizeof(f32)); +#ifdef __BIG_ENDIAN__ + bboxCenter.X = os::Byteswap::byteswap(bboxCenter.X); + bboxCenter.Y = os::Byteswap::byteswap(bboxCenter.Y); + bboxCenter.Z = os::Byteswap::byteswap(bboxCenter.Z); +#endif + bbox.addInternalPoint(bboxCenter); + bboxCenter=bbox.getCenter(); + data.read += 24; + } + break; + case C3DS_MORPH_SMOOTH: + { +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load morph smooth.", ELL_DEBUG); +#endif + f32 flag; + file->read(&flag, 4); +#ifdef __BIG_ENDIAN__ + flag = os::Byteswap::byteswap(flag); +#endif + data.read += 4; + } + break; + case C3DS_POS_TRACK_TAG: + case C3DS_ROT_TRACK_TAG: + case C3DS_SCL_TRACK_TAG: + readTrackChunk(file, data, mb, bboxCenter-pivot); + break; + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + data.read=0; + } + + return true; +} + + +bool C3DSMeshFileLoader::readChunk(io::IReadFile* file, ChunkData* parent) +{ + while(parent->read < parent->header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_VERSION: + { + u16 version; + file->read(&version, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + version = os::Byteswap::byteswap(version); +#endif + file->seek(data.header.length - data.read - 2, true); + data.read += data.header.length - data.read; + if (version != 0x03) + os::Printer::log("3ds file version is other than 3.", ELL_ERROR); + } + break; + case C3DS_EDIT_MATERIAL: + readMaterialChunk(file, &data); + break; + case C3DS_KEYF3DS: + readFrameChunk(file, &data); + break; + case C3DS_EDIT3DS: + break; + case C3DS_MESHVERSION: + case 0x01: + { + u32 version; + file->read(&version, sizeof(u32)); +#ifdef __BIG_ENDIAN__ + version = os::Byteswap::byteswap(version); +#endif + data.read += sizeof(u32); + } + break; + case C3DS_EDIT_OBJECT: + { + core::stringc name; + readString(file, data, name); + readObjectChunk(file, &data); + composeObject(file, name); + } + break; + + default: + // ignore chunk + file->seek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + } + + return true; +} + + +bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load object chunk.", ELL_DEBUG); +#endif + while(parent->read < parent->header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case C3DS_OBJTRIMESH: + readObjectChunk(file, &data); + break; + + case C3DS_TRIVERT: + readVertices(file, data); + break; + + case C3DS_POINTFLAGARRAY: + { + u16 numVertex, flags; + file->read(&numVertex, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + numVertex= os::Byteswap::byteswap(numVertex); +#endif + for (u16 i=0; iread(&flags, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + } + data.read += (numVertex+1)*sizeof(u16); + } + break; + + case C3DS_TRIFACE: + readIndices(file, data); + readObjectChunk(file, &data); // read smooth and material groups + break; + + case C3DS_TRIFACEMAT: + readMaterialGroup(file, data); + break; + + case C3DS_TRIUV: // getting texture coordinates + readTextureCoords(file, data); + break; + + case C3DS_TRIMATRIX: + { + f32 mat[4][3]; + file->read(&mat, 12*sizeof(f32)); + TransformationMatrix.makeIdentity(); + for (int i=0; i<4; ++i) + { + for (int j=0; j<3; ++j) + { +#ifdef __BIG_ENDIAN__ + TransformationMatrix(i,j)=os::Byteswap::byteswap(mat[i][j]); +#else + TransformationMatrix(i,j)=mat[i][j]; +#endif + } + } + data.read += 12*sizeof(f32); + } + break; + case C3DS_MESHCOLOR: + { + u8 flag; + file->read(&flag, sizeof(u8)); + ++data.read; + } + break; + case C3DS_TRISMOOTH: // TODO + { + SmoothingGroups = new u32[CountFaces]; + file->read(SmoothingGroups, CountFaces*sizeof(u32)); +#ifdef __BIG_ENDIAN__ + for (u16 i=0; iseek(data.header.length - data.read, true); + data.read += data.header.length - data.read; + } + + parent->read += data.read; + } + + return true; +} + + +void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Compose object.", ELL_DEBUG); +#endif + if (Mesh->getMeshBufferCount() != Materials.size()) + loadMaterials(file); + + if (MaterialGroups.empty()) + { + // no material group, so add all + SMaterialGroup group; + group.faceCount = CountFaces; + group.faces = new u16[group.faceCount]; + for (u16 i=0; iaddMeshBuffer(mb); + mb->getMaterial() = Materials[0].Material; + mb->drop(); + // add an empty mesh buffer name + MeshBufferNames.push_back(""); + } + } + + for (u32 i=0; igetVideoDriver()->getMaximalPrimitiveCount(), (u32)((1<<16)-1))-3; // currently hardcoded s16 max value for index pointers + + // find mesh buffer for this group + for (mbPos=0; mbPosgetMeshBuffer(mbPos); + mat=&Materials[mbPos].Material; + MeshBufferNames[mbPos]=name; + break; + } + } + + if (mb != 0) + { + // add geometry to the buffer. + + video::S3DVertex vtx; + core::vector3df vec; + vtx.Color=mat->DiffuseColor; + if (mat->MaterialType==video::EMT_TRANSPARENT_VERTEX_ALPHA) + { + vtx.Color.setAlpha((int)(255.0f*mat->MaterialTypeParam)); + } + vtx.Normal.set(0,0,0); + + for (s32 f=0; fVertices.size(); + if (vtxCount>maxPrimitives) + { + IMeshBuffer* tmp = mb; + mb = new SMeshBuffer(); + Mesh->addMeshBuffer(mb); + mb->drop(); + Mesh->MeshBuffers[mbPos] = Mesh->MeshBuffers.getLast(); + Mesh->MeshBuffers[Mesh->MeshBuffers.size()-1] = tmp; + mb->getMaterial() = tmp->getMaterial(); + vtxCount=0; + } + + for (s32 v=0; v<3; ++v) + { + s32 idx = Indices[MaterialGroups[i].faces[f]*4 +v]; + + if (CountVertices > idx) + { + vtx.Pos.X = Vertices[idx*3 + 0]; + vtx.Pos.Z = Vertices[idx*3 + 1]; + vtx.Pos.Y = Vertices[idx*3 + 2]; +// TransformationMatrix.transformVect(vtx.Pos); + } + + if (CountTCoords > idx) + { + vtx.TCoords.X = TCoords[idx*2 + 0]; + vtx.TCoords.Y = 1.0f -TCoords[idx*2 + 1]; + } + + mb->Vertices.push_back(vtx); + } + + // compute normal + core::plane3d pl(mb->Vertices[vtxCount].Pos, mb->Vertices[vtxCount+2].Pos, + mb->Vertices[vtxCount+1].Pos); + + mb->Vertices[vtxCount].Normal = pl.Normal; + mb->Vertices[vtxCount+1].Normal = pl.Normal; + mb->Vertices[vtxCount+2].Normal = pl.Normal; + + // add indices + + mb->Indices.push_back(vtxCount); + mb->Indices.push_back(vtxCount+2); + mb->Indices.push_back(vtxCount+1); + } + } + else + os::Printer::log("Found no matching material for Group in 3ds file.", ELL_WARNING); + } + + cleanUp(); +} + + +void C3DSMeshFileLoader::loadMaterials(io::IReadFile* file) +{ + // create a mesh buffer for every material + core::stringc modelFilename = file->getFileName(); + + if (Materials.empty()) + os::Printer::log("No materials found in 3ds file.", ELL_INFORMATION); + + MeshBufferNames.reallocate(Materials.size()); + for (u32 i=0; iaddMeshBuffer(m); + + m->getMaterial() = Materials[i].Material; + if (Materials[i].Filename[0].size()) + { + video::ITexture* texture = 0; + if (FileSystem->existFile(Materials[i].Filename[0])) + texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[0]); + if (!texture) + { + const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[0]); + if (FileSystem->existFile(fname)) + texture = SceneManager->getVideoDriver()->getTexture(fname); + } + if (!texture) + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[0].c_str(), ELL_WARNING); + else + m->getMaterial().setTexture(0, texture); + } + + if (Materials[i].Filename[2].size()) + { + video::ITexture* texture = 0; + if (FileSystem->existFile(Materials[i].Filename[2])) + texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[2]); + if (!texture) + { + const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[2]); + if (FileSystem->existFile(fname)) + texture = SceneManager->getVideoDriver()->getTexture(fname); + } + if (!texture) + { + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[2].c_str(), ELL_WARNING); + } + else + { + m->getMaterial().setTexture(0, texture); + m->getMaterial().MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; + } + } + + if (Materials[i].Filename[3].size()) + { + video::ITexture* texture = 0; + if (FileSystem->existFile(Materials[i].Filename[3])) + texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[3]); + if (!texture) + { + const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[3]); + if (FileSystem->existFile(fname)) + texture = SceneManager->getVideoDriver()->getTexture(fname); + } + + if (!texture) + { + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[3].c_str(), ELL_WARNING); + } + else + { + m->getMaterial().setTexture(1, m->getMaterial().getTexture(0)); + m->getMaterial().setTexture(0, texture); + m->getMaterial().MaterialType = video::EMT_REFLECTION_2_LAYER; + } + } + + if (Materials[i].Filename[4].size()) + { + video::ITexture* texture = 0; + if (FileSystem->existFile(Materials[i].Filename[4])) + texture = SceneManager->getVideoDriver()->getTexture(Materials[i].Filename[4]); + if (!texture) + { + const core::stringc fname = FileSystem->getFileDir(modelFilename) + "/" + FileSystem->getFileBasename(Materials[i].Filename[4]); + if (FileSystem->existFile(fname)) + texture = SceneManager->getVideoDriver()->getTexture(fname); + } + if (!texture) + os::Printer::log("Could not load a texture for entry in 3ds file", + Materials[i].Filename[4].c_str(), ELL_WARNING); + else + { + m->getMaterial().setTexture(1, texture); + SceneManager->getVideoDriver()->makeNormalMapTexture(texture, Materials[i].Strength[4]*10.f); + m->getMaterial().MaterialType=video::EMT_PARALLAX_MAP_SOLID; + m->getMaterial().MaterialTypeParam=.035f; + } + } + + m->drop(); + } +} + + +void C3DSMeshFileLoader::cleanUp() +{ + delete [] Vertices; + CountVertices = 0; + Vertices = 0; + delete [] Indices; + Indices = 0; + CountFaces = 0; + delete [] SmoothingGroups; + SmoothingGroups = 0; + delete [] TCoords; + TCoords = 0; + CountTCoords = 0; + + MaterialGroups.clear(); +} + + +void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data) +{ +#ifdef _IRR_DEBUG_3DS_LOADER_ + os::Printer::log("Load texture coords.", ELL_DEBUG); +#endif + file->read(&CountTCoords, sizeof(CountTCoords)); +#ifdef __BIG_ENDIAN__ + CountTCoords = os::Byteswap::byteswap(CountTCoords); +#endif + data.read += sizeof(CountTCoords); + + s32 tcoordsBufferByteSize = CountTCoords * sizeof(f32) * 2; + + if (data.header.length - data.read != tcoordsBufferByteSize) + { + os::Printer::log("Invalid size of tcoords found in 3ds file.", ELL_WARNING); + return; + } + + TCoords = new f32[CountTCoords * 3]; + file->read(TCoords, tcoordsBufferByteSize); +#ifdef __BIG_ENDIAN__ + for (int i=0;iread(&group.faceCount, sizeof(group.faceCount)); +#ifdef __BIG_ENDIAN__ + group.faceCount = os::Byteswap::byteswap(group.faceCount); +#endif + data.read += sizeof(group.faceCount); + + // read faces + group.faces = new u16[group.faceCount]; + file->read(group.faces, sizeof(u16) * group.faceCount); +#ifdef __BIG_ENDIAN__ + for (u32 i=0;iread(&CountFaces, sizeof(CountFaces)); +#ifdef __BIG_ENDIAN__ + CountFaces = os::Byteswap::byteswap(CountFaces); +#endif + data.read += sizeof(CountFaces); + + s32 indexBufferByteSize = CountFaces * sizeof(u16) * 4; + + // Indices are u16s. + // After every 3 Indices in the array, there follows an edge flag. + Indices = new u16[CountFaces * 4]; + file->read(Indices, indexBufferByteSize); +#ifdef __BIG_ENDIAN__ + for (int i=0;iread(&CountVertices, sizeof(CountVertices)); +#ifdef __BIG_ENDIAN__ + CountVertices = os::Byteswap::byteswap(CountVertices); +#endif + data.read += sizeof(CountVertices); + + const s32 vertexBufferByteSize = CountVertices * sizeof(f32) * 3; + + if (data.header.length - data.read != vertexBufferByteSize) + { + os::Printer::log("Invalid size of vertices found in 3ds file", core::stringc(CountVertices), ELL_ERROR); + return; + } + + Vertices = new f32[CountVertices * 3]; + file->read(Vertices, vertexBufferByteSize); +#ifdef __BIG_ENDIAN__ + for (int i=0;iread(&data.header, sizeof(ChunkHeader)); +#ifdef __BIG_ENDIAN__ + data.header.id = os::Byteswap::byteswap(data.header.id); + data.header.length = os::Byteswap::byteswap(data.header.length); +#endif + data.read += sizeof(ChunkHeader); +} + + +void C3DSMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) +{ + c8 c = 1; + out = ""; + + while (c) + { + file->read(&c, sizeof(c8)); + if (c) + out.append(c); + } + data.read+=out.size()+1; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_3DS_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.h new file mode 100644 index 0000000..2219251 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/C3DSMeshFileLoader.h @@ -0,0 +1,166 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_3DS_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_3DS_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "ISceneManager.h" +#include "irrString.h" +#include "SMesh.h" +#include "matrix4.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading 3ds meshes. +class C3DSMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~C3DSMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + +// byte-align structures +#include "irrpack.h" + + struct ChunkHeader + { + u16 id; + s32 length; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + struct ChunkData + { + ChunkData() : read(0) {} + + ChunkHeader header; + s32 read; + }; + + struct SCurrentMaterial + { + void clear() { + Material=video::SMaterial(); + Name=""; + Filename[0]=""; + Filename[1]=""; + Filename[2]=""; + Filename[3]=""; + Filename[4]=""; + Strength[0]=0.f; + Strength[1]=0.f; + Strength[2]=0.f; + Strength[3]=0.f; + Strength[4]=0.f; + } + + video::SMaterial Material; + core::stringc Name; + core::stringc Filename[5]; + f32 Strength[5]; + }; + + struct SMaterialGroup + { + SMaterialGroup() : faceCount(0), faces(0) {}; + + SMaterialGroup(const SMaterialGroup& o) + { + *this = o; + } + + ~SMaterialGroup() + { + clear(); + } + + void clear() + { + delete [] faces; + faces = 0; + faceCount = 0; + } + + void operator =(const SMaterialGroup& o) + { + MaterialName = o.MaterialName; + faceCount = o.faceCount; + faces = new u16[faceCount]; + for (u16 i=0; i TempIndices; + f32* TCoords; + u16 CountVertices; + u16 CountFaces; // = CountIndices/4 + u16 CountTCoords; + core::array MaterialGroups; + + SCurrentMaterial CurrentMaterial; + core::array Materials; + core::array MeshBufferNames; + core::matrix4 TransformationMatrix; + + SMesh* Mesh; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.cpp new file mode 100644 index 0000000..6531e1a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.cpp @@ -0,0 +1,1695 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ + +#include "CAnimatedMeshHalfLife.h" +#include "os.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "coreutil.h" +#include "SMeshBuffer.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" + +namespace irr +{ +namespace scene +{ + + using namespace video; + + void AngleQuaternion(const core::vector3df& angles, vec4_hl quaternion) + { + f32 angle; + f32 sr, sp, sy, cr, cp, cy; + + // FIXME: rescale the inputs to 1/2 angle + angle = angles.Z * 0.5f; + sy = sin(angle); + cy = cos(angle); + angle = angles.Y * 0.5f; + sp = sin(angle); + cp = cos(angle); + angle = angles.X * 0.5f; + sr = sin(angle); + cr = cos(angle); + + quaternion[0] = sr*cp*cy-cr*sp*sy; // X + quaternion[1] = cr*sp*cy+sr*cp*sy; // Y + quaternion[2] = cr*cp*sy-sr*sp*cy; // Z + quaternion[3] = cr*cp*cy+sr*sp*sy; // W + } + + void QuaternionMatrix( const vec4_hl quaternion, f32 (*matrix)[4] ) + { + matrix[0][0] = 1.f - 2.f * quaternion[1] * quaternion[1] - 2.f * quaternion[2] * quaternion[2]; + matrix[1][0] = 2.f * quaternion[0] * quaternion[1] + 2.f * quaternion[3] * quaternion[2]; + matrix[2][0] = 2.f * quaternion[0] * quaternion[2] - 2.f * quaternion[3] * quaternion[1]; + + matrix[0][1] = 2.f * quaternion[0] * quaternion[1] - 2.f * quaternion[3] * quaternion[2]; + matrix[1][1] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[2] * quaternion[2]; + matrix[2][1] = 2.f * quaternion[1] * quaternion[2] + 2.f * quaternion[3] * quaternion[0]; + + matrix[0][2] = 2.f * quaternion[0] * quaternion[2] + 2.f * quaternion[3] * quaternion[1]; + matrix[1][2] = 2.f * quaternion[1] * quaternion[2] - 2.f * quaternion[3] * quaternion[0]; + matrix[2][2] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[1] * quaternion[1]; + } + + void QuaternionSlerp( const vec4_hl p, vec4_hl q, f32 t, vec4_hl qt ) + { + s32 i; + f32 omega, cosom, sinom, sclp, sclq; + + // decide if one of the quaternions is backwards + f32 a = 0; + f32 b = 0; + for (i = 0; i < 4; i++) { + a += (p[i]-q[i])*(p[i]-q[i]); + b += (p[i]+q[i])*(p[i]+q[i]); + } + if (a > b) { + for (i = 0; i < 4; i++) { + q[i] = -q[i]; + } + } + + cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; + + if ((1.f + cosom) > 0.00000001) { + if ((1.f - cosom) > 0.00000001) { + omega = acos( cosom ); + sinom = sin( omega ); + sclp = sin( (1.f - t)*omega) / sinom; + sclq = sin( t*omega ) / sinom; + } + else { + sclp = 1.f - t; + sclq = t; + } + for (i = 0; i < 4; i++) { + qt[i] = sclp * p[i] + sclq * q[i]; + } + } + else { + qt[0] = -p[1]; + qt[1] = p[0]; + qt[2] = -p[3]; + qt[3] = p[2]; + sclp = sin( (1.f - t) * 0.5f * core::PI); + sclq = sin( t * 0.5f * core::PI); + for (i = 0; i < 3; i++) { + qt[i] = sclp * p[i] + sclq * qt[i]; + } + } + } + + void R_ConcatTransforms (const f32 in1[3][4], const f32 in2[3][4], f32 out[3][4]) + { + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2]; + out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2]; + out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2]; + out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3]; + } + + #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) + + inline void VectorTransform(const vec3_hl in1, const f32 in2[3][4], core::vector3df& out) + { + out.X = DotProduct(in1, in2[0]) + in2[0][3]; + out.Z = DotProduct(in1, in2[1]) + in2[1][3]; + out.Y = DotProduct(in1, in2[2]) + in2[2][3]; + } + + static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix + + void getBoneVector ( core::vector3df &out, u32 index ) + { + out.X = BoneTransform[index][0][3]; + out.Z = BoneTransform[index][1][3]; + out.Y = BoneTransform[index][2][3]; + } + + void getBoneBox ( core::aabbox3df &box, u32 index, f32 size = 0.5f ) + { + box.MinEdge.X = BoneTransform[index][0][3] - size; + box.MinEdge.Z = BoneTransform[index][1][3] - size; + box.MinEdge.Y = BoneTransform[index][2][3] - size; + + size *= 2.f; + box.MaxEdge.X = box.MinEdge.X + size; + box.MaxEdge.Y = box.MinEdge.Y + size; + box.MaxEdge.Z = box.MinEdge.Z + size; + } + + void getTransformedBoneVector ( core::vector3df &out, u32 index, const vec3_hl in) + { + out.X = DotProduct(in, BoneTransform[index][0]) + BoneTransform[index][0][3]; + out.Z = DotProduct(in, BoneTransform[index][1]) + BoneTransform[index][1][3]; + out.Y = DotProduct(in, BoneTransform[index][2]) + BoneTransform[index][2][3]; + + } + + +//! Constructor +CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader( + scene::ISceneManager* smgr) : SceneManager(smgr) +{ +#ifdef _DEBUG + setDebugName("CHalflifeMDLMeshFileLoader"); +#endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CHalflifeMDLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension(filename, "mdl"); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CHalflifeMDLMeshFileLoader::createMesh(io::IReadFile* file) +{ + CAnimatedMeshHalfLife* msh = new CAnimatedMeshHalfLife(); + if (msh) + { + if (msh->loadModelFile(file, SceneManager)) + return msh; + msh->drop(); + } + + return 0; +} + + +//! Constructor +CAnimatedMeshHalfLife::CAnimatedMeshHalfLife() + : FrameCount(0), MeshIPol(0), SceneManager(0), Header(0), TextureHeader(0), + OwnTexModel(false), SequenceIndex(0), CurrentFrame(0), FramesPerSecond(25.f), + SkinGroupSelection(0) +#ifdef HL_TEXTURE_ATLAS + , TextureMaster(0) +#endif +{ +#ifdef _DEBUG + setDebugName("CAnimatedMeshHalfLife"); +#endif + initData(); +} + +/*! + loads a complete model +*/ +bool CAnimatedMeshHalfLife::loadModelFile(io::IReadFile* file, + ISceneManager* smgr) +{ + if (!file) + return false; + + SceneManager = smgr; + + if ( loadModel(file, file->getFileName()) ) + { + if ( postLoadModel ( file->getFileName() ) ) + { + initModel (); + //dumpModelInfo ( 1 ); + return true; + } + } + return false; +} + + +//! Destructor +CAnimatedMeshHalfLife::~CAnimatedMeshHalfLife() +{ + delete [] (u8*) Header; + if (OwnTexModel) + delete [] (u8*) TextureHeader; + + for (u32 i = 0; i < 32; ++i) + delete [] (u8*) AnimationHeader[i]; + + if (MeshIPol) + MeshIPol->drop(); +} + + +//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. +u32 CAnimatedMeshHalfLife::getFrameCount() const +{ + return FrameCount; +} + + +//! set the hardware mapping hint, for driver +void CAnimatedMeshHalfLife::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,E_BUFFER_TYPE buffer) +{ +} + + +//! flags the meshbuffer as changed, reloads hardware buffers +void CAnimatedMeshHalfLife::setDirty(E_BUFFER_TYPE buffer) +{ +} + + +static core::vector3df TransformedVerts[MAXSTUDIOVERTS]; // transformed vertices +//static core::vector3df TransformedNormals[MAXSTUDIOVERTS]; // light surface normals + + +/*! +*/ +void CAnimatedMeshHalfLife::initModel() +{ + // init Sequences to Animation + KeyFrameInterpolation ipol; + ipol.Name.reserve ( 64 ); + u32 i; + + AnimList.clear(); + FrameCount = 0; + + SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); + for ( i = 0; i < Header->numseq; i++) + { + ipol.Name = seq[i].label; + ipol.StartFrame = FrameCount; + ipol.Frames = core::max_ ( 1, seq[i].numframes - 1 ); + ipol.EndFrame = ipol.StartFrame + ipol.Frames - 1; + ipol.FramesPerSecond = seq[i].fps; + ipol.AnimationType = seq[i].flags & STUDIO_LOOPING ? EAMT_LOOPING : EAMT_WAYPOINT; + AnimList.push_back ( ipol ); + + FrameCount += ipol.Frames; + } + + // initBoneControllers +/* + SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); + for ( i = 0; i < Header->numbonecontrollers; i++) + { + printf ( "BoneController%d index:%d%s range:%f - %f\n", + i, + bonecontroller[i].index, bonecontroller[i].index == MOUTH_CONTROLLER ? " (Mouth)": "", + bonecontroller[i].start,bonecontroller[i].end + ); + } + + // initSkins + for (i = 0; i < TextureHeader->numskinfamilies; i++) + { + printf ( "Skin%d\n", i + 1); + } +*/ + + // initBodyparts + u32 meshBuffer = 0; + BodyList.clear(); + SHalflifeBody *body = (SHalflifeBody *) ((u8*) Header + Header->bodypartindex); + for (i=0; i < Header->numbodyparts; ++i) + { + BodyPart part; + part.name = body[i].name; + part.defaultModel = core::max_ ( 0, (s32) body[i].base - 1 ); + + SHalflifeModel * model = (SHalflifeModel *)((u8*) Header + body[i].modelindex); + for ( u32 g = 0; g < body[i].nummodels; ++g) + { + SubModel sub; + sub.name = model[g].name; + sub.startBuffer = meshBuffer; + sub.endBuffer = sub.startBuffer + model[g].nummesh; + sub.state = g == part.defaultModel; + part.model.push_back ( sub ); + meshBuffer += model[g].nummesh; + } + BodyList.push_back ( part ); + } + + SequenceIndex = 0; + CurrentFrame = 0.f; + + SetController(0, 0.f); + SetController(1, 0.f); + SetController(2, 0.f); + SetController(3, 0.f); + SetController(MOUTH_CONTROLLER, 0.f); + + SetSkin (0); + + // init Meshbuffers + const SHalflifeTexture *tex = (SHalflifeTexture *) ((u8*) TextureHeader + TextureHeader->textureindex); + const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); + if ((SkinGroupSelection != 0) && (SkinGroupSelection < TextureHeader->numskinfamilies)) + skinref += (SkinGroupSelection * TextureHeader->numskinref); + + core::vector2df tex_scale; + core::vector2di tex_trans ( 0, 0 ); + +#ifdef HL_TEXTURE_ATLAS + TextureAtlas.getScale(tex_scale); +#endif + + for (u32 bodypart=0 ; bodypart < Header->numbodyparts ; ++bodypart) + { + const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; + + for (u32 modelnr = 0; modelnr < body->nummodels; ++modelnr) + { + const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; +#if 0 + const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); + const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex); +#endif + for (i = 0; i < model->nummesh; ++i) + { + const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i; + const SHalflifeTexture *currentex = &tex[skinref[mesh->skinref]]; + +#ifdef HL_TEXTURE_ATLAS + TextureAtlas.getTranslation ( currentex->name, tex_trans ); +#else + tex_scale.X = 1.f/(f32)currentex->width; + tex_scale.Y = 1.f/(f32)currentex->height; +#endif + + SMeshBuffer * buffer = new SMeshBuffer(); + + // count index vertex size indexcount = mesh->numtris * 3 + u32 indexCount = 0; + u32 vertexCount = 0; + + const s16 *tricmd = (s16*)((u8*)Header + mesh->triindex); + s32 c; + while ( (c = *(tricmd++)) ) + { + if (c < 0) + c = -c; + + indexCount += ( c - 2 ) * 3; + vertexCount += c; + tricmd += ( 4 * c ); + } + + // indices + buffer->Indices.set_used ( indexCount ); + buffer->Vertices.set_used ( vertexCount ); + + // fill in static indices and vertex + u16 *index = buffer->Indices.pointer(); + video::S3DVertex * v = buffer->Vertices.pointer(); + + // blow up gl_triangle_fan/gl_triangle_strip to indexed triangle list + E_PRIMITIVE_TYPE type; + vertexCount = 0; + indexCount = 0; + tricmd = (s16*)((u8*)Header + mesh->triindex); + while ( (c = *(tricmd++)) ) + { + if (c < 0) + { + // triangle fan + c = -c; + type = EPT_TRIANGLE_FAN; + } + else + { + type = EPT_TRIANGLE_STRIP; + } + + for ( s32 g = 0; g < c; ++g, v += 1, tricmd += 4 ) + { + // fill vertex + #if 0 + const f32 *av = studioverts[tricmd[0]]; + v->Pos.X = av[0]; + v->Pos.Z = av[1]; + v->Pos.Y = av[2]; + + av = studionorms[tricmd[1]]; + v->Normal.X = av[0]; + v->Normal.Z = av[1]; + v->Normal.Y = av[2]; + + #endif + v->Normal.X = 0.f; + v->Normal.Z = 0.f; + v->Normal.Y = 1.f; + + v->TCoords.X = (tex_trans.X + tricmd[2])*tex_scale.X; + v->TCoords.Y = (tex_trans.Y + tricmd[3])*tex_scale.Y; + + v->Color.color = 0xFFFFFFFF; + + // fill index + if ( g < c - 2 ) + { + if ( type == EPT_TRIANGLE_FAN ) + { + index[indexCount+0] = vertexCount; + index[indexCount+1] = vertexCount+g+1; + index[indexCount+2] = vertexCount+g+2; + } + else + { + if ( g & 1 ) + { + index[indexCount+0] = vertexCount+g+1; + index[indexCount+1] = vertexCount+g+0; + index[indexCount+2] = vertexCount+g+2; + } + else + { + index[indexCount+0] = vertexCount+g+0; + index[indexCount+1] = vertexCount+g+1; + index[indexCount+2] = vertexCount+g+2; + } + } + + indexCount += 3; + } + } + + vertexCount += c; + } + + // material + video::SMaterial &m = buffer->getMaterial(); + + m.MaterialType = video::EMT_SOLID; + m.BackfaceCulling = true; + + if ( currentex->flags & STUDIO_NF_CHROME ) + { + // don't know what to do with chrome here + } + +#ifdef HL_TEXTURE_ATLAS + io::path store = TextureBaseName + "atlas"; +#else + io::path fname; + io::path ext; + core::splitFilename ( currentex->name, 0, &fname, &ext ); + io::path store = TextureBaseName + fname; +#endif + m.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture ( store ); + m.Lighting = false; + + MeshIPol->addMeshBuffer(buffer); + buffer->recalculateBoundingBox(); + buffer->drop(); + } // mesh + MeshIPol->recalculateBoundingBox(); + } // model + } // body part +} + + +/*! +*/ +void CAnimatedMeshHalfLife::buildVertices() +{ +/* + const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); + if (SkinGroupSelection != 0 && SkinGroupSelection < TextureHeader->numskinfamilies) + skinref += (SkinGroupSelection * TextureHeader->numskinref); +*/ + u32 i; + s32 c,g; + const s16 *tricmd; + + u32 meshBufferNr = 0; + for ( u32 bodypart = 0 ; bodypart < Header->numbodyparts; ++bodypart) + { + const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; + + for ( u32 modelnr = 0; modelnr < body->nummodels; ++modelnr ) + { + const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; + + const u8 *vertbone = ((u8*)Header + model->vertinfoindex); + + const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); + + for ( i = 0; i < model->numverts; i++) + { + VectorTransform ( studioverts[i], BoneTransform[vertbone[i]], TransformedVerts[i] ); + } + /* + const u8 *normbone = ((u8*)Header + model->norminfoindex); + const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex); + for ( i = 0; i < model->numnorms; i++) + { + VectorTransform ( studionorms[i], BoneTransform[normbone[i]], TransformedNormals[i] ); + } + */ + for (i = 0; i < model->nummesh; i++) + { + const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i; + + IMeshBuffer * buffer = MeshIPol->getMeshBuffer ( meshBufferNr++ ); + video::S3DVertex* v = (video::S3DVertex* ) buffer->getVertices(); + + tricmd = (s16*)((u8*)Header + mesh->triindex); + while ( (c = *(tricmd++)) ) + { + if (c < 0) + c = -c; + + for ( g = 0; g < c; ++g, v += 1, tricmd += 4 ) + { + // fill vertex + const core::vector3df& av = TransformedVerts[tricmd[0]]; + v->Pos = av; + /* + const core::vector3df& an = TransformedNormals[tricmd[1]]; + v->Normal = an; + //v->Normal.normalize(); + */ + } + } // tricmd + } // nummesh + } // model + } // bodypart +} + + +/*! + render Bones +*/ +void CAnimatedMeshHalfLife::renderModel(u32 param, IVideoDriver * driver, const core::matrix4 &absoluteTransformation) +{ + SHalflifeBone *bone = (SHalflifeBone *) ((u8 *) Header + Header->boneindex); + + video::SColor blue(0xFF000080); + video::SColor red(0xFF800000); + video::SColor yellow(0xFF808000); + video::SColor cyan(0xFF008080); + + core::aabbox3df box; + + u32 i; + for ( i = 0; i < Header->numbones; i++) + { + if (bone[i].parent >= 0) + { + getBoneVector ( box.MinEdge, bone[i].parent ); + getBoneVector ( box.MaxEdge, i ); + driver->draw3DLine ( box.MinEdge, box.MaxEdge, blue ); + + // draw parent bone node + if (bone[bone[i].parent].parent >=0 ) + { + getBoneBox ( box, bone[i].parent ); + driver->draw3DBox ( box, blue ); + } + getBoneBox ( box, i ); + driver->draw3DBox ( box, blue ); + } + else + { + // draw parent bone node + getBoneBox ( box, i, 1.f ); + driver->draw3DBox ( box , red ); + } + } + + // attachements + SHalflifeAttachment *attach = (SHalflifeAttachment *) ((u8*) Header + Header->attachmentindex); + core::vector3df v[8]; + for ( i = 0; i < Header->numattachments; i++) + { + getTransformedBoneVector ( v[0],attach[i].bone,attach[i].org ); + getTransformedBoneVector ( v[1],attach[i].bone,attach[i].vectors[0] ); + getTransformedBoneVector ( v[2],attach[i].bone,attach[i].vectors[1] ); + getTransformedBoneVector ( v[3],attach[i].bone,attach[i].vectors[2] ); + driver->draw3DLine ( v[0], v[1], cyan ); + driver->draw3DLine ( v[0], v[2], cyan ); + driver->draw3DLine ( v[0], v[3], cyan ); + } + + // hit boxes + SHalflifeBBox *hitbox = (SHalflifeBBox *) ((u8*) Header + Header->hitboxindex); + f32 *bbmin,*bbmax; + vec3_hl v2[8]; + for (i = 0; i < Header->numhitboxes; i++) + { + bbmin = hitbox[i].bbmin; + bbmax = hitbox[i].bbmax; + + v2[0][0] = bbmin[0]; + v2[0][1] = bbmax[1]; + v2[0][2] = bbmin[2]; + + v2[1][0] = bbmin[0]; + v2[1][1] = bbmin[1]; + v2[1][2] = bbmin[2]; + + v2[2][0] = bbmax[0]; + v2[2][1] = bbmax[1]; + v2[2][2] = bbmin[2]; + + v2[3][0] = bbmax[0]; + v2[3][1] = bbmin[1]; + v2[3][2] = bbmin[2]; + + v2[4][0] = bbmax[0]; + v2[4][1] = bbmax[1]; + v2[4][2] = bbmax[2]; + + v2[5][0] = bbmax[0]; + v2[5][1] = bbmin[1]; + v2[5][2] = bbmax[2]; + + v2[6][0] = bbmin[0]; + v2[6][1] = bbmax[1]; + v2[6][2] = bbmax[2]; + + v2[7][0] = bbmin[0]; + v2[7][1] = bbmin[1]; + v2[7][2] = bbmax[2]; + + for ( u32 g = 0; g < 8; ++g ) + getTransformedBoneVector ( v[g],hitbox[i].bone,v2[g] ); + + driver->draw3DLine(v[0], v[1], yellow); + driver->draw3DLine(v[1], v[3], yellow); + driver->draw3DLine(v[3], v[2], yellow); + driver->draw3DLine(v[2], v[0], yellow); + + driver->draw3DLine(v[4], v[5], yellow); + driver->draw3DLine(v[5], v[7], yellow); + driver->draw3DLine(v[7], v[6], yellow); + driver->draw3DLine(v[6], v[4], yellow); + + driver->draw3DLine(v[0], v[6], yellow); + driver->draw3DLine(v[1], v[7], yellow); + driver->draw3DLine(v[3], v[5], yellow); + driver->draw3DLine(v[2], v[4], yellow); + } +} + + +//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. +IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + f32 frame = frameInt + (detailLevel * 0.001f); + u32 frameA = core::floor32 ( frame ); +// f32 blend = core::fract ( frame ); + + SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); + + // find SequenceIndex from summed list + u32 frameCount = 0; + for (u32 i = 0; i < Header->numseq; ++i) + { + u32 val = core::max_ ( 1, seq[i].numframes - 1 ); + if ( frameCount + val > frameA ) + { + SequenceIndex = i; + CurrentFrame = frame - frameCount; + break; + } + frameCount += val; + } + + seq += SequenceIndex; + + //SetBodyPart ( 1, 1 ); + setUpBones (); + buildVertices(); + + MeshIPol->BoundingBox.MinEdge.X = seq->bbmin[0]; + MeshIPol->BoundingBox.MinEdge.Z = seq->bbmin[1]; + MeshIPol->BoundingBox.MinEdge.Y = seq->bbmin[2]; + + MeshIPol->BoundingBox.MaxEdge.X = seq->bbmax[0]; + MeshIPol->BoundingBox.MaxEdge.Z = seq->bbmax[1]; + MeshIPol->BoundingBox.MaxEdge.Y = seq->bbmax[2]; + + return MeshIPol; +} + + +/*! +*/ +void CAnimatedMeshHalfLife::initData () +{ + u32 i; + + Header = 0; + TextureHeader = 0; + OwnTexModel = false; + + for ( i = 0; i < 32; ++i ) + AnimationHeader[i] = 0; + + SequenceIndex = 0; + CurrentFrame = 0.f; + + for ( i = 0; i < 5; ++i ) + BoneController[i] = 0; + + for ( i = 0; i < 2; ++i ) + Blending[i] = 0; + + SkinGroupSelection = 0; + + AnimList.clear(); + FrameCount = 0; + + if (!MeshIPol) + MeshIPol = new SMesh(); + MeshIPol->clear(); + +#ifdef HL_TEXTURE_ATLAS + TextureAtlas.release(); +#endif +} + + +/*! +*/ +void STextureAtlas::release() +{ + for (u32 i = 0; i < atlas.size(); i++) + { + if ( atlas[i].image ) + { + atlas[i].image->drop(); + atlas[i].image = 0; + } + } + Master = 0; +} + + +/*! +*/ +void STextureAtlas::addSource ( const c8 * name, video::IImage * image ) +{ + TextureAtlasEntry entry; + entry.name = name; + entry.image = image; + entry.width = image->getDimension().Width; + entry.height = image->getDimension().Height; + entry.pos.X = 0; + entry.pos.Y = 0; + atlas.push_back ( entry ); +} + + +/*! +*/ +void STextureAtlas::getScale(core::vector2df& scale) +{ + for (s32 i = static_cast(atlas.size()) - 1; i >= 0; --i) + { + if ( atlas[i].name == "_merged_" ) + { + scale.X = 1.f / atlas[i].width; + scale.Y = 1.f / atlas[i].height; + return; + } + } + scale.X = 1.f; + scale.Y = 1.f; +} + + +/*! +*/ +void STextureAtlas::getTranslation(const c8* name, core::vector2di& pos) +{ + for ( u32 i = 0; i < atlas.size(); ++i) + { + if ( atlas[i].name == name ) + { + pos = atlas[i].pos; + return; + } + } +} + + +/*! +*/ +void STextureAtlas::create(u32 border, E_TEXTURE_CLAMP texmode) +{ + u32 i = 0; + u32 w = 0; + u32 w2; + u32 h2; + u32 h; + u32 wsum; + u32 hsum = 0; + ECOLOR_FORMAT format = ECF_R8G8B8; + + const s32 frame = core::s32_max ( 0, (border - 1 ) / 2 ); + + // sort for biggest coming first + atlas.sort(); + + // split size + wsum = frame; + for (i = 0; i < atlas.size(); i++) + { + // make space + w2 = atlas[i].width + border; + + // align + w2 = (w2 + 1) & ~1; + wsum += w2; + } + u32 splitsize = 256; + if ( wsum > 512 ) + splitsize = 512; + + wsum = frame; + hsum = frame; + w = frame; + h = 0; + for (i = 0; i < atlas.size(); i++) + { + if ( atlas[i].image->getColorFormat() == ECF_A8R8G8B8 ) + { + format = ECF_A8R8G8B8; + } + + // make space + w2 = atlas[i].width + border; + h2 = atlas[i].height + border; + + // align + w2 = (w2 + 1) & ~1; + h2 = (h2 + 1) & ~1; + + h = core::s32_max ( h, h2 ); + + if ( w + w2 >= splitsize ) + { + hsum += h; + wsum = core::s32_max ( wsum, w ); + h = h2; + w = frame; + } + + atlas[i].pos.X = w; + atlas[i].pos.Y = hsum; + + w += w2; + + } + hsum += h; + wsum = core::s32_max ( wsum, w ); + + // build image + core::dimension2d dim = core::dimension2d( wsum, hsum ).getOptimalSize(); + IImage* master = new CImage(format, dim); + master->fill(0); + + video::SColor col[2]; + + static const u8 wrap[][4] = + { + {1, 0}, // ETC_REPEAT + {0, 1}, // ETC_CLAMP + {0, 1}, // ETC_CLAMP_TO_EDGE + {0, 1} // ETC_MIRROR + }; + + s32 a,b; + for (i = 0; i < atlas.size(); i++) + { + atlas[i].image->copyTo ( master, atlas[i].pos ); + + // clamp/wrap ( copy edges, filtering needs it ) + + for ( b = 0; b < frame; ++b ) + { + for ( a = 0 - b; a <= (s32) atlas[i].width + b; ++a ) + { + col[0] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), 0 ); + col[1] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), atlas[i].height - 1 ); + + master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + ( b + 1 ) * -1, col[wrap[texmode][0]] ); + master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + atlas[i].height - 1 + ( b + 1 ) * 1, col[wrap[texmode][1]] ); + } + + for ( a = -1 - b; a <= (s32) atlas[i].height + b; ++a ) + { + col[0] = atlas[i].image->getPixel ( 0, core::s32_clamp ( a, 0, atlas[i].height - 1 ) ); + col[1] = atlas[i].image->getPixel ( atlas[i].width - 1, core::s32_clamp ( a, 0, atlas[i].height - 1 ) ); + + master->setPixel ( atlas[i].pos.X + ( b + 1 ) * -1, atlas[i].pos.Y + a, col[wrap[texmode][0]] ); + master->setPixel ( atlas[i].pos.X + atlas[i].width + b, atlas[i].pos.Y + a, col[wrap[texmode][1]] ); + } + } + } + + addSource ( "_merged_", master ); + Master = master; +} + + +/*! +*/ +SHalflifeHeader* CAnimatedMeshHalfLife::loadModel(io::IReadFile* file, const io::path& filename) +{ + bool closefile = false; + + // if secondary files are needed, open here and mark for closing + if ( 0 == file ) + { + file = SceneManager->getFileSystem()->createAndOpenFile(filename); + closefile = true; + } + + if ( 0 == file ) + return 0; + + // read into memory + u8* pin = new u8[file->getSize()]; + file->read(pin, file->getSize()); + + SHalflifeHeader* header = (SHalflifeHeader*) pin; + + const bool idst = (0 == strncmp(header->id, "IDST", 4)); + const bool idsq = (0 == strncmp(header->id, "IDSQ", 4)); + + if ( (!idst && !idsq) || (idsq && !Header) ) + { + os::Printer::log("MDL Halflife Loader: Wrong file header", file->getFileName(), ELL_WARNING); + if ( closefile ) + { + file->drop(); + file = 0; + } + delete [] pin; + return 0; + } + + // don't know the real header.. idsg might be different + if (header->textureindex && idst ) + { + io::path path; + io::path fname; + io::path ext; + + core::splitFilename(file->getFileName(), &path, &fname, &ext); + TextureBaseName = path + fname + "_"; + + SHalflifeTexture *tex = (SHalflifeTexture *)(pin + header->textureindex); + u32 *palette = new u32[256]; + for (u32 i = 0; i < header->numtextures; ++i) + { + const u8 *src = pin + tex[i].index; + + // convert rgb to argb palette + { + const u8 *pal = src + tex[i].width * tex[i].height; + for( u32 g=0; g<256; ++g ) + { + palette[g] = 0xFF000000 | pal[0] << 16 | pal[1] << 8 | pal[2]; + pal += 3; + } + } + + IImage* image = SceneManager->getVideoDriver()->createImage(ECF_R8G8B8, core::dimension2d(tex[i].width, tex[i].height)); + + CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false); + image->unlock(); + +#ifdef HL_TEXTURE_ATLAS + TextureAtlas.addSource ( tex[i].name, image ); +#else + core::splitFilename ( tex[i].name, 0, &fname, &ext ); + SceneManager->getVideoDriver()->addTexture ( TextureBaseName + fname, image ); + image->drop(); +#endif + } + delete [] palette; + +#ifdef HL_TEXTURE_ATLAS + TextureAtlas.create ( 2 * 2 + 1, ETC_CLAMP ); + SceneManager->getVideoDriver()->addTexture ( TextureBaseName + "atlas", TextureAtlas.Master ); + TextureAtlas.release(); +#endif + } + + if (!Header) + Header = header; + + if ( closefile ) + { + file->drop(); + file = 0; + } + + return header; +} + + +/*! +*/ +f32 CAnimatedMeshHalfLife::SetController( s32 controllerIndex, f32 value ) +{ + if (!Header) + return 0.f; + + SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); + + // find first controller that matches the index + u32 i; + for (i = 0; i < Header->numbonecontrollers; i++, bonecontroller++) + { + if (bonecontroller->index == controllerIndex) + break; + } + if (i >= Header->numbonecontrollers) + return value; + + // wrap 0..360 if it's a rotational controller + if (bonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) + { + // ugly hack, invert value if end < start + if (bonecontroller->end < bonecontroller->start) + value = -value; + + // does the controller not wrap? + if (bonecontroller->start + 359.f >= bonecontroller->end) + { + if (value > ((bonecontroller->start + bonecontroller->end) / 2.f) + 180.f) + value = value - 360.f; + if (value < ((bonecontroller->start + bonecontroller->end) / 2.f) - 180.f) + value = value + 360.f; + } + else + { + if (value > 360.f) + value = value - (s32)(value / 360.f) * 360.f; + else if (value < 0.f) + value = value + (s32)((value / -360.f) + 1) * 360.f; + } + } + + s32 range = controllerIndex == MOUTH_CONTROLLER ? 64 : 255; + + s32 setting = (s32) ( (f32) range * (value - bonecontroller->start) / (bonecontroller->end - bonecontroller->start)); + + if (setting < 0) setting = 0; + if (setting > range) setting = range; + + BoneController[controllerIndex] = setting; + + return setting * (1.f / (f32) range ) * (bonecontroller->end - bonecontroller->start) + bonecontroller->start; +} + + +/*! +*/ +u32 CAnimatedMeshHalfLife::SetSkin( u32 value ) +{ + if (value < Header->numskinfamilies) + SkinGroupSelection = value; + + return SkinGroupSelection; +} + + +/*! +*/ +bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename ) +{ + io::path path; + io::path texname; + io::path submodel; + + core::splitFilename ( filename ,&path, &texname, 0 ); + + // preload textures + // if no textures are stored in main file, use texfile + if (Header->numtextures == 0) + { + submodel = path + texname + "T.mdl"; + TextureHeader = loadModel(0, submodel); + if (!TextureHeader) + return false; + OwnTexModel = true; + } + else + { + TextureHeader = Header; + OwnTexModel = false; + } + + // preload animations + if (Header->numseqgroups > 1) + { + c8 seq[8]; + for (u32 i = 1; i < Header->numseqgroups; i++) + { + snprintf( seq, 8, "%02d.mdl", i ); + submodel = path + texname + seq; + + AnimationHeader[i] = loadModel(0, submodel); + if (!AnimationHeader[i]) + return false; + } + } + + return true; +} + + +/*! +*/ +void CAnimatedMeshHalfLife::dumpModelInfo(u32 level) const +{ + const u8 *phdr = (const u8*) Header; + const SHalflifeHeader * hdr = Header; + u32 i; + + if (level == 0) + { + printf ( + "Bones: %d\n" + "Bone Controllers: %d\n" + "Hit Boxes: %d\n" + "Sequences: %d\n" + "Sequence Groups: %d\n", + hdr->numbones, + hdr->numbonecontrollers, + hdr->numhitboxes, + hdr->numseq, + hdr->numseqgroups + ); + printf ( + "Textures: %d\n" + "Skin Families: %d\n" + "Bodyparts: %d\n" + "Attachments: %d\n" + "Transitions: %d\n", + hdr->numtextures, + hdr->numskinfamilies, + hdr->numbodyparts, + hdr->numattachments, + hdr->numtransitions); + return; + } + + printf("id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]); + printf("version: %d\n", hdr->version); + printf("name: \"%s\"\n", hdr->name); + printf("length: %d\n\n", hdr->length); + + printf("eyeposition: %f %f %f\n", hdr->eyeposition[0], hdr->eyeposition[1], hdr->eyeposition[2]); + printf("min: %f %f %f\n", hdr->min[0], hdr->min[1], hdr->min[2]); + printf("max: %f %f %f\n", hdr->max[0], hdr->max[1], hdr->max[2]); + printf("bbmin: %f %f %f\n", hdr->bbmin[0], hdr->bbmin[1], hdr->bbmin[2]); + printf("bbmax: %f %f %f\n", hdr->bbmax[0], hdr->bbmax[1], hdr->bbmax[2]); + + printf("flags: %d\n\n", hdr->flags); + + printf("numbones: %d\n", hdr->numbones); + for (i = 0; i < hdr->numbones; i++) + { + const SHalflifeBone *bone = (const SHalflifeBone *) (phdr + hdr->boneindex); + printf("bone %d.name: \"%s\"\n", i + 1, bone[i].name); + printf("bone %d.parent: %d\n", i + 1, bone[i].parent); + printf("bone %d.flags: %d\n", i + 1, bone[i].flags); + printf("bone %d.bonecontroller: %d %d %d %d %d %d\n", i + 1, bone[i].bonecontroller[0], bone[i].bonecontroller[1], bone[i].bonecontroller[2], bone[i].bonecontroller[3], bone[i].bonecontroller[4], bone[i].bonecontroller[5]); + printf("bone %d.value: %f %f %f %f %f %f\n", i + 1, bone[i].value[0], bone[i].value[1], bone[i].value[2], bone[i].value[3], bone[i].value[4], bone[i].value[5]); + printf("bone %d.scale: %f %f %f %f %f %f\n", i + 1, bone[i].scale[0], bone[i].scale[1], bone[i].scale[2], bone[i].scale[3], bone[i].scale[4], bone[i].scale[5]); + } + + printf("\nnumbonecontrollers: %d\n", hdr->numbonecontrollers); + const SHalflifeBoneController *bonecontrollers = (const SHalflifeBoneController *) (phdr + hdr->bonecontrollerindex); + for (i = 0; i < hdr->numbonecontrollers; i++) + { + printf("bonecontroller %d.bone: %d\n", i + 1, bonecontrollers[i].bone); + printf("bonecontroller %d.type: %d\n", i + 1, bonecontrollers[i].type); + printf("bonecontroller %d.start: %f\n", i + 1, bonecontrollers[i].start); + printf("bonecontroller %d.end: %f\n", i + 1, bonecontrollers[i].end); + printf("bonecontroller %d.rest: %d\n", i + 1, bonecontrollers[i].rest); + printf("bonecontroller %d.index: %d\n", i + 1, bonecontrollers[i].index); + } + + printf("\nnumhitboxes: %d\n", hdr->numhitboxes); + const SHalflifeBBox *box = (const SHalflifeBBox *) (phdr + hdr->hitboxindex); + for (i = 0; i < hdr->numhitboxes; i++) + { + printf("hitbox %d.bone: %d\n", i + 1, box[i].bone); + printf("hitbox %d.group: %d\n", i + 1, box[i].group); + printf("hitbox %d.bbmin: %f %f %f\n", i + 1, box[i].bbmin[0], box[i].bbmin[1], box[i].bbmin[2]); + printf("hitbox %d.bbmax: %f %f %f\n", i + 1, box[i].bbmax[0], box[i].bbmax[1], box[i].bbmax[2]); + } + + printf("\nnumseq: %d\n", hdr->numseq); + const SHalflifeSequence *seq = (const SHalflifeSequence *) (phdr + hdr->seqindex); + for (i = 0; i < hdr->numseq; i++) + { + printf("seqdesc %d.label: \"%s\"\n", i + 1, seq[i].label); + printf("seqdesc %d.fps: %f\n", i + 1, seq[i].fps); + printf("seqdesc %d.flags: %d\n", i + 1, seq[i].flags); + printf("<...>\n"); + } + + printf("\nnumseqgroups: %d\n", hdr->numseqgroups); + for (i = 0; i < hdr->numseqgroups; i++) + { + const SHalflifeSequenceGroup *group = (const SHalflifeSequenceGroup *) (phdr + hdr->seqgroupindex); + printf("\nseqgroup %d.label: \"%s\"\n", i + 1, group[i].label); + printf("\nseqgroup %d.namel: \"%s\"\n", i + 1, group[i].name); + printf("\nseqgroup %d.data: %d\n", i + 1, group[i].data); + } + + printf("\nnumskinref: %d\n", hdr->numskinref); + printf("numskinfamilies: %d\n", hdr->numskinfamilies); + + printf("\nnumbodyparts: %d\n", hdr->numbodyparts); + const SHalflifeBody *pbodyparts = (const SHalflifeBody*) ((const u8*) hdr + hdr->bodypartindex); + for (i = 0; i < hdr->numbodyparts; i++) + { + printf("bodypart %d.name: \"%s\"\n", i + 1, pbodyparts[i].name); + printf("bodypart %d.nummodels: %d\n", i + 1, pbodyparts[i].nummodels); + printf("bodypart %d.base: %d\n", i + 1, pbodyparts[i].base); + printf("bodypart %d.modelindex: %d\n", i + 1, pbodyparts[i].modelindex); + } + + printf("\nnumattachments: %d\n", hdr->numattachments); + for (i = 0; i < hdr->numattachments; i++) + { + const SHalflifeAttachment *attach = (const SHalflifeAttachment *) ((const u8*) hdr + hdr->attachmentindex); + printf("attachment %d.name: \"%s\"\n", i + 1, attach[i].name); + } + + hdr = TextureHeader; + printf("\nnumtextures: %d\n", hdr->numtextures); + printf("textureindex: %d\n", hdr->textureindex); + printf("texturedataindex: %d\n", hdr->texturedataindex); + const SHalflifeTexture *ptextures = (const SHalflifeTexture *) ((const u8*) hdr + hdr->textureindex); + for (i = 0; i < hdr->numtextures; i++) + { + printf("texture %d.name: \"%s\"\n", i + 1, ptextures[i].name); + printf("texture %d.flags: %d\n", i + 1, ptextures[i].flags); + printf("texture %d.width: %d\n", i + 1, ptextures[i].width); + printf("texture %d.height: %d\n", i + 1, ptextures[i].height); + printf("texture %d.index: %d\n", i + 1, ptextures[i].index); + } +} + + +/*! +*/ +void CAnimatedMeshHalfLife::ExtractBbox(s32 sequence, core::aabbox3df &box) const +{ + const SHalflifeSequence *seq = (const SHalflifeSequence *)((const u8*)Header + Header->seqindex) + sequence; + + box.MinEdge.X = seq[0].bbmin[0]; + box.MinEdge.Y = seq[0].bbmin[1]; + box.MinEdge.Z = seq[0].bbmin[2]; + + box.MaxEdge.X = seq[0].bbmax[0]; + box.MaxEdge.Y = seq[0].bbmax[1]; + box.MaxEdge.Z = seq[0].bbmax[2]; +} + + +/*! +*/ +void CAnimatedMeshHalfLife::calcBoneAdj() +{ + const SHalflifeBoneController *bonecontroller = + (const SHalflifeBoneController *)((const u8*) Header + Header->bonecontrollerindex); + + for (u32 j = 0; j < Header->numbonecontrollers; j++) + { + const s32 i = bonecontroller[j].index; + // check for 360% wrapping + f32 value; + if (bonecontroller[j].type & STUDIO_RLOOP) + { + value = BoneController[i] * (360.f/256.f) + bonecontroller[j].start; + } + else + { + const f32 range = i <= 3 ? 255.f : 64.f; + value = core::clamp(BoneController[i] / range,0.f,1.f); + value = (1.f - value) * bonecontroller[j].start + value * bonecontroller[j].end; + } + + switch(bonecontroller[j].type & STUDIO_TYPES) + { + case STUDIO_XR: + case STUDIO_YR: + case STUDIO_ZR: + BoneAdj[j] = value * core::DEGTORAD; + break; + case STUDIO_X: + case STUDIO_Y: + case STUDIO_Z: + BoneAdj[j] = value; + break; + } + } +} + + +/*! +*/ +void CAnimatedMeshHalfLife::calcBoneQuaternion(const s32 frame, const SHalflifeBone * const bone, + SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const +{ + // three vector components + if (anim->offset[j+3] == 0) + { + angle2 = angle1 = bone->value[j+3]; // default + } + else + { + SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j+3]); + s32 k = frame; + while (animvalue->num.total <= k) + { + k -= animvalue->num.total; + animvalue += animvalue->num.valid + 1; + } + // Bah, missing blend! + if (animvalue->num.valid > k) + { + angle1 = animvalue[k+1].value; + + if (animvalue->num.valid > k + 1) + { + angle2 = animvalue[k+2].value; + } + else + { + if (animvalue->num.total > k + 1) + angle2 = angle1; + else + angle2 = animvalue[animvalue->num.valid+2].value; + } + } + else + { + angle1 = animvalue[animvalue->num.valid].value; + if (animvalue->num.total > k + 1) + { + angle2 = angle1; + } + else + { + angle2 = animvalue[animvalue->num.valid + 2].value; + } + } + angle1 = bone->value[j+3] + angle1 * bone->scale[j+3]; + angle2 = bone->value[j+3] + angle2 * bone->scale[j+3]; + } + + if (bone->bonecontroller[j+3] != -1) + { + angle1 += BoneAdj[bone->bonecontroller[j+3]]; + angle2 += BoneAdj[bone->bonecontroller[j+3]]; + } +} + + +/*! +*/ +void CAnimatedMeshHalfLife::calcBonePosition(const s32 frame, f32 s, + const SHalflifeBone * const bone, SHalflifeAnimOffset *anim, f32 *pos) const +{ + for (s32 j = 0; j < 3; ++j) + { + pos[j] = bone->value[j]; // default; + if (anim->offset[j] != 0) + { + SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j]); + + s32 k = frame; + // find span of values that includes the frame we want + while (animvalue->num.total <= k) + { + k -= animvalue->num.total; + animvalue += animvalue->num.valid + 1; + } + // if we're inside the span + if (animvalue->num.valid > k) + { + // and there's more data in the span + if (animvalue->num.valid > k + 1) + { + pos[j] += (animvalue[k+1].value * (1.f - s) + s * animvalue[k+2].value) * bone->scale[j]; + } + else + { + pos[j] += animvalue[k+1].value * bone->scale[j]; + } + } + else + { + // are we at the end of the repeating values section and there's another section with data? + if (animvalue->num.total <= k + 1) + { + pos[j] += (animvalue[animvalue->num.valid].value * (1.f - s) + s * animvalue[animvalue->num.valid + 2].value) * bone->scale[j]; + } + else + { + pos[j] += animvalue[animvalue->num.valid].value * bone->scale[j]; + } + } + } + if (bone->bonecontroller[j] != -1) + { + pos[j] += BoneAdj[bone->bonecontroller[j]]; + } + } +} + + +/*! +*/ +void CAnimatedMeshHalfLife::calcRotations(vec3_hl *pos, vec4_hl *q, + SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f) +{ + s32 frame = (s32)f; + f32 s = (f - frame); + + // add in programatic controllers + calcBoneAdj(); + + SHalflifeBone *bone = (SHalflifeBone *)((u8 *)Header + Header->boneindex); + for ( u32 i = 0; i < Header->numbones; i++, bone++, anim++) + { + core::vector3df angle1, angle2; + calcBoneQuaternion(frame, bone, anim, 0, angle1.X, angle2.X); + calcBoneQuaternion(frame, bone, anim, 1, angle1.Y, angle2.Y); + calcBoneQuaternion(frame, bone, anim, 2, angle1.Z, angle2.Z); + + if (!angle1.equals(angle2)) + { + vec4_hl q1, q2; + AngleQuaternion( angle1, q1 ); + AngleQuaternion( angle2, q2 ); + QuaternionSlerp( q1, q2, s, q[i] ); + } + else + { + AngleQuaternion( angle1, q[i] ); + } + + calcBonePosition(frame, s, bone, anim, pos[i]); + } + + if (seq->motiontype & STUDIO_X) + pos[seq->motionbone][0] = 0.f; + if (seq->motiontype & STUDIO_Y) + pos[seq->motionbone][1] = 0.f; + if (seq->motiontype & STUDIO_Z) + pos[seq->motionbone][2] = 0.f; +} + + +/*! +*/ +SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq ) +{ + SHalflifeSequenceGroup *seqgroup = (SHalflifeSequenceGroup *)((u8*)Header + Header->seqgroupindex) + seq->seqgroup; + + if (seq->seqgroup == 0) + { + return (SHalflifeAnimOffset *)((u8*)Header + seqgroup->data + seq->animindex); + } + + return (SHalflifeAnimOffset *)((u8*)AnimationHeader[seq->seqgroup] + seq->animindex); +} + + +/*! +*/ +void CAnimatedMeshHalfLife::slerpBones(vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s) +{ + if (s < 0) + s = 0; + else if (s > 1.f) + s = 1.f; + + f32 s1 = 1.f - s; + + for ( u32 i = 0; i < Header->numbones; i++) + { + vec4_hl q3; + QuaternionSlerp( q1[i], q2[i], s, q3 ); + q1[i][0] = q3[0]; + q1[i][1] = q3[1]; + q1[i][2] = q3[2]; + q1[i][3] = q3[3]; + pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s; + pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s; + pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s; + } +} + + +/*! +*/ +void CAnimatedMeshHalfLife::setUpBones() +{ + static vec3_hl pos[MAXSTUDIOBONES]; + f32 bonematrix[3][4]; + static vec4_hl q[MAXSTUDIOBONES]; + + static vec3_hl pos2[MAXSTUDIOBONES]; + static vec4_hl q2[MAXSTUDIOBONES]; + static vec3_hl pos3[MAXSTUDIOBONES]; + static vec4_hl q3[MAXSTUDIOBONES]; + static vec3_hl pos4[MAXSTUDIOBONES]; + static vec4_hl q4[MAXSTUDIOBONES]; + + if (SequenceIndex >= Header->numseq) + SequenceIndex = 0; + + SHalflifeSequence *seq = (SHalflifeSequence *)((u8*) Header + Header->seqindex) + SequenceIndex; + + SHalflifeAnimOffset *anim = getAnim(seq); + calcRotations(pos, q, seq, anim, CurrentFrame); + + if (seq->numblends > 1) + { + anim += Header->numbones; + calcRotations( pos2, q2, seq, anim, CurrentFrame ); + f32 s = Blending[0] / 255.f; + + slerpBones( q, pos, q2, pos2, s ); + + if (seq->numblends == 4) + { + anim += Header->numbones; + calcRotations( pos3, q3, seq, anim, CurrentFrame ); + + anim += Header->numbones; + calcRotations( pos4, q4, seq, anim, CurrentFrame ); + + s = Blending[0] / 255.f; + slerpBones( q3, pos3, q4, pos4, s ); + + s = Blending[1] / 255.f; + slerpBones( q, pos, q3, pos3, s ); + } + } + + SHalflifeBone *bone = (SHalflifeBone *)((u8*) Header + Header->boneindex); + + for (u32 i = 0; i < Header->numbones; i++) + { + QuaternionMatrix( q[i], bonematrix ); + + bonematrix[0][3] = pos[i][0]; + bonematrix[1][3] = pos[i][1]; + bonematrix[2][3] = pos[i][2]; + + if (bone[i].parent == -1) { + memcpy(BoneTransform[i], bonematrix, sizeof(f32) * 12); + } + else { + R_ConcatTransforms (BoneTransform[bone[i].parent], bonematrix, BoneTransform[i]); + } + } +} + + +//! Returns an axis aligned bounding box +const core::aabbox3d& CAnimatedMeshHalfLife::getBoundingBox() const +{ + return MeshIPol->BoundingBox; +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CAnimatedMeshHalfLife::getMeshType() const +{ + return EAMT_MDL_HALFLIFE; +} + + +//! returns amount of mesh buffers. +u32 CAnimatedMeshHalfLife::getMeshBufferCount() const +{ + return MeshIPol->getMeshBufferCount(); +} + + +//! returns pointer to a mesh buffer +IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const +{ + return MeshIPol->getMeshBuffer(nr); +} + + +//! Returns pointer to a mesh buffer which fits a material +/** \param material: material to search for +\return Returns the pointer to the mesh buffer or +NULL if there is no such mesh buffer. */ +IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(const video::SMaterial &material) const +{ + return MeshIPol->getMeshBuffer(material); +} + + +void CAnimatedMeshHalfLife::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) +{ + MeshIPol->setMaterialFlag ( flag, newvalue ); +} + + +//! set user axis aligned bounding box +void CAnimatedMeshHalfLife::setBoundingBox(const core::aabbox3df& box) +{ + MeshIPol->setBoundingBox(box); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD3_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.h new file mode 100644 index 0000000..32a4ef8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshHalfLife.h @@ -0,0 +1,630 @@ +// Copyright (C) 2002-2012 Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_HALFLIFE_H_INCLUDED__ +#define __C_ANIMATED_MESH_HALFLIFE_H_INCLUDED__ + +#include "IAnimatedMesh.h" +#include "ISceneManager.h" +#include "irrArray.h" +#include "irrString.h" +#include "IMeshLoader.h" +#include "SMesh.h" +#include "IReadFile.h" + +namespace irr +{ +namespace scene +{ + + + // STUDIO MODELS, Copyright (c) 1998, Valve LLC. All rights reserved. + #define MAXSTUDIOTRIANGLES 20000 // TODO: tune this + #define MAXSTUDIOVERTS 2048 // TODO: tune this + #define MAXSTUDIOSEQUENCES 256 // total animation sequences + #define MAXSTUDIOSKINS 100 // total textures + #define MAXSTUDIOSRCBONES 512 // bones allowed at source movement + #define MAXSTUDIOBONES 128 // total bones actually used + #define MAXSTUDIOMODELS 32 // sub-models per model + #define MAXSTUDIOBODYPARTS 32 + #define MAXSTUDIOGROUPS 4 + #define MAXSTUDIOANIMATIONS 512 // per sequence + #define MAXSTUDIOMESHES 256 + #define MAXSTUDIOEVENTS 1024 + #define MAXSTUDIOPIVOTS 256 + #define MAXSTUDIOCONTROLLERS 8 + + typedef f32 vec3_hl[3]; // x,y,z + typedef f32 vec4_hl[4]; // x,y,z,w + +// byte-align structures +#include "irrpack.h" + + struct SHalflifeHeader + { + c8 id[4]; + s32 version; + + c8 name[64]; + s32 length; + + vec3_hl eyeposition; // ideal eye position + vec3_hl min; // ideal movement hull size + vec3_hl max; + + vec3_hl bbmin; // clipping bounding box + vec3_hl bbmax; + + s32 flags; + + u32 numbones; // bones + u32 boneindex; + + u32 numbonecontrollers; // bone controllers + u32 bonecontrollerindex; + + u32 numhitboxes; // complex bounding boxes + u32 hitboxindex; + + u32 numseq; // animation sequences + u32 seqindex; + + u32 numseqgroups; // demand loaded sequences + u32 seqgroupindex; + + u32 numtextures; // raw textures + u32 textureindex; + u32 texturedataindex; + + u32 numskinref; // replaceable textures + u32 numskinfamilies; + u32 skinindex; + + u32 numbodyparts; + u32 bodypartindex; + + u32 numattachments; // queryable attachable points + u32 attachmentindex; + + s32 soundtable; + s32 soundindex; + s32 soundgroups; + s32 soundgroupindex; + + s32 numtransitions; // animation node to animation node transition graph + s32 transitionindex; + } PACK_STRUCT; + + // header for demand loaded sequence group data + struct studioseqhdr_t + { + s32 id; + s32 version; + + c8 name[64]; + s32 length; + } PACK_STRUCT; + + // bones + struct SHalflifeBone + { + c8 name[32]; // bone name for symbolic links + s32 parent; // parent bone + s32 flags; // ?? + s32 bonecontroller[6]; // bone controller index, -1 == none + f32 value[6]; // default DoF values + f32 scale[6]; // scale for delta DoF values + } PACK_STRUCT; + + + // bone controllers + struct SHalflifeBoneController + { + s32 bone; // -1 == 0 + s32 type; // X, Y, Z, XR, YR, ZR, M + f32 start; + f32 end; + s32 rest; // byte index value at rest + s32 index; // 0-3 user set controller, 4 mouth + } PACK_STRUCT; + + // intersection boxes + struct SHalflifeBBox + { + s32 bone; + s32 group; // intersection group + vec3_hl bbmin; // bounding box + vec3_hl bbmax; + } PACK_STRUCT; + +#ifndef ZONE_H + // NOTE: this was a void*, but that crashes on 64bit. + // I have found no mdl format desc, so not sure what it's meant to be, but s32 at least works. + typedef s32 cache_user_t; +#endif + + // demand loaded sequence groups + struct SHalflifeSequenceGroup + { + c8 label[32]; // textual name + c8 name[64]; // file name + cache_user_t cache; // cache index pointer + s32 data; // hack for group 0 + } PACK_STRUCT; + + // sequence descriptions + struct SHalflifeSequence + { + c8 label[32]; // sequence label + + f32 fps; // frames per second + s32 flags; // looping/non-looping flags + + s32 activity; + s32 actweight; + + s32 numevents; + s32 eventindex; + + s32 numframes; // number of frames per sequence + + u32 numpivots; // number of foot pivots + u32 pivotindex; + + s32 motiontype; + s32 motionbone; + vec3_hl linearmovement; + s32 automoveposindex; + s32 automoveangleindex; + + vec3_hl bbmin; // per sequence bounding box + vec3_hl bbmax; + + s32 numblends; + s32 animindex; // SHalflifeAnimOffset pointer relative to start of sequence group data + // [blend][bone][X, Y, Z, XR, YR, ZR] + + s32 blendtype[2]; // X, Y, Z, XR, YR, ZR + f32 blendstart[2]; // starting value + f32 blendend[2]; // ending value + s32 blendparent; + + s32 seqgroup; // sequence group for demand loading + + s32 entrynode; // transition node at entry + s32 exitnode; // transition node at exit + s32 nodeflags; // transition rules + + s32 nextseq; // auto advancing sequences + } PACK_STRUCT; + + // events + struct mstudioevent_t + { + s32 frame; + s32 event; + s32 type; + c8 options[64]; + } PACK_STRUCT; + + + // pivots + struct mstudiopivot_t + { + vec3_hl org; // pivot point + s32 start; + s32 end; + } PACK_STRUCT; + + // attachment + struct SHalflifeAttachment + { + c8 name[32]; + s32 type; + s32 bone; + vec3_hl org; // attachment point + vec3_hl vectors[3]; + } PACK_STRUCT; + + struct SHalflifeAnimOffset + { + u16 offset[6]; + } PACK_STRUCT; + + // animation frames + union SHalflifeAnimationFrame + { + struct { + u8 valid; + u8 total; + } PACK_STRUCT num; + s16 value; + } PACK_STRUCT; + + + // body part index + struct SHalflifeBody + { + c8 name[64]; + u32 nummodels; + u32 base; + u32 modelindex; // index into models array + } PACK_STRUCT; + + + // skin info + struct SHalflifeTexture + { + c8 name[64]; + s32 flags; + s32 width; + s32 height; + s32 index; + } PACK_STRUCT; + + + // skin families + // short index[skinfamilies][skinref] + + // studio models + struct SHalflifeModel + { + c8 name[64]; + s32 type; + + f32 boundingradius; + + u32 nummesh; + u32 meshindex; + + u32 numverts; // number of unique vertices + u32 vertinfoindex; // vertex bone info + u32 vertindex; // vertex vec3_hl + u32 numnorms; // number of unique surface normals + u32 norminfoindex; // normal bone info + u32 normindex; // normal vec3_hl + + u32 numgroups; // deformation groups + u32 groupindex; + } PACK_STRUCT; + + + // meshes + struct SHalflifeMesh + { + u32 numtris; + u32 triindex; + u32 skinref; + u32 numnorms; // per mesh normals + u32 normindex; // normal vec3_hl + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + // lighting options + #define STUDIO_NF_FLATSHADE 0x0001 + #define STUDIO_NF_CHROME 0x0002 + #define STUDIO_NF_FULLBRIGHT 0x0004 + + // motion flags + #define STUDIO_X 0x0001 + #define STUDIO_Y 0x0002 + #define STUDIO_Z 0x0004 + #define STUDIO_XR 0x0008 + #define STUDIO_YR 0x0010 + #define STUDIO_ZR 0x0020 + #define STUDIO_LX 0x0040 + #define STUDIO_LY 0x0080 + #define STUDIO_LZ 0x0100 + #define STUDIO_AX 0x0200 + #define STUDIO_AY 0x0400 + #define STUDIO_AZ 0x0800 + #define STUDIO_AXR 0x1000 + #define STUDIO_AYR 0x2000 + #define STUDIO_AZR 0x4000 + #define STUDIO_TYPES 0x7FFF + #define STUDIO_RLOOP 0x8000 // controller that wraps shortest distance + + // sequence flags + #define STUDIO_LOOPING 0x0001 + + // bone flags + #define STUDIO_HAS_NORMALS 0x0001 + #define STUDIO_HAS_VERTICES 0x0002 + #define STUDIO_HAS_BBOX 0x0004 + #define STUDIO_HAS_CHROME 0x0008 // if any of the textures have chrome on them + + #define RAD_TO_STUDIO (32768.0/M_PI) + #define STUDIO_TO_RAD (M_PI/32768.0) + + /*! + Textureatlas + Combine Source Images with arbitrary size and bithdepth to an Image with 2^n size + borders from the source images are copied around for allowing filtering ( bilinear, mipmap ) + */ + struct STextureAtlas + { + STextureAtlas () + { + release(); + } + + virtual ~STextureAtlas () + { + release (); + } + + void release (); + void addSource ( const c8 * name, video::IImage * image ); + void create ( u32 pixelborder, video::E_TEXTURE_CLAMP texmode ); + void getScale ( core::vector2df &scale ); + void getTranslation ( const c8 * name, core::vector2di &pos ); + + struct TextureAtlasEntry + { + io::path name; + u32 width; + u32 height; + + core::vector2di pos; + + video::IImage * image; + + bool operator < ( const TextureAtlasEntry & other ) + { + return height > other.height; + } + }; + + + core::array < TextureAtlasEntry > atlas; + video::IImage * Master; + }; + + + //! Possible types of Animation Type + enum E_ANIMATION_TYPE + { + //! No Animation + EAMT_STILL, + //! From Start to End, then Stop ( Limited Line ) + EAMT_WAYPOINT, + //! Linear Cycling Animation ( Sawtooth ) + EAMT_LOOPING, + //! Linear bobbing ( Triangle ) + EAMT_PINGPONG + }; + + //! Names for Animation Type + const c8* const MeshAnimationTypeNames[] = + { + "still", + "waypoint", + "looping", + "pingpong", + 0 + }; + + + //! Data for holding named Animation Info + struct KeyFrameInterpolation + { + core::stringc Name; // Name of the current Animation/Bone + E_ANIMATION_TYPE AnimationType; // Type of Animation ( looping, usw..) + + f32 CurrentFrame; // Current Frame + s32 NextFrame; // Frame which will be used next. For blending + + s32 StartFrame; // Absolute Frame where the current animation start + s32 Frames; // Relative Frames how much Frames this animation have + s32 LoopingFrames; // How much of Frames sould be looped + s32 EndFrame; // Absolute Frame where the current animation ends End = start + frames - 1 + + f32 FramesPerSecond; // Speed in Frames/Seconds the animation is played + f32 RelativeSpeed; // Factor Original fps is modified + + u32 BeginTime; // Animation started at this thime + u32 EndTime; // Animation end at this time + u32 LastTime; // Last Keyframe was done at this time + + KeyFrameInterpolation ( const c8 * name = "", s32 start = 0, s32 frames = 0, s32 loopingframes = 0, + f32 fps = 0.f, f32 relativefps = 1.f ) + : Name ( name ), AnimationType ( loopingframes ? EAMT_LOOPING : EAMT_WAYPOINT), + CurrentFrame ( (f32) start ), NextFrame ( start ), StartFrame ( start ), + Frames ( frames ), LoopingFrames ( loopingframes ), EndFrame ( start + frames - 1 ), + FramesPerSecond ( fps ), RelativeSpeed ( relativefps ), + BeginTime ( 0 ), EndTime ( 0 ), LastTime ( 0 ) + { + } + + // linear search + bool operator == ( const KeyFrameInterpolation & other ) const + { + return Name.equals_ignore_case ( other.Name ); + } + + }; + + + //! a List holding named Animations + typedef core::array < KeyFrameInterpolation > IAnimationList; + + //! a List holding named Skins + typedef core::array < core::stringc > ISkinList; + + + // Current Model per Body + struct SubModel + { + core::stringc name; + u32 startBuffer; + u32 endBuffer; + u32 state; + }; + + struct BodyPart + { + core::stringc name; + u32 defaultModel; + core::array < SubModel > model; + }; + //! a List holding named Models and SubModels + typedef core::array < BodyPart > IBodyList; + + + class CAnimatedMeshHalfLife : public IAnimatedMesh + { + public: + + //! constructor + CAnimatedMeshHalfLife(); + + //! destructor + virtual ~CAnimatedMeshHalfLife(); + + //! loads a Halflife mdl file + virtual bool loadModelFile( io::IReadFile* file, ISceneManager * smgr ); + + //IAnimatedMesh + virtual u32 getFrameCount() const; + virtual IMesh* getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop); + virtual const core::aabbox3d& getBoundingBox() const; + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + virtual void renderModel ( u32 param, video::IVideoDriver * driver, const core::matrix4 &absoluteTransformation); + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const; + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const; + //! Returns pointer to a mesh buffer which fits a material + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const; + + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! set user axis aligned bounding box + virtual void setBoundingBox(const core::aabbox3df& box); + + //! Gets the default animation speed of the animated mesh. + /** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ + virtual f32 getAnimationSpeed() const + { + return FramesPerSecond; + } + + //! Gets the frame count of the animated mesh. + /** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. + The actual speed is set in the scene node the mesh is instantiated in.*/ + virtual void setAnimationSpeed(f32 fps) + { + FramesPerSecond=fps; + } + + //! Get the Animation List + virtual IAnimationList* getAnimList () { return &AnimList; } + + //! Return the named Body List of this Animated Mesh + virtual IBodyList *getBodyList() { return &BodyList; } + + private: + + // KeyFrame Animation List + IAnimationList AnimList; + // Sum of all sequences + u32 FrameCount; + + // Named meshes of the Body + IBodyList BodyList; + + //! return a Mesh per frame + SMesh* MeshIPol; + + ISceneManager *SceneManager; + + SHalflifeHeader *Header; + SHalflifeHeader *TextureHeader; + bool OwnTexModel; // do we have a modelT.mdl ? + SHalflifeHeader *AnimationHeader[32]; // sequences named model01.mdl, model02.mdl + + void initData (); + SHalflifeHeader * loadModel( io::IReadFile* file, const io::path &filename ); + bool postLoadModel( const io::path &filename ); + + u32 SequenceIndex; // sequence index + f32 CurrentFrame; // Current Frame + f32 FramesPerSecond; + + #define MOUTH_CONTROLLER 4 + u8 BoneController[4 + 1 ]; // bone controllers + mouth position + u8 Blending[2]; // animation blending + + vec4_hl BoneAdj; + f32 SetController( s32 controllerIndex, f32 value ); + + u32 SkinGroupSelection; // skin group selection + u32 SetSkin( u32 value ); + + void initModel(); + void dumpModelInfo(u32 level) const; + + void ExtractBbox(s32 sequence, core::aabbox3df &box) const; + + void setUpBones (); + SHalflifeAnimOffset * getAnim( SHalflifeSequence *seq ); + void slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s ); + void calcRotations ( vec3_hl *pos, vec4_hl *q, SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f ); + + void calcBoneAdj(); + void calcBoneQuaternion(const s32 frame, const SHalflifeBone *bone, SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const; + void calcBonePosition(const s32 frame, f32 s, const SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *pos ) const; + + void buildVertices (); + + io::path TextureBaseName; + +#define HL_TEXTURE_ATLAS + +#ifdef HL_TEXTURE_ATLAS + STextureAtlas TextureAtlas; + video::ITexture *TextureMaster; +#endif + + }; + + + //! Meshloader capable of loading HalfLife Model files + class CHalflifeMDLMeshFileLoader : public IMeshLoader + { + public: + + //! Constructor + CHalflifeMDLMeshFileLoader( scene::ISceneManager* smgr ); + + //! returns true if the file maybe is able to be loaded by this class + /** based on the file extension (e.g. ".bsp") */ + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + /** \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information. + */ + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + private: + scene::ISceneManager* SceneManager; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp new file mode 100644 index 0000000..3c4f55c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.cpp @@ -0,0 +1,457 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ + +#include "CAnimatedMeshMD2.h" +#include "SColor.h" +#include "irrMath.h" + +namespace irr +{ +namespace scene +{ + +const s32 MD2_FRAME_SHIFT = 2; +const f32 MD2_FRAME_SHIFT_RECIPROCAL = 1.f / (1 << MD2_FRAME_SHIFT); + +const s32 Q2_VERTEX_NORMAL_TABLE_SIZE = 162; + +static const f32 Q2_VERTEX_NORMAL_TABLE[Q2_VERTEX_NORMAL_TABLE_SIZE][3] = { + {-0.525731f, 0.000000f, 0.850651f}, + {-0.442863f, 0.238856f, 0.864188f}, + {-0.295242f, 0.000000f, 0.955423f}, + {-0.309017f, 0.500000f, 0.809017f}, + {-0.162460f, 0.262866f, 0.951056f}, + {0.000000f, 0.000000f, 1.000000f}, + {0.000000f, 0.850651f, 0.525731f}, + {-0.147621f, 0.716567f, 0.681718f}, + {0.147621f, 0.716567f, 0.681718f}, + {0.000000f, 0.525731f, 0.850651f}, + {0.309017f, 0.500000f, 0.809017f}, + {0.525731f, 0.000000f, 0.850651f}, + {0.295242f, 0.000000f, 0.955423f}, + {0.442863f, 0.238856f, 0.864188f}, + {0.162460f, 0.262866f, 0.951056f}, + {-0.681718f, 0.147621f, 0.716567f}, + {-0.809017f, 0.309017f, 0.500000f}, + {-0.587785f, 0.425325f, 0.688191f}, + {-0.850651f, 0.525731f, 0.000000f}, + {-0.864188f, 0.442863f, 0.238856f}, + {-0.716567f, 0.681718f, 0.147621f}, + {-0.688191f, 0.587785f, 0.425325f}, + {-0.500000f, 0.809017f, 0.309017f}, + {-0.238856f, 0.864188f, 0.442863f}, + {-0.425325f, 0.688191f, 0.587785f}, + {-0.716567f, 0.681718f, -0.147621f}, + {-0.500000f, 0.809017f, -0.309017f}, + {-0.525731f, 0.850651f, 0.000000f}, + {0.000000f, 0.850651f, -0.525731f}, + {-0.238856f, 0.864188f, -0.442863f}, + {0.000000f, 0.955423f, -0.295242f}, + {-0.262866f, 0.951056f, -0.162460f}, + {0.000000f, 1.000000f, 0.000000f}, + {0.000000f, 0.955423f, 0.295242f}, + {-0.262866f, 0.951056f, 0.162460f}, + {0.238856f, 0.864188f, 0.442863f}, + {0.262866f, 0.951056f, 0.162460f}, + {0.500000f, 0.809017f, 0.309017f}, + {0.238856f, 0.864188f, -0.442863f}, + {0.262866f, 0.951056f, -0.162460f}, + {0.500000f, 0.809017f, -0.309017f}, + {0.850651f, 0.525731f, 0.000000f}, + {0.716567f, 0.681718f, 0.147621f}, + {0.716567f, 0.681718f, -0.147621f}, + {0.525731f, 0.850651f, 0.000000f}, + {0.425325f, 0.688191f, 0.587785f}, + {0.864188f, 0.442863f, 0.238856f}, + {0.688191f, 0.587785f, 0.425325f}, + {0.809017f, 0.309017f, 0.500000f}, + {0.681718f, 0.147621f, 0.716567f}, + {0.587785f, 0.425325f, 0.688191f}, + {0.955423f, 0.295242f, 0.000000f}, + {1.000000f, 0.000000f, 0.000000f}, + {0.951056f, 0.162460f, 0.262866f}, + {0.850651f, -0.525731f, 0.000000f}, + {0.955423f, -0.295242f, 0.000000f}, + {0.864188f, -0.442863f, 0.238856f}, + {0.951056f, -0.162460f, 0.262866f}, + {0.809017f, -0.309017f, 0.500000f}, + {0.681718f, -0.147621f, 0.716567f}, + {0.850651f, 0.000000f, 0.525731f}, + {0.864188f, 0.442863f, -0.238856f}, + {0.809017f, 0.309017f, -0.500000f}, + {0.951056f, 0.162460f, -0.262866f}, + {0.525731f, 0.000000f, -0.850651f}, + {0.681718f, 0.147621f, -0.716567f}, + {0.681718f, -0.147621f, -0.716567f}, + {0.850651f, 0.000000f, -0.525731f}, + {0.809017f, -0.309017f, -0.500000f}, + {0.864188f, -0.442863f, -0.238856f}, + {0.951056f, -0.162460f, -0.262866f}, + {0.147621f, 0.716567f, -0.681718f}, + {0.309017f, 0.500000f, -0.809017f}, + {0.425325f, 0.688191f, -0.587785f}, + {0.442863f, 0.238856f, -0.864188f}, + {0.587785f, 0.425325f, -0.688191f}, + {0.688191f, 0.587785f, -0.425325f}, + {-0.147621f, 0.716567f, -0.681718f}, + {-0.309017f, 0.500000f, -0.809017f}, + {0.000000f, 0.525731f, -0.850651f}, + {-0.525731f, 0.000000f, -0.850651f}, + {-0.442863f, 0.238856f, -0.864188f}, + {-0.295242f, 0.000000f, -0.955423f}, + {-0.162460f, 0.262866f, -0.951056f}, + {0.000000f, 0.000000f, -1.000000f}, + {0.295242f, 0.000000f, -0.955423f}, + {0.162460f, 0.262866f, -0.951056f}, + {-0.442863f, -0.238856f, -0.864188f}, + {-0.309017f, -0.500000f, -0.809017f}, + {-0.162460f, -0.262866f, -0.951056f}, + {0.000000f, -0.850651f, -0.525731f}, + {-0.147621f, -0.716567f, -0.681718f}, + {0.147621f, -0.716567f, -0.681718f}, + {0.000000f, -0.525731f, -0.850651f}, + {0.309017f, -0.500000f, -0.809017f}, + {0.442863f, -0.238856f, -0.864188f}, + {0.162460f, -0.262866f, -0.951056f}, + {0.238856f, -0.864188f, -0.442863f}, + {0.500000f, -0.809017f, -0.309017f}, + {0.425325f, -0.688191f, -0.587785f}, + {0.716567f, -0.681718f, -0.147621f}, + {0.688191f, -0.587785f, -0.425325f}, + {0.587785f, -0.425325f, -0.688191f}, + {0.000000f, -0.955423f, -0.295242f}, + {0.000000f, -1.000000f, 0.000000f}, + {0.262866f, -0.951056f, -0.162460f}, + {0.000000f, -0.850651f, 0.525731f}, + {0.000000f, -0.955423f, 0.295242f}, + {0.238856f, -0.864188f, 0.442863f}, + {0.262866f, -0.951056f, 0.162460f}, + {0.500000f, -0.809017f, 0.309017f}, + {0.716567f, -0.681718f, 0.147621f}, + {0.525731f, -0.850651f, 0.000000f}, + {-0.238856f, -0.864188f, -0.442863f}, + {-0.500000f, -0.809017f, -0.309017f}, + {-0.262866f, -0.951056f, -0.162460f}, + {-0.850651f, -0.525731f, 0.000000f}, + {-0.716567f, -0.681718f, -0.147621f}, + {-0.716567f, -0.681718f, 0.147621f}, + {-0.525731f, -0.850651f, 0.000000f}, + {-0.500000f, -0.809017f, 0.309017f}, + {-0.238856f, -0.864188f, 0.442863f}, + {-0.262866f, -0.951056f, 0.162460f}, + {-0.864188f, -0.442863f, 0.238856f}, + {-0.809017f, -0.309017f, 0.500000f}, + {-0.688191f, -0.587785f, 0.425325f}, + {-0.681718f, -0.147621f, 0.716567f}, + {-0.442863f, -0.238856f, 0.864188f}, + {-0.587785f, -0.425325f, 0.688191f}, + {-0.309017f, -0.500000f, 0.809017f}, + {-0.147621f, -0.716567f, 0.681718f}, + {-0.425325f, -0.688191f, 0.587785f}, + {-0.162460f, -0.262866f, 0.951056f}, + {0.442863f, -0.238856f, 0.864188f}, + {0.162460f, -0.262866f, 0.951056f}, + {0.309017f, -0.500000f, 0.809017f}, + {0.147621f, -0.716567f, 0.681718f}, + {0.000000f, -0.525731f, 0.850651f}, + {0.425325f, -0.688191f, 0.587785f}, + {0.587785f, -0.425325f, 0.688191f}, + {0.688191f, -0.587785f, 0.425325f}, + {-0.955423f, 0.295242f, 0.000000f}, + {-0.951056f, 0.162460f, 0.262866f}, + {-1.000000f, 0.000000f, 0.000000f}, + {-0.850651f, 0.000000f, 0.525731f}, + {-0.955423f, -0.295242f, 0.000000f}, + {-0.951056f, -0.162460f, 0.262866f}, + {-0.864188f, 0.442863f, -0.238856f}, + {-0.951056f, 0.162460f, -0.262866f}, + {-0.809017f, 0.309017f, -0.500000f}, + {-0.864188f, -0.442863f, -0.238856f}, + {-0.951056f, -0.162460f, -0.262866f}, + {-0.809017f, -0.309017f, -0.500000f}, + {-0.681718f, 0.147621f, -0.716567f}, + {-0.681718f, -0.147621f, -0.716567f}, + {-0.850651f, 0.000000f, -0.525731f}, + {-0.688191f, 0.587785f, -0.425325f}, + {-0.587785f, 0.425325f, -0.688191f}, + {-0.425325f, 0.688191f, -0.587785f}, + {-0.425325f, -0.688191f, -0.587785f}, + {-0.587785f, -0.425325f, -0.688191f}, + {-0.688191f, -0.587785f, -0.425325f}, + }; + +struct SMD2AnimationType +{ + s32 begin; + s32 end; + s32 fps; +}; + +static const SMD2AnimationType MD2AnimationTypeList[21] = +{ + { 0, 39, 9}, // STAND + { 40, 45, 10}, // RUN + { 46, 53, 10}, // ATTACK + { 54, 57, 7}, // PAIN_A + { 58, 61, 7}, // PAIN_B + { 62, 65, 7}, // PAIN_C + { 66, 71, 7}, // JUMP + { 72, 83, 7}, // FLIP + { 84, 94, 7}, // SALUTE + { 95, 111, 10}, // FALLBACK + {112, 122, 7}, // WAVE + {123, 134, 6}, // POINT + {135, 153, 10}, // CROUCH_STAND + {154, 159, 7}, // CROUCH_WALK + {160, 168, 10}, // CROUCH_ATTACK + {169, 172, 7}, // CROUCH_PAIN + {173, 177, 5}, // CROUCH_DEATH + {178, 183, 7}, // DEATH_FALLBACK + {184, 189, 7}, // DEATH_FALLFORWARD + {190, 197, 7}, // DEATH_FALLBACKSLOW + {198, 198, 5}, // BOOM +}; + + +//! constructor +CAnimatedMeshMD2::CAnimatedMeshMD2() + : InterpolationBuffer(0), FrameList(0), FrameCount(0), FramesPerSecond((f32)(MD2AnimationTypeList[0].fps << MD2_FRAME_SHIFT)) +{ + #ifdef _DEBUG + IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh"); + IMesh::setDebugName("CAnimatedMeshMD2 IMesh"); + #endif + InterpolationBuffer = new SMeshBuffer; +} + + +//! destructor +CAnimatedMeshMD2::~CAnimatedMeshMD2() +{ + delete [] FrameList; + if (InterpolationBuffer) + InterpolationBuffer->drop(); +} + + +//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. +u32 CAnimatedMeshMD2::getFrameCount() const +{ + return FrameCount< getFrameCount()) + frame = (frame % getFrameCount()); + + if (startFrameLoop == -1 && endFrameLoop == -1) + { + startFrameLoop = 0; + endFrameLoop = getFrameCount(); + } + + updateInterpolationBuffer(frame, startFrameLoop, endFrameLoop); + return this; +} + + +//! returns amount of mesh buffers. MD2 meshes only have one buffer +u32 CAnimatedMeshMD2::getMeshBufferCount() const +{ + return 1; +} + + +//! returns pointer to a mesh buffer +IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(u32 nr) const +{ + if (nr == 0) + return InterpolationBuffer; + else + return 0; +} + + +//! Returns pointer to a mesh buffer which fits a material +IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const +{ + if (InterpolationBuffer->Material == material) + return InterpolationBuffer; + else + return 0; +} + + +// updates the interpolation buffer +void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop, s32 endFrameLoop) +{ + u32 firstFrame, secondFrame; + f32 div; + + // TA: resolve missing ipol in loop between end-start + + if (endFrameLoop - startFrameLoop == 0) + { + firstFrame = frame>>MD2_FRAME_SHIFT; + secondFrame = frame>>MD2_FRAME_SHIFT; + div = 1.0f; + } + else + { + // key frames + u32 s = startFrameLoop >> MD2_FRAME_SHIFT; + u32 e = endFrameLoop >> MD2_FRAME_SHIFT; + + firstFrame = frame >> MD2_FRAME_SHIFT; + secondFrame = core::if_c_a_else_b(firstFrame + 1 > e, s, firstFrame + 1); + + firstFrame = core::s32_min(FrameCount - 1, firstFrame); + secondFrame = core::s32_min(FrameCount - 1, secondFrame); + + //div = (frame % (1<(InterpolationBuffer->getVertices()); + SMD2Vert* first = FrameList[firstFrame].pointer(); + SMD2Vert* second = FrameList[secondFrame].pointer(); + + // interpolate both frames + const u32 count = FrameList[firstFrame].size(); + for (u32 i=0; iPos.X) * FrameTransforms[firstFrame].scale.X + FrameTransforms[firstFrame].translate.X, + f32(first->Pos.Y) * FrameTransforms[firstFrame].scale.Y + FrameTransforms[firstFrame].translate.Y, + f32(first->Pos.Z) * FrameTransforms[firstFrame].scale.Z + FrameTransforms[firstFrame].translate.Z); + const core::vector3df two = core::vector3df(f32(second->Pos.X) * FrameTransforms[secondFrame].scale.X + FrameTransforms[secondFrame].translate.X, + f32(second->Pos.Y) * FrameTransforms[secondFrame].scale.Y + FrameTransforms[secondFrame].translate.Y, + f32(second->Pos.Z) * FrameTransforms[secondFrame].scale.Z + FrameTransforms[secondFrame].translate.Z); + target->Pos = two.getInterpolated(one, div); + const core::vector3df n1( + Q2_VERTEX_NORMAL_TABLE[first->NormalIdx][0], + Q2_VERTEX_NORMAL_TABLE[first->NormalIdx][2], + Q2_VERTEX_NORMAL_TABLE[first->NormalIdx][1]); + const core::vector3df n2( + Q2_VERTEX_NORMAL_TABLE[second->NormalIdx][0], + Q2_VERTEX_NORMAL_TABLE[second->NormalIdx][2], + Q2_VERTEX_NORMAL_TABLE[second->NormalIdx][1]); + target->Normal = n2.getInterpolated(n1, div); + ++target; + ++first; + ++second; + } + + //update bounding box + InterpolationBuffer->setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div)); + InterpolationBuffer->setDirty(); +} + + +//! sets a flag of all contained materials to a new value +void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) +{ + InterpolationBuffer->Material.setFlag(flag, newvalue); +} + + +//! set the hardware mapping hint, for driver +void CAnimatedMeshMD2::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, + E_BUFFER_TYPE buffer) +{ + InterpolationBuffer->setHardwareMappingHint(newMappingHint, buffer); +} + + +//! flags the meshbuffer as changed, reloads hardware buffers +void CAnimatedMeshMD2::setDirty(E_BUFFER_TYPE buffer) +{ + InterpolationBuffer->setDirty(buffer); +} + + +//! returns an axis aligned bounding box +const core::aabbox3d& CAnimatedMeshMD2::getBoundingBox() const +{ + return InterpolationBuffer->BoundingBox; +} + + +//! set user axis aligned bounding box +void CAnimatedMeshMD2::setBoundingBox(const core::aabbox3df& box) +{ + InterpolationBuffer->BoundingBox = box; +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CAnimatedMeshMD2::getMeshType() const +{ + return EAMT_MD2; +} + + +//! Returns frame loop data for a special MD2 animation type. +void CAnimatedMeshMD2::getFrameLoop(EMD2_ANIMATION_TYPE l, + s32& outBegin, s32& outEnd, s32& outFPS) const +{ + if (l < 0 || l >= EMAT_COUNT) + return; + + outBegin = MD2AnimationTypeList[l].begin << MD2_FRAME_SHIFT; + outEnd = MD2AnimationTypeList[l].end << MD2_FRAME_SHIFT; + + // correct to anim between last->first frame + outEnd += MD2_FRAME_SHIFT == 0 ? 1 : (1 << MD2_FRAME_SHIFT) - 1; + outFPS = MD2AnimationTypeList[l].fps << MD2_FRAME_SHIFT; +} + + +//! Returns frame loop data for a special MD2 animation type. +bool CAnimatedMeshMD2::getFrameLoop(const c8* name, + s32& outBegin, s32&outEnd, s32& outFPS) const +{ + for (u32 i=0; i < AnimationData.size(); ++i) + { + if (AnimationData[i].name == name) + { + outBegin = AnimationData[i].begin << MD2_FRAME_SHIFT; + outEnd = AnimationData[i].end << MD2_FRAME_SHIFT; + outEnd += MD2_FRAME_SHIFT == 0 ? 1 : (1 << MD2_FRAME_SHIFT) - 1; + outFPS = AnimationData[i].fps << MD2_FRAME_SHIFT; + return true; + } + } + + return false; +} + + +//! Returns amount of md2 animations in this file. +s32 CAnimatedMeshMD2::getAnimationCount() const +{ + return AnimationData.size(); +} + + +//! Returns name of md2 animation. +const c8* CAnimatedMeshMD2::getAnimationName(s32 nr) const +{ + if ((u32)nr >= AnimationData.size()) + return 0; + + return AnimationData[nr].name.c_str(); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD2_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.h new file mode 100644 index 0000000..0014910 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD2.h @@ -0,0 +1,154 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_MD2_H_INCLUDED__ +#define __C_ANIMATED_MESH_MD2_H_INCLUDED__ + +#include "IAnimatedMeshMD2.h" +#include "IMesh.h" +#include "CMeshBuffer.h" +#include "IReadFile.h" +#include "S3DVertex.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + + class CAnimatedMeshMD2 : public IAnimatedMeshMD2 + { + public: + + //! constructor + CAnimatedMeshMD2(); + + //! destructor + virtual ~CAnimatedMeshMD2(); + + //! returns the amount of frames. If the amount is 1, it is a static (=non animated) mesh. + virtual u32 getFrameCount() const; + + //! Gets the default animation speed of the animated mesh. + /** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ + virtual f32 getAnimationSpeed() const + { + return FramesPerSecond; + } + + //! Gets the frame count of the animated mesh. + /** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. + The actual speed is set in the scene node the mesh is instantiated in.*/ + virtual void setAnimationSpeed(f32 fps) + { + FramesPerSecond=fps; + } + + //! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. + virtual IMesh* getMesh(s32 frame, s32 detailLevel=255, s32 startFrameLoop=-1, s32 endFrameLoop=-1); + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const; + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const; + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Returns the pointer to the mesh buffer or + NULL if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const; + + //! returns an axis aligned bounding box + virtual const core::aabbox3d& getBoundingBox() const; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box); + + //! sets a flag of all contained materials to a new value + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! Returns frame loop data for a special MD2 animation type. + virtual void getFrameLoop(EMD2_ANIMATION_TYPE, + s32& outBegin, s32& outEnd, s32& outFps) const; + + //! Returns frame loop data for a special MD2 animation type. + virtual bool getFrameLoop(const c8* name, + s32& outBegin, s32& outEnd, s32& outFps) const; + + //! Returns amount of md2 animations in this file. + virtual s32 getAnimationCount() const; + + //! Returns name of md2 animation. + //! \param nr: Zero based index of animation. + virtual const c8* getAnimationName(s32 nr) const; + + + // + // exposed for loader + // + + //! the buffer that contains the most recent animation + SMeshBuffer* InterpolationBuffer; + + //! named animations + struct SAnimationData + { + core::stringc name; + s32 begin; + s32 end; + s32 fps; + }; + + //! scale and translations for keyframes + struct SKeyFrameTransform + { + core::vector3df scale; + core::vector3df translate; + }; + + //! md2 vertex data + struct SMD2Vert + { + core::vector3d Pos; + u8 NormalIdx; + }; + + //! keyframe transformations + core::array FrameTransforms; + + //! keyframe vertex data + core::array *FrameList; + + //! bounding boxes for each keyframe + core::array > BoxList; + + //! named animations + core::array< SAnimationData > AnimationData; + + u32 FrameCount; + + private: + + //! updates the interpolation buffer + void updateInterpolationBuffer(s32 frame, s32 startFrame, s32 endFrame); + + f32 FramesPerSecond; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.cpp new file mode 100644 index 0000000..0d3a091 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.cpp @@ -0,0 +1,468 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ + +#include "CAnimatedMeshMD3.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +// byte-align structures +#include "irrpack.h" + +//! General properties of a single animation frame. +struct SMD3Frame +{ + f32 mins[3]; // bounding box per frame + f32 maxs[3]; + f32 position[3]; // position of bounding box + f32 radius; // radius of bounding sphere + c8 creator[16]; // name of frame +} PACK_STRUCT; + + +//! An attachment point for another MD3 model. +struct SMD3Tag +{ + c8 Name[64]; //name of 'tag' as it's usually called in the md3 files try to see it as a sub-mesh/seperate mesh-part. + f32 position[3]; //relative position of tag + f32 rotationMatrix[9]; //3x3 rotation direction of tag +} PACK_STRUCT; + +//!Shader +struct SMD3Shader +{ + c8 name[64]; // name of shader + s32 shaderIndex; +} PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + +//! Constructor +CAnimatedMeshMD3::CAnimatedMeshMD3() +:Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f)//, FramesPerSecond(25.f) +{ +#ifdef _DEBUG + setDebugName("CAnimatedMeshMD3"); +#endif + + Mesh = new SMD3Mesh(); + MeshIPol = new SMesh(); + setInterpolationShift(0, 0); +} + + +//! Destructor +CAnimatedMeshMD3::~CAnimatedMeshMD3() +{ + if (Mesh) + Mesh->drop(); + if (MeshIPol) + MeshIPol->drop(); +} + + +//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. +u32 CAnimatedMeshMD3::getFrameCount() const +{ + return Mesh->MD3Header.numFrames << IPolShift; +} + + +//! Rendering Hint +void CAnimatedMeshMD3::setInterpolationShift(u32 shift, u32 loopMode) +{ + IPolShift = shift; + LoopMode = loopMode; +} + + +//! returns amount of mesh buffers. +u32 CAnimatedMeshMD3::getMeshBufferCount() const +{ + return MeshIPol->getMeshBufferCount(); +} + + +//! returns pointer to a mesh buffer +IMeshBuffer* CAnimatedMeshMD3::getMeshBuffer(u32 nr) const +{ + return MeshIPol->getMeshBuffer(nr); +} + + +//! Returns pointer to a mesh buffer which fits a material +IMeshBuffer* CAnimatedMeshMD3::getMeshBuffer(const video::SMaterial &material) const +{ + return MeshIPol->getMeshBuffer(material); +} + + +void CAnimatedMeshMD3::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) +{ + MeshIPol->setMaterialFlag(flag, newvalue); +} + + +//! set the hardware mapping hint, for driver +void CAnimatedMeshMD3::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, + E_BUFFER_TYPE buffer) +{ + MeshIPol->setHardwareMappingHint(newMappingHint, buffer); +} + + +//! flags the meshbuffer as changed, reloads hardware buffers +void CAnimatedMeshMD3::setDirty(E_BUFFER_TYPE buffer) +{ + MeshIPol->setDirty(buffer); +} + + +//! set user axis aligned bounding box +void CAnimatedMeshMD3::setBoundingBox(const core::aabbox3df& box) +{ + MeshIPol->setBoundingBox(box); +} + + +//! Returns the animated tag list based on a detail level. 0 is the lowest, 255 the highest detail. +SMD3QuaternionTagList *CAnimatedMeshMD3::getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + if (0 == Mesh) + return 0; + + getMesh(frame, detailLevel, startFrameLoop, endFrameLoop); + return &TagListIPol; +} + + +//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. +IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + if (0 == Mesh) + return 0; + + //! check if we have the mesh in our private cache + SCacheInfo candidate(frame, startFrameLoop, endFrameLoop); + if (candidate == Current) + return MeshIPol; + + startFrameLoop = core::s32_max(0, startFrameLoop >> IPolShift); + endFrameLoop = core::if_c_a_else_b(endFrameLoop < 0, Mesh->MD3Header.numFrames - 1, endFrameLoop >> IPolShift); + + const u32 mask = 1 << IPolShift; + + s32 frameA; + s32 frameB; + f32 iPol; + + if (LoopMode) + { + // correct frame to "pixel center" + frame -= mask >> 1; + + // interpolation + iPol = f32(frame & (mask - 1)) * core::reciprocal(f32(mask)); + + // wrap anim + frame >>= IPolShift; + frameA = core::if_c_a_else_b(frame < startFrameLoop, endFrameLoop, frame); + frameB = core::if_c_a_else_b(frameA + 1 > endFrameLoop, startFrameLoop, frameA + 1); + } + else + { + // correct frame to "pixel center" + frame -= mask >> 1; + + iPol = f32(frame & (mask - 1)) * core::reciprocal(f32(mask)); + + // clamp anim + frame >>= IPolShift; + frameA = core::s32_clamp(frame, startFrameLoop, endFrameLoop); + frameB = core::s32_min(frameA + 1, endFrameLoop); + } + + // build current vertex + for (u32 i = 0; i!= Mesh->Buffer.size(); ++i) + { + buildVertexArray(frameA, frameB, iPol, + Mesh->Buffer[i], + (SMeshBufferLightMap*) MeshIPol->getMeshBuffer(i)); + } + MeshIPol->recalculateBoundingBox(); + + // build current tags + buildTagArray(frameA, frameB, iPol); + + Current = candidate; + return MeshIPol; +} + + +//! create a Irrlicht MeshBuffer for a MD3 MeshBuffer +IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source, + io::IFileSystem* fs, video::IVideoDriver * driver) +{ + SMeshBufferLightMap * dest = new SMeshBufferLightMap(); + dest->Vertices.set_used(source->MeshHeader.numVertices); + dest->Indices.set_used(source->Indices.size()); + + u32 i; + + // fill in static face info + for (i = 0; i < source->Indices.size(); i += 3) + { + dest->Indices[i + 0] = (u16) source->Indices[i + 0]; + dest->Indices[i + 1] = (u16) source->Indices[i + 1]; + dest->Indices[i + 2] = (u16) source->Indices[i + 2]; + } + + // fill in static vertex info + for (i = 0; i!= (u32)source->MeshHeader.numVertices; ++i) + { + video::S3DVertex2TCoords &v = dest->Vertices[i]; + v.Color = 0xFFFFFFFF; + v.TCoords.X = source->Tex[i].u; + v.TCoords.Y = source->Tex[i].v; + v.TCoords2.X = 0.f; + v.TCoords2.Y = 0.f; + } + + // load static texture + u32 pos = 0; + quake3::tTexArray textureArray; + quake3::getTextures(textureArray, source->Shader, pos, fs, driver); + dest->Material.MaterialType = video::EMT_SOLID; + dest->Material.setTexture(0, textureArray[0]); + dest->Material.Lighting = false; + + return dest; +} + + +//! build final mesh's vertices from frames frameA and frameB with linear interpolation. +void CAnimatedMeshMD3::buildVertexArray(u32 frameA, u32 frameB, f32 interpolate, + const SMD3MeshBuffer* source, + SMeshBufferLightMap* dest) +{ + const u32 frameOffsetA = frameA * source->MeshHeader.numVertices; + const u32 frameOffsetB = frameB * source->MeshHeader.numVertices; + const f32 scale = (1.f/ 64.f); + + for (s32 i = 0; i != source->MeshHeader.numVertices; ++i) + { + video::S3DVertex2TCoords &v = dest->Vertices [ i ]; + + const SMD3Vertex &vA = source->Vertices [ frameOffsetA + i ]; + const SMD3Vertex &vB = source->Vertices [ frameOffsetB + i ]; + + // position + v.Pos.X = scale * (vA.position[0] + interpolate * (vB.position[0] - vA.position[0])); + v.Pos.Y = scale * (vA.position[2] + interpolate * (vB.position[2] - vA.position[2])); + v.Pos.Z = scale * (vA.position[1] + interpolate * (vB.position[1] - vA.position[1])); + + // normal + const core::vector3df nA(quake3::getMD3Normal(vA.normal[0], vA.normal[1])); + const core::vector3df nB(quake3::getMD3Normal(vB.normal[0], vB.normal[1])); + + v.Normal.X = nA.X + interpolate * (nB.X - nA.X); + v.Normal.Y = nA.Z + interpolate * (nB.Z - nA.Z); + v.Normal.Z = nA.Y + interpolate * (nB.Y - nA.Y); + } + + dest->recalculateBoundingBox(); +} + + +//! build final mesh's tag from frames frameA and frameB with linear interpolation. +void CAnimatedMeshMD3::buildTagArray(u32 frameA, u32 frameB, f32 interpolate) +{ + const u32 frameOffsetA = frameA * Mesh->MD3Header.numTags; + const u32 frameOffsetB = frameB * Mesh->MD3Header.numTags; + + for (s32 i = 0; i != Mesh->MD3Header.numTags; ++i) + { + SMD3QuaternionTag &d = TagListIPol [ i ]; + + const SMD3QuaternionTag &qA = Mesh->TagList[ frameOffsetA + i]; + const SMD3QuaternionTag &qB = Mesh->TagList[ frameOffsetB + i]; + + // rotation + d.rotation.slerp(qA.rotation, qB.rotation, interpolate); + + // position + d.position.X = qA.position.X + interpolate * (qB.position.X - qA.position.X); + d.position.Y = qA.position.Y + interpolate * (qB.position.Y - qA.position.Y); + d.position.Z = qA.position.Z + interpolate * (qB.position.Z - qA.position.Z); + } +} + + +/*! + loads a model +*/ +bool CAnimatedMeshMD3::loadModelFile(u32 modelIndex, io::IReadFile* file, + io::IFileSystem* fs, video::IVideoDriver* driver) +{ + if (!file) + return false; + + //! Check MD3Header + { + file->read(&Mesh->MD3Header, sizeof(SMD3Header)); + + if (strncmp("IDP3", Mesh->MD3Header.headerID, 4)) + { + os::Printer::log("MD3 Loader: invalid header"); + return false; + } + } + + //! store model name + Mesh->Name = file->getFileName(); + + u32 i; + + //! Frame Data (ignore) +#if 0 + SMD3Frame frameImport; + file->seek(Mesh->MD3Header.frameStart); + for (i = 0; i != Mesh->MD3Header.numFrames; ++i) + { + file->read(&frameImport, sizeof(frameImport)); + } +#endif + + //! Tag Data + const u32 totalTags = Mesh->MD3Header.numTags * Mesh->MD3Header.numFrames; + + SMD3Tag import; + + file->seek(Mesh->MD3Header.tagStart); + Mesh->TagList.set_used(totalTags); + for (i = 0; i != totalTags; ++i) + { + file->read(&import, sizeof(import)); + + SMD3QuaternionTag &exp = Mesh->TagList[i]; + + //! tag name + exp.Name = import.Name; + + //! position + exp.position.X = import.position[0]; + exp.position.Y = import.position[2]; + exp.position.Z = import.position[1]; + + //! construct quaternion from a RH 3x3 Matrix + exp.rotation.set(import.rotationMatrix[7], + 0.f, + -import.rotationMatrix[6], + 1 + import.rotationMatrix[8]); + exp.rotation.normalize(); + } + + //! Meshes + u32 offset = Mesh->MD3Header.tagEnd; + + for (i = 0; i != (u32)Mesh->MD3Header.numMeshes; ++i) + { + //! construct a new mesh buffer + SMD3MeshBuffer * buf = new SMD3MeshBuffer(); + + // !read mesh header info + SMD3MeshHeader &meshHeader = buf->MeshHeader; + + //! read mesh info + file->seek(offset); + file->read(&meshHeader, sizeof(SMD3MeshHeader)); + + //! prepare memory + buf->Vertices.set_used(meshHeader.numVertices * Mesh->MD3Header.numFrames); + buf->Indices.set_used(meshHeader.numTriangles * 3); + buf->Tex.set_used(meshHeader.numVertices); + + //! read skins (shaders). should be 1 per meshbuffer + SMD3Shader skin; + file->seek(offset + buf->MeshHeader.offset_shaders); + for (s32 g = 0; g != buf->MeshHeader.numShader; ++g) + { + file->read(&skin, sizeof(skin)); + + io::path name; + cutFilenameExtension(name, skin.name); + name.replace('\\', '/'); + buf->Shader = name; + } + + //! read texture coordinates + file->seek(offset + buf->MeshHeader.offset_st); + file->read(buf->Tex.pointer(), buf->MeshHeader.numVertices * sizeof(SMD3TexCoord)); + + //! read vertices + file->seek(offset + meshHeader.vertexStart); + file->read(buf->Vertices.pointer(), Mesh->MD3Header.numFrames * meshHeader.numVertices * sizeof(SMD3Vertex)); + + //! read indices + file->seek(offset + meshHeader.offset_triangles); + file->read(buf->Indices.pointer(), meshHeader.numTriangles * sizeof(SMD3Face)); + + //! store meshBuffer + Mesh->Buffer.push_back(buf); + + offset += meshHeader.offset_end; + } + + // Init Mesh Interpolation + for (i = 0; i != Mesh->Buffer.size(); ++i) + { + IMeshBuffer * buffer = createMeshBuffer(Mesh->Buffer[i], fs, driver); + MeshIPol->addMeshBuffer(buffer); + buffer->drop(); + } + MeshIPol->recalculateBoundingBox(); + + // Init Tag Interpolation + for (i = 0; i != (u32)Mesh->MD3Header.numTags; ++i) + { + TagListIPol.push_back(Mesh->TagList[i]); + } + + return true; +} + + +SMD3Mesh * CAnimatedMeshMD3::getOriginalMesh() +{ + return Mesh; +} + + +//! Returns an axis aligned bounding box +const core::aabbox3d& CAnimatedMeshMD3::getBoundingBox() const +{ + return MeshIPol->BoundingBox; +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CAnimatedMeshMD3::getMeshType() const +{ + return EAMT_MD3; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD3_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.h new file mode 100644 index 0000000..1b01eee --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshMD3.h @@ -0,0 +1,135 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_MD3_H_INCLUDED__ +#define __C_ANIMATED_MESH_MD3_H_INCLUDED__ + +#include "IAnimatedMeshMD3.h" +#include "IReadFile.h" +#include "IFileSystem.h" +#include "irrArray.h" +#include "irrString.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + + class CAnimatedMeshMD3 : public IAnimatedMeshMD3 + { + public: + + //! constructor + CAnimatedMeshMD3(); + + //! destructor + virtual ~CAnimatedMeshMD3(); + + //! loads a quake3 md3 file + virtual bool loadModelFile(u32 modelIndex, io::IReadFile* file, + io::IFileSystem* fs, video::IVideoDriver* driver); + + // IAnimatedMeshMD3 + virtual void setInterpolationShift(u32 shift, u32 loopMode); + virtual SMD3Mesh* getOriginalMesh(); + virtual SMD3QuaternionTagList* getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop); + + //IAnimatedMesh + virtual u32 getFrameCount() const; + + //! Gets the default animation speed of the animated mesh. + /** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ + virtual f32 getAnimationSpeed() const + { + return FramesPerSecond; + } + + //! Gets the frame count of the animated mesh. + /** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. + The actual speed is set in the scene node the mesh is instantiated in.*/ + virtual void setAnimationSpeed(f32 fps) + { + FramesPerSecond=fps; + } + + virtual IMesh* getMesh(s32 frame, s32 detailLevel, + s32 startFrameLoop, s32 endFrameLoop); + virtual const core::aabbox3d& getBoundingBox() const; + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const; + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const; + + //! Returns pointer to a mesh buffer which fits a material + virtual IMeshBuffer* getMeshBuffer(const video::SMaterial &material) const; + + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + //! set user axis aligned bounding box + virtual void setBoundingBox(const core::aabbox3df& box); + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + private: + //! animates one frame + inline void Animate(u32 frame); + + video::SMaterial Material; + + //! hold original compressed MD3 Info + SMD3Mesh *Mesh; + + u32 IPolShift; + u32 LoopMode; + f32 Scaling; + + //! Cache Info + struct SCacheInfo + { + SCacheInfo(s32 frame=-1, s32 start=-1, s32 end=-1 ) : + Frame(frame), startFrameLoop(start), + endFrameLoop(end) + {} + + bool operator == ( const SCacheInfo &other ) const + { + return 0 == memcmp ( this, &other, sizeof ( SCacheInfo ) ); + } + s32 Frame; + s32 startFrameLoop; + s32 endFrameLoop; + }; + SCacheInfo Current; + + //! return a Mesh per frame + SMesh* MeshIPol; + SMD3QuaternionTagList TagListIPol; + + IMeshBuffer* createMeshBuffer(const SMD3MeshBuffer* source, + io::IFileSystem* fs, video::IVideoDriver* driver); + + void buildVertexArray(u32 frameA, u32 frameB, f32 interpolate, + const SMD3MeshBuffer* source, + SMeshBufferLightMap* dest); + + void buildTagArray(u32 frameA, u32 frameB, f32 interpolate); + f32 FramesPerSecond; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.cpp new file mode 100644 index 0000000..9b9f533 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.cpp @@ -0,0 +1,1132 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CAnimatedMeshSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "os.h" +#include "CShadowVolumeSceneNode.h" +#include "IAnimatedMeshMD3.h" +#include "CSkinnedMesh.h" +#include "IDummyTransformationSceneNode.h" +#include "IBoneSceneNode.h" +#include "IMaterialRenderer.h" +#include "IMesh.h" +#include "IMeshCache.h" +#include "IAnimatedMesh.h" +#include "quaternion.h" + + +namespace irr +{ +namespace scene +{ + + +//! constructor +CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh, + ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) +: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), + StartFrame(0), EndFrame(0), FramesPerSecond(0.025f), + CurrentFrameNr(0.f), LastTimeMs(0), + TransitionTime(0), Transiting(0.f), TransitingBlend(0.f), + JointMode(EJUOR_NONE), JointsUsed(false), + Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false), + LoopCallBack(0), PassCount(0), Shadow(0), MD3Special(0) +{ + #ifdef _DEBUG + setDebugName("CAnimatedMeshSceneNode"); + #endif + + setMesh(mesh); +} + + +//! destructor +CAnimatedMeshSceneNode::~CAnimatedMeshSceneNode() +{ + if (MD3Special) + MD3Special->drop(); + + if (Mesh) + Mesh->drop(); + + if (Shadow) + Shadow->drop(); + + if (LoopCallBack) + LoopCallBack->drop(); +} + + +//! Sets the current frame. From now on the animation is played from this frame. +void CAnimatedMeshSceneNode::setCurrentFrame(f32 frame) +{ + // if you pass an out of range value, we just clamp it + CurrentFrameNr = core::clamp ( frame, (f32)StartFrame, (f32)EndFrame ); + + beginTransition(); //transit to this frame if enabled +} + + +//! Returns the currently displayed frame number. +f32 CAnimatedMeshSceneNode::getFrameNr() const +{ + return CurrentFrameNr; +} + + +//! Get CurrentFrameNr and update transiting settings +void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs) +{ + if (Transiting!=0.f) + { + TransitingBlend += (f32)(timeMs) * Transiting; + if (TransitingBlend > 1.f) + { + Transiting=0.f; + TransitingBlend=0.f; + } + } + + if ((StartFrame==EndFrame)) + { + CurrentFrameNr = (f32)StartFrame; //Support for non animated meshes + } + else if (Looping) + { + // play animation looped + CurrentFrameNr += timeMs * FramesPerSecond; + + // We have no interpolation between EndFrame and StartFrame, + // the last frame must be identical to first one with our current solution. + if (FramesPerSecond > 0.f) //forwards... + { + if (CurrentFrameNr > EndFrame) + CurrentFrameNr = StartFrame + fmod(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame)); + } + else //backwards... + { + if (CurrentFrameNr < StartFrame) + CurrentFrameNr = EndFrame - fmod(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame)); + } + } + else + { + // play animation non looped + + CurrentFrameNr += timeMs * FramesPerSecond; + if (FramesPerSecond > 0.f) //forwards... + { + if (CurrentFrameNr > (f32)EndFrame) + { + CurrentFrameNr = (f32)EndFrame; + if (LoopCallBack) + LoopCallBack->OnAnimationEnd(this); + } + } + else //backwards... + { + if (CurrentFrameNr < (f32)StartFrame) + { + CurrentFrameNr = (f32)StartFrame; + if (LoopCallBack) + LoopCallBack->OnAnimationEnd(this); + } + } + } +} + + +void CAnimatedMeshSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + // because this node supports rendering of mixed mode meshes consisting of + // transparent and solid material at the same time, we need to go through all + // materials, check of what type they are and register this node for the right + // render pass according to that. + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + PassCount = 0; + int transparentCount = 0; + int solidCount = 0; + + // count transparent and solid materials in this scene node + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + + // register according to material types counted + + if (solidCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + + if (transparentCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); + } +} + +IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame() +{ + if(Mesh->getMeshType() != EAMT_SKINNED) + { + s32 frameNr = (s32) getFrameNr(); + s32 frameBlend = (s32) (core::fract ( getFrameNr() ) * 1000.f); + return Mesh->getMesh(frameNr, frameBlend, StartFrame, EndFrame); + } + else + { +#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + return 0; +#else + + // As multiple scene nodes may be sharing the same skinned mesh, we have to + // re-animate it every frame to ensure that this node gets the mesh that it needs. + + CSkinnedMesh* skinnedMesh = reinterpret_cast(Mesh); + + if (JointMode == EJUOR_CONTROL)//write to mesh + skinnedMesh->transferJointsToMesh(JointChildSceneNodes); + else + skinnedMesh->animateMesh(getFrameNr(), 1.0f); + + // Update the skinned mesh for the current joint transforms. + skinnedMesh->skinMesh(); + + if (JointMode == EJUOR_READ)//read from mesh + { + skinnedMesh->recoverJointsFromMesh(JointChildSceneNodes); + + //---slow--- + for (u32 n=0;ngetParent()==this) + { + JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option + } + } + + if(JointMode == EJUOR_CONTROL) + { + // For meshes other than EJUOR_CONTROL, this is done by calling animateMesh() + skinnedMesh->updateBoundingBox(); + } + + return skinnedMesh; +#endif + } +} + + +//! OnAnimate() is called just before rendering the whole scene. +void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs) +{ + if (LastTimeMs==0) // first frame + { + LastTimeMs = timeMs; + } + + // set CurrentFrameNr + buildFrameNr(timeMs-LastTimeMs); + + // update bbox + if (Mesh) + { + scene::IMesh * mesh = getMeshForCurrentFrame(); + + if (mesh) + Box = mesh->getBoundingBox(); + } + LastTimeMs = timeMs; + + IAnimatedMeshSceneNode::OnAnimate(timeMs); +} + + +//! renders the node. +void CAnimatedMeshSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (!Mesh || !driver) + return; + + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + + ++PassCount; + + scene::IMesh* m = getMeshForCurrentFrame(); + + if(m) + { + Box = m->getBoundingBox(); + } + else + { + #ifdef _DEBUG + os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING); + #endif + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + if (Shadow && PassCount==1) + Shadow->updateShadowVolumes(); + + // for debug purposes only: + + bool renderMeshes = true; + video::SMaterial mat; + if (DebugDataVisible && PassCount==1) + { + // overwrite half transparency + if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) + { + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = m->getMeshBuffer(i); + mat = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; + mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; + if (RenderFromIdentity) + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); + else if (Mesh->getMeshType() == EAMT_SKINNED) + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); + + driver->setMaterial(mat); + driver->drawMeshBuffer(mb); + } + renderMeshes = false; + } + } + + // render original meshes + if (renderMeshes) + { + for (u32 i=0; igetMeshBufferCount(); ++i) + { + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + scene::IMeshBuffer* mb = m->getMeshBuffer(i); + const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; + if (RenderFromIdentity) + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); + else if (Mesh->getMeshType() == EAMT_SKINNED) + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); + + driver->setMaterial(material); + driver->drawMeshBuffer(mb); + } + } + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + // for debug purposes only: + if (DebugDataVisible && PassCount==1) + { + video::SMaterial debug_mat; + debug_mat.Lighting = false; + debug_mat.AntiAliasing=0; + driver->setMaterial(debug_mat); + // show normals + if (DebugDataVisible & scene::EDS_NORMALS) + { + const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); + const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); + const u32 count = m->getMeshBufferCount(); + + // draw normals + for (u32 g=0; g < count; ++g) + { + driver->drawMeshBufferNormals(m->getMeshBuffer(g), debugNormalLength, debugNormalColor); + } + } + + debug_mat.ZBuffer = video::ECFN_NEVER; + debug_mat.Lighting = false; + driver->setMaterial(debug_mat); + + if (DebugDataVisible & scene::EDS_BBOX) + driver->draw3DBox(Box, video::SColor(255,255,255,255)); + + // show bounding box + if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) + { + for (u32 g=0; g< m->getMeshBufferCount(); ++g) + { + const IMeshBuffer* mb = m->getMeshBuffer(g); + + if (Mesh->getMeshType() == EAMT_SKINNED) + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); + driver->draw3DBox(mb->getBoundingBox(), video::SColor(255,190,128,128)); + } + } + + // show skeleton + if (DebugDataVisible & scene::EDS_SKELETON) + { + if (Mesh->getMeshType() == EAMT_SKINNED) + { + // draw skeleton + + for (u32 g=0; g < ((ISkinnedMesh*)Mesh)->getAllJoints().size(); ++g) + { + ISkinnedMesh::SJoint *joint=((ISkinnedMesh*)Mesh)->getAllJoints()[g]; + + for (u32 n=0;nChildren.size();++n) + { + driver->draw3DLine(joint->GlobalAnimatedMatrix.getTranslation(), + joint->Children[n]->GlobalAnimatedMatrix.getTranslation(), + video::SColor(255,51,66,255)); + } + } + } + + // show tag for quake3 models + if (Mesh->getMeshType() == EAMT_MD3) + { + IAnimatedMesh * arrow = + SceneManager->addArrowMesh ( + "__tag_show", + 0xFF0000FF, 0xFF000088, + 4, 8, 5.f, 4.f, 0.5f, + 1.f); + if (!arrow) + { + arrow = SceneManager->getMesh ( "__tag_show" ); + } + IMesh *arrowMesh = arrow->getMesh(0); + + core::matrix4 matr; + + SMD3QuaternionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList( + (s32)getFrameNr(), 255, + getStartFrame(), getEndFrame()); + if (taglist) + { + for ( u32 ts = 0; ts != taglist->size(); ++ts ) + { + (*taglist)[ts].setto(matr); + + driver->setTransform(video::ETS_WORLD, matr ); + + for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a ) + driver->drawMeshBuffer(arrowMesh->getMeshBuffer(a)); + } + } + } + } + + // show mesh + if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) + { + debug_mat.Lighting = false; + debug_mat.Wireframe = true; + debug_mat.ZBuffer = video::ECFN_NEVER; + driver->setMaterial(debug_mat); + + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + const IMeshBuffer* mb = m->getMeshBuffer(g); + if (RenderFromIdentity) + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); + else if (Mesh->getMeshType() == EAMT_SKINNED) + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((SSkinMeshBuffer*)mb)->Transformation); + driver->drawMeshBuffer(mb); + } + } + } +} + + +//! Returns the current start frame number. +s32 CAnimatedMeshSceneNode::getStartFrame() const +{ + return StartFrame; +} + + +//! Returns the current start frame number. +s32 CAnimatedMeshSceneNode::getEndFrame() const +{ + return EndFrame; +} + + +//! sets the frames between the animation is looped. +//! the default is 0 - MaximalFrameCount of the mesh. +bool CAnimatedMeshSceneNode::setFrameLoop(s32 begin, s32 end) +{ + const s32 maxFrameCount = Mesh->getFrameCount() - 1; + if (end < begin) + { + StartFrame = core::s32_clamp(end, 0, maxFrameCount); + EndFrame = core::s32_clamp(begin, StartFrame, maxFrameCount); + } + else + { + StartFrame = core::s32_clamp(begin, 0, maxFrameCount); + EndFrame = core::s32_clamp(end, StartFrame, maxFrameCount); + } + if (FramesPerSecond < 0) + setCurrentFrame((f32)EndFrame); + else + setCurrentFrame((f32)StartFrame); + + return true; +} + + +//! sets the speed with witch the animation is played +void CAnimatedMeshSceneNode::setAnimationSpeed(f32 framesPerSecond) +{ + FramesPerSecond = framesPerSecond * 0.001f; +} + + +f32 CAnimatedMeshSceneNode::getAnimationSpeed() const +{ + return FramesPerSecond * 1000.f; +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CAnimatedMeshSceneNode::getBoundingBox() const +{ + return Box; +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CAnimatedMeshSceneNode::getMaterial(u32 i) +{ + if (i >= Materials.size()) + return ISceneNode::getMaterial(i); + + return Materials[i]; +} + + + +//! returns amount of materials used by this scene node. +u32 CAnimatedMeshSceneNode::getMaterialCount() const +{ + return Materials.size(); +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* CAnimatedMeshSceneNode::addShadowVolumeSceneNode( + const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (!shadowMesh) + shadowMesh = Mesh; // if null is given, use the mesh of node + + if (Shadow) + Shadow->drop(); + + Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + +//! Returns a pointer to a child node, which has the same transformation as +//! the corresponding joint, if the mesh in this scene node is a skinned mesh. +IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(const c8* jointName) +{ +#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + os::Printer::log("Compiled without _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_", ELL_WARNING); + return 0; +#else + + if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) + { + os::Printer::log("No mesh, or mesh not of skinned mesh type", ELL_WARNING); + return 0; + } + + checkJoints(); + + ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh; + + const s32 number = skinnedMesh->getJointNumber(jointName); + + if (number == -1) + { + os::Printer::log("Joint with specified name not found in skinned mesh", jointName, ELL_DEBUG); + return 0; + } + + if ((s32)JointChildSceneNodes.size() <= number) + { + os::Printer::log("Joint was found in mesh, but is not loaded into node", jointName, ELL_WARNING); + return 0; + } + + return JointChildSceneNodes[number]; +#endif +} + + + +//! Returns a pointer to a child node, which has the same transformation as +//! the corresponding joint, if the mesh in this scene node is a skinned mesh. +IBoneSceneNode* CAnimatedMeshSceneNode::getJointNode(u32 jointID) +{ +#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + os::Printer::log("Compiled without _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_", ELL_WARNING); + return 0; +#else + + if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) + { + os::Printer::log("No mesh, or mesh not of skinned mesh type", ELL_WARNING); + return 0; + } + + checkJoints(); + + if (JointChildSceneNodes.size() <= jointID) + { + os::Printer::log("Joint not loaded into node", ELL_WARNING); + return 0; + } + + return JointChildSceneNodes[jointID]; +#endif +} + +//! Gets joint count. +u32 CAnimatedMeshSceneNode::getJointCount() const +{ +#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + return 0; +#else + + if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) + return 0; + + ISkinnedMesh *skinnedMesh=(ISkinnedMesh*)Mesh; + + return skinnedMesh->getJointCount(); +#endif +} + + +//! Returns a pointer to a child node, which has the same transformation as +//! the corresponding joint, if the mesh in this scene node is a ms3d mesh. +ISceneNode* CAnimatedMeshSceneNode::getMS3DJointNode(const c8* jointName) +{ + return getJointNode(jointName); +} + + +//! Returns a pointer to a child node, which has the same transformation as +//! the corresponding joint, if the mesh in this scene node is a .x mesh. +ISceneNode* CAnimatedMeshSceneNode::getXJointNode(const c8* jointName) +{ + return getJointNode(jointName); +} + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool CAnimatedMeshSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + } + + if (ISceneNode::removeChild(child)) + { + if (JointsUsed) //stop weird bugs caused while changing parents as the joints are being created + { + for (u32 i=0; igetMeshType() != EAMT_MD2) + return false; + + IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh; + + s32 begin, end, speed; + md->getFrameLoop(anim, begin, end, speed); + + setAnimationSpeed( f32(speed) ); + setFrameLoop(begin, end); + return true; +} + + +//! Starts a special MD2 animation. +bool CAnimatedMeshSceneNode::setMD2Animation(const c8* animationName) +{ + if (!Mesh || Mesh->getMeshType() != EAMT_MD2) + return false; + + IAnimatedMeshMD2* md = (IAnimatedMeshMD2*)Mesh; + + s32 begin, end, speed; + if (!md->getFrameLoop(animationName, begin, end, speed)) + return false; + + setAnimationSpeed( (f32)speed ); + setFrameLoop(begin, end); + return true; +} + + +//! Sets looping mode which is on by default. If set to false, +//! animations will not be looped. +void CAnimatedMeshSceneNode::setLoopMode(bool playAnimationLooped) +{ + Looping = playAnimationLooped; +} + +//! returns the current loop mode +bool CAnimatedMeshSceneNode::getLoopMode() const +{ + return Looping; +} + + +//! Sets a callback interface which will be called if an animation +//! playback has ended. Set this to 0 to disable the callback again. +void CAnimatedMeshSceneNode::setAnimationEndCallback(IAnimationEndCallBack* callback) +{ + if (callback == LoopCallBack) + return; + + if (LoopCallBack) + LoopCallBack->drop(); + + LoopCallBack = callback; + + if (LoopCallBack) + LoopCallBack->grab(); +} + + +//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. +void CAnimatedMeshSceneNode::setReadOnlyMaterials(bool readonly) +{ + ReadOnlyMaterials = readonly; +} + + +//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style +bool CAnimatedMeshSceneNode::isReadOnlyMaterials() const +{ + return ReadOnlyMaterials; +} + + +//! Writes attributes of the scene node. +void CAnimatedMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IAnimatedMeshSceneNode::serializeAttributes(out, options); + + if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename) + { + const io::path path = SceneManager->getFileSystem()->getRelativeFilename( + SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()), + options->Filename); + out->addString("Mesh", path.c_str()); + } + else + out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str()); + out->addBool("Looping", Looping); + out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); + out->addFloat("FramesPerSecond", FramesPerSecond); + out->addInt("StartFrame", StartFrame); + out->addInt("EndFrame", EndFrame); +} + + +//! Reads attributes of the scene node. +void CAnimatedMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IAnimatedMeshSceneNode::deserializeAttributes(in, options); + + io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh); + io::path newMeshStr = in->getAttributeAsString("Mesh"); + + Looping = in->getAttributeAsBool("Looping"); + ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); + FramesPerSecond = in->getAttributeAsFloat("FramesPerSecond"); + StartFrame = in->getAttributeAsInt("StartFrame"); + EndFrame = in->getAttributeAsInt("EndFrame"); + + if (newMeshStr != "" && oldMeshStr != newMeshStr) + { + IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); + + if (newAnimatedMesh) + setMesh(newAnimatedMesh); + } + + // TODO: read animation names instead of frame begin and ends +} + + +//! Sets a new mesh +void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh) +{ + if (!mesh) + return; // won't set null mesh + + if (Mesh != mesh) + { + if (Mesh) + Mesh->drop(); + + Mesh = mesh; + + // grab the mesh (it's non-null!) + Mesh->grab(); + } + + // get materials and bounding box + Box = Mesh->getBoundingBox(); + + IMesh* m = Mesh->getMesh(0,0); + if (m) + { + Materials.clear(); + Materials.reallocate(m->getMeshBufferCount()); + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* mb = m->getMeshBuffer(i); + if (mb) + Materials.push_back(mb->getMaterial()); + else + Materials.push_back(video::SMaterial()); + } + } + + // clean up joint nodes + if (JointsUsed) + { + JointsUsed=false; + checkJoints(); + } + + // get start and begin time +// setAnimationSpeed(Mesh->getAnimationSpeed()); + setFrameLoop(0, Mesh->getFrameCount()); +} + + +// returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, +// or the absolutetransformation if it's a normal scenenode +const SMD3QuaternionTag* CAnimatedMeshSceneNode::getMD3TagTransformation(const core::stringc& tagname) +{ + return MD3Special ? MD3Special->AbsoluteTagList.get(tagname) : 0; +} + + +//! updates the absolute position based on the relative and the parents position +void CAnimatedMeshSceneNode::updateAbsolutePosition() +{ + IAnimatedMeshSceneNode::updateAbsolutePosition(); + + if (!Mesh || Mesh->getMeshType() != EAMT_MD3) + return; + + SMD3QuaternionTagList *taglist; + taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( (s32)getFrameNr(),255,getStartFrame (),getEndFrame () ); + if (taglist) + { + if (!MD3Special) + { + MD3Special = new SMD3Special(); + } + + SMD3QuaternionTag parent ( MD3Special->Tagname ); + if (Parent && Parent->getType() == ESNT_ANIMATED_MESH) + { + const SMD3QuaternionTag * p = ((IAnimatedMeshSceneNode*) Parent)->getMD3TagTransformation + ( MD3Special->Tagname ); + + if (p) + parent = *p; + } + + SMD3QuaternionTag relative( RelativeTranslation, RelativeRotation ); + + MD3Special->AbsoluteTagList.set_used ( taglist->size () ); + for ( u32 i=0; i!= taglist->size (); ++i ) + { + MD3Special->AbsoluteTagList[i].position = parent.position + (*taglist)[i].position + relative.position; + MD3Special->AbsoluteTagList[i].rotation = parent.rotation * (*taglist)[i].rotation * relative.rotation; + } + } +} + +//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set) +void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode) +{ + checkJoints(); + JointMode=mode; +} + +//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2) +//! you must call animateJoints(), or the mesh will not animate +void CAnimatedMeshSceneNode::setTransitionTime(f32 time) +{ + const u32 ttime = (u32)core::floor32(time*1000.0f); + if (TransitionTime==ttime) + return; + TransitionTime = ttime; + if (ttime != 0) + setJointMode(EJUOR_CONTROL); + else + setJointMode(EJUOR_NONE); +} + + +//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected) +void CAnimatedMeshSceneNode::setRenderFromIdentity(bool enable) +{ + RenderFromIdentity=enable; +} + + +//! updates the joint positions of this mesh +void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions) +{ +#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + return; +#else + if (Mesh && Mesh->getMeshType() == EAMT_SKINNED ) + { + checkJoints(); + const f32 frame = getFrameNr(); //old? + + CSkinnedMesh* skinnedMesh=reinterpret_cast(Mesh); + + skinnedMesh->transferOnlyJointsHintsToMesh( JointChildSceneNodes ); + skinnedMesh->animateMesh(frame, 1.0f); + skinnedMesh->recoverJointsFromMesh( JointChildSceneNodes); + + //----------------------------------------- + // Transition + //----------------------------------------- + + if (Transiting != 0.f) + { + // Init additional matrices + if (PretransitingSave.size()setPosition( + core::lerp( + PretransitingSave[n].getTranslation(), + JointChildSceneNodes[n]->getPosition(), + TransitingBlend)); + + //------Rotation------ + + //Code is slow, needs to be fixed up + + const core::quaternion RotationStart(PretransitingSave[n].getRotationDegrees()*core::DEGTORAD); + const core::quaternion RotationEnd(JointChildSceneNodes[n]->getRotation()*core::DEGTORAD); + + core::quaternion QRotation; + QRotation.slerp(RotationStart, RotationEnd, TransitingBlend); + + core::vector3df tmpVector; + QRotation.toEuler(tmpVector); + tmpVector*=core::RADTODEG; //convert from radians back to degrees + JointChildSceneNodes[n]->setRotation( tmpVector ); + + //------Scale------ + + //JointChildSceneNodes[n]->setScale( + // core::lerp( + // PretransitingSave[n].getScale(), + // JointChildSceneNodes[n]->getScale(), + // TransitingBlend)); + } + } + + if (CalculateAbsolutePositions) + { + //---slow--- + for (u32 n=0;ngetParent()==this) + { + JointChildSceneNodes[n]->updateAbsolutePositionOfAllChildren(); //temp, should be an option + } + } + } + } +#endif +} + +/*! +*/ +void CAnimatedMeshSceneNode::checkJoints() +{ +#ifndef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + return; +#else + + if (!Mesh || Mesh->getMeshType() != EAMT_SKINNED) + return; + + if (!JointsUsed) + { + for (u32 i=0; iaddJoints(JointChildSceneNodes, this, SceneManager); + ((CSkinnedMesh*)Mesh)->recoverJointsFromMesh(JointChildSceneNodes); + + JointsUsed=true; + JointMode=EJUOR_READ; + } +#endif +} + +/*! +*/ +void CAnimatedMeshSceneNode::beginTransition() +{ + if (!JointsUsed) + return; + + if (TransitionTime != 0) + { + //Check the array is big enough + if (PretransitingSave.size()getRelativeTransformation(); + + Transiting = core::reciprocal((f32)TransitionTime); + } + TransitingBlend = 0.f; +} + + +/*! +*/ +ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CAnimatedMeshSceneNode* newNode = + new CAnimatedMeshSceneNode(Mesh, NULL, newManager, ID, RelativeTranslation, + RelativeRotation, RelativeScale); + + if (newParent) + { + newNode->setParent(newParent); // not in constructor because virtual overload for updateAbsolutePosition won't be called + newNode->drop(); + } + + newNode->cloneMembers(this, newManager); + + newNode->Materials = Materials; + newNode->Box = Box; + newNode->Mesh = Mesh; + newNode->StartFrame = StartFrame; + newNode->EndFrame = EndFrame; + newNode->FramesPerSecond = FramesPerSecond; + newNode->CurrentFrameNr = CurrentFrameNr; + newNode->JointMode = JointMode; + newNode->JointsUsed = JointsUsed; + newNode->TransitionTime = TransitionTime; + newNode->Transiting = Transiting; + newNode->TransitingBlend = TransitingBlend; + newNode->Looping = Looping; + newNode->ReadOnlyMaterials = ReadOnlyMaterials; + newNode->LoopCallBack = LoopCallBack; + if (newNode->LoopCallBack) + newNode->LoopCallBack->grab(); + newNode->PassCount = PassCount; + newNode->Shadow = Shadow; + if (newNode->Shadow) + newNode->Shadow->grab(); + newNode->JointChildSceneNodes = JointChildSceneNodes; + newNode->PretransitingSave = PretransitingSave; + newNode->RenderFromIdentity = RenderFromIdentity; + newNode->MD3Special = MD3Special; + + return newNode; +} + + +} // end namespace scene +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.h new file mode 100644 index 0000000..522393d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAnimatedMeshSceneNode.h @@ -0,0 +1,227 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ +#define __C_ANIMATED_MESH_SCENE_NODE_H_INCLUDED__ + +#include "IAnimatedMeshSceneNode.h" +#include "IAnimatedMesh.h" + +#include "matrix4.h" + + +namespace irr +{ +namespace scene +{ + class IDummyTransformationSceneNode; + + class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode + { + public: + + //! constructor + CAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CAnimatedMeshSceneNode(); + + //! sets the current frame. from now on the animation is played from this frame. + virtual void setCurrentFrame(f32 frame); + + //! frame + virtual void OnRegisterSceneNode(); + + //! OnAnimate() is called just before rendering the whole scene. + virtual void OnAnimate(u32 timeMs); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the frames between the animation is looped. + //! the default is 0 - MaximalFrameCount of the mesh. + virtual bool setFrameLoop(s32 begin, s32 end); + + //! Sets looping mode which is on by default. If set to false, + //! animations will not be looped. + virtual void setLoopMode(bool playAnimationLooped); + + //! returns the current loop mode + virtual bool getLoopMode() const; + + //! Sets a callback interface which will be called if an animation + //! playback has ended. Set this to 0 to disable the callback again. + virtual void setAnimationEndCallback(IAnimationEndCallBack* callback=0); + + //! sets the speed with which the animation is played + virtual void setAnimationSpeed(f32 framesPerSecond); + + //! gets the speed with which the animation is played + virtual f32 getAnimationSpeed() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh, + s32 id, bool zfailmethod=true, f32 infinity=1000.0f); + + //! Returns a pointer to a child node, which has the same transformation as + //! the corrsesponding joint, if the mesh in this scene node is a skinned mesh. + virtual IBoneSceneNode* getJointNode(const c8* jointName); + + //! same as getJointNode(const c8* jointName), but based on id + virtual IBoneSceneNode* getJointNode(u32 jointID); + + //! Gets joint count. + virtual u32 getJointCount() const; + + //! Deprecated command, please use getJointNode. + virtual ISceneNode* getMS3DJointNode(const c8* jointName); + + //! Deprecated command, please use getJointNode. + virtual ISceneNode* getXJointNode(const c8* jointName); + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + + //! Starts a MD2 animation. + virtual bool setMD2Animation(EMD2_ANIMATION_TYPE anim); + + //! Starts a special MD2 animation. + virtual bool setMD2Animation(const c8* animationName); + + //! Returns the current displayed frame number. + virtual f32 getFrameNr() const; + //! Returns the current start frame number. + virtual s32 getStartFrame() const; + //! Returns the current end frame number. + virtual s32 getEndFrame() const; + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly); + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const; + + //! Sets a new mesh + virtual void setMesh(IAnimatedMesh* mesh); + + //! Returns the current mesh + virtual IAnimatedMesh* getMesh(void) { return Mesh; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_ANIMATED_MESH; } + + // returns the absolute transformation for a special MD3 Tag if the mesh is a md3 mesh, + // or the absolutetransformation if it's a normal scenenode + const SMD3QuaternionTag* getMD3TagTransformation( const core::stringc & tagname); + + //! updates the absolute position based on the relative and the parents position + virtual void updateAbsolutePosition(); + + + //! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set) + virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode); + + //! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2) + //! you must call animateJoints(), or the mesh will not animate + virtual void setTransitionTime(f32 Time); + + //! updates the joint positions of this mesh + virtual void animateJoints(bool CalculateAbsolutePositions=true); + + //! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected) + virtual void setRenderFromIdentity( bool On ); + + //! Creates a clone of this scene node and its children. + /** \param newParent An optional new parent. + \param newManager An optional new scene manager. + \return The newly created clone of this node. */ + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + //! Get a static mesh for the current frame of this animated mesh + IMesh* getMeshForCurrentFrame(); + + void buildFrameNr(u32 timeMs); + void checkJoints(); + void beginTransition(); + + core::array Materials; + core::aabbox3d Box; + IAnimatedMesh* Mesh; + + s32 StartFrame; + s32 EndFrame; + f32 FramesPerSecond; + f32 CurrentFrameNr; + + u32 LastTimeMs; + u32 TransitionTime; //Transition time in millisecs + f32 Transiting; //is mesh transiting (plus cache of TransitionTime) + f32 TransitingBlend; //0-1, calculated on buildFrameNr + + //0-unused, 1-get joints only, 2-set joints only, 3-move and set + E_JOINT_UPDATE_ON_RENDER JointMode; + bool JointsUsed; + + bool Looping; + bool ReadOnlyMaterials; + bool RenderFromIdentity; + + IAnimationEndCallBack* LoopCallBack; + s32 PassCount; + + IShadowVolumeSceneNode* Shadow; + + core::array JointChildSceneNodes; + core::array PretransitingSave; + + // Quake3 Model + struct SMD3Special : public virtual IReferenceCounted + { + core::stringc Tagname; + SMD3QuaternionTagList AbsoluteTagList; + + SMD3Special & operator = (const SMD3Special & copyMe) + { + Tagname = copyMe.Tagname; + AbsoluteTagList = copyMe.AbsoluteTagList; + return *this; + } + }; + SMD3Special *MD3Special; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributeImpl.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributeImpl.h new file mode 100644 index 0000000..f59c27c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributeImpl.h @@ -0,0 +1,2071 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CAttributes.h" +#include "fast_atof.h" +#include "ITexture.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace io +{ + +/* + basic types +*/ + +// Attribute implemented for boolean values +class CBoolAttribute : public IAttribute +{ +public: + + CBoolAttribute(const char* name, bool value) + { + Name = name; + setBool(value); + } + + virtual s32 getInt() + { + return BoolValue ? 1 : 0; + } + + virtual f32 getFloat() + { + return BoolValue ? 1.0f : 0.0f; + } + + virtual bool getBool() + { + return BoolValue; + } + + virtual core::stringw getStringW() + { + return core::stringw( BoolValue ? L"true" : L"false" ); + } + + virtual void setInt(s32 intValue) + { + BoolValue = (intValue != 0); + } + + virtual void setFloat(f32 floatValue) + { + BoolValue = (floatValue != 0); + } + + virtual void setBool(bool boolValue) + { + BoolValue = boolValue; + } + + virtual void setString(const char* string) + { + BoolValue = strcmp(string, "true") == 0; + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_BOOL; + } + + virtual const wchar_t* getTypeString() const + { + return L"bool"; + } + + bool BoolValue; +}; + +// Attribute implemented for integers +class CIntAttribute : public IAttribute +{ +public: + + CIntAttribute(const char* name, s32 value) + { + Name = name; + setInt(value); + } + + virtual s32 getInt() + { + return Value; + } + + virtual f32 getFloat() + { + return (f32)Value; + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + return core::stringw(Value); + } + + virtual void setInt(s32 intValue) + { + Value = intValue; + } + + virtual void setFloat(f32 floatValue) + { + Value = (s32)floatValue; + }; + + virtual void setString(const char* text) + { + Value = atoi(text); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_INT; + } + + + virtual const wchar_t* getTypeString() const + { + return L"int"; + } + + s32 Value; +}; + +// Attribute implemented for floats +class CFloatAttribute : public IAttribute +{ +public: + + CFloatAttribute(const char* name, f32 value) + { + Name = name; + setFloat(value); + } + + virtual s32 getInt() + { + return (s32)Value; + } + + virtual f32 getFloat() + { + return Value; + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + return core::stringw((double)Value); + } + + virtual void setInt(s32 intValue) + { + Value = (f32)intValue; + } + + virtual void setFloat(f32 floatValue) + { + Value = floatValue; + } + + virtual void setString(const char* text) + { + Value = core::fast_atof(text); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_FLOAT; + } + + + virtual const wchar_t* getTypeString() const + { + return L"float"; + } + + f32 Value; +}; + + + +/* + Types which can be represented as a list of numbers +*/ + +// Base class for all attributes which are a list of numbers- +// vectors, colors, positions, triangles, etc +class CNumbersAttribute : public IAttribute +{ +public: + + CNumbersAttribute(const char* name, video::SColorf value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.r); + ValueF.push_back(value.g); + ValueF.push_back(value.b); + ValueF.push_back(value.a); + } + + CNumbersAttribute(const char* name, video::SColor value) : + ValueI(), ValueF(), Count(4), IsFloat(false) + { + Name = name; + ValueI.push_back(value.getRed()); + ValueI.push_back(value.getGreen()); + ValueI.push_back(value.getBlue()); + ValueI.push_back(value.getAlpha()); + } + + + CNumbersAttribute(const char* name, core::vector3df value) : + ValueI(), ValueF(), Count(3), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + ValueF.push_back(value.Z); + } + + CNumbersAttribute(const char* name, core::rect value) : + ValueI(), ValueF(), Count(4), IsFloat(false) + { + Name = name; + ValueI.push_back(value.UpperLeftCorner.X); + ValueI.push_back(value.UpperLeftCorner.Y); + ValueI.push_back(value.LowerRightCorner.X); + ValueI.push_back(value.LowerRightCorner.Y); + } + + CNumbersAttribute(const char* name, core::rect value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.UpperLeftCorner.X); + ValueF.push_back(value.UpperLeftCorner.Y); + ValueF.push_back(value.LowerRightCorner.X); + ValueF.push_back(value.LowerRightCorner.Y); + } + + CNumbersAttribute(const char* name, core::matrix4 value) : + ValueI(), ValueF(), Count(16), IsFloat(true) + { + Name = name; + for (s32 r=0; r<4; ++r) + for (s32 c=0; c<4; ++c) + ValueF.push_back(value(r,c)); + } + + CNumbersAttribute(const char* name, core::quaternion value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + ValueF.push_back(value.Z); + ValueF.push_back(value.W); + } + + CNumbersAttribute(const char* name, core::aabbox3d value) : + ValueI(), ValueF(), Count(6), IsFloat(true) + { + Name = name; + ValueF.push_back(value.MinEdge.X); + ValueF.push_back(value.MinEdge.Y); + ValueF.push_back(value.MinEdge.Z); + ValueF.push_back(value.MaxEdge.X); + ValueF.push_back(value.MaxEdge.Y); + ValueF.push_back(value.MaxEdge.Z); + } + + CNumbersAttribute(const char* name, core::plane3df value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.Normal.X); + ValueF.push_back(value.Normal.Y); + ValueF.push_back(value.Normal.Z); + ValueF.push_back(value.D); + } + + CNumbersAttribute(const char* name, core::triangle3df value) : + ValueI(), ValueF(), Count(9), IsFloat(true) + { + Name = name; + ValueF.push_back(value.pointA.X); + ValueF.push_back(value.pointA.Y); + ValueF.push_back(value.pointA.Z); + ValueF.push_back(value.pointB.X); + ValueF.push_back(value.pointB.Y); + ValueF.push_back(value.pointB.Z); + ValueF.push_back(value.pointC.X); + ValueF.push_back(value.pointC.Y); + ValueF.push_back(value.pointC.Z); + } + + CNumbersAttribute(const char* name, core::vector2df value) : + ValueI(), ValueF(), Count(2), IsFloat(true) + { + Name = name; + ValueF.push_back(value.X); + ValueF.push_back(value.Y); + } + + CNumbersAttribute(const char* name, core::vector2di value) : + ValueI(), ValueF(), Count(2), IsFloat(false) + { + Name = name; + ValueI.push_back(value.X); + ValueI.push_back(value.Y); + } + + CNumbersAttribute(const char* name, core::line2di value) : + ValueI(), ValueF(), Count(4), IsFloat(false) + { + Name = name; + ValueI.push_back(value.start.X); + ValueI.push_back(value.start.Y); + ValueI.push_back(value.end.X); + ValueI.push_back(value.end.Y); + } + + CNumbersAttribute(const char* name, core::line2df value) : + ValueI(), ValueF(), Count(4), IsFloat(true) + { + Name = name; + ValueF.push_back(value.start.X); + ValueF.push_back(value.start.Y); + ValueF.push_back(value.end.X); + ValueF.push_back(value.end.Y); + } + + CNumbersAttribute(const char* name, core::line3df value) : + ValueI(), ValueF(), Count(6), IsFloat(true) + { + Name = name; + ValueF.push_back(value.start.X); + ValueF.push_back(value.start.Y); + ValueF.push_back(value.start.Z); + ValueF.push_back(value.end.X); + ValueF.push_back(value.end.Y); + ValueF.push_back(value.end.Z); + } + + CNumbersAttribute(const char* name, core::dimension2du value) : + ValueI(), ValueF(), Count(2), IsFloat(false) + { + Name = name; + ValueI.push_back(value.Width); + ValueI.push_back(value.Height); + } + + + CNumbersAttribute(const char* name, core::dimension2df value) : + ValueI(), ValueF(), Count(2), IsFloat(true) + { + Name = name; + ValueF.push_back(value.Width); + ValueF.push_back(value.Height); + } + + + + // getting values + virtual s32 getInt() + { + if (Count==0) + return 0; + + if (IsFloat) + return (s32)ValueF[0]; + else + return ValueI[0]; + } + + virtual f32 getFloat() + { + if (Count==0) + return 0.0f; + + if (IsFloat) + return ValueF[0]; + else + return (f32)ValueI[0]; + } + + virtual bool getBool() + { + // return true if any number is nonzero + bool ret=false; + + for (u32 i=0; i < Count; ++i) + if ( IsFloat ? (ValueF[i] != 0) : (ValueI[i] != 0) ) + { + ret=true; + break; + } + + return ret; + + } + + + virtual core::stringc getString() + { + core::stringc outstr; + + for (u32 i=0; i 0 ? ValueF[0] : 0); + p.Y = (s32)(Count > 1 ? ValueF[1] : 0); + } + else + { + p.X = Count > 0 ? ValueI[0] : 0; + p.Y = Count > 1 ? ValueI[1] : 0; + } + + return p; + } + + virtual core::vector3df getVector() + { + core::vector3df v; + + if (IsFloat) + { + v.X = Count > 0 ? ValueF[0] : 0; + v.Y = Count > 1 ? ValueF[1] : 0; + v.Z = Count > 2 ? ValueF[2] : 0; + } + else + { + v.X = (f32)(Count > 0 ? ValueI[0] : 0); + v.Y = (f32)(Count > 1 ? ValueI[1] : 0); + v.Z = (f32)(Count > 2 ? ValueI[2] : 0); + } + + return v; + } + + virtual core::vector2df getVector2d() + { + core::vector2df v; + + if (IsFloat) + { + v.X = Count > 0 ? ValueF[0] : 0; + v.Y = Count > 1 ? ValueF[1] : 0; + } + else + { + v.X = (f32)(Count > 0 ? ValueI[0] : 0); + v.Y = (f32)(Count > 1 ? ValueI[1] : 0); + } + + return v; + } + + virtual video::SColorf getColorf() + { + video::SColorf c; + if (IsFloat) + { + c.setColorComponentValue(0, Count > 0 ? ValueF[0] : 0); + c.setColorComponentValue(1, Count > 1 ? ValueF[1] : 0); + c.setColorComponentValue(2, Count > 2 ? ValueF[2] : 0); + c.setColorComponentValue(3, Count > 3 ? ValueF[3] : 0); + } + else + { + c.setColorComponentValue(0, Count > 0 ? (f32)(ValueI[0]) / 255.0f : 0); + c.setColorComponentValue(1, Count > 1 ? (f32)(ValueI[1]) / 255.0f : 0); + c.setColorComponentValue(2, Count > 2 ? (f32)(ValueI[2]) / 255.0f : 0); + c.setColorComponentValue(3, Count > 3 ? (f32)(ValueI[3]) / 255.0f : 0); + } + + return c; + } + + virtual video::SColor getColor() + { + return getColorf().toSColor(); + } + + + virtual core::rect getRect() + { + core::rect r; + + if (IsFloat) + { + r.UpperLeftCorner.X = (s32)(Count > 0 ? ValueF[0] : 0); + r.UpperLeftCorner.Y = (s32)(Count > 1 ? ValueF[1] : 0); + r.LowerRightCorner.X = (s32)(Count > 2 ? ValueF[2] : r.UpperLeftCorner.X); + r.LowerRightCorner.Y = (s32)(Count > 3 ? ValueF[3] : r.UpperLeftCorner.Y); + } + else + { + r.UpperLeftCorner.X = Count > 0 ? ValueI[0] : 0; + r.UpperLeftCorner.Y = Count > 1 ? ValueI[1] : 0; + r.LowerRightCorner.X = Count > 2 ? ValueI[2] : r.UpperLeftCorner.X; + r.LowerRightCorner.Y = Count > 3 ? ValueI[3] : r.UpperLeftCorner.Y; + } + return r; + } + + virtual core::dimension2du getDimension2d() + { + core::dimension2d dim; + + if (IsFloat) + { + dim.Width = (u32)(Count > 0 ? ValueF[0] : 0); + dim.Height = (u32)(Count > 1 ? ValueF[1] : 0); + } + else + { + dim.Width = (u32)(Count > 0 ? ValueI[0] : 0); + dim.Height = (u32)(Count > 1 ? ValueI[1] : 0); + } + return dim; + } + + virtual core::matrix4 getMatrix() + { + core::matrix4 ret; + if (IsFloat) + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ret(r,c) = ValueF[c+r*4]; + } + else + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ret(r,c) = (f32)ValueI[c+r*4]; + } + return ret; + } + + virtual core::quaternion getQuaternion() + { + core::quaternion ret; + if (IsFloat) + { + ret.X = Count > 0 ? ValueF[0] : 0.0f; + ret.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.W = Count > 3 ? ValueF[3] : 0.0f; + } + else + { + ret.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.W = Count > 3 ? (f32)ValueI[3] : 0.0f; + } + return ret; + } + + virtual core::triangle3df getTriangle() + { + core::triangle3df ret; + + if (IsFloat) + { + ret.pointA.X = Count > 0 ? ValueF[0] : 0.0f; + ret.pointA.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.pointA.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.pointB.X = Count > 3 ? ValueF[3] : 0.0f; + ret.pointB.Y = Count > 4 ? ValueF[4] : 0.0f; + ret.pointB.Z = Count > 5 ? ValueF[5] : 0.0f; + ret.pointC.X = Count > 6 ? ValueF[6] : 0.0f; + ret.pointC.Y = Count > 7 ? ValueF[7] : 0.0f; + ret.pointC.Z = Count > 8 ? ValueF[8] : 0.0f; + } + else + { + ret.pointA.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.pointA.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.pointA.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.pointB.X = Count > 3 ? (f32)ValueI[3] : 0.0f; + ret.pointB.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; + ret.pointB.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; + ret.pointC.X = Count > 6 ? (f32)ValueI[6] : 0.0f; + ret.pointC.Y = Count > 7 ? (f32)ValueI[7] : 0.0f; + ret.pointC.Z = Count > 8 ? (f32)ValueI[8] : 0.0f; + } + + return ret; + } + + virtual core::plane3df getPlane() + { + core::plane3df ret; + + if (IsFloat) + { + ret.Normal.X = Count > 0 ? ValueF[0] : 0.0f; + ret.Normal.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.Normal.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.D = Count > 3 ? ValueF[3] : 0.0f; + } + else + { + ret.Normal.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.Normal.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.Normal.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.D = Count > 3 ? (f32)ValueI[3] : 0.0f; + } + + return ret; + } + + virtual core::aabbox3df getBBox() + { + core::aabbox3df ret; + if (IsFloat) + { + ret.MinEdge.X = Count > 0 ? ValueF[0] : 0.0f; + ret.MinEdge.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.MinEdge.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.MaxEdge.X = Count > 3 ? ValueF[3] : 0.0f; + ret.MaxEdge.Y = Count > 4 ? ValueF[4] : 0.0f; + ret.MaxEdge.Z = Count > 5 ? ValueF[5] : 0.0f; + } + else + { + ret.MinEdge.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.MinEdge.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.MinEdge.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.MaxEdge.X = Count > 3 ? (f32)ValueI[3] : 0.0f; + ret.MaxEdge.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; + ret.MaxEdge.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; + } + return ret; + + } + + virtual core::line2df getLine2d() + { + core::line2df ret; + if (IsFloat) + { + ret.start.X = Count > 0 ? ValueF[0] : 0.0f; + ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.end.X = Count > 2 ? ValueF[2] : 0.0f; + ret.end.Y = Count > 3 ? ValueF[3] : 0.0f; + } + else + { + ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.end.X = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.end.Y = Count > 3 ? (f32)ValueI[3] : 0.0f; + } + return ret; + } + + virtual core::line3df getLine3d() + { + core::line3df ret; + if (IsFloat) + { + ret.start.X = Count > 0 ? ValueF[0] : 0.0f; + ret.start.Y = Count > 1 ? ValueF[1] : 0.0f; + ret.start.Z = Count > 2 ? ValueF[2] : 0.0f; + ret.end.X = Count > 3 ? ValueF[3] : 0.0f; + ret.end.Y = Count > 4 ? ValueF[4] : 0.0f; + ret.end.Z = Count > 5 ? ValueF[5] : 0.0f; + } + else + { + ret.start.X = Count > 0 ? (f32)ValueI[0] : 0.0f; + ret.start.Y = Count > 1 ? (f32)ValueI[1] : 0.0f; + ret.start.Z = Count > 2 ? (f32)ValueI[2] : 0.0f; + ret.end.X = Count > 3 ? (f32)ValueI[3] : 0.0f; + ret.end.Y = Count > 4 ? (f32)ValueI[4] : 0.0f; + ret.end.Z = Count > 5 ? (f32)ValueI[5] : 0.0f; + } + return ret; + } + + //! get float array + virtual core::array getFloatArray() + { + if (!IsFloat) + { + ValueF.clear(); + for (u32 i=0; i getIntArray() + { + if (IsFloat) + { + ValueI.clear(); + for (u32 i=0; i '9') ) ) + ++P; + + // set value + if ( *P) + { + if (IsFloat) + { + f32 c = 0; + P = core::fast_atof_move(P, c); + ValueF[i] = c; + } + else + { + // todo: fix this to read ints properly + f32 c = 0; + P = core::fast_atof_move(P, c); + ValueI[i] = (s32)c; + + } + } + } + // todo: warning message + //if (i < Count-1) + //{ + // + //} + } + + virtual void setPosition(core::position2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.X; + if (Count > 1) ValueF[1] = (f32)v.Y; + } + else + { + if (Count > 0) ValueI[0] = v.X; + if (Count > 1) ValueI[1] = v.Y; + } + } + + virtual void setVector(core::vector3df v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = v.X; + if (Count > 1) ValueF[1] = v.Y; + if (Count > 2) ValueF[2] = v.Z; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.X; + if (Count > 1) ValueI[1] = (s32)v.Y; + if (Count > 2) ValueI[2] = (s32)v.Z; + } + } + + virtual void setColor(video::SColorf color) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = color.r; + if (Count > 1) ValueF[1] = color.g; + if (Count > 2) ValueF[2] = color.b; + if (Count > 3) ValueF[3] = color.a; + } + else + { + if (Count > 0) ValueI[0] = (s32)(color.r * 255); + if (Count > 1) ValueI[1] = (s32)(color.g * 255); + if (Count > 2) ValueI[2] = (s32)(color.b * 255); + if (Count > 3) ValueI[3] = (s32)(color.a * 255); + } + + } + + virtual void setColor(video::SColor color) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)color.getRed() / 255.0f; + if (Count > 1) ValueF[1] = (f32)color.getGreen() / 255.0f; + if (Count > 2) ValueF[2] = (f32)color.getBlue() / 255.0f; + if (Count > 3) ValueF[3] = (f32)color.getAlpha() / 255.0f; + } + else + { + if (Count > 0) ValueI[0] = color.getRed(); + if (Count > 1) ValueI[1] = color.getGreen(); + if (Count > 2) ValueI[2] = color.getBlue(); + if (Count > 3) ValueI[3] = color.getAlpha(); + } + } + + virtual void setRect(core::rect value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)value.UpperLeftCorner.X; + if (Count > 1) ValueF[1] = (f32)value.UpperLeftCorner.Y; + if (Count > 2) ValueF[2] = (f32)value.LowerRightCorner.X; + if (Count > 3) ValueF[3] = (f32)value.LowerRightCorner.Y; + } + else + { + if (Count > 0) ValueI[0] = value.UpperLeftCorner.X; + if (Count > 1) ValueI[1] = value.UpperLeftCorner.Y; + if (Count > 2) ValueI[2] = value.LowerRightCorner.X; + if (Count > 3) ValueI[3] = value.LowerRightCorner.Y; + } + } + + virtual void setMatrix(core::matrix4 value) + { + reset(); + if (IsFloat) + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ValueF[c+r*4] = value(r,c); + } + else + { + for (u32 r=0; r<4; ++r) + for (u32 c=0; c<4; ++c) + if (Count > c+r*4) + ValueI[c+r*4] = (s32)value(r,c); + } + } + + virtual void setQuaternion(core::quaternion value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.X; + if (Count > 1) ValueF[1] = value.Y; + if (Count > 2) ValueF[2] = value.Z; + if (Count > 3) ValueF[3] = value.W; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.X; + if (Count > 1) ValueI[1] = (s32)value.Y; + if (Count > 2) ValueI[2] = (s32)value.Z; + if (Count > 3) ValueI[3] = (s32)value.W; + } + } + + virtual void setBoundingBox(core::aabbox3d value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.MinEdge.X; + if (Count > 1) ValueF[1] = value.MinEdge.Y; + if (Count > 2) ValueF[2] = value.MinEdge.Z; + if (Count > 3) ValueF[3] = value.MaxEdge.X; + if (Count > 4) ValueF[4] = value.MaxEdge.Y; + if (Count > 5) ValueF[5] = value.MaxEdge.Z; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.MinEdge.X; + if (Count > 1) ValueI[1] = (s32)value.MinEdge.Y; + if (Count > 2) ValueI[2] = (s32)value.MinEdge.Z; + if (Count > 3) ValueI[3] = (s32)value.MaxEdge.X; + if (Count > 4) ValueI[4] = (s32)value.MaxEdge.Y; + if (Count > 5) ValueI[5] = (s32)value.MaxEdge.Z; + } + } + + virtual void setPlane(core::plane3df value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.Normal.X; + if (Count > 1) ValueF[1] = value.Normal.Y; + if (Count > 2) ValueF[2] = value.Normal.Z; + if (Count > 3) ValueF[3] = value.D; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.Normal.X; + if (Count > 1) ValueI[1] = (s32)value.Normal.Y; + if (Count > 2) ValueI[2] = (s32)value.Normal.Z; + if (Count > 3) ValueI[3] = (s32)value.D; + } + } + + virtual void setTriangle3d(core::triangle3df value) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = value.pointA.X; + if (Count > 1) ValueF[1] = value.pointA.Y; + if (Count > 2) ValueF[2] = value.pointA.Z; + if (Count > 3) ValueF[3] = value.pointB.X; + if (Count > 4) ValueF[4] = value.pointB.Y; + if (Count > 5) ValueF[5] = value.pointB.Z; + if (Count > 6) ValueF[6] = value.pointC.X; + if (Count > 7) ValueF[7] = value.pointC.Y; + if (Count > 8) ValueF[8] = value.pointC.Z; + } + else + { + if (Count > 0) ValueI[0] = (s32)value.pointA.X; + if (Count > 1) ValueI[1] = (s32)value.pointA.Y; + if (Count > 2) ValueI[2] = (s32)value.pointA.Z; + if (Count > 3) ValueI[3] = (s32)value.pointB.X; + if (Count > 4) ValueI[4] = (s32)value.pointB.Y; + if (Count > 5) ValueI[5] = (s32)value.pointB.Z; + if (Count > 6) ValueI[6] = (s32)value.pointC.X; + if (Count > 7) ValueI[7] = (s32)value.pointC.Y; + if (Count > 8) ValueI[8] = (s32)value.pointC.Z; + } + } + + virtual void setVector2d(core::vector2df v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = v.X; + if (Count > 1) ValueF[1] = v.Y; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.X; + if (Count > 1) ValueI[1] = (s32)v.Y; + } + } + + virtual void setVector2d(core::vector2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.X; + if (Count > 1) ValueF[1] = (f32)v.Y; + } + else + { + if (Count > 0) ValueI[0] = v.X; + if (Count > 1) ValueI[1] = v.Y; + } + } + + virtual void setLine2d(core::line2di v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.start.X; + if (Count > 1) ValueF[1] = (f32)v.start.Y; + if (Count > 2) ValueF[2] = (f32)v.end.X; + if (Count > 3) ValueF[3] = (f32)v.end.Y; + } + else + { + if (Count > 0) ValueI[0] = v.start.X; + if (Count > 1) ValueI[1] = v.start.Y; + if (Count > 2) ValueI[2] = v.end.X; + if (Count > 3) ValueI[3] = v.end.Y; + } + } + + virtual void setLine2d(core::line2df v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = v.start.X; + if (Count > 1) ValueF[1] = v.start.Y; + if (Count > 2) ValueF[2] = v.end.X; + if (Count > 3) ValueF[3] = v.end.Y; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.start.X; + if (Count > 1) ValueI[1] = (s32)v.start.Y; + if (Count > 2) ValueI[2] = (s32)v.end.X; + if (Count > 3) ValueI[3] = (s32)v.end.Y; + } + } + + virtual void setDimension2d(core::dimension2du v) + { + reset(); + if (IsFloat) + { + if (Count > 0) ValueF[0] = (f32)v.Width; + if (Count > 1) ValueF[1] = (f32)v.Height; + } + else + { + if (Count > 0) ValueI[0] = (s32)v.Width; + if (Count > 1) ValueI[1] = (s32)v.Height; + } + } + + //! set float array + virtual void setFloatArray(core::array &vals) + { + reset(); + + for (u32 i=0; i &vals) + { + reset(); + + for (u32 i=0; i ValueI; + core::array ValueF; + u32 Count; + bool IsFloat; +}; + + +// Attribute implemented for floating point colors +class CColorfAttribute : public CNumbersAttribute +{ +public: + + CColorfAttribute(const char* name, video::SColorf value) : CNumbersAttribute(name, value) {} + + virtual s32 getInt() + { + return getColor().color; + } + + virtual f32 getFloat() + { + return (f32)getColor().color; + } + + virtual void setInt(s32 intValue) + { + video::SColorf c = video::SColor(intValue); + ValueF[0] = c.r; + ValueF[1] = c.g; + ValueF[2] = c.b; + ValueF[3] = c.a; + } + + virtual void setFloat(f32 floatValue) + { + setInt((s32)floatValue); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_COLORF; + } + + virtual const wchar_t* getTypeString() const + { + return L"colorf"; + } +}; + + + +// Attribute implemented for colors +class CColorAttribute : public CNumbersAttribute +{ +public: + + CColorAttribute(const char* name, const video::SColorf& value) : CNumbersAttribute(name, value) {} + + CColorAttribute(const char* name, const video::SColor& value) : CNumbersAttribute(name, value) {} + + virtual s32 getInt() + { + return getColor().color; + } + + virtual f32 getFloat() + { + return (f32)getColor().color; + } + + virtual void setInt(s32 intValue) + { + video::SColorf c = video::SColor(intValue); + ValueF[0] = c.r; + ValueF[1] = c.g; + ValueF[2] = c.b; + ValueF[3] = c.a; + } + + virtual void setFloat(f32 floatValue) + { + setInt((s32)floatValue); + } + + virtual core::stringw getStringW() + { + char tmp[10]; + const video::SColor c = getColor(); + sprintf(tmp, "%02x%02x%02x%02x", c.getAlpha(), c.getRed(), c.getGreen(), c.getBlue()); + return core::stringw(tmp); + } + + virtual void setString(const char* text) + { + u32 c; + if (sscanf(text, "%08x", &c)!=1) + { + CNumbersAttribute::setString(text); + } + else + setColor(c); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_COLOR; + } + + + virtual const wchar_t* getTypeString() const + { + return L"color"; + } + +}; + + +// Attribute implemented for 3d vectors +class CVector3DAttribute : public CNumbersAttribute +{ +public: + + CVector3DAttribute(const char* name, core::vector3df value) : CNumbersAttribute(name, value) {} + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_VECTOR3D; + } + + virtual core::matrix4 getMatrix() + { + core::matrix4 ret; + ret.makeIdentity(); + ret.setTranslation( core::vector3df(ValueF[0],ValueF[1],ValueF[2]) ); + return ret; + } + + virtual const wchar_t* getTypeString() const + { + return L"vector3d"; + } +}; + +// Attribute implemented for 2d vectors +class CVector2DAttribute : public CNumbersAttribute +{ +public: + + CVector2DAttribute(const char* name, core::vector2df value) : CNumbersAttribute(name, value) {} + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_VECTOR2D; + } + + virtual const wchar_t* getTypeString() const + { + return L"vector2d"; + } +}; + +// Attribute implemented for 2d vectors +class CPosition2DAttribute : public CNumbersAttribute +{ +public: + + CPosition2DAttribute(const char* name, core::position2di value) : CNumbersAttribute(name, value) {} + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_POSITION2D; + } + + virtual const wchar_t* getTypeString() const + { + return L"position"; + } +}; + + + +// Attribute implemented for rectangles +class CRectAttribute : public CNumbersAttribute +{ +public: + + CRectAttribute(const char* name, core::rect value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_RECT; + } + + virtual const wchar_t* getTypeString() const + { + return L"rect"; + } +}; + + +// Attribute implemented for dimension +class CDimension2dAttribute : public CNumbersAttribute +{ +public: + + CDimension2dAttribute (const char* name, core::dimension2d value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_DIMENSION2D; + } + + virtual const wchar_t* getTypeString() const + { + return L"dimension2d"; + } +}; + +// Attribute implemented for matrices +class CMatrixAttribute : public CNumbersAttribute +{ +public: + + CMatrixAttribute(const char* name, core::matrix4 value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_MATRIX; + } + + virtual core::quaternion getQuaternion() + { + return core::quaternion(getMatrix()); + } + + virtual const wchar_t* getTypeString() const + { + return L"matrix"; + } +}; + +// Attribute implemented for quaternions +class CQuaternionAttribute : public CNumbersAttribute +{ +public: + + CQuaternionAttribute(const char* name, core::quaternion value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_QUATERNION; + } + + virtual core::matrix4 getMatrix() + { + return getQuaternion().getMatrix(); + } + + virtual const wchar_t* getTypeString() const + { + return L"quaternion"; + } +}; + + +// Attribute implemented for bounding boxes +class CBBoxAttribute : public CNumbersAttribute +{ +public: + + CBBoxAttribute(const char* name, core::aabbox3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_BBOX; + } + + virtual const wchar_t* getTypeString() const + { + return L"box3d"; + } +}; + +// Attribute implemented for planes +class CPlaneAttribute : public CNumbersAttribute +{ +public: + + CPlaneAttribute(const char* name, core::plane3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_PLANE; + } + + virtual const wchar_t* getTypeString() const + { + return L"plane"; + } +}; + +// Attribute implemented for triangles +class CTriangleAttribute : public CNumbersAttribute +{ +public: + + CTriangleAttribute(const char* name, core::triangle3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_TRIANGLE3D; + } + + virtual core::plane3df getPlane() + { + return getTriangle().getPlane(); + } + + virtual const wchar_t* getTypeString() const + { + return L"triangle"; + } +}; + + +// Attribute implemented for 2d lines +class CLine2dAttribute : public CNumbersAttribute +{ +public: + + CLine2dAttribute(const char* name, core::line2df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_LINE2D; + } + + virtual const wchar_t* getTypeString() const + { + return L"line2d"; + } +}; + +// Attribute implemented for 3d lines +class CLine3dAttribute : public CNumbersAttribute +{ +public: + + CLine3dAttribute(const char* name, core::line3df value) : CNumbersAttribute(name, value) { } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_LINE3D; + } + + virtual const wchar_t* getTypeString() const + { + return L"line3d"; + } +}; + + +// vector2df +// dimension2du + +/* + Special attributes +*/ + +// Attribute implemented for enumeration literals +class CEnumAttribute : public IAttribute +{ +public: + + CEnumAttribute(const char* name, const char* value, const char* const* literals) + { + Name = name; + setEnum(value, literals); + } + + virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) + { + int literalCount = 0; + + if (enumerationLiterals) + { + s32 i; + for (i=0; enumerationLiterals[i]; ++i) + ++literalCount; + + EnumLiterals.reallocate(literalCount); + for (i=0; enumerationLiterals[i]; ++i) + EnumLiterals.push_back(enumerationLiterals[i]); + } + + setString(enumValue); + } + + virtual s32 getInt() + { + for (s32 i=0; EnumLiterals.size(); ++i) + if (Value.equals_ignore_case(EnumLiterals[i])) + { + return i; + } + + return -1; + } + + virtual f32 getFloat() + { + return (f32)getInt(); + } + + virtual bool getBool() + { + return (getInt() != 0); // does not make a lot of sense, I know + } + + virtual core::stringc getString() + { + return Value; + } + + virtual core::stringw getStringW() + { + return core::stringw(Value.c_str()); + } + + virtual void setInt(s32 intValue) + { + if (intValue>=0 && intValue<(s32)EnumLiterals.size()) + Value = EnumLiterals[intValue]; + else + Value = ""; + } + + virtual void setFloat(f32 floatValue) + { + setInt((s32)floatValue); + }; + + virtual void setString(const char* text) + { + Value = text; + } + + virtual const char* getEnum() + { + return Value.c_str(); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_ENUM; + } + + + virtual const wchar_t* getTypeString() const + { + return L"enum"; + } + + core::stringc Value; + core::array EnumLiterals; +}; + + + + + +// Attribute implemented for strings +class CStringAttribute : public IAttribute +{ +public: + + CStringAttribute(const char* name, const char* value) + { + IsStringW=false; + Name = name; + setString(value); + } + + CStringAttribute(const char* name, const wchar_t* value) + { + IsStringW = true; + Name = name; + setString(value); + } + + CStringAttribute(const char* name, void* binaryData, s32 lenghtInBytes) + { + IsStringW=false; + Name = name; + setBinary(binaryData, lenghtInBytes); + } + + virtual s32 getInt() + { + if (IsStringW) + return atoi(core::stringc(ValueW.c_str()).c_str()); + else + return atoi(Value.c_str()); + } + + virtual f32 getFloat() + { + if (IsStringW) + return core::fast_atof(core::stringc(ValueW.c_str()).c_str()); + else + return core::fast_atof(Value.c_str()); + } + + virtual bool getBool() + { + if (IsStringW) + return ValueW.equals_ignore_case(L"true"); + else + return Value.equals_ignore_case("true"); + } + + virtual core::stringc getString() + { + if (IsStringW) + return core::stringc(ValueW.c_str()); + else + return Value; + } + virtual core::stringw getStringW() + { + if (IsStringW) + return ValueW; + else + return core::stringw(Value.c_str()); + } + + virtual void setInt(s32 intValue) + { + if (IsStringW) + ValueW = core::stringw(intValue); + else + Value = core::stringc(intValue); + } + + virtual void setFloat(f32 floatValue) + { + if (IsStringW) + { + ValueW = core::stringw((double)floatValue); + } + else + { + Value = core::stringc((double)floatValue); + } + }; + + virtual void setString(const char* text) + { + if (IsStringW) + ValueW = core::stringw(text); + else + Value = text; + } + + virtual void setString(const wchar_t* text) + { + if (IsStringW) + ValueW = text; + else + Value = core::stringc(text); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_STRING; + } + + + virtual const wchar_t* getTypeString() const + { + return L"string"; + } + + virtual void getBinary(void* outdata, s32 maxLength) + { + s32 dataSize = maxLength; + c8* datac8 = (c8*)(outdata); + s32 p = 0; + const c8* dataString = Value.c_str(); + + for (s32 i=0; i= '0' && h <='9') + return h-'0'; + + if (h >= 'a' && h <='f') + return h-'a' + 10; + + return 0; + } + + static inline void getHexStrFromByte(c8 byte, c8* out) + { + s32 b = (byte & 0xf0) >> 4; + + for (s32 i=0; i<2; ++i) + { + if (b >=0 && b <= 9) + out[i] = b+'0'; + if (b >=10 && b <= 15) + out[i] = (b-10)+'a'; + + b = byte & 0x0f; + } + } +}; + +// Attribute implemented for binary data +class CBinaryAttribute : public CStringAttribute +{ +public: + + CBinaryAttribute(const char* name, void* binaryData, s32 lenghtInBytes) + : CStringAttribute(name, binaryData, lenghtInBytes) + { + + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_BINARY; + } + + + virtual const wchar_t* getTypeString() const + { + return L"binary"; + } +}; + + + +// Attribute implemented for texture references +class CTextureAttribute : public IAttribute +{ +public: + + CTextureAttribute(const char* name, video::ITexture* value, video::IVideoDriver* driver, const io::path& filename) + : Value(0), Driver(driver), OverrideName(filename) + { + if (Driver) + Driver->grab(); + + Name = name; + setTexture(value); + } + + ~CTextureAttribute() + { + if (Driver) + Driver->drop(); + + if (Value) + Value->drop(); + } + + virtual video::ITexture* getTexture() + { + return Value; + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + // (note: don't try to put all this in some ?: operators, or c++ builder will choke) + if ( OverrideName.size() ) + return core::stringw(OverrideName); + + if ( Value ) + return core::stringw(Value->getName().getPath().c_str()); + + return core::stringw(0); + } + + virtual core::stringc getString() + { + // since texture names can be stringw we are careful with the types + if ( OverrideName.size() ) + return core::stringc(OverrideName); + + if ( Value ) + return core::stringc(Value->getName().getPath().c_str()); + + return core::stringc(0); + } + + virtual void setString(const char* text) + { + if (Driver) + { + if (text && *text) + { + setTexture(Driver->getTexture(text)); + OverrideName=text; + } + else + setTexture(0); + } + } + + virtual void setTexture(video::ITexture* value) + { + if ( value == Value ) + return; + + if (Value) + Value->drop(); + + Value = value; + + if (Value) + Value->grab(); + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_TEXTURE; + } + + + virtual const wchar_t* getTypeString() const + { + return L"texture"; + } + + video::ITexture* Value; + video::IVideoDriver* Driver; + io::path OverrideName; +}; + + + +// Attribute implemented for array of stringw +class CStringWArrayAttribute : public IAttribute +{ +public: + + CStringWArrayAttribute(const char* name, const core::array& value) + { + Name = name; + setArray(value); + } + + virtual core::array getArray() + { + return Value; + } + + virtual void setArray(const core::array& value) + { + Value = value; + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_STRINGWARRAY; + } + + virtual const wchar_t* getTypeString() const + { + return L"stringwarray"; + } + + core::array Value; +}; + + +// Attribute implemented for user pointers +class CUserPointerAttribute : public IAttribute +{ +public: + + CUserPointerAttribute(const char* name, void* value) + { + Name = name; + Value = value; + } + + virtual s32 getInt() + { + return *static_cast(Value); + } + + virtual bool getBool() + { + return (Value != 0); + } + + virtual core::stringw getStringW() + { + wchar_t buf[32]; + swprintf(buf, 32, L"%p", Value); + + return core::stringw(buf); + } + + virtual void setString(const char* text) + { + u32 tmp; + sscanf(text, "0x%x", &tmp); + Value = (void *) tmp; + } + + virtual E_ATTRIBUTE_TYPE getType() const + { + return EAT_USER_POINTER; + } + + virtual void setUserPointer(void* v) + { + Value = v; + } + + virtual void* getUserPointer() + { + return Value; + } + + + virtual const wchar_t* getTypeString() const + { + return L"userPointer"; + } + + void* Value; +}; + + + +// todo: CGUIFontAttribute + +} // end namespace io +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.cpp new file mode 100644 index 0000000..21ebe1f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.cpp @@ -0,0 +1,1665 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CAttributes.h" +#include "CAttributeImpl.h" +#include "ITexture.h" +#include "IXMLWriter.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace io +{ + +CAttributes::CAttributes(video::IVideoDriver* driver) +: Driver(driver) +{ + #ifdef _DEBUG + setDebugName("CAttributes"); + #endif + + if (Driver) + Driver->grab(); +} + +CAttributes::~CAttributes() +{ + clear(); + + if (Driver) + Driver->drop(); +} + + +//! Removes all attributes +void CAttributes::clear() +{ + for (u32 i=0; idrop(); + + Attributes.clear(); +} + + +//! Sets a string attribute. +//! \param attributeName: Name for the attribute +//! \param value: Value for the attribute. Set this to 0 to delete the attribute +void CAttributes::setAttribute(const c8* attributeName, const c8* value) +{ + for (u32 i=0; iName == attributeName) + { + if (!value) + { + Attributes[i]->drop(); + Attributes.erase(i); + } + else + Attributes[i]->setString(value); + + return; + } + + if (value) + { + Attributes.push_back(new CStringAttribute(attributeName, value)); + } +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setStringAttribute() +//! or 0 if attribute is not set. +core::stringc CAttributes::getAttributeAsString(const c8* attributeName) +{ + core::stringc str; + + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getString(); + else + return str; +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \param target: Buffer where the string is copied to. +void CAttributes::getAttributeAsString(const c8* attributeName, char* target) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + { + core::stringc str = att->getString(); + strcpy(target,str.c_str()); + } + else + target[0] = 0; +} + +//! Returns string attribute value by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::stringc CAttributes::getAttributeAsString(s32 index) +{ + core::stringc str; + + if ((u32)index < Attributes.size()) + return Attributes[index]->getString(); + + return str; +} + + +//! Sets a string attribute. +//! \param attributeName: Name for the attribute +//! \param value: Value for the attribute. Set this to 0 to delete the attribute +void CAttributes::setAttribute(const c8* attributeName, const wchar_t* value) +{ + for (u32 i=0; iName == attributeName) + { + if (!value) + { + Attributes[i]->drop(); + Attributes.erase(i); + } + else + Attributes[i]->setString(value); + + return; + } + } + + if (value) + { + Attributes.push_back(new CStringAttribute(attributeName, value)); + } +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setStringAttribute() +//! or 0 if attribute is not set. +core::stringw CAttributes::getAttributeAsStringW(const c8* attributeName) +{ + core::stringw str; + + IAttribute* att = getAttributeP(attributeName); + if (att) + str = att->getStringW(); + + return str; +} + +//! Gets a string attribute. +//! \param attributeName: Name of the attribute to get. +//! \param target: Buffer where the string is copied to. +void CAttributes::getAttributeAsStringW(const c8* attributeName, wchar_t* target) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + { + core::stringw str = att->getStringW(); + wcscpy(target,str.c_str()); + } + else + target[0] = 0; +} + +//! Returns string attribute value by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::stringw CAttributes::getAttributeAsStringW(s32 index) +{ + + if ((u32)index < Attributes.size()) + return Attributes[index]->getStringW(); + else + return core::stringw(); +} + + +//! Adds an attribute as an array of wide strings +void CAttributes::addArray(const c8* attributeName, const core::array& value) +{ + Attributes.push_back(new CStringWArrayAttribute(attributeName, value)); +} + +//! Sets an attribute value as an array of wide strings. +void CAttributes::setAttribute(const c8* attributeName, const core::array& value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setArray(value); + else + { + Attributes.push_back(new CStringWArrayAttribute(attributeName, value)); + } +} + +//! Gets an attribute as an array of wide strings. +core::array CAttributes::getAttributeAsArray(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getArray(); + else + return core::array(); +} + +//! Returns attribute value as an array of wide strings by index. +core::array CAttributes::getAttributeAsArray(s32 index) +{ + core::array ret; + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getArray(); + + return ret; +} + +//! Sets an attribute as an array of wide strings +void CAttributes::setAttribute(s32 index, const core::array& value) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setArray(value); +} + + + + +//! Returns attribute index from name, -1 if not found +s32 CAttributes::findAttribute(const c8* attributeName) const +{ + for (u32 i=0; iName == attributeName) + return i; + + return -1; +} + + +IAttribute* CAttributes::getAttributeP(const c8* attributeName) const +{ + for (u32 i=0; iName == attributeName) + return Attributes[i]; + + return 0; +} + + +//! Sets a attribute as boolean value +void CAttributes::setAttribute(const c8* attributeName, bool value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setBool(value); + else + { + Attributes.push_back(new CBoolAttribute(attributeName, value)); + } +} + +//! Gets a attribute as boolean value +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() as bool +//! or 0 if attribute is not set. +bool CAttributes::getAttributeAsBool(const c8* attributeName) +{ + bool ret = false; + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getBool(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +//! Sets a attribute as integer value +void CAttributes::setAttribute(const c8* attributeName, s32 value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setInt(value); + else + { + Attributes.push_back(new CIntAttribute(attributeName, value)); + } +} + +//! Gets a attribute as integer value +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() as integer +//! or 0 if attribute is not set. +s32 CAttributes::getAttributeAsInt(const c8* attributeName) const +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getInt(); + else + return 0; +} + +//! Sets a attribute as float value +void CAttributes::setAttribute(const c8* attributeName, f32 value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setFloat(value); + else + Attributes.push_back(new CFloatAttribute(attributeName, value)); +} + +//! Gets a attribute as integer value +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() as float value +//! or 0 if attribute is not set. +f32 CAttributes::getAttributeAsFloat(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getFloat(); + + return 0.f; +} + +//! Sets a attribute as color +void CAttributes::setAttribute(const c8* attributeName, video::SColor value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setColor(value); + else + Attributes.push_back(new CColorAttribute(attributeName, value)); +} + +//! Gets an attribute as color +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +video::SColor CAttributes::getAttributeAsColor(const c8* attributeName) +{ + video::SColor ret(0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getColor(); + + return ret; +} + +//! Sets a attribute as floating point color +void CAttributes::setAttribute(const c8* attributeName, video::SColorf value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setColor(value); + else + Attributes.push_back(new CColorfAttribute(attributeName, value)); +} + +//! Gets an attribute as floating point color +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +video::SColorf CAttributes::getAttributeAsColorf(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getColorf(); + else + return video::SColorf(); +} + +//! Sets a attribute as 2d position +void CAttributes::setAttribute(const c8* attributeName, core::position2di value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setPosition(value); + else + Attributes.push_back(new CPosition2DAttribute(attributeName, value)); +} + +//! Gets an attribute as 2d position +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::position2di CAttributes::getAttributeAsPosition2d(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getPosition(); + else + return core::position2di(); +} + +//! Sets a attribute as rectangle +void CAttributes::setAttribute(const c8* attributeName, core::rect value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setRect(value); + else + Attributes.push_back(new CRectAttribute(attributeName, value)); +} + +//! Gets an attribute as rectangle +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::rect CAttributes::getAttributeAsRect(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getRect(); + else + return core::rect(); +} + +//! Sets a attribute as dimension2d +void CAttributes::setAttribute(const c8* attributeName, core::dimension2d value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setDimension2d(value); + else + Attributes.push_back(new CDimension2dAttribute(attributeName, value)); +} + +//! Gets an attribute as dimension2d +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::dimension2d CAttributes::getAttributeAsDimension2d(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getDimension2d(); + else + return core::dimension2d(); +} + +//! Sets a attribute as vector +void CAttributes::setAttribute(const c8* attributeName, core::vector3df value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setVector(value); + else + Attributes.push_back(new CVector3DAttribute(attributeName, value)); +} + +//! Sets a attribute as vector +void CAttributes::setAttribute(const c8* attributeName, core::vector2df value) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setVector2d(value); + else + Attributes.push_back(new CVector2DAttribute(attributeName, value)); +} + +//! Gets an attribute as vector +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +core::vector3df CAttributes::getAttributeAsVector3d(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getVector(); + else + return core::vector3df(); +} + +//! Gets an attribute as vector +core::vector2df CAttributes::getAttributeAsVector2d(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getVector2d(); + else + return core::vector2df(); +} + +//! Sets an attribute as binary data +void CAttributes::setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes ) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setBinary(data, dataSizeInBytes); + else + Attributes.push_back(new CBinaryAttribute(attributeName, data, dataSizeInBytes)); +} + +//! Gets an attribute as binary data +//! \param attributeName: Name of the attribute to get. +void CAttributes::getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->getBinary(outData, maxSizeInBytes); +} + +//! Sets an attribute as enumeration +void CAttributes::setAttribute(const c8* attributeName, const char* enumValue, const char* const* enumerationLiterals) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setEnum(enumValue, enumerationLiterals); + else + Attributes.push_back(new CEnumAttribute(attributeName, enumValue, enumerationLiterals)); +} + +//! Gets an attribute as enumeration +//! \param attributeName: Name of the attribute to get. +//! \return Returns value of the attribute previously set by setAttribute() +const char* CAttributes::getAttributeAsEnumeration(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getEnum(); + else + return 0; +} + +//! Gets an attribute as enumeration +s32 CAttributes::getAttributeAsEnumeration(const c8* attributeName, const char* const* enumerationLiteralsToUse) +{ + IAttribute* att = getAttributeP(attributeName); + + if (enumerationLiteralsToUse && att) + { + const char* value = att->getEnum(); + if (value) + { + for (s32 i=0; enumerationLiteralsToUse[i]; ++i) + if (!strcmp(value, enumerationLiteralsToUse[i])) + return i; + } + } + + return -1; +} + +//! Gets the list of enumeration literals of an enumeration attribute +//! \param attributeName: Name of the attribute to get. +void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array& outLiterals) +{ + IAttribute* att = getAttributeP(attributeName); + + if (att && att->getType() == EAT_ENUM) + outLiterals = ((CEnumAttribute*)att)->EnumLiterals; +} + +//! Sets an attribute as texture reference +void CAttributes::setAttribute(const c8* attributeName, video::ITexture* value, const io::path& filename) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setTexture(value, filename); + else + Attributes.push_back(new CTextureAttribute(attributeName, value, Driver, filename)); +} + + +//! Gets an attribute as texture reference +//! \param attributeName: Name of the attribute to get. +video::ITexture* CAttributes::getAttributeAsTexture(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getTexture(); + else + return 0; +} + +//! Gets an attribute as texture reference +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +video::ITexture* CAttributes::getAttributeAsTexture(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getTexture(); + else + return 0; +} + + +//! Returns amount of string attributes set in this scene manager. +u32 CAttributes::getAttributeCount() const +{ + return Attributes.size(); +} + +//! Returns string attribute name by index. +//! \param index: Index value, must be between 0 and getStringAttributeCount()-1. +const c8* CAttributes::getAttributeName(s32 index) +{ + if ((u32)index >= Attributes.size()) + return 0; + + return Attributes[index]->Name.c_str(); +} + +//! Returns the type of an attribute +E_ATTRIBUTE_TYPE CAttributes::getAttributeType(const c8* attributeName) +{ + E_ATTRIBUTE_TYPE ret = EAT_UNKNOWN; + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getType(); + + return ret; +} + +//! Returns attribute type by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +E_ATTRIBUTE_TYPE CAttributes::getAttributeType(s32 index) +{ + if ((u32)index >= Attributes.size()) + return EAT_UNKNOWN; + + return Attributes[index]->getType(); +} + +//! Returns the type of an attribute +const wchar_t* CAttributes::getAttributeTypeString(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getTypeString(); + else + return L"unknown"; +} + +//! Returns attribute type string by index. +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +const wchar_t* CAttributes::getAttributeTypeString(s32 index) +{ + if ((u32)index >= Attributes.size()) + return L"unknown"; + + return Attributes[index]->getTypeString(); +} + +//! Gets an attribute as boolean value +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +bool CAttributes::getAttributeAsBool(s32 index) +{ + bool ret = false; + + if ((u32)index < Attributes.size()) + ret = Attributes[index]->getBool(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +//! Gets an attribute as integer value +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +s32 CAttributes::getAttributeAsInt(s32 index) const +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getInt(); + else + return 0; +} + +//! Gets an attribute as float value +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +f32 CAttributes::getAttributeAsFloat(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getFloat(); + else + return 0.f; +} + +//! Gets an attribute as color +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +video::SColor CAttributes::getAttributeAsColor(s32 index) +{ + video::SColor ret(0); + + if ((u32)index < Attributes.size()) + ret = Attributes[index]->getColor(); + + return ret; +} + +//! Gets an attribute as floating point color +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +video::SColorf CAttributes::getAttributeAsColorf(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getColorf(); + + return video::SColorf(); +} + +//! Gets an attribute as 3d vector +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::vector3df CAttributes::getAttributeAsVector3d(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getVector(); + else + return core::vector3df(); +} + +//! Gets an attribute as 2d vector +core::vector2df CAttributes::getAttributeAsVector2d(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getVector2d(); + else + return core::vector2df(); +} + +//! Gets an attribute as position2d +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::position2di CAttributes::getAttributeAsPosition2d(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getPosition(); + else + return core::position2di(); +} + +//! Gets an attribute as rectangle +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::rect CAttributes::getAttributeAsRect(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getRect(); + else + return core::rect(); +} + +//! Gets an attribute as dimension2d +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +core::dimension2d CAttributes::getAttributeAsDimension2d(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getDimension2d(); + else + return core::dimension2d(); +} + + +//! Gets an attribute as binary data +///! \param index: Index value, must be between 0 and getAttributeCount()-1. +void CAttributes::getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->getBinary(outData, maxSizeInBytes); +} + + +//! Gets an attribute as enumeration +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +const char* CAttributes::getAttributeAsEnumeration(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getEnum(); + else + return 0; +} + + +//! Gets an attribute as enumeration +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +s32 CAttributes::getAttributeAsEnumeration(s32 index, const char* const* enumerationLiteralsToUse) +{ + if ((u32)index < Attributes.size()) + { + IAttribute* att = Attributes[index]; + + if (enumerationLiteralsToUse && att) + { + const char* value = att->getEnum(); + if (value) + { + for (s32 i=0; enumerationLiteralsToUse[i]; ++i) + if (!strcmp(value, enumerationLiteralsToUse[i])) + return i; + } + } + } + + return -1; +} + +//! Gets the list of enumeration literals of an enumeration attribute +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array& outLiterals) +{ + if ((u32)index < Attributes.size() && + Attributes[index]->getType() == EAT_ENUM) + outLiterals = ((CEnumAttribute*)Attributes[index])->EnumLiterals; +} + + +//! Adds an attribute as integer +void CAttributes::addInt(const c8* attributeName, s32 value) +{ + Attributes.push_back(new CIntAttribute(attributeName, value)); +} + +//! Adds an attribute as float +void CAttributes::addFloat(const c8* attributeName, f32 value) +{ + Attributes.push_back(new CFloatAttribute(attributeName, value)); +} + +//! Adds an attribute as string +void CAttributes::addString(const c8* attributeName, const char* value) +{ + Attributes.push_back(new CStringAttribute(attributeName, value)); +} + +//! Adds an attribute as wchar string +void CAttributes::addString(const c8* attributeName, const wchar_t* value) +{ + Attributes.push_back(new CStringAttribute(attributeName, value)); +} + +//! Adds an attribute as bool +void CAttributes::addBool(const c8* attributeName, bool value) +{ + Attributes.push_back(new CBoolAttribute(attributeName, value)); +} + +//! Adds an attribute as enum +void CAttributes::addEnum(const c8* attributeName, const char* enumValue, const char* const* enumerationLiterals) +{ + Attributes.push_back(new CEnumAttribute(attributeName, enumValue, enumerationLiterals)); +} + +//! Adds an attribute as enum +void CAttributes::addEnum(const c8* attributeName, s32 enumValue, const char* const* enumerationLiterals) +{ + addEnum(attributeName, "", enumerationLiterals); + Attributes.getLast()->setInt(enumValue); +} + +//! Adds an attribute as color +void CAttributes::addColor(const c8* attributeName, video::SColor value) +{ + Attributes.push_back(new CColorAttribute(attributeName, value)); +} + +//! Adds an attribute as floating point color +void CAttributes::addColorf(const c8* attributeName, video::SColorf value) +{ + Attributes.push_back(new CColorfAttribute(attributeName, value)); +} + +//! Adds an attribute as 3d vector +void CAttributes::addVector3d(const c8* attributeName, core::vector3df value) +{ + Attributes.push_back(new CVector3DAttribute(attributeName, value)); +} + +//! Adds an attribute as 2d vector +void CAttributes::addVector2d(const c8* attributeName, core::vector2df value) +{ + Attributes.push_back(new CVector2DAttribute(attributeName, value)); +} + + +//! Adds an attribute as 2d position +void CAttributes::addPosition2d(const c8* attributeName, core::position2di value) +{ + Attributes.push_back(new CPosition2DAttribute(attributeName, value)); +} + +//! Adds an attribute as rectangle +void CAttributes::addRect(const c8* attributeName, core::rect value) +{ + Attributes.push_back(new CRectAttribute(attributeName, value)); +} + +//! Adds an attribute as dimension2d +void CAttributes::addDimension2d(const c8* attributeName, core::dimension2d value) +{ + Attributes.push_back(new CDimension2dAttribute(attributeName, value)); +} + +//! Adds an attribute as binary data +void CAttributes::addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes) +{ + Attributes.push_back(new CBinaryAttribute(attributeName, data, dataSizeInBytes)); +} + +//! Adds an attribute as texture reference +void CAttributes::addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename) +{ + Attributes.push_back(new CTextureAttribute(attributeName, texture, Driver, filename)); +} + +//! Returns if an attribute with a name exists +bool CAttributes::existsAttribute(const c8* attributeName) +{ + return getAttributeP(attributeName) != 0; +} + +//! Sets an attribute value as string. +//! \param attributeName: Name for the attribute +void CAttributes::setAttribute(s32 index, const c8* value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setString(value); +} + +//! Sets an attribute value as string. +//! \param attributeName: Name for the attribute +void CAttributes::setAttribute(s32 index, const wchar_t* value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setString(value); +} + +//! Sets an attribute as boolean value +void CAttributes::setAttribute(s32 index, bool value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setBool(value); +} + +//! Sets an attribute as integer value +void CAttributes::setAttribute(s32 index, s32 value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setInt(value); +} + +//! Sets a attribute as float value +void CAttributes::setAttribute(s32 index, f32 value) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setFloat(value); +} + +//! Sets a attribute as color +void CAttributes::setAttribute(s32 index, video::SColor color) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setColor(color); +} + +//! Sets a attribute as floating point color +void CAttributes::setAttribute(s32 index, video::SColorf color) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setColor(color); +} + +//! Sets a attribute as vector +void CAttributes::setAttribute(s32 index, core::vector3df v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setVector(v); +} + +//! Sets a attribute as vector +void CAttributes::setAttribute(s32 index, core::vector2df v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setVector2d(v); +} + +//! Sets a attribute as position +void CAttributes::setAttribute(s32 index, core::position2di v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setPosition(v); +} + +//! Sets a attribute as rectangle +void CAttributes::setAttribute(s32 index, core::rect v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setRect(v); +} + +//! Sets a attribute as dimension2d +void CAttributes::setAttribute(s32 index, core::dimension2d v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setDimension2d(v); +} + +//! Sets an attribute as binary data +void CAttributes::setAttribute(s32 index, void* data, s32 dataSizeInBytes ) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setBinary(data, dataSizeInBytes); +} + + +//! Sets an attribute as enumeration +void CAttributes::setAttribute(s32 index, const char* enumValue, const char* const* enumerationLiterals) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setEnum(enumValue, enumerationLiterals); +} + + +//! Sets an attribute as texture reference +void CAttributes::setAttribute(s32 index, video::ITexture* texture, const io::path& filename) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setTexture(texture, filename); +} + + +//! Adds an attribute as matrix +void CAttributes::addMatrix(const c8* attributeName, const core::matrix4& v) +{ + Attributes.push_back(new CMatrixAttribute(attributeName, v)); +} + + +//! Sets an attribute as matrix +void CAttributes::setAttribute(const c8* attributeName, const core::matrix4& v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setMatrix(v); + else + Attributes.push_back(new CMatrixAttribute(attributeName, v)); +} + +//! Gets an attribute as a matrix4 +core::matrix4 CAttributes::getAttributeAsMatrix(const c8* attributeName) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + return att->getMatrix(); + else + return core::matrix4(); + +} + +//! Gets an attribute as matrix +core::matrix4 CAttributes::getAttributeAsMatrix(s32 index) +{ + if ((u32)index < Attributes.size()) + return Attributes[index]->getMatrix(); + else + return core::matrix4(); +} + +//! Sets an attribute as matrix +void CAttributes::setAttribute(s32 index, const core::matrix4& v) +{ + if ((u32)index < Attributes.size()) + Attributes[index]->setMatrix(v); +} + + +//! Adds an attribute as quaternion +void CAttributes::addQuaternion(const c8* attributeName, core::quaternion v) +{ + Attributes.push_back(new CQuaternionAttribute(attributeName, v)); +} + + +//! Sets an attribute as quaternion +void CAttributes::setAttribute(const c8* attributeName, core::quaternion v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setQuaternion(v); + else + { + Attributes.push_back(new CQuaternionAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a quaternion +core::quaternion CAttributes::getAttributeAsQuaternion(const c8* attributeName) +{ + core::quaternion ret(0,1,0, 0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getQuaternion(); + + return ret; +} + +//! Gets an attribute as quaternion +core::quaternion CAttributes::getAttributeAsQuaternion(s32 index) +{ + core::quaternion ret(0,1,0, 0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getQuaternion(); + + return ret; +} + +//! Sets an attribute as quaternion +void CAttributes::setAttribute(s32 index, core::quaternion v) +{ +if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setQuaternion(v); +} + +//! Adds an attribute as axis aligned bounding box +void CAttributes::addBox3d(const c8* attributeName, core::aabbox3df v) +{ + Attributes.push_back(new CBBoxAttribute(attributeName, v)); +} + +//! Sets an attribute as axis aligned bounding box +void CAttributes::setAttribute(const c8* attributeName, core::aabbox3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setBBox(v); + else + { + Attributes.push_back(new CBBoxAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a axis aligned bounding box +core::aabbox3df CAttributes::getAttributeAsBox3d(const c8* attributeName) +{ + core::aabbox3df ret(0,0,0, 0,0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getBBox(); + + return ret; +} + +//! Gets an attribute as axis aligned bounding box +core::aabbox3df CAttributes::getAttributeAsBox3d(s32 index) +{ + core::aabbox3df ret(0,0,0, 0,0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getBBox(); + + return ret; +} + +//! Sets an attribute as axis aligned bounding box +void CAttributes::setAttribute(s32 index, core::aabbox3df v) +{ +if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setBBox(v); +} + +//! Adds an attribute as 3d plane +void CAttributes::addPlane3d(const c8* attributeName, core::plane3df v) +{ + Attributes.push_back(new CPlaneAttribute(attributeName, v)); +} + +//! Sets an attribute as 3d plane +void CAttributes::setAttribute(const c8* attributeName, core::plane3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setPlane(v); + else + { + Attributes.push_back(new CPlaneAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 3d plane +core::plane3df CAttributes::getAttributeAsPlane3d(const c8* attributeName) +{ + core::plane3df ret(0,0,0, 0,1,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getPlane(); + + return ret; +} + +//! Gets an attribute as 3d plane +core::plane3df CAttributes::getAttributeAsPlane3d(s32 index) +{ + core::plane3df ret(0,0,0, 0,1,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getPlane(); + + return ret; +} + +//! Sets an attribute as 3d plane +void CAttributes::setAttribute(s32 index, core::plane3df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setPlane(v); +} + +//! Adds an attribute as 3d triangle +void CAttributes::addTriangle3d(const c8* attributeName, core::triangle3df v) +{ + Attributes.push_back(new CTriangleAttribute(attributeName, v)); +} + +//! Sets an attribute as 3d triangle +void CAttributes::setAttribute(const c8* attributeName, core::triangle3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setTriangle(v); + else + { + Attributes.push_back(new CTriangleAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 3d triangle +core::triangle3df CAttributes::getAttributeAsTriangle3d(const c8* attributeName) +{ + core::triangle3df ret; + ret.pointA = ret.pointB = ret.pointC = core::vector3df(0,0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getTriangle(); + + return ret; +} + +//! Gets an attribute as 3d triangle +core::triangle3df CAttributes::getAttributeAsTriangle3d(s32 index) +{ + core::triangle3df ret; + ret.pointA = ret.pointB = ret.pointC = core::vector3df(0,0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getTriangle(); + + return ret; +} + +//! Sets an attribute as 3d triangle +void CAttributes::setAttribute(s32 index, core::triangle3df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setTriangle(v); +} + +//! Adds an attribute as a 2d line +void CAttributes::addLine2d(const c8* attributeName, core::line2df v) +{ + Attributes.push_back(new CLine2dAttribute(attributeName, v)); +} + +//! Sets an attribute as a 2d line +void CAttributes::setAttribute(const c8* attributeName, core::line2df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setLine2d(v); + else + { + Attributes.push_back(new CLine2dAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 2d line +core::line2df CAttributes::getAttributeAsLine2d(const c8* attributeName) +{ + core::line2df ret(0,0, 0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getLine2d(); + + return ret; +} + +//! Gets an attribute as a 2d line +core::line2df CAttributes::getAttributeAsLine2d(s32 index) +{ + core::line2df ret(0,0, 0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getLine2d(); + + return ret; +} + +//! Sets an attribute as a 2d line +void CAttributes::setAttribute(s32 index, core::line2df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setLine2d(v); +} + +//! Adds an attribute as a 3d line +void CAttributes::addLine3d(const c8* attributeName, core::line3df v) +{ + Attributes.push_back(new CLine3dAttribute(attributeName, v)); +} + +//! Sets an attribute as a 3d line +void CAttributes::setAttribute(const c8* attributeName, core::line3df v) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setLine3d(v); + else + { + Attributes.push_back(new CLine3dAttribute(attributeName, v)); + } +} + +//! Gets an attribute as a 3d line +core::line3df CAttributes::getAttributeAsLine3d(const c8* attributeName) +{ + core::line3df ret(0,0,0, 0,0,0); + + IAttribute* att = getAttributeP(attributeName); + if (att) + ret = att->getLine3d(); + + return ret; +} + +//! Gets an attribute as a 3d line +core::line3df CAttributes::getAttributeAsLine3d(s32 index) +{ + core::line3df ret(0,0,0, 0,0,0); + + if (index >= 0 && index < (s32)Attributes.size()) + ret = Attributes[index]->getLine3d(); + + return ret; +} + +//! Sets an attribute as a 3d line +void CAttributes::setAttribute(s32 index, core::line3df v) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setLine3d(v); + +} + + +//! Adds an attribute as user pointner +void CAttributes::addUserPointer(const c8* attributeName, void* userPointer) +{ + Attributes.push_back(new CUserPointerAttribute(attributeName, userPointer)); +} + +//! Sets an attribute as user pointer +void CAttributes::setAttribute(const c8* attributeName, void* userPointer) +{ + IAttribute* att = getAttributeP(attributeName); + if (att) + att->setUserPointer(userPointer); + else + { + Attributes.push_back(new CUserPointerAttribute(attributeName, userPointer)); + } +} + +//! Gets an attribute as user pointer +//! \param attributeName: Name of the attribute to get. +void* CAttributes::getAttributeAsUserPointer(const c8* attributeName) +{ + void* value = 0; + + IAttribute* att = getAttributeP(attributeName); + if (att) + value = att->getUserPointer(); + + return value; +} + +//! Gets an attribute as user pointer +//! \param index: Index value, must be between 0 and getAttributeCount()-1. +void* CAttributes::getAttributeAsUserPointer(s32 index) +{ + void* value = 0; + + if (index >= 0 && index < (s32)Attributes.size()) + value = Attributes[index]->getUserPointer(); + + return value; +} + +//! Sets an attribute as user pointer +void CAttributes::setAttribute(s32 index, void* userPointer) +{ + if (index >= 0 && index < (s32)Attributes.size() ) + Attributes[index]->setUserPointer(userPointer); +} + + +//! Reads attributes from a xml file. +//! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. +//! IF set to false, the first appearing list attributes are read. +bool CAttributes::read(io::IXMLReader* reader, bool readCurrentElementOnly, + const wchar_t* nonDefaultElementName) +{ + if (!reader) + return false; + + clear(); + + core::stringw elementName = L"attributes"; + if (nonDefaultElementName) + elementName = nonDefaultElementName; + + if (readCurrentElementOnly) + { + if (elementName != reader->getNodeName()) + return false; + } + + while(reader->read()) + { + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT: + readAttributeFromXML(reader); + break; + case io::EXN_ELEMENT_END: + if (elementName == reader->getNodeName()) + return true; + break; + default: + break; + } + } + + return true; +} + + +void CAttributes::readAttributeFromXML(io::IXMLReader* reader) +{ + core::stringw element = reader->getNodeName(); + core::stringc name = reader->getAttributeValue(L"name"); + + if (element == L"enum") + { + addEnum(name.c_str(), 0, 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"binary") + { + addBinary(name.c_str(), 0, 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"color") + { + addColor(name.c_str(), video::SColor()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"colorf") + { + addColorf(name.c_str(), video::SColorf()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"float") + { + addFloat(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"int") + { + addInt(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"bool") + { + addBool(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"string") + { + addString(name.c_str(), L""); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"texture") + { + addTexture(name.c_str(), 0); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"vector3d") + { + addVector3d(name.c_str(), core::vector3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"vector2d") + { + addVector2d(name.c_str(), core::vector2df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"position") + { + addPosition2d(name.c_str(), core::position2di()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"rect") + { + addRect(name.c_str(), core::rect()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"matrix") + { + addMatrix(name.c_str(), core::matrix4()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"quaternion") + { + addQuaternion(name.c_str(), core::quaternion()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"box3d") + { + addBox3d(name.c_str(), core::aabbox3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"plane") + { + addPlane3d(name.c_str(), core::plane3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"triangle") + { + addTriangle3d(name.c_str(), core::triangle3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"line2d") + { + addLine2d(name.c_str(), core::line2df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"line3d") + { + addLine3d(name.c_str(), core::line3df()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } + else + if (element == L"stringwarray") + { + core::array tmpArray; + + s32 count = reader->getAttributeValueAsInt(L"count"); + s32 n=0; + const core::stringw tmpName(L"value"); + for (; ngetAttributeValue((tmpName+core::stringw(n)).c_str())); + } + addArray(name.c_str(),tmpArray); + } + else + if (element == L"userPointer") + { + // It's debatable if a pointer should be set or not, but it's more likely that adding it now would wreck user-applications. + // Also it probably doesn't makes sense setting this to a value when it comes from file. + } + else + if (element == L"dimension2d") + { + addDimension2d(name.c_str(), core::dimension2d()); + Attributes.getLast()->setString(reader->getAttributeValue(L"value")); + } +} + +//! Write these attributes into a xml file +bool CAttributes::write(io::IXMLWriter* writer, bool writeXMLHeader, + const wchar_t* nonDefaultElementName) +{ + if (!writer) + return false; + + if (writeXMLHeader) + writer->writeXMLHeader(); + + core::stringw elementName = L"attributes"; + if (nonDefaultElementName) + elementName = nonDefaultElementName; + + writer->writeElement(elementName.c_str(), false); + writer->writeLineBreak(); + + s32 i=0; + for (; i<(s32)Attributes.size(); ++i) + { + if ( Attributes[i]->getType() == EAT_STRINGWARRAY ) + { + core::array arraynames, arrayvalues; + core::array arrayinput = Attributes[i]->getArray(); + + // build arrays + + // name + arraynames.push_back(core::stringw(L"name")); + arrayvalues.push_back(core::stringw(Attributes[i]->Name.c_str()) ); + + // count + arraynames.push_back(core::stringw(L"count")); + arrayvalues.push_back(core::stringw((s32)arrayinput.size())); + + // array... + u32 n=0; + const core::stringw tmpName(L"value"); + for (; n < arrayinput.size(); ++n) + { + arraynames.push_back((tmpName+core::stringw(n)).c_str()); + arrayvalues.push_back(arrayinput[n]); + } + + // write them + writer->writeElement( Attributes[i]->getTypeString(), true, arraynames, arrayvalues); + } + else + { + writer->writeElement( + Attributes[i]->getTypeString(), true, + L"name", core::stringw(Attributes[i]->Name.c_str()).c_str(), + L"value", Attributes[i]->getStringW().c_str() ); + } + + writer->writeLineBreak(); + } + + writer->writeClosingTag(elementName.c_str()); + writer->writeLineBreak(); + + return true; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.h new file mode 100644 index 0000000..1675a3a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CAttributes.h @@ -0,0 +1,712 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ATTRIBUTES_H_INCLUDED__ +#define __C_ATTRIBUTES_H_INCLUDED__ + +#include "IAttributes.h" +#include "IAttribute.h" + +namespace irr +{ +namespace video +{ + class ITexture; + class IVideoDriver; +} +namespace io +{ + + +//! Implementation of the IAttributes interface +class CAttributes : public IAttributes +{ +public: + + CAttributes(video::IVideoDriver* driver=0); + ~CAttributes(); + + //! Returns amount of attributes in this collection of attributes. + virtual u32 getAttributeCount() const; + + //! Returns attribute name by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeName(s32 index); + + //! Returns the type of an attribute + //! \param attributeName: Name for the attribute + virtual E_ATTRIBUTE_TYPE getAttributeType(const c8* attributeName); + + //! Returns attribute type by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual E_ATTRIBUTE_TYPE getAttributeType(s32 index); + + //! Returns the type string of the attribute + //! \param attributeName: String for the attribute type + virtual const wchar_t* getAttributeTypeString(const c8* attributeName); + + //! Returns the type string of the attribute by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const wchar_t* getAttributeTypeString(s32 index); + + //! Returns if an attribute with a name exists + virtual bool existsAttribute(const c8* attributeName); + + //! Returns attribute index from name, -1 if not found + virtual s32 findAttribute(const c8* attributeName) const; + + //! Removes all attributes + virtual void clear(); + + //! Reads attributes from a xml file. + //! \param readCurrentElementOnly: If set to true, reading only works if current element has the name 'attributes'. + //! IF set to false, the first appearing list attributes are read. + virtual bool read(io::IXMLReader* reader, bool readCurrentElementOnly=false, + const wchar_t* nonDefaultElementName = 0); + + //! Write these attributes into a xml file + virtual bool write(io::IXMLWriter* writer, bool writeXMLHeader=false, const wchar_t* nonDefaultElementName=0); + + + /* + + Integer Attribute + + */ + + //! Adds an attribute as integer + virtual void addInt(const c8* attributeName, s32 value); + + //! Sets an attribute as integer value + virtual void setAttribute(const c8* attributeName, s32 value); + + //! Gets an attribute as integer value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsInt(const c8* attributeName) const; + + //! Gets an attribute as integer value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsInt(s32 index) const; + + //! Sets an attribute as integer value + virtual void setAttribute(s32 index, s32 value); + + /* + + Float Attribute + + */ + + //! Adds an attribute as float + virtual void addFloat(const c8* attributeName, f32 value); + + //! Sets a attribute as float value + virtual void setAttribute(const c8* attributeName, f32 value); + + //! Gets an attribute as float value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual f32 getAttributeAsFloat(const c8* attributeName); + + //! Gets an attribute as float value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual f32 getAttributeAsFloat(s32 index); + + //! Sets an attribute as float value + virtual void setAttribute(s32 index, f32 value); + + /* + + String Attribute + + */ + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const c8* value); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const c8* value); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringc getAttributeAsString(const c8* attributeName); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsString(const c8* attributeName, c8* target); + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringc getAttributeAsString(s32 index); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + virtual void setAttribute(s32 index, const c8* value); + + // wide strings + + //! Adds an attribute as string + virtual void addString(const c8* attributeName, const wchar_t* value); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const wchar_t* value); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::stringw getAttributeAsStringW(const c8* attributeName); + + //! Gets an attribute as string. + //! \param attributeName: Name of the attribute to get. + //! \param target: Buffer where the string is copied to. + virtual void getAttributeAsStringW(const c8* attributeName, wchar_t* target); + + //! Returns attribute value as string by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::stringw getAttributeAsStringW(s32 index); + + //! Sets an attribute value as string. + //! \param attributeName: Name for the attribute + virtual void setAttribute(s32 index, const wchar_t* value); + + /* + + Binary Data Attribute + + */ + + //! Adds an attribute as binary data + virtual void addBinary(const c8* attributeName, void* data, s32 dataSizeInBytes); + + //! Sets an attribute as binary data + virtual void setAttribute(const c8* attributeName, void* data, s32 dataSizeInBytes); + + //! Gets an attribute as binary data + //! \param attributeName: Name of the attribute to get. + virtual void getAttributeAsBinaryData(const c8* attributeName, void* outData, s32 maxSizeInBytes); + + //! Gets an attribute as binary data + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void getAttributeAsBinaryData(s32 index, void* outData, s32 maxSizeInBytes); + + //! Sets an attribute as binary data + virtual void setAttribute(s32 index, void* data, s32 dataSizeInBytes); + + + /* + + Array Attribute + + */ + + //! Adds an attribute as wide string array + virtual void addArray(const c8* attributeName, const core::array& value); + + //! Sets an attribute value as a wide string array. + //! \param attributeName: Name for the attribute + //! \param value: Value for the attribute. Set this to 0 to delete the attribute + virtual void setAttribute(const c8* attributeName, const core::array& value); + + //! Gets an attribute as an array of wide strings. + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + //! or 0 if attribute is not set. + virtual core::array getAttributeAsArray(const c8* attributeName); + + //! Returns attribute value as an array of wide strings by index. + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::array getAttributeAsArray(s32 index); + + //! Sets an attribute as an array of wide strings + virtual void setAttribute(s32 index, const core::array& value); + + /* + + Bool Attribute + + */ + + //! Adds an attribute as bool + virtual void addBool(const c8* attributeName, bool value); + + //! Sets an attribute as boolean value + virtual void setAttribute(const c8* attributeName, bool value); + + //! Gets an attribute as boolean value + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual bool getAttributeAsBool(const c8* attributeName); + + //! Gets an attribute as boolean value + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual bool getAttributeAsBool(s32 index); + + //! Sets an attribute as boolean value + virtual void setAttribute(s32 index, bool value); + + /* + + Enumeration Attribute + + */ + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals); + + //! Adds an attribute as enum + virtual void addEnum(const c8* attributeName, s32 enumValue, const c8* const* enumerationLiterals); + + //! Sets an attribute as enumeration + virtual void setAttribute(const c8* attributeName, const c8* enumValue, const c8* const* enumerationLiterals); + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual const c8* getAttributeAsEnumeration(const c8* attributeName); + + //! Gets an attribute as enumeration + //! \param attributeName: Name of the attribute to get. + //! \param enumerationLiteralsToUse: Use these enumeration literals to get the index value instead of the set ones. + //! This is useful when the attribute list maybe was read from an xml file, and only contains the enumeration string, but + //! no information about its index. + //! \return Returns value of the attribute previously set by setAttribute() + virtual s32 getAttributeAsEnumeration(const c8* attributeName, const c8* const* enumerationLiteralsToUse); + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual s32 getAttributeAsEnumeration(s32 index, const c8* const* enumerationLiteralsToUse); + + //! Gets an attribute as enumeration + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual const c8* getAttributeAsEnumeration(s32 index); + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param attributeName: Name of the attribute to get. + virtual void getAttributeEnumerationLiteralsOfEnumeration(const c8* attributeName, core::array& outLiterals); + + //! Gets the list of enumeration literals of an enumeration attribute + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void getAttributeEnumerationLiteralsOfEnumeration(s32 index, core::array& outLiterals); + + //! Sets an attribute as enumeration + virtual void setAttribute(s32 index, const c8* enumValue, const c8* const* enumerationLiterals); + + + /* + + SColor Attribute + + */ + + //! Adds an attribute as color + virtual void addColor(const c8* attributeName, video::SColor value); + + //! Sets a attribute as color + virtual void setAttribute(const c8* attributeName, video::SColor color); + + //! Gets an attribute as color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColor getAttributeAsColor(const c8* attributeName); + + //! Gets an attribute as color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColor getAttributeAsColor(s32 index); + + //! Sets an attribute as color + virtual void setAttribute(s32 index, video::SColor color); + + /* + + SColorf Attribute + + */ + + //! Adds an attribute as floating point color + virtual void addColorf(const c8* attributeName, video::SColorf value); + + //! Sets a attribute as floating point color + virtual void setAttribute(const c8* attributeName, video::SColorf color); + + //! Gets an attribute as floating point color + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual video::SColorf getAttributeAsColorf(const c8* attributeName); + + //! Gets an attribute as floating point color + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::SColorf getAttributeAsColorf(s32 index); + + //! Sets an attribute as floating point color + virtual void setAttribute(s32 index, video::SColorf color); + + + /* + + Vector3d Attribute + + */ + + //! Adds an attribute as 3d vector + virtual void addVector3d(const c8* attributeName, core::vector3df value); + + //! Sets a attribute as 3d vector + virtual void setAttribute(const c8* attributeName, core::vector3df v); + + //! Gets an attribute as 3d vector + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::vector3df getAttributeAsVector3d(const c8* attributeName); + + //! Gets an attribute as 3d vector + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::vector3df getAttributeAsVector3d(s32 index); + + //! Sets an attribute as vector + virtual void setAttribute(s32 index, core::vector3df v); + + + /* + + Vector2d Attribute + + */ + + //! Adds an attribute as 2d vector + virtual void addVector2d(const c8* attributeName, core::vector2df value); + + //! Sets a attribute as 2d vector + virtual void setAttribute(const c8* attributeName, core::vector2df v); + + //! Gets an attribute as 2d vector + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::vector2df getAttributeAsVector2d(const c8* attributeName); + + //! Gets an attribute as 3d vector + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::vector2df getAttributeAsVector2d(s32 index); + + //! Sets an attribute as vector + virtual void setAttribute(s32 index, core::vector2df v); + + + /* + + Position2d Attribute + + */ + + //! Adds an attribute as 2d position + virtual void addPosition2d(const c8* attributeName, core::position2di value); + + //! Sets a attribute as 2d position + virtual void setAttribute(const c8* attributeName, core::position2di v); + + //! Gets an attribute as position + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::position2di getAttributeAsPosition2d(const c8* attributeName); + + //! Gets an attribute as position + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::position2di getAttributeAsPosition2d(s32 index); + + //! Sets an attribute as 2d position + virtual void setAttribute(s32 index, core::position2di v); + + /* + + Rectangle Attribute + + */ + + //! Adds an attribute as rectangle + virtual void addRect(const c8* attributeName, core::rect value); + + //! Sets an attribute as rectangle + virtual void setAttribute(const c8* attributeName, core::rect v); + + //! Gets an attribute as rectangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::rect getAttributeAsRect(const c8* attributeName); + + //! Gets an attribute as rectangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::rect getAttributeAsRect(s32 index); + + //! Sets an attribute as rectangle + virtual void setAttribute(s32 index, core::rect v); + + + /* + + Dimension2d Attribute + + */ + + //! Adds an attribute as dimension2d + virtual void addDimension2d(const c8* attributeName, core::dimension2d value); + + //! Sets an attribute as dimension2d + virtual void setAttribute(const c8* attributeName, core::dimension2d v); + + //! Gets an attribute as dimension2d + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::dimension2d getAttributeAsDimension2d(const c8* attributeName); + + //! Gets an attribute as dimension2d + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::dimension2d getAttributeAsDimension2d(s32 index); + + //! Sets an attribute as dimension2d + virtual void setAttribute(s32 index, core::dimension2d v); + + + /* + + matrix attribute + + */ + + //! Adds an attribute as matrix + virtual void addMatrix(const c8* attributeName, const core::matrix4& v); + + //! Sets an attribute as matrix + virtual void setAttribute(const c8* attributeName, const core::matrix4& v); + + //! Gets an attribute as a matrix4 + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::matrix4 getAttributeAsMatrix(const c8* attributeName); + + //! Gets an attribute as matrix + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::matrix4 getAttributeAsMatrix(s32 index); + + //! Sets an attribute as matrix + virtual void setAttribute(s32 index, const core::matrix4& v); + + /* + quaternion attribute + + */ + + //! Adds an attribute as quaternion + virtual void addQuaternion(const c8* attributeName, core::quaternion v); + + //! Sets an attribute as quaternion + virtual void setAttribute(const c8* attributeName, core::quaternion v); + + //! Gets an attribute as a quaternion + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::quaternion getAttributeAsQuaternion(const c8* attributeName); + + //! Gets an attribute as quaternion + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::quaternion getAttributeAsQuaternion(s32 index); + + //! Sets an attribute as quaternion + virtual void setAttribute(s32 index, core::quaternion v); + + /* + + 3d bounding box + + */ + + //! Adds an attribute as axis aligned bounding box + virtual void addBox3d(const c8* attributeName, core::aabbox3df v); + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(const c8* attributeName, core::aabbox3df v); + + //! Gets an attribute as a axis aligned bounding box + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::aabbox3df getAttributeAsBox3d(const c8* attributeName); + + //! Gets an attribute as axis aligned bounding box + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::aabbox3df getAttributeAsBox3d(s32 index); + + //! Sets an attribute as axis aligned bounding box + virtual void setAttribute(s32 index, core::aabbox3df v); + + /* + + plane + + */ + + //! Adds an attribute as 3d plane + virtual void addPlane3d(const c8* attributeName, core::plane3df v); + + //! Sets an attribute as 3d plane + virtual void setAttribute(const c8* attributeName, core::plane3df v); + + //! Gets an attribute as a 3d plane + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::plane3df getAttributeAsPlane3d(const c8* attributeName); + + //! Gets an attribute as 3d plane + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::plane3df getAttributeAsPlane3d(s32 index); + + //! Sets an attribute as 3d plane + virtual void setAttribute(s32 index, core::plane3df v); + + + /* + + 3d triangle + + */ + + //! Adds an attribute as 3d triangle + virtual void addTriangle3d(const c8* attributeName, core::triangle3df v); + + //! Sets an attribute as 3d trianle + virtual void setAttribute(const c8* attributeName, core::triangle3df v); + + //! Gets an attribute as a 3d triangle + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::triangle3df getAttributeAsTriangle3d(const c8* attributeName); + + //! Gets an attribute as 3d triangle + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::triangle3df getAttributeAsTriangle3d(s32 index); + + //! Sets an attribute as 3d triangle + virtual void setAttribute(s32 index, core::triangle3df v); + + + /* + + line 2d + + */ + + //! Adds an attribute as a 2d line + virtual void addLine2d(const c8* attributeName, core::line2df v); + + //! Sets an attribute as a 2d line + virtual void setAttribute(const c8* attributeName, core::line2df v); + + //! Gets an attribute as a 2d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line2df getAttributeAsLine2d(const c8* attributeName); + + //! Gets an attribute as a 2d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line2df getAttributeAsLine2d(s32 index); + + //! Sets an attribute as a 2d line + virtual void setAttribute(s32 index, core::line2df v); + + + /* + + line 3d + + */ + + //! Adds an attribute as a 3d line + virtual void addLine3d(const c8* attributeName, core::line3df v); + + //! Sets an attribute as a 3d line + virtual void setAttribute(const c8* attributeName, core::line3df v); + + //! Gets an attribute as a 3d line + //! \param attributeName: Name of the attribute to get. + //! \return Returns value of the attribute previously set by setAttribute() + virtual core::line3df getAttributeAsLine3d(const c8* attributeName); + + //! Gets an attribute as a 3d line + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual core::line3df getAttributeAsLine3d(s32 index); + + //! Sets an attribute as a 3d line + virtual void setAttribute(s32 index, core::line3df v); + + + /* + + Texture Attribute + + */ + + //! Adds an attribute as texture reference + virtual void addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename = ""); + + //! Sets an attribute as texture reference + virtual void setAttribute(const c8* attributeName, video::ITexture* texture, const io::path& filename = ""); + + //! Gets an attribute as texture reference + //! \param attributeName: Name of the attribute to get. + virtual video::ITexture* getAttributeAsTexture(const c8* attributeName); + + //! Gets an attribute as texture reference + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual video::ITexture* getAttributeAsTexture(s32 index); + + //! Sets an attribute as texture reference + virtual void setAttribute(s32 index, video::ITexture* texture, const io::path& filename = ""); + + + + /* + + User Pointer Attribute + + */ + + //! Adds an attribute as user pointner + virtual void addUserPointer(const c8* attributeName, void* userPointer); + + //! Sets an attribute as user pointer + virtual void setAttribute(const c8* attributeName, void* userPointer); + + //! Gets an attribute as user pointer + //! \param attributeName: Name of the attribute to get. + virtual void* getAttributeAsUserPointer(const c8* attributeName); + + //! Gets an attribute as user pointer + //! \param index: Index value, must be between 0 and getAttributeCount()-1. + virtual void* getAttributeAsUserPointer(s32 index); + + //! Sets an attribute as user pointer + virtual void setAttribute(s32 index, void* userPointer); + +protected: + + void readAttributeFromXML(io::IXMLReader* reader); + + core::array Attributes; + + IAttribute* getAttributeP(const c8* attributeName) const; + + video::IVideoDriver* Driver; +}; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CB3DMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CB3DMeshFileLoader.cpp new file mode 100644 index 0000000..3d8769e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CB3DMeshFileLoader.cpp @@ -0,0 +1,1105 @@ +// Copyright (C) 2006-2012 Luke Hoschke +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// B3D Mesh loader +// File format designed by Mark Sibly for the Blitz3D engine and has been +// declared public domain + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_B3D_LOADER_ + +#include "CB3DMeshFileLoader.h" + +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "os.h" + +#ifdef _DEBUG +#define _B3D_READER_DEBUG +#endif + +namespace irr +{ +namespace scene +{ + +//! Constructor +CB3DMeshFileLoader::CB3DMeshFileLoader(scene::ISceneManager* smgr) +: SceneManager(smgr), AnimatedMesh(0), B3DFile(0), NormalsInFile(false), + HasVertexColors(false), ShowWarning(true) +{ + #ifdef _DEBUG + setDebugName("CB3DMeshFileLoader"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CB3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "b3d" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CB3DMeshFileLoader::createMesh(io::IReadFile* f) +{ + if (!f) + return 0; + + B3DFile = f; + AnimatedMesh = new scene::CSkinnedMesh(); + ShowWarning = true; // If true a warning is issued if too many textures are used + VerticesStart=0; + + if ( load() ) + { + AnimatedMesh->finalize(); + } + else + { + AnimatedMesh->drop(); + AnimatedMesh = 0; + } + + return AnimatedMesh; +} + + +bool CB3DMeshFileLoader::load() +{ + B3dStack.clear(); + + NormalsInFile=false; + HasVertexColors=false; + + //------ Get header ------ + + SB3dChunkHeader header; + B3DFile->read(&header, sizeof(header)); +#ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); +#endif + + if ( strncmp( header.name, "BB3D", 4 ) != 0 ) + { + os::Printer::log("File is not a b3d file. Loading failed (No header found)", B3DFile->getFileName(), ELL_ERROR); + return false; + } + + // Add main chunk... + B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); + + // Get file version, but ignore it, as it's not important with b3d files... + s32 fileVersion; + B3DFile->read(&fileVersion, sizeof(fileVersion)); +#ifdef __BIG_ENDIAN__ + fileVersion = os::Byteswap::byteswap(fileVersion); +#endif + + //------ Read main chunk ------ + + while ( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos() ) + { + B3DFile->read(&header, sizeof(header)); +#ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); +#endif + B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); + + if ( strncmp( B3dStack.getLast().name, "TEXS", 4 ) == 0 ) + { + if (!readChunkTEXS()) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "BRUS", 4 ) == 0 ) + { + if (!readChunkBRUS()) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) + { + if (!readChunkNODE((CSkinnedMesh::SJoint*)0) ) + return false; + } + else + { + os::Printer::log("Unknown chunk found in mesh base - skipping"); + B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + B3dStack.erase(B3dStack.size()-1); + } + } + + B3dStack.clear(); + + BaseVertices.clear(); + AnimatedVertices_VertexID.clear(); + AnimatedVertices_BufferID.clear(); + + Materials.clear(); + Textures.clear(); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkNODE(CSkinnedMesh::SJoint *inJoint) +{ + CSkinnedMesh::SJoint *joint = AnimatedMesh->addJoint(inJoint); + readString(joint->Name); + +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkNODE"; + os::Printer::log(logStr.c_str(), joint->Name.c_str()); +#endif + + f32 position[3], scale[3], rotation[4]; + + readFloats(position, 3); + readFloats(scale, 3); + readFloats(rotation, 4); + + joint->Animatedposition = core::vector3df(position[0],position[1],position[2]) ; + joint->Animatedscale = core::vector3df(scale[0],scale[1],scale[2]); + joint->Animatedrotation = core::quaternion(rotation[1], rotation[2], rotation[3], rotation[0]); + + //Build LocalMatrix: + + core::matrix4 positionMatrix; + positionMatrix.setTranslation( joint->Animatedposition ); + core::matrix4 scaleMatrix; + scaleMatrix.setScale( joint->Animatedscale ); + core::matrix4 rotationMatrix; + joint->Animatedrotation.getMatrix_transposed(rotationMatrix); + + joint->LocalMatrix = positionMatrix * rotationMatrix * scaleMatrix; + + if (inJoint) + joint->GlobalMatrix = inJoint->GlobalMatrix * joint->LocalMatrix; + else + joint->GlobalMatrix = joint->LocalMatrix; + + while(B3dStack.getLast().startposition + B3dStack.getLast().length > B3DFile->getPos()) // this chunk repeats + { + SB3dChunkHeader header; + B3DFile->read(&header, sizeof(header)); +#ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); +#endif + + B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); + + if ( strncmp( B3dStack.getLast().name, "NODE", 4 ) == 0 ) + { + if (!readChunkNODE(joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "MESH", 4 ) == 0 ) + { + VerticesStart=BaseVertices.size(); + if (!readChunkMESH(joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "BONE", 4 ) == 0 ) + { + if (!readChunkBONE(joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "KEYS", 4 ) == 0 ) + { + if(!readChunkKEYS(joint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "ANIM", 4 ) == 0 ) + { + if (!readChunkANIM()) + return false; + } + else + { + os::Printer::log("Unknown chunk found in node chunk - skipping"); + B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + B3dStack.erase(B3dStack.size()-1); + } + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkMESH"; + os::Printer::log(logStr.c_str()); +#endif + + s32 brushID; + B3DFile->read(&brushID, sizeof(brushID)); +#ifdef __BIG_ENDIAN__ + brushID = os::Byteswap::byteswap(brushID); +#endif + + NormalsInFile=false; + HasVertexColors=false; + + while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats + { + SB3dChunkHeader header; + B3DFile->read(&header, sizeof(header)); +#ifdef __BIG_ENDIAN__ + header.size = os::Byteswap::byteswap(header.size); +#endif + + B3dStack.push_back(SB3dChunk(header, B3DFile->getPos()-8)); + + if ( strncmp( B3dStack.getLast().name, "VRTS", 4 ) == 0 ) + { + if (!readChunkVRTS(inJoint)) + return false; + } + else if ( strncmp( B3dStack.getLast().name, "TRIS", 4 ) == 0 ) + { + scene::SSkinMeshBuffer *meshBuffer = AnimatedMesh->addMeshBuffer(); + + if (brushID!=-1) + { + loadTextures(Materials[brushID]); + meshBuffer->Material=Materials[brushID].Material; + } + + if(readChunkTRIS(meshBuffer,AnimatedMesh->getMeshBuffers().size()-1, VerticesStart)==false) + return false; + + if (!NormalsInFile) + { + s32 i; + + for ( i=0; i<(s32)meshBuffer->Indices.size(); i+=3) + { + core::plane3df p(meshBuffer->getVertex(meshBuffer->Indices[i+0])->Pos, + meshBuffer->getVertex(meshBuffer->Indices[i+1])->Pos, + meshBuffer->getVertex(meshBuffer->Indices[i+2])->Pos); + + meshBuffer->getVertex(meshBuffer->Indices[i+0])->Normal += p.Normal; + meshBuffer->getVertex(meshBuffer->Indices[i+1])->Normal += p.Normal; + meshBuffer->getVertex(meshBuffer->Indices[i+2])->Normal += p.Normal; + } + + for ( i = 0; i<(s32)meshBuffer->getVertexCount(); ++i ) + { + meshBuffer->getVertex(i)->Normal.normalize(); + BaseVertices[VerticesStart+i].Normal=meshBuffer->getVertex(i)->Normal; + } + } + } + else + { + os::Printer::log("Unknown chunk found in mesh - skipping"); + B3DFile->seek(B3dStack.getLast().startposition + B3dStack.getLast().length); + B3dStack.erase(B3dStack.size()-1); + } + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +/* +VRTS: + int flags ;1=normal values present, 2=rgba values present + int tex_coord_sets ;texture coords per vertex (eg: 1 for simple U/V) max=8 + but we only support 3 + int tex_coord_set_size ;components per set (eg: 2 for simple U/V) max=4 + { + float x,y,z ;always present + float nx,ny,nz ;vertex normal: present if (flags&1) + float red,green,blue,alpha ;vertex color: present if (flags&2) + float tex_coords[tex_coord_sets][tex_coord_set_size] ;tex coords + } +*/ +bool CB3DMeshFileLoader::readChunkVRTS(CSkinnedMesh::SJoint *inJoint) +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "ChunkVRTS"; + os::Printer::log(logStr.c_str()); +#endif + + const s32 max_tex_coords = 3; + s32 flags, tex_coord_sets, tex_coord_set_size; + + B3DFile->read(&flags, sizeof(flags)); + B3DFile->read(&tex_coord_sets, sizeof(tex_coord_sets)); + B3DFile->read(&tex_coord_set_size, sizeof(tex_coord_set_size)); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); + tex_coord_sets = os::Byteswap::byteswap(tex_coord_sets); + tex_coord_set_size = os::Byteswap::byteswap(tex_coord_set_size); +#endif + + if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong + { + os::Printer::log("tex_coord_sets or tex_coord_set_size too big", B3DFile->getFileName(), ELL_ERROR); + return false; + } + + //------ Allocate Memory, for speed -----------// + + s32 numberOfReads = 3; + + if (flags & 1) + { + NormalsInFile = true; + numberOfReads += 3; + } + if (flags & 2) + { + numberOfReads += 4; + HasVertexColors=true; + } + + numberOfReads += tex_coord_sets*tex_coord_set_size; + + const s32 memoryNeeded = (B3dStack.getLast().length / sizeof(f32)) / numberOfReads; + + BaseVertices.reallocate(memoryNeeded + BaseVertices.size() + 1); + AnimatedVertices_VertexID.reallocate(memoryNeeded + AnimatedVertices_VertexID.size() + 1); + + //--------------------------------------------// + + while( (B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats + { + f32 position[3]; + f32 normal[3]={0.f, 0.f, 0.f}; + f32 color[4]={1.0f, 1.0f, 1.0f, 1.0f}; + f32 tex_coords[max_tex_coords][4]; + + readFloats(position, 3); + + if (flags & 1) + readFloats(normal, 3); + if (flags & 2) + readFloats(color, 4); + + for (s32 i=0; i= 1 && tex_coord_set_size >= 2) + { + tu=tex_coords[0][0]; + tv=tex_coords[0][1]; + } + + f32 tu2=0.0f, tv2=0.0f; + if (tex_coord_sets>1 && tex_coord_set_size>1) + { + tu2=tex_coords[1][0]; + tv2=tex_coords[1][1]; + } + + // Create Vertex... + video::S3DVertex2TCoords Vertex(position[0], position[1], position[2], + normal[0], normal[1], normal[2], + video::SColorf(color[0], color[1], color[2], color[3]).toSColor(), + tu, tv, tu2, tv2); + + // Transform the Vertex position by nested node... + inJoint->GlobalMatrix.transformVect(Vertex.Pos); + inJoint->GlobalMatrix.rotateVect(Vertex.Normal); + + //Add it... + BaseVertices.push_back(Vertex); + + AnimatedVertices_VertexID.push_back(-1); + AnimatedVertices_BufferID.push_back(-1); + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 meshBufferID, s32 vertices_Start) +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "ChunkTRIS"; + os::Printer::log(logStr.c_str()); +#endif + + bool showVertexWarning=false; + + s32 triangle_brush_id; // Note: Irrlicht can't have different brushes for each triangle (using a workaround) + B3DFile->read(&triangle_brush_id, sizeof(triangle_brush_id)); +#ifdef __BIG_ENDIAN__ + triangle_brush_id = os::Byteswap::byteswap(triangle_brush_id); +#endif + + SB3dMaterial *B3dMaterial; + + if (triangle_brush_id != -1) + { + loadTextures(Materials[triangle_brush_id]); + B3dMaterial = &Materials[triangle_brush_id]; + meshBuffer->Material = B3dMaterial->Material; + } + else + B3dMaterial = 0; + + const s32 memoryNeeded = B3dStack.getLast().length / sizeof(s32); + meshBuffer->Indices.reallocate(memoryNeeded + meshBuffer->Indices.size() + 1); + + while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats + { + s32 vertex_id[3]; + + B3DFile->read(vertex_id, 3*sizeof(s32)); +#ifdef __BIG_ENDIAN__ + vertex_id[0] = os::Byteswap::byteswap(vertex_id[0]); + vertex_id[1] = os::Byteswap::byteswap(vertex_id[1]); + vertex_id[2] = os::Byteswap::byteswap(vertex_id[2]); +#endif + + //Make Ids global: + vertex_id[0] += vertices_Start; + vertex_id[1] += vertices_Start; + vertex_id[2] += vertices_Start; + + for(s32 i=0; i<3; ++i) + { + if ((u32)vertex_id[i] >= AnimatedVertices_VertexID.size()) + { + os::Printer::log("Illegal vertex index found", B3DFile->getFileName(), ELL_ERROR); + return false; + } + + if (AnimatedVertices_VertexID[ vertex_id[i] ] != -1) + { + if ( AnimatedVertices_BufferID[ vertex_id[i] ] != (s32)meshBufferID ) //If this vertex is linked in a different meshbuffer + { + AnimatedVertices_VertexID[ vertex_id[i] ] = -1; + AnimatedVertices_BufferID[ vertex_id[i] ] = -1; + showVertexWarning=true; + } + } + if (AnimatedVertices_VertexID[ vertex_id[i] ] == -1) //If this vertex is not in the meshbuffer + { + //Check for lightmapping: + if (BaseVertices[ vertex_id[i] ].TCoords2 != core::vector2df(0.f,0.f)) + meshBuffer->convertTo2TCoords(); //Will only affect the meshbuffer the first time this is called + + //Add the vertex to the meshbuffer: + if (meshBuffer->VertexType == video::EVT_STANDARD) + meshBuffer->Vertices_Standard.push_back( BaseVertices[ vertex_id[i] ] ); + else + meshBuffer->Vertices_2TCoords.push_back(BaseVertices[ vertex_id[i] ] ); + + //create vertex id to meshbuffer index link: + AnimatedVertices_VertexID[ vertex_id[i] ] = meshBuffer->getVertexCount()-1; + AnimatedVertices_BufferID[ vertex_id[i] ] = meshBufferID; + + if (B3dMaterial) + { + // Apply Material/Color/etc... + video::S3DVertex *Vertex=meshBuffer->getVertex(meshBuffer->getVertexCount()-1); + + if (!HasVertexColors) + Vertex->Color=B3dMaterial->Material.DiffuseColor; + else if (Vertex->Color.getAlpha() == 255) + Vertex->Color.setAlpha( (s32)(B3dMaterial->alpha * 255.0f) ); + + // Use texture's scale + if (B3dMaterial->Textures[0]) + { + Vertex->TCoords.X *= B3dMaterial->Textures[0]->Xscale; + Vertex->TCoords.Y *= B3dMaterial->Textures[0]->Yscale; + } + /* + if (B3dMaterial->Textures[1]) + { + Vertex->TCoords2.X *=B3dMaterial->Textures[1]->Xscale; + Vertex->TCoords2.Y *=B3dMaterial->Textures[1]->Yscale; + } + */ + } + } + } + + meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[0] ] ); + meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[1] ] ); + meshBuffer->Indices.push_back( AnimatedVertices_VertexID[ vertex_id[2] ] ); + } + + B3dStack.erase(B3dStack.size()-1); + + if (showVertexWarning) + os::Printer::log("B3dMeshLoader: Warning, different meshbuffers linking to the same vertex, this will cause problems with animated meshes"); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkBONE(CSkinnedMesh::SJoint *inJoint) +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkBONE"; + os::Printer::log(logStr.c_str()); +#endif + + if (B3dStack.getLast().length > 8) + { + while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats + { + u32 globalVertexID; + f32 strength; + B3DFile->read(&globalVertexID, sizeof(globalVertexID)); + B3DFile->read(&strength, sizeof(strength)); +#ifdef __BIG_ENDIAN__ + globalVertexID = os::Byteswap::byteswap(globalVertexID); + strength = os::Byteswap::byteswap(strength); +#endif + globalVertexID += VerticesStart; + + if (AnimatedVertices_VertexID[globalVertexID]==-1) + { + os::Printer::log("B3dMeshLoader: Weight has bad vertex id (no link to meshbuffer index found)"); + } + else if (strength >0) + { + CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(inJoint); + weight->strength=strength; + //Find the meshbuffer and Vertex index from the Global Vertex ID: + weight->vertex_id = AnimatedVertices_VertexID[globalVertexID]; + weight->buffer_id = AnimatedVertices_BufferID[globalVertexID]; + } + } + } + + B3dStack.erase(B3dStack.size()-1); + return true; +} + + +bool CB3DMeshFileLoader::readChunkKEYS(CSkinnedMesh::SJoint *inJoint) +{ +#ifdef _B3D_READER_DEBUG + // Only print first, that's just too much output otherwise + if ( !inJoint || (inJoint->PositionKeys.empty() && inJoint->ScaleKeys.empty() && inJoint->RotationKeys.empty()) ) + { + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkKEYS"; + os::Printer::log(logStr.c_str()); + } +#endif + + s32 flags; + B3DFile->read(&flags, sizeof(flags)); +#ifdef __BIG_ENDIAN__ + flags = os::Byteswap::byteswap(flags); +#endif + + CSkinnedMesh::SPositionKey *oldPosKey=0; + core::vector3df oldPos[2]; + CSkinnedMesh::SScaleKey *oldScaleKey=0; + core::vector3df oldScale[2]; + CSkinnedMesh::SRotationKey *oldRotKey=0; + core::quaternion oldRot[2]; + bool isFirst[3]={true,true,true}; + while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats + { + s32 frame; + + B3DFile->read(&frame, sizeof(frame)); + #ifdef __BIG_ENDIAN__ + frame = os::Byteswap::byteswap(frame); + #endif + + // Add key frames, frames in Irrlicht are zero-based + f32 data[4]; + if (flags & 1) + { + readFloats(data, 3); + if ((oldPosKey!=0) && (oldPos[0]==oldPos[1])) + { + const core::vector3df pos(data[0], data[1], data[2]); + if (oldPos[1]==pos) + oldPosKey->frame = (f32)frame-1; + else + { + oldPos[0]=oldPos[1]; + oldPosKey=AnimatedMesh->addPositionKey(inJoint); + oldPosKey->frame = (f32)frame-1; + oldPos[1].set(oldPosKey->position.set(pos)); + } + } + else if (oldPosKey==0 && isFirst[0]) + { + oldPosKey=AnimatedMesh->addPositionKey(inJoint); + oldPosKey->frame = (f32)frame-1; + oldPos[0].set(oldPosKey->position.set(data[0], data[1], data[2])); + oldPosKey=0; + isFirst[0]=false; + } + else + { + if (oldPosKey!=0) + oldPos[0]=oldPos[1]; + oldPosKey=AnimatedMesh->addPositionKey(inJoint); + oldPosKey->frame = (f32)frame-1; + oldPos[1].set(oldPosKey->position.set(data[0], data[1], data[2])); + } + } + if (flags & 2) + { + readFloats(data, 3); + if ((oldScaleKey!=0) && (oldScale[0]==oldScale[1])) + { + const core::vector3df scale(data[0], data[1], data[2]); + if (oldScale[1]==scale) + oldScaleKey->frame = (f32)frame-1; + else + { + oldScale[0]=oldScale[1]; + oldScaleKey=AnimatedMesh->addScaleKey(inJoint); + oldScaleKey->frame = (f32)frame-1; + oldScale[1].set(oldScaleKey->scale.set(scale)); + } + } + else if (oldScaleKey==0 && isFirst[1]) + { + oldScaleKey=AnimatedMesh->addScaleKey(inJoint); + oldScaleKey->frame = (f32)frame-1; + oldScale[0].set(oldScaleKey->scale.set(data[0], data[1], data[2])); + oldScaleKey=0; + isFirst[1]=false; + } + else + { + if (oldScaleKey!=0) + oldScale[0]=oldScale[1]; + oldScaleKey=AnimatedMesh->addScaleKey(inJoint); + oldScaleKey->frame = (f32)frame-1; + oldScale[1].set(oldScaleKey->scale.set(data[0], data[1], data[2])); + } + } + if (flags & 4) + { + readFloats(data, 4); + if ((oldRotKey!=0) && (oldRot[0]==oldRot[1])) + { + // meant to be in this order since b3d stores W first + const core::quaternion rot(data[1], data[2], data[3], data[0]); + if (oldRot[1]==rot) + oldRotKey->frame = (f32)frame-1; + else + { + oldRot[0]=oldRot[1]; + oldRotKey=AnimatedMesh->addRotationKey(inJoint); + oldRotKey->frame = (f32)frame-1; + oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); + } + } + else if (oldRotKey==0 && isFirst[2]) + { + oldRotKey=AnimatedMesh->addRotationKey(inJoint); + oldRotKey->frame = (f32)frame-1; + // meant to be in this order since b3d stores W first + oldRot[0].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); + oldRotKey=0; + isFirst[2]=false; + } + else + { + if (oldRotKey!=0) + oldRot[0]=oldRot[1]; + oldRotKey=AnimatedMesh->addRotationKey(inJoint); + oldRotKey->frame = (f32)frame-1; + // meant to be in this order since b3d stores W first + oldRot[1].set(oldRotKey->rotation.set(data[1], data[2], data[3], data[0])); + } + } + } + + B3dStack.erase(B3dStack.size()-1); + return true; +} + + +bool CB3DMeshFileLoader::readChunkANIM() +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkANIM"; + os::Printer::log(logStr.c_str()); +#endif + + s32 animFlags; //not stored\used + s32 animFrames;//not stored\used + f32 animFPS; //not stored\used + + B3DFile->read(&animFlags, sizeof(s32)); + B3DFile->read(&animFrames, sizeof(s32)); + readFloats(&animFPS, 1); + if (animFPS>0.f) + AnimatedMesh->setAnimationSpeed(animFPS); + os::Printer::log("FPS", io::path((double)animFPS), ELL_DEBUG); + + #ifdef __BIG_ENDIAN__ + animFlags = os::Byteswap::byteswap(animFlags); + animFrames = os::Byteswap::byteswap(animFrames); + #endif + + B3dStack.erase(B3dStack.size()-1); + return true; +} + + +bool CB3DMeshFileLoader::readChunkTEXS() +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkTEXS"; + os::Printer::log(logStr.c_str()); +#endif + + while((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) //this chunk repeats + { + Textures.push_back(SB3dTexture()); + SB3dTexture& B3dTexture = Textures.getLast(); + + readString(B3dTexture.TextureName); + B3dTexture.TextureName.replace('\\','/'); +#ifdef _B3D_READER_DEBUG + os::Printer::log("read Texture", B3dTexture.TextureName.c_str()); +#endif + + B3DFile->read(&B3dTexture.Flags, sizeof(s32)); + B3DFile->read(&B3dTexture.Blend, sizeof(s32)); +#ifdef __BIG_ENDIAN__ + B3dTexture.Flags = os::Byteswap::byteswap(B3dTexture.Flags); + B3dTexture.Blend = os::Byteswap::byteswap(B3dTexture.Blend); +#endif +#ifdef _B3D_READER_DEBUG + os::Printer::log("Flags", core::stringc(B3dTexture.Flags).c_str()); + os::Printer::log("Blend", core::stringc(B3dTexture.Blend).c_str()); +#endif + readFloats(&B3dTexture.Xpos, 1); + readFloats(&B3dTexture.Ypos, 1); + readFloats(&B3dTexture.Xscale, 1); + readFloats(&B3dTexture.Yscale, 1); + readFloats(&B3dTexture.Angle, 1); + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +bool CB3DMeshFileLoader::readChunkBRUS() +{ +#ifdef _B3D_READER_DEBUG + core::stringc logStr; + for ( u32 i=1; i < B3dStack.size(); ++i ) + logStr += "-"; + logStr += "read ChunkBRUS"; + os::Printer::log(logStr.c_str()); +#endif + + u32 n_texs; + B3DFile->read(&n_texs, sizeof(u32)); +#ifdef __BIG_ENDIAN__ + n_texs = os::Byteswap::byteswap(n_texs); +#endif + + // number of texture ids read for Irrlicht + const u32 num_textures = core::min_(n_texs, video::MATERIAL_MAX_TEXTURES); + // number of bytes to skip (for ignored texture ids) + const u32 n_texs_offset = (num_textures B3DFile->getPos()) //this chunk repeats + { + // This is what blitz basic calls a brush, like a Irrlicht Material + + core::stringc name; + readString(name); +#ifdef _B3D_READER_DEBUG + os::Printer::log("read Material", name); +#endif + Materials.push_back(SB3dMaterial()); + SB3dMaterial& B3dMaterial=Materials.getLast(); + + readFloats(&B3dMaterial.red, 1); + readFloats(&B3dMaterial.green, 1); + readFloats(&B3dMaterial.blue, 1); + readFloats(&B3dMaterial.alpha, 1); + readFloats(&B3dMaterial.shininess, 1); + + B3DFile->read(&B3dMaterial.blend, sizeof(B3dMaterial.blend)); + B3DFile->read(&B3dMaterial.fx, sizeof(B3dMaterial.fx)); +#ifdef __BIG_ENDIAN__ + B3dMaterial.blend = os::Byteswap::byteswap(B3dMaterial.blend); + B3dMaterial.fx = os::Byteswap::byteswap(B3dMaterial.fx); +#endif +#ifdef _B3D_READER_DEBUG + os::Printer::log("Blend", core::stringc(B3dMaterial.blend).c_str()); + os::Printer::log("FX", core::stringc(B3dMaterial.fx).c_str()); +#endif + + u32 i; + for (i=0; iread(&texture_id, sizeof(s32)); +#ifdef __BIG_ENDIAN__ + texture_id = os::Byteswap::byteswap(texture_id); +#endif + //--- Get pointers to the texture, based on the IDs --- + if ((u32)texture_id < Textures.size()) + { + B3dMaterial.Textures[i]=&Textures[texture_id]; +#ifdef _B3D_READER_DEBUG + os::Printer::log("Layer", core::stringc(i).c_str()); + os::Printer::log("using texture", Textures[texture_id].TextureName.c_str()); +#endif + } + else + B3dMaterial.Textures[i]=0; + } + // skip other texture ids + for (i=0; iread(&texture_id, sizeof(s32)); +#ifdef __BIG_ENDIAN__ + texture_id = os::Byteswap::byteswap(texture_id); +#endif + if (ShowWarning && (texture_id != -1) && (n_texs>video::MATERIAL_MAX_TEXTURES)) + { + os::Printer::log("Too many textures used in one material", B3DFile->getFileName(), ELL_WARNING); + ShowWarning = false; + } + } + + //Fixes problems when the lightmap is on the first texture: + if (B3dMaterial.Textures[0] != 0) + { + if (B3dMaterial.Textures[0]->Flags & 65536) // 65536 = secondary UV + { + SB3dTexture *TmpTexture; + TmpTexture = B3dMaterial.Textures[1]; + B3dMaterial.Textures[1] = B3dMaterial.Textures[0]; + B3dMaterial.Textures[0] = TmpTexture; + } + } + + //If a preceeding texture slot is empty move the others down: + for (i=num_textures; i>0; --i) + { + for (u32 j=i-1; jBlend == 5) //(Multiply 2) + B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP_M2; + else + B3dMaterial.Material.MaterialType = video::EMT_LIGHTMAP; + B3dMaterial.Material.Lighting = false; + } + else + { + B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + B3dMaterial.Material.ZWriteEnable = false; + } + } + else if (B3dMaterial.Textures[0]) //One texture: + { + // Flags & 0x1 is usual SOLID, 0x8 is mipmap (handled before) + if (B3dMaterial.Textures[0]->Flags & 0x2) //(Alpha mapped) + { + B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + B3dMaterial.Material.ZWriteEnable = false; + } + else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked) + B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture + else if (B3dMaterial.Textures[0]->Flags & 0x40) + B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; + else if (B3dMaterial.Textures[0]->Flags & 0x80) + B3dMaterial.Material.MaterialType = video::EMT_SPHERE_MAP; // TODO: Should be cube map + else if (B3dMaterial.alpha == 1.f) + B3dMaterial.Material.MaterialType = video::EMT_SOLID; + else + { + B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + B3dMaterial.Material.ZWriteEnable = false; + } + } + else //No texture: + { + if (B3dMaterial.alpha == 1.f) + B3dMaterial.Material.MaterialType = video::EMT_SOLID; + else + { + B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + B3dMaterial.Material.ZWriteEnable = false; + } + } + + B3dMaterial.Material.DiffuseColor = video::SColorf(B3dMaterial.red, B3dMaterial.green, B3dMaterial.blue, B3dMaterial.alpha).toSColor(); + B3dMaterial.Material.ColorMaterial=video::ECM_NONE; + + //------ Material fx ------ + + if (B3dMaterial.fx & 1) //full-bright + { + B3dMaterial.Material.AmbientColor = video::SColor(255, 255, 255, 255); + B3dMaterial.Material.Lighting = false; + } + else + B3dMaterial.Material.AmbientColor = B3dMaterial.Material.DiffuseColor; + + if (B3dMaterial.fx & 2) //use vertex colors instead of brush color + B3dMaterial.Material.ColorMaterial=video::ECM_DIFFUSE_AND_AMBIENT; + + if (B3dMaterial.fx & 4) //flatshaded + B3dMaterial.Material.GouraudShading = false; + + if (B3dMaterial.fx & 16) //disable backface culling + B3dMaterial.Material.BackfaceCulling = false; + + if (B3dMaterial.fx & 32) //force vertex alpha-blending + { + B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + B3dMaterial.Material.ZWriteEnable = false; + } + + B3dMaterial.Material.Shininess = B3dMaterial.shininess; + } + + B3dStack.erase(B3dStack.size()-1); + + return true; +} + + +void CB3DMeshFileLoader::loadTextures(SB3dMaterial& material) const +{ + const bool previous32BitTextureFlag = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true); + + // read texture from disk + // note that mipmaps might be disabled by Flags & 0x8 + const bool doMipMaps = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + for (u32 i=0; iTextureName.size() && !material.Material.getTexture(i)) + { + if (!SceneManager->getParameters()->getAttributeAsBool(B3D_LOADER_IGNORE_MIPMAP_FLAG)) + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, (B3dTexture->Flags & 0x8) ? true:false); + { + video::ITexture* tex = 0; + io::IFileSystem* fs = SceneManager->getFileSystem(); + io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(B3D_TEXTURE_PATH) ); + if ( texnameWithUserPath.size() ) + { + texnameWithUserPath += '/'; + texnameWithUserPath += B3dTexture->TextureName; + } + if (fs->existFile(texnameWithUserPath)) + tex = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath); + else if (fs->existFile(B3dTexture->TextureName)) + tex = SceneManager->getVideoDriver()->getTexture(B3dTexture->TextureName); + else if (fs->existFile(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName))) + tex = SceneManager->getVideoDriver()->getTexture(fs->getFileDir(B3DFile->getFileName()) +"/"+ fs->getFileBasename(B3dTexture->TextureName)); + else + tex = SceneManager->getVideoDriver()->getTexture(fs->getFileBasename(B3dTexture->TextureName)); + + material.Material.setTexture(i, tex); + } + if (material.Textures[i]->Flags & 0x10) // Clamp U + material.Material.TextureLayer[i].TextureWrapU=video::ETC_CLAMP; + if (material.Textures[i]->Flags & 0x20) // Clamp V + material.Material.TextureLayer[i].TextureWrapV=video::ETC_CLAMP; + } + } + + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, doMipMaps); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, previous32BitTextureFlag); +} + + +void CB3DMeshFileLoader::readString(core::stringc& newstring) +{ + newstring=""; + while (B3DFile->getPos() <= B3DFile->getSize()) + { + c8 character; + B3DFile->read(&character, sizeof(character)); + if (character==0) + return; + newstring.append(character); + } +} + + +void CB3DMeshFileLoader::readFloats(f32* vec, u32 count) +{ + B3DFile->read(vec, count*sizeof(f32)); + #ifdef __BIG_ENDIAN__ + for (u32 n=0; n B3dStack; + + core::array Materials; + core::array Textures; + + core::array AnimatedVertices_VertexID; + + core::array AnimatedVertices_BufferID; + + core::array BaseVertices; + + ISceneManager* SceneManager; + CSkinnedMesh* AnimatedMesh; + io::IReadFile* B3DFile; + + //B3Ds have Vertex ID's local within the mesh I don't want this + // Variable needs to be class member due to recursion in calls + u32 VerticesStart; + + bool NormalsInFile; + bool HasVertexColors; + bool ShowWarning; +}; + + +} // end namespace scene +} // end namespace irr + +#endif // __C_B3D_MESH_LOADER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.cpp new file mode 100644 index 0000000..01ac04a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + +#include "CBSPMeshFileLoader.h" +#include "CQ3LevelMesh.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CBSPMeshFileLoader::CBSPMeshFileLoader(scene::ISceneManager* smgr, + io::IFileSystem* fs) +: FileSystem(fs), SceneManager(smgr) +{ + + #ifdef _DEBUG + setDebugName("CBSPMeshFileLoader"); + #endif + + if (FileSystem) + FileSystem->grab(); +} + + +//! destructor +CBSPMeshFileLoader::~CBSPMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CBSPMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "bsp", "shader", "cfg" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file) +{ + s32 type = core::isFileExtension ( file->getFileName(), "bsp", "shader", "cfg" ); + CQ3LevelMesh* q = 0; + + switch ( type ) + { + case 1: + q = new CQ3LevelMesh(FileSystem, SceneManager, LoadParam); + + // determine real shaders in LoadParam + if ( 0 == LoadParam.loadAllShaders ) + { + q->getShader("scripts/common.shader"); + q->getShader("scripts/sfx.shader"); + q->getShader("scripts/gfx.shader"); + q->getShader("scripts/liquid.shader"); + q->getShader("scripts/models.shader"); + q->getShader("scripts/walls.shader"); + //q->getShader("scripts/sky.shader"); + } + + if ( q->loadFile(file) ) + return q; + + q->drop(); + break; + + case 2: + q = new CQ3LevelMesh(FileSystem, SceneManager,LoadParam); + q->getShader( file ); + return q; + break; + + case 3: + // load quake 3 loading parameter + if ( file->getFileName() == "levelparameter.cfg" ) + { + file->read ( &LoadParam, sizeof ( LoadParam ) ); + } + else + { + q = new CQ3LevelMesh(FileSystem, SceneManager,LoadParam); + q->getConfiguration( file ); + return q; + } + break; + } + + return 0; +} + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BSP_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.h new file mode 100644 index 0000000..2845037 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBSPMeshFileLoader.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_BSP_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_BSP_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading Quake 3 BSP files and shaders +class CBSPMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CBSPMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~CBSPMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + io::IFileSystem* FileSystem; + scene::ISceneManager* SceneManager; + + quake3::Q3LevelLoadParameter LoadParam; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp new file mode 100644 index 0000000..22d41bd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.cpp @@ -0,0 +1,294 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CBillboardSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CBillboardSceneNode::CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::dimension2d& size, + video::SColor colorTop, video::SColor colorBottom) + : IBillboardSceneNode(parent, mgr, id, position) +{ + #ifdef _DEBUG + setDebugName("CBillboardSceneNode"); + #endif + + setSize(size); + + indices[0] = 0; + indices[1] = 2; + indices[2] = 1; + indices[3] = 0; + indices[4] = 3; + indices[5] = 2; + + vertices[0].TCoords.set(1.0f, 1.0f); + vertices[0].Color = colorBottom; + + vertices[1].TCoords.set(1.0f, 0.0f); + vertices[1].Color = colorTop; + + vertices[2].TCoords.set(0.0f, 0.0f); + vertices[2].Color = colorTop; + + vertices[3].TCoords.set(0.0f, 1.0f); + vertices[3].Color = colorBottom; +} + + +//! pre render event +void CBillboardSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! render +void CBillboardSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + // make billboard look to camera + + core::vector3df pos = getAbsolutePosition(); + + core::vector3df campos = camera->getAbsolutePosition(); + core::vector3df target = camera->getTarget(); + core::vector3df up = camera->getUpVector(); + core::vector3df view = target - campos; + view.normalize(); + + core::vector3df horizontal = up.crossProduct(view); + if ( horizontal.getLength() == 0 ) + { + horizontal.set(up.Y,up.X,up.Z); + } + horizontal.normalize(); + core::vector3df topHorizontal = horizontal * 0.5f * TopEdgeWidth; + horizontal *= 0.5f * Size.Width; + + // pointing down! + core::vector3df vertical = horizontal.crossProduct(view); + vertical.normalize(); + vertical *= 0.5f * Size.Height; + + view *= -1.0f; + + for (s32 i=0; i<4; ++i) + vertices[i].Normal = view; + + /* Vertices are: + 2--1 + |\ | + | \| + 3--0 + */ + vertices[0].Pos = pos + horizontal + vertical; + vertices[1].Pos = pos + topHorizontal - vertical; + vertices[2].Pos = pos - topHorizontal - vertical; + vertices[3].Pos = pos - horizontal + vertical; + + // draw + + if (DebugDataVisible & scene::EDS_BBOX) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(BBox, video::SColor(0,208,195,152)); + } + + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + + driver->setMaterial(Material); + + driver->drawIndexedTriangleList(vertices, 4, indices, 2); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CBillboardSceneNode::getBoundingBox() const +{ + return BBox; +} + + +//! sets the size of the billboard +void CBillboardSceneNode::setSize(const core::dimension2d& size) +{ + Size = size; + + if (core::equals(Size.Width, 0.0f)) + Size.Width = 1.0f; + TopEdgeWidth = Size.Width; + + if (core::equals(Size.Height, 0.0f)) + Size.Height = 1.0f; + + const f32 avg = (Size.Width + Size.Height)/6; + BBox.MinEdge.set(-avg,-avg,-avg); + BBox.MaxEdge.set(avg,avg,avg); +} + + +void CBillboardSceneNode::setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth) +{ + Size.set(bottomEdgeWidth, height); + TopEdgeWidth = topEdgeWidth; + + if (core::equals(Size.Height, 0.0f)) + Size.Height = 1.0f; + + if (core::equals(Size.Width, 0.f) && core::equals(TopEdgeWidth, 0.f)) + { + Size.Width = 1.0f; + TopEdgeWidth = 1.0f; + } + + const f32 avg = (core::max_(Size.Width,TopEdgeWidth) + Size.Height)/6; + BBox.MinEdge.set(-avg,-avg,-avg); + BBox.MaxEdge.set(avg,avg,avg); +} + + +video::SMaterial& CBillboardSceneNode::getMaterial(u32 i) +{ + return Material; +} + + +//! returns amount of materials used by this scene node. +u32 CBillboardSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! gets the size of the billboard +const core::dimension2d& CBillboardSceneNode::getSize() const +{ + return Size; +} + + +//! Gets the widths of the top and bottom edges of the billboard. +void CBillboardSceneNode::getSize(f32& height, f32& bottomEdgeWidth, + f32& topEdgeWidth) const +{ + height = Size.Height; + bottomEdgeWidth = Size.Width; + topEdgeWidth = TopEdgeWidth; +} + + +//! Writes attributes of the scene node. +void CBillboardSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IBillboardSceneNode::serializeAttributes(out, options); + + out->addFloat("Width", Size.Width); + out->addFloat("TopEdgeWidth", TopEdgeWidth); + out->addFloat("Height", Size.Height); + out->addColor("Shade_Top", vertices[1].Color); + out->addColor("Shade_Down", vertices[0].Color); +} + + +//! Reads attributes of the scene node. +void CBillboardSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IBillboardSceneNode::deserializeAttributes(in, options); + + Size.Width = in->getAttributeAsFloat("Width"); + Size.Height = in->getAttributeAsFloat("Height"); + + if (in->existsAttribute("TopEdgeWidth")) + { + TopEdgeWidth = in->getAttributeAsFloat("TopEdgeWidth"); + if (Size.Width != TopEdgeWidth) + setSize(Size.Height, Size.Width, TopEdgeWidth); + } + else + setSize(Size); + vertices[1].Color = in->getAttributeAsColor("Shade_Top"); + vertices[0].Color = in->getAttributeAsColor("Shade_Down"); + vertices[2].Color = vertices[1].Color; + vertices[3].Color = vertices[0].Color; +} + + +//! Set the color of all vertices of the billboard +//! \param overallColor: the color to set +void CBillboardSceneNode::setColor(const video::SColor& overallColor) +{ + for(u32 vertex = 0; vertex < 4; ++vertex) + vertices[vertex].Color = overallColor; +} + + +//! Set the color of the top and bottom vertices of the billboard +//! \param topColor: the color to set the top vertices +//! \param bottomColor: the color to set the bottom vertices +void CBillboardSceneNode::setColor(const video::SColor& topColor, + const video::SColor& bottomColor) +{ + vertices[0].Color = bottomColor; + vertices[1].Color = topColor; + vertices[2].Color = topColor; + vertices[3].Color = bottomColor; +} + + +//! Gets the color of the top and bottom vertices of the billboard +//! \param[out] topColor: stores the color of the top vertices +//! \param[out] bottomColor: stores the color of the bottom vertices +void CBillboardSceneNode::getColor(video::SColor& topColor, + video::SColor& bottomColor) const +{ + bottomColor = vertices[0].Color; + topColor = vertices[1].Color; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CBillboardSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CBillboardSceneNode* nb = new CBillboardSceneNode(newParent, + newManager, ID, RelativeTranslation, Size); + + nb->cloneMembers(this, newManager); + nb->Material = Material; + nb->TopEdgeWidth = this->TopEdgeWidth; + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.h new file mode 100644 index 0000000..416b6ff --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBillboardSceneNode.h @@ -0,0 +1,99 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_BILLBOARD_SCENE_NODE_H_INCLUDED__ +#define __C_BILLBOARD_SCENE_NODE_H_INCLUDED__ + +#include "IBillboardSceneNode.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a billboard. A billboard is like a 3d sprite: A 2d element, +//! which always looks to the camera. +class CBillboardSceneNode : virtual public IBillboardSceneNode +{ +public: + + //! constructor + CBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::dimension2d& size, + video::SColor colorTop=video::SColor(0xFFFFFFFF), + video::SColor colorBottom=video::SColor(0xFFFFFFFF)); + + //! pre render event + virtual void OnRegisterSceneNode(); + + //! render + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the size of the billboard + virtual void setSize(const core::dimension2d& size); + + //! Sets the widths of the top and bottom edges of the billboard independently. + virtual void setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth); + + //! gets the size of the billboard + virtual const core::dimension2d& getSize() const; + + //! Gets the widths of the top and bottom edges of the billboard. + virtual void getSize(f32& height, f32& bottomEdgeWidth, f32& topEdgeWidth) const; + + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Set the color of all vertices of the billboard + //! \param overallColor: the color to set + virtual void setColor(const video::SColor& overallColor); + + //! Set the color of the top and bottom vertices of the billboard + //! \param topColor: the color to set the top vertices + //! \param bottomColor: the color to set the bottom vertices + virtual void setColor(const video::SColor& topColor, + const video::SColor& bottomColor); + + //! Gets the color of the top and bottom vertices of the billboard + //! \param[out] topColor: stores the color of the top vertices + //! \param[out] bottomColor: stores the color of the bottom vertices + virtual void getColor(video::SColor& topColor, + video::SColor& bottomColor) const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_BILLBOARD; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + +private: + + //! Size.Width is the bottom edge width + core::dimension2d Size; + f32 TopEdgeWidth; + core::aabbox3d BBox; + video::SMaterial Material; + + video::S3DVertex vertices[4]; + u16 indices[6]; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBlit.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CBlit.h new file mode 100644 index 0000000..a8572e9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBlit.h @@ -0,0 +1,1273 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_BLIT_H_INCLUDED_ +#define _C_BLIT_H_INCLUDED_ + +#include "SoftwareDriver2_helper.h" + +namespace irr +{ + + struct SBlitJob + { + AbsRectangle Dest; + AbsRectangle Source; + + u32 argb; + + void * src; + void * dst; + + s32 width; + s32 height; + + u32 srcPitch; + u32 dstPitch; + + u32 srcPixelMul; + u32 dstPixelMul; + + bool stretch; + float x_stretch; + float y_stretch; + + SBlitJob() : stretch(false) {} + }; + + // Bitfields Cohen Sutherland + enum eClipCode + { + CLIPCODE_EMPTY = 0, + CLIPCODE_BOTTOM = 1, + CLIPCODE_TOP = 2, + CLIPCODE_LEFT = 4, + CLIPCODE_RIGHT = 8 + }; + +inline u32 GetClipCode( const AbsRectangle &r, const core::position2d &p ) +{ + u32 code = CLIPCODE_EMPTY; + + if ( p.X < r.x0 ) + code = CLIPCODE_LEFT; + else + if ( p.X > r.x1 ) + code = CLIPCODE_RIGHT; + + if ( p.Y < r.y0 ) + code |= CLIPCODE_TOP; + else + if ( p.Y > r.y1 ) + code |= CLIPCODE_BOTTOM; + + return code; +} + + +/*! + Cohen Sutherland clipping + @return: 1 if valid +*/ + +static int ClipLine(const AbsRectangle &clipping, + core::position2d &p0, + core::position2d &p1, + const core::position2d& p0_in, + const core::position2d& p1_in) +{ + u32 code0; + u32 code1; + u32 code; + + p0 = p0_in; + p1 = p1_in; + + code0 = GetClipCode( clipping, p0 ); + code1 = GetClipCode( clipping, p1 ); + + // trivial accepted + while ( code0 | code1 ) + { + s32 x=0; + s32 y=0; + + // trivial reject + if ( code0 & code1 ) + return 0; + + if ( code0 ) + { + // clip first point + code = code0; + } + else + { + // clip last point + code = code1; + } + + if ( (code & CLIPCODE_BOTTOM) == CLIPCODE_BOTTOM ) + { + // clip bottom viewport + y = clipping.y1; + x = p0.X + ( p1.X - p0.X ) * ( y - p0.Y ) / ( p1.Y - p0.Y ); + } + else + if ( (code & CLIPCODE_TOP) == CLIPCODE_TOP ) + { + // clip to viewport + y = clipping.y0; + x = p0.X + ( p1.X - p0.X ) * ( y - p0.Y ) / ( p1.Y - p0.Y ); + } + else + if ( (code & CLIPCODE_RIGHT) == CLIPCODE_RIGHT ) + { + // clip right viewport + x = clipping.x1; + y = p0.Y + ( p1.Y - p0.Y ) * ( x - p0.X ) / ( p1.X - p0.X ); + } + else + if ( (code & CLIPCODE_LEFT) == CLIPCODE_LEFT ) + { + // clip left viewport + x = clipping.x0; + y = p0.Y + ( p1.Y - p0.Y ) * ( x - p0.X ) / ( p1.X - p0.X ); + } + + if ( code == code0 ) + { + // modify first point + p0.X = x; + p0.Y = y; + code0 = GetClipCode( clipping, p0 ); + } + else + { + // modify second point + p1.X = x; + p1.Y = y; + code1 = GetClipCode( clipping, p1 ); + } + } + + return 1; +} + +/* +*/ +inline void GetClip(AbsRectangle &clipping, video::IImage * t) +{ + clipping.x0 = 0; + clipping.y0 = 0; + clipping.x1 = t->getDimension().Width - 1; + clipping.y1 = t->getDimension().Height - 1; +} + +/* + return alpha in [0;256] Granularity from 32-Bit ARGB + add highbit alpha ( alpha > 127 ? + 1 ) +*/ +static inline u32 extractAlpha(const u32 c) +{ + return ( c >> 24 ) + ( c >> 31 ); +} + +/* + return alpha in [0;255] Granularity and 32-Bit ARGB + add highbit alpha ( alpha > 127 ? + 1 ) +*/ +static inline u32 packAlpha(const u32 c) +{ + return (c > 127 ? c - 1 : c) << 24; +} + + +/*! + Scale Color by (1/value) + value 0 - 256 ( alpha ) +*/ +inline u32 PixelLerp32(const u32 source, const u32 value) +{ + u32 srcRB = source & 0x00FF00FF; + u32 srcXG = (source & 0xFF00FF00) >> 8; + + srcRB *= value; + srcXG *= value; + + srcRB >>= 8; + //srcXG >>= 8; + + srcXG &= 0xFF00FF00; + srcRB &= 0x00FF00FF; + + return srcRB | srcXG; +} + + +/* +*/ +static void RenderLine32_Decal(video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb ) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 4; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u32 *dst; + dst = (u32*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + do + { + *dst = argb; + + dst = (u32*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u32*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } while (run>=0); + + t->unlock(); +} + + +/* +*/ +static void RenderLine32_Blend(video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb, u32 alpha) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 4; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u32 *dst; + dst = (u32*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + const u32 packA = packAlpha ( alpha ); + do + { + *dst = packA | PixelBlend32( *dst, argb, alpha ); + + dst = (u32*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u32*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } while (run>=0); + + t->unlock(); +} + +/* +*/ +static void RenderLine16_Decal(video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u32 argb ) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 2; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u16 *dst; + dst = (u16*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + do + { + *dst = (u16)argb; + + dst = (u16*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u16*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } while (run>=0); + + t->unlock(); +} + +/* +*/ +static void RenderLine16_Blend(video::IImage *t, + const core::position2d &p0, + const core::position2d &p1, + u16 argb, + u16 alpha) +{ + s32 dx = p1.X - p0.X; + s32 dy = p1.Y - p0.Y; + + s32 c; + s32 m; + s32 d = 0; + s32 run; + + s32 xInc = 2; + s32 yInc = (s32) t->getPitch(); + + if ( dx < 0 ) + { + xInc = -xInc; + dx = -dx; + } + + if ( dy < 0 ) + { + yInc = -yInc; + dy = -dy; + } + + u16 *dst; + dst = (u16*) ( (u8*) t->lock() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) ); + + if ( dy > dx ) + { + s32 tmp; + tmp = dx; + dx = dy; + dy = tmp; + tmp = xInc; + xInc = yInc; + yInc = tmp; + } + + c = dx << 1; + m = dy << 1; + + run = dx; + const u16 packA = alpha ? 0x8000 : 0; + do + { + *dst = packA | PixelBlend16( *dst, argb, alpha ); + + dst = (u16*) ( (u8*) dst + xInc ); // x += xInc + d += m; + if ( d > dx ) + { + dst = (u16*) ( (u8*) dst + yInc ); // y += yInc + d -= c; + } + run -= 1; + } while (run>=0); + + t->unlock(); +} + + +/*! +*/ +static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + if (job->stretch) + { + const u32 *src = static_cast(job->src); + u32 *dst = static_cast(job->dst); + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y ); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u32 src_x = (u32)(dx*wscale); + dst[dx] = src[src_x]; + } + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + const u32 widthPitch = job->width * job->dstPixelMul; + const void *src = (void*) job->src; + void *dst = (void*) job->dst; + + for ( u32 dy = 0; dy != h; ++dy ) + { + memcpy( dst, src, widthPitch ); + + src = (void*) ( (u8*) (src) + job->srcPitch ); + dst = (void*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + +/*! +*/ +static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u32 *src = static_cast(job->src); + u16 *dst = static_cast(job->dst); + + if (job->stretch) + { + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y ); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u32 src_x = (u32)(dx*wscale); + //16 bit Blitter depends on pre-multiplied color + const u32 s = PixelLerp32( src[src_x] | 0xFF000000, extractAlpha( src[src_x] ) ); + dst[dx] = video::A8R8G8B8toA1R5G5B5( s ); + } + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + for ( u32 dy = 0; dy != h; ++dy ) + { + for ( u32 dx = 0; dx != w; ++dx ) + { + //16 bit Blitter depends on pre-multiplied color + const u32 s = PixelLerp32( src[dx] | 0xFF000000, extractAlpha( src[dx] ) ); + dst[dx] = video::A8R8G8B8toA1R5G5B5( s ); + } + + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + +/*! +*/ +static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u8 *src = static_cast(job->src); + u16 *dst = static_cast(job->dst); + + if (job->stretch) + { + const float wscale = 3.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u8*)(job->src) + job->srcPitch*src_y; + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u8* src_x = src+(u32)(dx*wscale); + dst[dx] = video::RGBA16(src_x[0], src_x[1], src_x[2]); + } + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + for ( u32 dy = 0; dy != h; ++dy ) + { + const u8* s = src; + for ( u32 dx = 0; dx != w; ++dx ) + { + dst[dx] = video::RGBA16(s[0], s[1], s[2]); + s += 3; + } + + src = src+job->srcPitch; + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + + +/*! +*/ +static void executeBlit_TextureCopy_16_to_32( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u16 *src = static_cast(job->src); + u32 *dst = static_cast(job->dst); + + if (job->stretch) + { + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u16*) ( (u8*) (job->src) + job->srcPitch*src_y ); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u32 src_x = (u32)(dx*wscale); + dst[dx] = video::A1R5G5B5toA8R8G8B8(src[src_x]); + } + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + for ( u32 dy = 0; dy != h; ++dy ) + { + for ( u32 dx = 0; dx != w; ++dx ) + { + dst[dx] = video::A1R5G5B5toA8R8G8B8( src[dx] ); + } + + src = (u16*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + +static void executeBlit_TextureCopy_16_to_24( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u16 *src = static_cast(job->src); + u8 *dst = static_cast(job->dst); + + if (job->stretch) + { + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u16*) ( (u8*) (job->src) + job->srcPitch*src_y ); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u32 src_x = (u32)(dx*wscale); + u32 color = video::A1R5G5B5toA8R8G8B8(src[src_x]); + u8 * writeTo = &dst[dx * 3]; + *writeTo++ = (color >> 16)& 0xFF; + *writeTo++ = (color >> 8) & 0xFF; + *writeTo++ = color & 0xFF; + } + dst += job->dstPitch; + } + } + else + { + for ( u32 dy = 0; dy != h; ++dy ) + { + for ( u32 dx = 0; dx != w; ++dx ) + { + u32 color = video::A1R5G5B5toA8R8G8B8(src[dx]); + u8 * writeTo = &dst[dx * 3]; + *writeTo++ = (color >> 16)& 0xFF; + *writeTo++ = (color >> 8) & 0xFF; + *writeTo++ = color & 0xFF; + } + + src = (u16*) ( (u8*) (src) + job->srcPitch ); + dst += job->dstPitch; + } + } +} + +/*! +*/ +static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u8 *src = static_cast(job->src); + u32 *dst = static_cast(job->dst); + + if (job->stretch) + { + const float wscale = 3.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (const u8*)job->src+(job->srcPitch*src_y); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u8* s = src+(u32)(dx*wscale); + dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2]; + } + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + for ( s32 dy = 0; dy != job->height; ++dy ) + { + const u8* s = src; + + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2]; + s += 3; + } + + src = src + job->srcPitch; + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + +static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u32 *src = static_cast(job->src); + u8 *dst = static_cast(job->dst); + + if (job->stretch) + { + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u32 src_x = src[(u32)(dx*wscale)]; + u8 * writeTo = &dst[dx * 3]; + *writeTo++ = (src_x >> 16)& 0xFF; + *writeTo++ = (src_x >> 8) & 0xFF; + *writeTo++ = src_x & 0xFF; + } + dst += job->dstPitch; + } + } + else + { + for ( u32 dy = 0; dy != h; ++dy ) + { + for ( u32 dx = 0; dx != w; ++dx ) + { + u8 * writeTo = &dst[dx * 3]; + *writeTo++ = (src[dx] >> 16)& 0xFF; + *writeTo++ = (src[dx] >> 8) & 0xFF; + *writeTo++ = src[dx] & 0xFF; + } + + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst += job->dstPitch; + } + } +} + +/*! +*/ +static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u32 rdx = w>>1; + + const u32 *src = (u32*) job->src; + u32 *dst = (u32*) job->dst; + + if (job->stretch) + { + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + const u32 off = core::if_c_a_else_b(w&1, (u32)((w-1)*wscale), 0); + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y ); + + for ( u32 dx = 0; dx < rdx; ++dx ) + { + const u32 src_x = (u32)(dx*wscale); + dst[dx] = PixelBlend16_simd( dst[dx], src[src_x] ); + } + if ( off ) + { + ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] ); + } + + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + const u32 off = core::if_c_a_else_b(w&1, w-1, 0); + for (u32 dy = 0; dy != h; ++dy ) + { + for (u32 dx = 0; dx != rdx; ++dx ) + { + dst[dx] = PixelBlend16_simd( dst[dx], src[dx] ); + } + + if ( off ) + { + ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] ); + } + + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + +/*! +*/ +static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job ) +{ + const u32 w = job->width; + const u32 h = job->height; + const u32 *src = (u32*) job->src; + u32 *dst = (u32*) job->dst; + + if (job->stretch) + { + const float wscale = 1.f/job->x_stretch; + const float hscale = 1.f/job->y_stretch; + for ( u32 dy = 0; dy < h; ++dy ) + { + const u32 src_y = (u32)(dy*hscale); + src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y ); + + for ( u32 dx = 0; dx < w; ++dx ) + { + const u32 src_x = (u32)(dx*wscale); + dst[dx] = PixelBlend32( dst[dx], src[src_x] ); + } + + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } + else + { + for ( u32 dy = 0; dy != h; ++dy ) + { + for ( u32 dx = 0; dx != w; ++dx ) + { + dst[dx] = PixelBlend32( dst[dx], src[dx] ); + } + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } + } +} + +/*! +*/ +static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job ) +{ + u16 *src = (u16*) job->src; + u16 *dst = (u16*) job->dst; + + u16 blend = video::A8R8G8B8toA1R5G5B5 ( job->argb ); + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + if ( 0 == (src[dx] & 0x8000) ) + continue; + + dst[dx] = PixelMul16_2( src[dx], blend ); + } + src = (u16*) ( (u8*) (src) + job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + + +/*! +*/ +static void executeBlit_TextureBlendColor_32_to_32( const SBlitJob * job ) +{ + u32 *src = (u32*) job->src; + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = PixelBlend32( dst[dx], PixelMul32_2( src[dx], job->argb ) ); + } + src = (u32*) ( (u8*) (src) + job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_Color_16_to_16( const SBlitJob * job ) +{ + const u16 c = video::A8R8G8B8toA1R5G5B5(job->argb); + u16 *dst = (u16*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + memset16(dst, c, job->srcPitch); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_Color_32_to_32( const SBlitJob * job ) +{ + u32 *dst = (u32*) job->dst; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + memset32( dst, job->argb, job->srcPitch ); + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job ) +{ + u16 *dst = (u16*) job->dst; + + const u16 alpha = extractAlpha( job->argb ) >> 3; + if ( 0 == alpha ) + return; + const u32 src = video::A8R8G8B8toA1R5G5B5( job->argb ); + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = 0x8000 | PixelBlend16( dst[dx], src, alpha ); + } + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); + } +} + +/*! +*/ +static void executeBlit_ColorAlpha_32_to_32( const SBlitJob * job ) +{ + u32 *dst = (u32*) job->dst; + + const u32 alpha = extractAlpha( job->argb ); + const u32 src = job->argb; + + for ( s32 dy = 0; dy != job->height; ++dy ) + { + for ( s32 dx = 0; dx != job->width; ++dx ) + { + dst[dx] = (job->argb & 0xFF000000 ) | PixelBlend32( dst[dx], src, alpha ); + } + dst = (u32*) ( (u8*) (dst) + job->dstPitch ); + } +} + +// Blitter Operation +enum eBlitter +{ + BLITTER_INVALID = 0, + BLITTER_COLOR, + BLITTER_COLOR_ALPHA, + BLITTER_TEXTURE, + BLITTER_TEXTURE_ALPHA_BLEND, + BLITTER_TEXTURE_ALPHA_COLOR_BLEND +}; + +typedef void (*tExecuteBlit) ( const SBlitJob * job ); + + +/*! +*/ +struct blitterTable +{ + eBlitter operation; + s32 destFormat; + s32 sourceFormat; + tExecuteBlit func; +}; + +static const blitterTable blitTable[] = +{ + { BLITTER_TEXTURE, -2, -2, executeBlit_TextureCopy_x_to_x }, + { BLITTER_TEXTURE, video::ECF_A1R5G5B5, video::ECF_A8R8G8B8, executeBlit_TextureCopy_32_to_16 }, + { BLITTER_TEXTURE, video::ECF_A1R5G5B5, video::ECF_R8G8B8, executeBlit_TextureCopy_24_to_16 }, + { BLITTER_TEXTURE, video::ECF_A8R8G8B8, video::ECF_A1R5G5B5, executeBlit_TextureCopy_16_to_32 }, + { BLITTER_TEXTURE, video::ECF_A8R8G8B8, video::ECF_R8G8B8, executeBlit_TextureCopy_24_to_32 }, + { BLITTER_TEXTURE, video::ECF_R8G8B8, video::ECF_A1R5G5B5, executeBlit_TextureCopy_16_to_24 }, + { BLITTER_TEXTURE, video::ECF_R8G8B8, video::ECF_A8R8G8B8, executeBlit_TextureCopy_32_to_24 }, + { BLITTER_TEXTURE_ALPHA_BLEND, video::ECF_A1R5G5B5, video::ECF_A1R5G5B5, executeBlit_TextureBlend_16_to_16 }, + { BLITTER_TEXTURE_ALPHA_BLEND, video::ECF_A8R8G8B8, video::ECF_A8R8G8B8, executeBlit_TextureBlend_32_to_32 }, + { BLITTER_TEXTURE_ALPHA_COLOR_BLEND, video::ECF_A1R5G5B5, video::ECF_A1R5G5B5, executeBlit_TextureBlendColor_16_to_16 }, + { BLITTER_TEXTURE_ALPHA_COLOR_BLEND, video::ECF_A8R8G8B8, video::ECF_A8R8G8B8, executeBlit_TextureBlendColor_32_to_32 }, + { BLITTER_COLOR, video::ECF_A1R5G5B5, -1, executeBlit_Color_16_to_16 }, + { BLITTER_COLOR, video::ECF_A8R8G8B8, -1, executeBlit_Color_32_to_32 }, + { BLITTER_COLOR_ALPHA, video::ECF_A1R5G5B5, -1, executeBlit_ColorAlpha_16_to_16 }, + { BLITTER_COLOR_ALPHA, video::ECF_A8R8G8B8, -1, executeBlit_ColorAlpha_32_to_32 }, + { BLITTER_INVALID, -1, -1, 0 } +}; + + +static inline tExecuteBlit getBlitter2( eBlitter operation,const video::IImage * dest,const video::IImage * source ) +{ + video::ECOLOR_FORMAT sourceFormat = (video::ECOLOR_FORMAT) ( source ? source->getColorFormat() : -1 ); + video::ECOLOR_FORMAT destFormat = (video::ECOLOR_FORMAT) ( dest ? dest->getColorFormat() : -1 ); + + const blitterTable * b = blitTable; + + while ( b->operation != BLITTER_INVALID ) + { + if ( b->operation == operation ) + { + if (( b->destFormat == -1 || b->destFormat == destFormat ) && + ( b->sourceFormat == -1 || b->sourceFormat == sourceFormat ) ) + return b->func; + else + if ( b->destFormat == -2 && ( sourceFormat == destFormat ) ) + return b->func; + } + b += 1; + } + return 0; +} + + +// bounce clipping to texture +inline void setClip ( AbsRectangle &out, const core::rect *clip, + const video::IImage * tex, s32 passnative ) +{ + if ( clip && 0 == tex && passnative ) + { + out.x0 = clip->UpperLeftCorner.X; + out.x1 = clip->LowerRightCorner.X; + out.y0 = clip->UpperLeftCorner.Y; + out.y1 = clip->LowerRightCorner.Y; + return; + } + + const s32 w = tex ? tex->getDimension().Width : 0; + const s32 h = tex ? tex->getDimension().Height : 0; + if ( clip ) + { + out.x0 = core::s32_clamp ( clip->UpperLeftCorner.X, 0, w ); + out.x1 = core::s32_clamp ( clip->LowerRightCorner.X, out.x0, w ); + out.y0 = core::s32_clamp ( clip->UpperLeftCorner.Y, 0, h ); + out.y1 = core::s32_clamp ( clip->LowerRightCorner.Y, out.y0, h ); + } + else + { + out.x0 = 0; + out.y0 = 0; + out.x1 = w; + out.y1 = h; + } + +} + +/*! + a generic 2D Blitter +*/ +static s32 Blit(eBlitter operation, + video::IImage * dest, + const core::rect *destClipping, + const core::position2d *destPos, + video::IImage * const source, + const core::rect *sourceClipping, + u32 argb) +{ + tExecuteBlit blitter = getBlitter2( operation, dest, source ); + if ( 0 == blitter ) + { + return 0; + } + + // Clipping + AbsRectangle sourceClip; + AbsRectangle destClip; + AbsRectangle v; + + SBlitJob job; + + setClip ( sourceClip, sourceClipping, source, 1 ); + setClip ( destClip, destClipping, dest, 0 ); + + v.x0 = destPos ? destPos->X : 0; + v.y0 = destPos ? destPos->Y : 0; + v.x1 = v.x0 + ( sourceClip.x1 - sourceClip.x0 ); + v.y1 = v.y0 + ( sourceClip.y1 - sourceClip.y0 ); + + if ( !intersect( job.Dest, destClip, v ) ) + return 0; + + job.width = job.Dest.x1 - job.Dest.x0; + job.height = job.Dest.y1 - job.Dest.y0; + + job.Source.x0 = sourceClip.x0 + ( job.Dest.x0 - v.x0 ); + job.Source.x1 = job.Source.x0 + job.width; + job.Source.y0 = sourceClip.y0 + ( job.Dest.y0 - v.y0 ); + job.Source.y1 = job.Source.y0 + job.height; + + job.argb = argb; + + if ( source ) + { + job.srcPitch = source->getPitch(); + job.srcPixelMul = source->getBytesPerPixel(); + job.src = (void*) ( (u8*) source->lock() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) ); + } + else + { + // use srcPitch for color operation on dest + job.srcPitch = job.width * dest->getBytesPerPixel(); + } + + job.dstPitch = dest->getPitch(); + job.dstPixelMul = dest->getBytesPerPixel(); + job.dst = (void*) ( (u8*) dest->lock() + ( job.Dest.y0 * job.dstPitch ) + ( job.Dest.x0 * job.dstPixelMul ) ); + + blitter( &job ); + + if ( source ) + source->unlock(); + + if ( dest ) + dest->unlock(); + + return 1; +} + +static s32 StretchBlit(eBlitter operation, + video::IImage* dest, const core::rect *destRect, + const core::rect *srcRect, video::IImage* const source, + u32 argb) +{ + tExecuteBlit blitter = getBlitter2( operation, dest, source ); + if ( 0 == blitter ) + { + return 0; + } + + SBlitJob job; + + // Clipping + setClip ( job.Source, srcRect, source, 1 ); + setClip ( job.Dest, destRect, dest, 0 ); + + job.width = job.Dest.x1-job.Dest.x0; + job.height = job.Dest.y1-job.Dest.y0; + + job.argb = argb; + + // use original dest size, despite any clipping + job.x_stretch = (float)destRect->getWidth() / (float)(job.Source.x1-job.Source.x0); + job.y_stretch = (float)destRect->getHeight() / (float)(job.Source.y1-job.Source.y0); + job.stretch = (job.x_stretch != 1.f) || (job.y_stretch != 1.f); + + if ( source ) + { + job.srcPitch = source->getPitch(); + job.srcPixelMul = source->getBytesPerPixel(); + job.src = (void*) ( (u8*) source->lock() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) ); + } + else + { + // use srcPitch for color operation on dest + job.srcPitch = job.width * dest->getBytesPerPixel(); + } + + job.dstPitch = dest->getPitch(); + job.dstPixelMul = dest->getBytesPerPixel(); + job.dst = (void*) ( (u8*) dest->lock() + ( job.Dest.y0 * job.dstPitch ) + ( job.Dest.x0 * job.dstPixelMul ) ); + + blitter( &job ); + + if ( source ) + source->unlock(); + + if ( dest ) + dest->unlock(); + + return 1; +} + + +// Methods for Software drivers +//! draws a rectangle +static void drawRectangle(video::IImage* img, const core::rect& rect, const video::SColor &color) +{ + Blit(color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA, + img, 0, &rect.UpperLeftCorner, 0, &rect, color.color); +} + + +//! draws a line from to with color +static void drawLine(video::IImage* img, const core::position2d& from, + const core::position2d& to, const video::SColor &color) +{ + AbsRectangle clip; + GetClip(clip, img); + + core::position2d p[2]; + if (ClipLine( clip, p[0], p[1], from, to)) + { + u32 alpha = extractAlpha(color.color); + + switch(img->getColorFormat()) + { + case video::ECF_A1R5G5B5: + if (alpha == 256) + { + RenderLine16_Decal(img, p[0], p[1], video::A8R8G8B8toA1R5G5B5(color.color)); + } + else + { + RenderLine16_Blend(img, p[0], p[1], video::A8R8G8B8toA1R5G5B5(color.color), alpha >> 3); + } + break; + case video::ECF_A8R8G8B8: + if (alpha == 256) + { + RenderLine32_Decal(img, p[0], p[1], color.color); + } + else + { + RenderLine32_Blend(img, p[0], p[1], color.color, alpha); + } + break; + default: + break; + } + } +} + + +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.cpp new file mode 100644 index 0000000..af54011 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.cpp @@ -0,0 +1,129 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + +#include "CBoneSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CBoneSceneNode::CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + u32 boneIndex, const c8* boneName) +: IBoneSceneNode(parent, mgr, id), BoneIndex(boneIndex), + AnimationMode(EBAM_AUTOMATIC), SkinningSpace(EBSS_LOCAL) +{ + #ifdef _DEBUG + setDebugName("CBoneSceneNode"); + #endif + setName(boneName); +} + + +//! Returns the index of the bone +u32 CBoneSceneNode::getBoneIndex() const +{ + return BoneIndex; +} + + +//! Sets the animation mode of the bone. Returns true if successful. +bool CBoneSceneNode::setAnimationMode(E_BONE_ANIMATION_MODE mode) +{ + AnimationMode = mode; + return true; +} + + +//! Gets the current animation mode of the bone +E_BONE_ANIMATION_MODE CBoneSceneNode::getAnimationMode() const +{ + return AnimationMode; +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CBoneSceneNode::getBoundingBox() const +{ + return Box; +} + + +/* +//! Returns the relative transformation of the scene node. +core::matrix4 CBoneSceneNode::getRelativeTransformation() const +{ + return core::matrix4(); // RelativeTransformation; +} +*/ + + +void CBoneSceneNode::OnAnimate(u32 timeMs) +{ + if (IsVisible) + { + // animate this node with all animators + + ISceneNodeAnimatorList::Iterator ait = Animators.begin(); + for (; ait != Animators.end(); ++ait) + (*ait)->animateNode(this, timeMs); + + // update absolute position + //updateAbsolutePosition(); + + // perform the post render process on all children + ISceneNodeList::Iterator it = Children.begin(); + for (; it != Children.end(); ++it) + (*it)->OnAnimate(timeMs); + } +} + + +void CBoneSceneNode::helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node) +{ + Node->updateAbsolutePosition(); + + ISceneNodeList::ConstIterator it = Node->getChildren().begin(); + for (; it != Node->getChildren().end(); ++it) + { + helper_updateAbsolutePositionOfAllChildren( (*it) ); + } +} + + +void CBoneSceneNode::updateAbsolutePositionOfAllChildren() +{ + helper_updateAbsolutePositionOfAllChildren( this ); +} + + +void CBoneSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IBoneSceneNode::serializeAttributes(out, options); + out->addInt("BoneIndex", BoneIndex); + out->addEnum("AnimationMode", AnimationMode, BoneAnimationModeNames); +} + + +void CBoneSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + BoneIndex = in->getAttributeAsInt("BoneIndex"); + AnimationMode = (E_BONE_ANIMATION_MODE)in->getAttributeAsEnumeration("AnimationMode", BoneAnimationModeNames); + // for legacy files (before 1.5) + const core::stringc boneName = in->getAttributeAsString("BoneName"); + setName(boneName); + IBoneSceneNode::deserializeAttributes(in, options); + // TODO: add/replace bone in parent with bone from mesh +} + + +} // namespace scene +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.h new file mode 100644 index 0000000..79b94ef --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBoneSceneNode.h @@ -0,0 +1,79 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_BONE_SCENE_NODE_H_INCLUDED__ +#define __C_BONE_SCENE_NODE_H_INCLUDED__ + +// Used with SkinnedMesh and IAnimatedMeshSceneNode, for boned meshes + +#include "IBoneSceneNode.h" + +namespace irr +{ +namespace scene +{ + + class CBoneSceneNode : public IBoneSceneNode + { + public: + + //! constructor + CBoneSceneNode(ISceneNode* parent, ISceneManager* mgr, + s32 id=-1, u32 boneIndex=0, const c8* boneName=0); + + //! Returns the index of the bone + virtual u32 getBoneIndex() const; + + //! Sets the animation mode of the bone. Returns true if successful. + virtual bool setAnimationMode(E_BONE_ANIMATION_MODE mode); + + //! Gets the current animation mode of the bone + virtual E_BONE_ANIMATION_MODE getAnimationMode() const; + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + /* + //! Returns the relative transformation of the scene node. + //virtual core::matrix4 getRelativeTransformation() const; + */ + + virtual void OnAnimate(u32 timeMs); + + virtual void updateAbsolutePositionOfAllChildren(); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! How the relative transformation of the bone is used + virtual void setSkinningSpace( E_BONE_SKINNING_SPACE space ) + { + SkinningSpace=space; + } + + virtual E_BONE_SKINNING_SPACE getSkinningSpace() const + { + return SkinningSpace; + } + + private: + void helper_updateAbsolutePositionOfAllChildren(ISceneNode *Node); + + u32 BoneIndex; + + core::aabbox3d Box; + + E_BONE_ANIMATION_MODE AnimationMode; + E_BONE_SKINNING_SPACE SkinningSpace; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CBurningShader_Raster_Reference.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CBurningShader_Raster_Reference.cpp new file mode 100644 index 0000000..dccdab6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CBurningShader_Raster_Reference.cpp @@ -0,0 +1,1143 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + + +namespace irr +{ + +namespace video +{ + + /*! Render states define set-up states for all kinds of vertex and pixel processing. + Some render states set up vertex processing, and some set up pixel processing (see Render States). + Render states can be saved and restored using stateblocks (see State Blocks Save and Restore State). + */ + enum BD3DRENDERSTATETYPE + { + /*! BD3DRS_ZENABLE + Depth-buffering state as one member of the BD3DZBUFFERTYPE enumerated type. + Set this state to D3DZB_TRUE to enable z-buffering, + D3DZB_USEW to enable w-buffering, or D3DZB_FALSE to disable depth buffering. + The default value for this render state is D3DZB_TRUE if a depth stencil was created + along with the swap chain by setting the EnableAutoDepthStencil member of the + D3DPRESENT_PARAMETERS structure to TRUE, and D3DZB_FALSE otherwise. + */ + BD3DRS_ZENABLE, + + /*! BD3DRS_FILLMODE + One or more members of the D3DFILLMODE enumerated type. The default value is D3DFILL_SOLID. + */ + BD3DRS_FILLMODE, + + /*! BD3DRS_SHADEMODE + One or more members of the D3DSHADEMODE enumerated type. The default value is D3DSHADE_GOURAUD. + */ + BD3DRS_SHADEMODE, + + /*! BD3DRS_ZWRITEENABLE + TRUE to enable the application to write to the depth buffer. The default value is TRUE. + This member enables an application to prevent the system from updating the depth buffer with + new depth values. If FALSE, depth comparisons are still made according to the render state + D3DRS_ZFUNC, assuming that depth buffering is taking place, but depth values are not written + to the buffer. + */ + BD3DRS_ZWRITEENABLE, + + /*! BD3DRS_ALPHATESTENABLE + TRUE to enable per pixel alpha testing. If the test passes, the pixel is processed by the frame + buffer. Otherwise, all frame-buffer processing is skipped for the pixel. The test is done by + comparing the incoming alpha value with the reference alpha value, using the comparison function + provided by the D3DRS_ALPHAFUNC render state. The reference alpha value is determined by the value + set for D3DRS_ALPHAREF. For more information, see Alpha Testing State. + The default value of this parameter is FALSE. + */ + BD3DRS_ALPHATESTENABLE, + + /*! BD3DRS_SRCBLEND + One member of the BD3DBLEND enumerated type. The default value is BD3DBLEND_ONE. + */ + BD3DRS_SRCBLEND, + + /*! BD3DRS_DESTBLEND + One member of the BD3DBLEND enumerated type. The default value is BD3DBLEND_ZERO. + */ + BD3DRS_DESTBLEND, + + /*! BD3DRS_CULLMODE + Specifies how back-facing triangles are culled, if at all. This can be set to one + member of the BD3DCULL enumerated type. The default value is BD3DCULL_CCW. + */ + BD3DRS_CULLMODE, + + /*! BD3DRS_ZFUNC + One member of the BD3DCMPFUNC enumerated type. The default value is BD3DCMP_LESSEQUAL. + This member enables an application to accept or reject a pixel, based on its distance from + the camera. The depth value of the pixel is compared with the depth-buffer value. If the depth + value of the pixel passes the comparison function, the pixel is written. + + The depth value is written to the depth buffer only if the render state is TRUE. + Software rasterizers and many hardware accelerators work faster if the depth test fails, + because there is no need to filter and modulate the texture if the pixel is not going to be + rendered. + */ + BD3DRS_ZFUNC, + + /*! BD3DRS_ALPHAREF + Value that specifies a reference alpha value against which pixels are tested when alpha testing + is enabled. This is an 8-bit value placed in the low 8 bits of the DWORD render-state value. + Values can range from 0x00000000 through 0x000000FF. The default value is 0. + */ + BD3DRS_ALPHAREF, + + /*! BD3DRS_ALPHAFUNC + One member of the BD3DCMPFUNC enumerated type. The default value is BD3DCMP_ALWAYS. + This member enables an application to accept or reject a pixel, based on its alpha value. + */ + BD3DRS_ALPHAFUNC, + + /*! BD3DRS_DITHERENABLE + TRUE to enable dithering. The default value is FALSE. + */ + BD3DRS_DITHERENABLE, + + /*! BD3DRS_ALPHABLENDENABLE + TRUE to enable alpha-blended transparency. The default value is FALSE. + The type of alpha blending is determined by the BD3DRS_SRCBLEND and BD3DRS_DESTBLEND render states. + */ + BD3DRS_ALPHABLENDENABLE, + + /*! BD3DRS_FOGENABLE + TRUE to enable fog blending. The default value is FALSE. For more information about using fog + blending, see Fog. + */ + BD3DRS_FOGENABLE, + + /*! BD3DRS_SPECULARENABLE + TRUE to enable specular highlights. The default value is FALSE. + Specular highlights are calculated as though every vertex in the object being lit is at the + object's origin. This gives the expected results as long as the object is modeled around the + origin and the distance from the light to the object is relatively large. In other cases, the + results as undefined. + When this member is set to TRUE, the specular color is added to the base color after the + texture cascade but before alpha blending. + */ + BD3DRS_SPECULARENABLE, + + /*! BD3DRS_FOGCOLOR + Value whose type is D3DCOLOR. The default value is 0. For more information about fog color, + see Fog Color. + */ + BD3DRS_FOGCOLOR, + + /*! BD3DRS_FOGTABLEMODE + The fog formula to be used for pixel fog. Set to one of the members of the D3DFOGMODE + enumerated type. The default value is D3DFOG_NONE. For more information about pixel fog, + see Pixel Fog. + */ + BD3DRS_FOGTABLEMODE, + + /*! BD3DRS_FOGSTART + Depth at which pixel or vertex fog effects begin for linear fog mode. The default value is 0.0f. + Depth is specified in world space for vertex fog and either device space [0.0, 1.0] or world + space for pixel fog. For pixel fog, these values are in device space when the system uses z for + fog calculations and world-world space when the system is using eye-relative fog (w-fog). For + more information, see Fog Parameters and Eye-Relative vs. Z-based Depth. + Values for the this render state are floating-point values. + Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your + application must cast a variable that contains the value, as shown in the following code example. + pDevice9->SetRenderState( BD3DRS_FOGSTART, *((DWORD*) (&fFogStart))); + */ + BD3DRS_FOGSTART, + + /*! BD3DRS_FOGEND + Depth at which pixel or vertex fog effects end for linear fog mode. The default value is 1.0f. + Depth is specified in world space for vertex fog and either device space [0.0, 1.0] or world space + for pixel fog. For pixel fog, these values are in device space when the system uses z for fog + calculations and in world space when the system is using eye-relative fog (w-fog). For more + information, see Fog Parameters and Eye-Relative vs. Z-based Depth. + Values for this render state are floating-point values. + */ + BD3DRS_FOGEND, + + /*! BD3DRS_FOGDENSITY + Fog density for pixel or vertex fog used in the exponential fog modes (D3DFOG_EXP and D3DFOG_EXP2). + Valid density values range from 0.0 through 1.0. The default value is 1.0. For more information, + see Fog Parameters. + Values for this render state are floating-point values. + */ + BD3DRS_FOGDENSITY, + + + /*! BD3DRS_RANGEFOGENABLE + TRUE to enable range-based vertex fog. The default value is FALSE, in which case the system + uses depth-based fog. In range-based fog, the distance of an object from the viewer is used + to compute fog effects, not the depth of the object (that is, the z-coordinate) in the scene. + In range-based fog, all fog methods work as usual, except that they use range instead of depth + in the computations. + Range is the correct factor to use for fog computations, but depth is commonly used instead + because range is time-consuming to compute and depth is generally already available. Using depth + to calculate fog has the undesirable effect of having the fogginess of peripheral objects change + as the viewer's eye moves - in this case, the depth changes and the range remains constant. + + Because no hardware currently supports per-pixel range-based fog, range correction is offered + only for vertex fog. + For more information, see Vertex Fog. + */ + BD3DRS_RANGEFOGENABLE = 48, + + /*! BD3DRS_STENCILENABLE + TRUE to enable stenciling, or FALSE to disable stenciling. The default value is FALSE. + For more information, see Stencil Buffer Techniques. + */ + BD3DRS_STENCILENABLE = 52, + + /*! BD3DRS_STENCILFAIL + Stencil operation to perform if the stencil test fails. Values are from the D3DSTENCILOP + enumerated type. The default value is D3DSTENCILOP_KEEP. + */ + BD3DRS_STENCILFAIL = 53, + + /*! BD3DRS_STENCILZFAIL + Stencil operation to perform if the stencil test passes and the depth test (z-test) fails. + Values are from the D3DSTENCILOP enumerated type. The default value is D3DSTENCILOP_KEEP. + */ + BD3DRS_STENCILZFAIL = 54, + + /*! BD3DRS_STENCILPASS + Stencil operation to perform if both the stencil and the depth (z) tests pass. Values are + from the D3DSTENCILOP enumerated type. The default value is D3DSTENCILOP_KEEP. + */ + BD3DRS_STENCILPASS = 55, + + /*! BD3DRS_STENCILFUNC + Comparison function for the stencil test. Values are from the D3DCMPFUNC enumerated type. + The default value is D3DCMP_ALWAYS. + The comparison function is used to compare the reference value to a stencil buffer entry. + This comparison applies only to the bits in the reference value and stencil buffer entry that + are set in the stencil mask (set by the D3DRS_STENCILMASK render state). If TRUE, the stencil + test passes. + */ + BD3DRS_STENCILFUNC = 56, + + /*! BD3DRS_STENCILREF + An int reference value for the stencil test. The default value is 0. + */ + BD3DRS_STENCILREF = 57, + + /*! BD3DRS_STENCILMASK + Mask applied to the reference value and each stencil buffer entry to determine the significant + bits for the stencil test. The default mask is 0xFFFFFFFF. + */ + BD3DRS_STENCILMASK = 58, + + /*! BD3DRS_STENCILWRITEMASK + Write mask applied to values written into the stencil buffer. The default mask is 0xFFFFFFFF. + */ + BD3DRS_STENCILWRITEMASK = 59, + + /*! BD3DRS_TEXTUREFACTOR + Color used for multiple-texture blending with the D3DTA_TFACTOR texture-blending argument or the + D3DTOP_BLENDFACTORALPHA texture-blending operation. The associated value is a D3DCOLOR variable. + The default value is opaque white (0xFFFFFFFF). + */ + BD3DRS_TEXTUREFACTOR = 60, + + /*! BD3DRS_WRAP0 + Texture-wrapping behavior for multiple sets of texture coordinates. Valid values for this + render state can be any combination of the D3DWRAPCOORD_0 (or D3DWRAP_U), D3DWRAPCOORD_1 + (or D3DWRAP_V), D3DWRAPCOORD_2 (or D3DWRAP_W), and D3DWRAPCOORD_3 flags. These cause the system + to wrap in the direction of the first, second, third, and fourth dimensions, sometimes referred + to as the s, t, r, and q directions, for a given texture. The default value for this render state + is 0 (wrapping disabled in all directions). + */ + BD3DRS_WRAP0 = 128, + BD3DRS_WRAP1 = 129, + BD3DRS_WRAP2 = 130, + BD3DRS_WRAP3 = 131, + BD3DRS_WRAP4 = 132, + BD3DRS_WRAP5 = 133, + BD3DRS_WRAP6 = 134, + BD3DRS_WRAP7 = 135, + + /*! BD3DRS_CLIPPING + TRUE to enable primitive clipping by Direct3D, or FALSE to disable it. The default value is TRUE. + */ + BD3DRS_CLIPPING = 136, + + /*! BD3DRS_LIGHTING + TRUE to enable Direct3D lighting, or FALSE to disable it. The default value is TRUE. Only + vertices that include a vertex normal are properly lit; vertices that do not contain a normal + employ a dot product of 0 in all lighting calculations. + */ + BD3DRS_LIGHTING = 137, + + /*! D3DRS_AMBIENT + Ambient light color. This value is of type D3DCOLOR. The default value is 0. + */ + BD3DRS_AMBIENT = 139, + + /*! BD3DRS_FOGVERTEXMODE + Fog formula to be used for vertex fog. Set to one member of the BD3DFOGMODE enumerated type. + The default value is D3DFOG_NONE. + */ + BD3DRS_FOGVERTEXMODE = 140, + + /*! BD3DRS_COLORVERTEX + TRUE to enable per-vertex color or FALSE to disable it. The default value is TRUE. Enabling + per-vertex color allows the system to include the color defined for individual vertices in its + lighting calculations. + For more information, see the following render states: + BD3DRS_DIFFUSEMATERIALSOURCE + BD3DRS_SPECULARMATERIALSOURCE + BD3DRS_AMBIENTMATERIALSOURCE + BD3DRS_EMISSIVEMATERIALSOURCE + */ + BD3DRS_COLORVERTEX = 141, + + /*! BD3DRS_LOCALVIEWER + TRUE to enable camera-relative specular highlights, or FALSE to use orthogonal specular + highlights. The default value is TRUE. Applications that use orthogonal projection should + specify false. + */ + BD3DRS_LOCALVIEWER = 142, + + /*! BD3DRS_NORMALIZENORMALS + TRUE to enable automatic normalization of vertex normals, or FALSE to disable it. The default + value is FALSE. Enabling this feature causes the system to normalize the vertex normals for + vertices after transforming them to camera space, which can be computationally time-consuming. + */ + BD3DRS_NORMALIZENORMALS = 143, + + /*! BD3DRS_DIFFUSEMATERIALSOURCE + Diffuse color source for lighting calculations. Valid values are members of the + D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR1. The value for this + render state is used only if the D3DRS_COLORVERTEX render state is set to TRUE. + */ + BD3DRS_DIFFUSEMATERIALSOURCE = 145, + + /*! BD3DRS_SPECULARMATERIALSOURCE + Specular color source for lighting calculations. Valid values are members of the + D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_COLOR2. + */ + BD3DRS_SPECULARMATERIALSOURCE = 146, + + /*! D3DRS_AMBIENTMATERIALSOURCE + Ambient color source for lighting calculations. Valid values are members of the + D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_MATERIAL. + */ + BD3DRS_AMBIENTMATERIALSOURCE = 147, + + /*! D3DRS_EMISSIVEMATERIALSOURCE + Emissive color source for lighting calculations. Valid values are members of the + D3DMATERIALCOLORSOURCE enumerated type. The default value is D3DMCS_MATERIAL. + */ + BD3DRS_EMISSIVEMATERIALSOURCE = 148, + + /*! D3DRS_VERTEXBLEND + Number of matrices to use to perform geometry blending, if any. Valid values are members + of the D3DVERTEXBLENDFLAGS enumerated type. The default value is D3DVBF_DISABLE. + */ + BD3DRS_VERTEXBLEND = 151, + + /* D3DRS_CLIPPLANEENABLE + Enables or disables user-defined clipping planes. Valid values are any DWORD in which the + status of each bit (set or not set) toggles the activation state of a corresponding user-defined + clipping plane. The least significant bit (bit 0) controls the first clipping plane at index 0, + and subsequent bits control the activation of clipping planes at higher indexes. If a bit is set, + the system applies the appropriate clipping plane during scene rendering. The default value is 0. + The D3DCLIPPLANEn macros are defined to provide a convenient way to enable clipping planes. + */ + BD3DRS_CLIPPLANEENABLE = 152, + BD3DRS_POINTSIZE = 154, + BD3DRS_POINTSIZE_MIN = 155, + BD3DRS_POINTSPRITEENABLE = 156, + BD3DRS_POINTSCALEENABLE = 157, + BD3DRS_POINTSCALE_A = 158, + BD3DRS_POINTSCALE_B = 159, + BD3DRS_POINTSCALE_C = 160, + BD3DRS_MULTISAMPLEANTIALIAS = 161, + BD3DRS_MULTISAMPLEMASK = 162, + BD3DRS_PATCHEDGESTYLE = 163, + BD3DRS_DEBUGMONITORTOKEN = 165, + BD3DRS_POINTSIZE_MAX = 166, + BD3DRS_INDEXEDVERTEXBLENDENABLE = 167, + BD3DRS_COLORWRITEENABLE = 168, + BD3DRS_TWEENFACTOR = 170, + BD3DRS_BLENDOP = 171, + BD3DRS_POSITIONDEGREE = 172, + BD3DRS_NORMALDEGREE = 173, + BD3DRS_SCISSORTESTENABLE = 174, + BD3DRS_SLOPESCALEDEPTHBIAS = 175, + BD3DRS_ANTIALIASEDLINEENABLE = 176, + BD3DRS_MINTESSELLATIONLEVEL = 178, + BD3DRS_MAXTESSELLATIONLEVEL = 179, + BD3DRS_ADAPTIVETESS_X = 180, + BD3DRS_ADAPTIVETESS_Y = 181, + BD3DRS_ADAPTIVETESS_Z = 182, + BD3DRS_ADAPTIVETESS_W = 183, + BD3DRS_ENABLEADAPTIVETESSELLATION = 184, + BD3DRS_TWOSIDEDSTENCILMODE = 185, + BD3DRS_CCW_STENCILFAIL = 186, + BD3DRS_CCW_STENCILZFAIL = 187, + BD3DRS_CCW_STENCILPASS = 188, + BD3DRS_CCW_STENCILFUNC = 189, + BD3DRS_COLORWRITEENABLE1 = 190, + BD3DRS_COLORWRITEENABLE2 = 191, + BD3DRS_COLORWRITEENABLE3 = 192, + BD3DRS_BLENDFACTOR = 193, + BD3DRS_SRGBWRITEENABLE = 194, + BD3DRS_DEPTHBIAS = 195, + BD3DRS_WRAP8 = 198, + BD3DRS_WRAP9 = 199, + BD3DRS_WRAP10 = 200, + BD3DRS_WRAP11 = 201, + BD3DRS_WRAP12 = 202, + BD3DRS_WRAP13 = 203, + BD3DRS_WRAP14 = 204, + BD3DRS_WRAP15 = 205, + BD3DRS_SEPARATEALPHABLENDENABLE = 206, + BD3DRS_SRCBLENDALPHA = 207, + BD3DRS_DESTBLENDALPHA = 208, + BD3DRS_BLENDOPALPHA = 209, + + BD3DRS_MAX_TYPE + }; + + + + /*! Defines constants that describe depth-buffer formats + Members of this enumerated type are used with the D3DRS_ZENABLE render state. + */ + enum BD3DZBUFFERTYPE + { + BD3DZB_FALSE = 0, // Disable depth buffering + BD3DZB_TRUE = 1, // Enable z-buffering + BD3DZB_USEW = 2 //Enable w-buffering. + }; + + //! Defines the supported compare functions. + enum BD3DCMPFUNC + { + BD3DCMP_NEVER = 1,// Always fail the test. + BD3DCMP_LESS, // Accept the new pixel if its value is less than the value of the current pixel. + BD3DCMP_EQUAL, // Accept the new pixel if its value equals the value of the current pixel. + BD3DCMP_LESSEQUAL, // Accept the new pixel if its value is less than or equal to the value of the current pixel. + BD3DCMP_GREATER, // Accept the new pixel if its value is greater than the value of the current pixel. + BD3DCMP_NOTEQUAL, // Accept the new pixel if its value does not equal the value of the current pixel. + BD3DCMP_GREATEREQUAL,// Accept the new pixel if its value is greater than or equal to the value of the current pixel. + BD3DCMP_ALWAYS // Always pass the test. + }; + + enum BD3DMATERIALCOLORSOURCE + { + BD3DMCS_MATERIAL = 0, // Use the color from the current material. + BD3DMCS_COLOR1 = 1, // Use the diffuse vertex color. + BD3DMCS_COLOR2 = 2 // Use the specular vertex color. + }; + + + //! Defines constants that describe the supported shading modes. + enum BD3DSHADEMODE + { + /*! BD3DSHADE_FLAT + Flat shading mode. The color and specular component of the first vertex in the triangle + are used to determine the color and specular component of the face. These colors remain + constant across the triangle; that is, they are not interpolated. The specular alpha is + interpolated. + */ + BD3DSHADE_FLAT = 1, + + /*! BD3DSHADE_GOURAUD + Gouraud shading mode. The color and specular components of the face are determined by a + linear interpolation between all three of the triangle's vertices. + */ + BD3DSHADE_GOURAUD = 2, + + /*! BD3DSHADE_PHONG + Not supported. + */ + BD3DSHADE_PHONG = 3 + }; + + /*! Defines constants describing the fill mode + The values in this enumerated type are used by the BD3DRS_FILLMODE render state + */ + enum BD3DFILLMODE + { + BD3DFILL_POINT = 1, // Fill points. + BD3DFILL_WIREFRAME = 2, // Fill wireframes. + BD3DFILL_SOLID = 3 // Fill solids. + }; + + + + /*! Defines the supported culling modes. + The values in this enumerated type are used by the B3DRS_CULLMODE render state. + The culling modes define how back faces are culled when rendering a geometry. + */ + enum BD3DCULL + { + BD3DCULL_NONE = 1, // Do not cull back faces. + BD3DCULL_CW = 2, // Cull back faces with clockwise vertices. + BD3DCULL_CCW = 3 // Cull back faces with counterclockwise vertices. + }; + + struct SShaderParam + { + u32 ColorUnits; + u32 TextureUnits; + + u32 RenderState [ BD3DRS_MAX_TYPE ]; + void SetRenderState ( BD3DRENDERSTATETYPE state, u32 value ); + }; + + void SShaderParam::SetRenderState ( BD3DRENDERSTATETYPE state, u32 value ) + { + RenderState [ state ] = value; + } + + + +class CBurningShader_Raster_Reference : public IBurningShader +{ +public: + + //! constructor + CBurningShader_Raster_Reference(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setMaterial ( const SBurningShaderMaterial &material ); + + +private: + void scanline (); + void scanline2 (); + + sScanLineData line; + sPixelShaderData pShader; + + void pShader_1 (); + void pShader_EMT_LIGHTMAP_M4 (); + + SShaderParam ShaderParam; + + REALINLINE u32 depthFunc (); + REALINLINE void depthWrite (); + + +}; + +//! constructor +CBurningShader_Raster_Reference::CBurningShader_Raster_Reference(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CBurningShader_Raster_Reference"); + #endif +} + + +/*! +*/ +void CBurningShader_Raster_Reference::pShader_EMT_LIGHTMAP_M4 () +{ + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + + f32 inversew = fix_inverse32 ( line.w[0] ); + + getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) ); + + + pShader.dst[pShader.i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + ); + +} + +/*! +*/ +void CBurningShader_Raster_Reference::pShader_1 () +{ + tFixPoint r0, g0, b0; + tFixPoint tx0, ty0; + + const f32 inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x, inversew ); + ty0 = tofix ( line.t[0][0].y, inversew ); + + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + pShader.dst[pShader.i] = fix_to_color ( r0, g0, b0 ); + +} + + +/*! +*/ +void CBurningShader_Raster_Reference::setMaterial ( const SBurningShaderMaterial &material ) +{ + const video::SMaterial &m = material.org; + + u32 i; + u32 enable; + + ShaderParam.ColorUnits = 0; + ShaderParam.TextureUnits = 0; + for ( i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i ) + { + if ( m.getTexture( i ) ) + ShaderParam.TextureUnits = i; + } + + // shademode + ShaderParam.SetRenderState( BD3DRS_SHADEMODE, + m.GouraudShading ? BD3DSHADE_GOURAUD : BD3DSHADE_FLAT + ); + + // fillmode + ShaderParam.SetRenderState( BD3DRS_FILLMODE, + m.Wireframe ? BD3DFILL_WIREFRAME : m.PointCloud ? BD3DFILL_POINT : BD3DFILL_SOLID + ); + + // back face culling + ShaderParam.SetRenderState( BD3DRS_CULLMODE, + m.BackfaceCulling ? BD3DCULL_CCW : BD3DCULL_NONE + ); + + // lighting + ShaderParam.SetRenderState( BD3DRS_LIGHTING, m.Lighting ); + + // specular highlights + enable = F32_LOWER_EQUAL_0 ( m.Shininess ); + ShaderParam.SetRenderState( BD3DRS_SPECULARENABLE, enable); + ShaderParam.SetRenderState( BD3DRS_NORMALIZENORMALS, enable); + ShaderParam.SetRenderState( BD3DRS_SPECULARMATERIALSOURCE, (m.ColorMaterial==ECM_SPECULAR)?BD3DMCS_COLOR1:BD3DMCS_MATERIAL); + + // depth buffer enable and compare + ShaderParam.SetRenderState( BD3DRS_ZENABLE, (material.org.ZBuffer==video::ECFN_NEVER) ? BD3DZB_FALSE : BD3DZB_USEW); + switch (material.org.ZBuffer) + { + case ECFN_NEVER: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_NEVER); + break; + case ECFN_LESSEQUAL: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_LESSEQUAL); + break; + case ECFN_EQUAL: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_EQUAL); + break; + case ECFN_LESS: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_LESSEQUAL); + break; + case ECFN_NOTEQUAL: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_NOTEQUAL); + break; + case ECFN_GREATEREQUAL: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_GREATEREQUAL); + break; + case ECFN_GREATER: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_GREATER); + break; + case ECFN_ALWAYS: + ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_ALWAYS); + break; + } + + // depth buffer write + ShaderParam.SetRenderState( BD3DRS_ZWRITEENABLE, m.ZWriteEnable ); +} + +/*! +*/ +REALINLINE u32 CBurningShader_Raster_Reference::depthFunc () +{ + if ( ShaderParam.RenderState [ BD3DRS_ZENABLE ] ) + { + switch ( ShaderParam.RenderState [ BD3DRS_ZFUNC ] ) + { + case BD3DCMP_LESSEQUAL: + return line.w[0] >= pShader.z[ pShader.i]; + case BD3DCMP_EQUAL: + return line.w[0] == pShader.z[ pShader.i]; + } + } + return 1; +} + +/*! +*/ +REALINLINE void CBurningShader_Raster_Reference::depthWrite () +{ + if ( ShaderParam.RenderState [ BD3DRS_ZWRITEENABLE ] ) + { + pShader.z[pShader.i] = line.w[0]; + } +} + +/*! +*/ +REALINLINE void CBurningShader_Raster_Reference::scanline2() +{ + // apply top-left fill-convention, left + pShader.xStart = core::ceil32( line.x[0] ); + pShader.xEnd = core::ceil32( line.x[1] ) - 1; + + pShader.dx = pShader.xEnd - pShader.xStart; + if ( pShader.dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] ); + const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0]; + + // store slopes in endpoint, and correct first pixel + + line.w[0] += (line.w[1] = (line.w[1] - line.w[0]) * invDeltaX) * subPixel; + + u32 i; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX; + line.c[i][0] += line.c[i][1] * subPixel; + } +#endif + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + line.t[i][1] = (line.t[i][1] - line.t[i][0]) * invDeltaX; + line.t[i][0] += line.t[i][1] * subPixel; + } + + pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->lock() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); + pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); + + for ( pShader.i = 0; pShader.i <= pShader.dx; ++pShader.i ) + { + if ( depthFunc() ) + { + depthWrite (); + } + + // advance next pixel + line.w[0] += line.w[1]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + line.c[i][0] += line.c[i][1]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + line.t[i][0] += line.t[i][1]; + } + } +} + + +/*! +*/ +REALINLINE void CBurningShader_Raster_Reference::scanline () +{ + u32 i; + + // apply top-left fill-convention, left + pShader.xStart = core::ceil32( line.x[0] ); + pShader.xEnd = core::ceil32( line.x[1] ) - 1; + + pShader.dx = pShader.xEnd - pShader.xStart; + if ( pShader.dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); + + // subTexel + const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0]; + + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + pShader.i = 0; + + if ( ShaderParam.RenderState [ BD3DRS_ZENABLE ] ) + { + u32 condition; + switch ( ShaderParam.RenderState [ BD3DRS_ZFUNC ] ) + { + case BD3DCMP_LESSEQUAL: + condition = a < pShader.z[pShader.i]; + break; + case BD3DCMP_EQUAL: + condition = a != pShader.z[pShader.i]; + break; + } + while ( a < pShader.z[pShader.i] ) + { + a += b; + + pShader.i += 1; + if ( pShader.i > pShader.dx ) + return; + + } + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; + + pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->lock() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); + + a = (f32) pShader.i + subPixel; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX; + line.c[i][0] += line.c[i][1] * a; + } +#endif + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + line.t[i][1] = (line.t[i][1] - line.t[i][0]) * invDeltaX; + line.t[i][0] += line.t[i][1] * a; + } + + for ( ; pShader.i <= pShader.dx; ++pShader.i ) + { + if ( line.w[0] >= pShader.z[pShader.i] ) + { + pShader.z[pShader.i] = line.w[0]; + + pShader_EMT_LIGHTMAP_M4 (); + } + + line.w[0] += line.w[1]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + line.c[i][0] += line.c[i][1]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + line.t[i][0] += line.t[i][1]; + } + } + +} + + + +void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + u32 i; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y ); + scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y ); + scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = a->Pos.y - c->Pos.y; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = b->Pos.y - a->Pos.y; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][0] = a->Color[i]; + scan.slopeC[i][0] = (c->Color[i] - a->Color[i]) * scan.invDeltaY[0]; + } +#endif + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][0] = a->Tex[i]; + scan.slopeT[i][0] = (c->Tex[i] - a->Tex[i]) * scan.invDeltaY[0]; + } + + // top left fill convention y run + s32 yStart; + s32 yEnd; + + f32 subPixel; + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][1] = a->Color[i]; + scan.slopeC[i][1] = (b->Color[i] - a->Color[i]) * scan.invDeltaY[1]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][1] = a->Tex[i]; + scan.slopeT[i][1] = (b->Tex[i] - a->Tex[i]) * scan.invDeltaY[1]; + } + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; + + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][0] += scan.slopeC[i][0] * subPixel; + scan.c[i][1] += scan.slopeC[i][1] * subPixel; + } + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][0] += scan.slopeT[i][0] * subPixel; + scan.t[i][1] += scan.slopeT[i][1] * subPixel; + } + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.w[scan.left] = scan.w[0]; + + line.x[scan.right] = scan.x[1]; + line.w[scan.right] = scan.w[1]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + line.c[i][scan.left] = scan.c[i][0]; + line.c[i][scan.right] = scan.c[i][1]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + line.t[i][scan.left] = scan.t[i][0]; + line.t[i][scan.right] = scan.t[i][1]; + } + + // render a scanline + scanline (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; + + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][0] += scan.slopeC[i][0]; + scan.c[i][1] += scan.slopeC[i][1]; + } + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][0] += scan.slopeT[i][0]; + scan.t[i][1] += scan.slopeT[i][1]; + } + + } + } + + // rasterize lower sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][0] = a->Color[i] + scan.slopeC[i][0] * temp[0]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][0] = a->Tex[i] + scan.slopeT[i][0] * temp[0]; + } + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][1] = b->Color[i]; + scan.slopeC[i][1] = (c->Color[i] - b->Color[i]) * scan.invDeltaY[2]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][1] = b->Tex[i]; + scan.slopeT[i][1] = (c->Tex[i] - b->Tex[i]) * scan.invDeltaY[2]; + } + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; + + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + scan.c[i][0] += scan.slopeC[i][0] * subPixel; + scan.c[i][1] += scan.slopeC[i][1] * subPixel; + } + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][0] += scan.slopeT[i][0] * subPixel; + scan.t[i][1] += scan.slopeT[i][1] * subPixel; + } + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.w[scan.left] = scan.w[0]; + + line.x[scan.right] = scan.x[1]; + line.w[scan.right] = scan.w[1]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( i = 0; i != ShaderParam.ColorUnits; ++i ) + { + line.c[i][scan.left] = scan.c[i][0]; + line.c[i][scan.right] = scan.c[i][1]; + } +#endif + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + line.t[i][scan.left] = scan.t[i][0]; + line.t[i][scan.right] = scan.t[i][1]; + } + + // render a scanline + scanline (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.c[i][0] += scan.slopeC[i][0]; + scan.c[i][1] += scan.slopeC[i][1]; + } + + for ( i = 0; i != ShaderParam.TextureUnits; ++i ) + { + scan.t[i][0] += scan.slopeT[i][0]; + scan.t[i][1] += scan.slopeT[i][1]; + } + } + } +} + + +} // end namespace video +} // end namespace irr + + +namespace irr +{ +namespace video +{ + + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver) +{ + return new CBurningShader_Raster_Reference(driver); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.cpp new file mode 100644 index 0000000..048fb01 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.cpp @@ -0,0 +1,872 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was written by Saurav Mohapatra and modified by Nikolaus Gebhardt. +// See CCSMLoader.h for details. + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_CSM_LOADER_ + +#include "CCSMLoader.h" +#include "os.h" +#include "IFileSystem.h" +#include "IReadFile.h" +#include "ISceneManager.h" +#include "IAttributes.h" +#include "SMesh.h" +#include "IVideoDriver.h" +#include "SAnimatedMesh.h" +#include "SMeshBufferLightMap.h" + +#ifdef _DEBUG +#define _IRR_DEBUG_CSM_LOADER_ +#endif + +namespace irr +{ +namespace scene +{ + // + // the CSM data types + // + struct color_rgb_t + { + s32 red; + s32 green; + s32 blue; + + color_rgb_t() : red(0), green(0), blue(0) {} + void clear() { red=0; green=0; blue=0; } + video::SColor toSColor() const { return video::SColor(255, red, green, blue); } + }; + + + // + // A Binary File Reader + // + struct BinaryFileReader + { + BinaryFileReader(io::IReadFile* pFile) : file(pFile) { } + + s32 readBuffer(void* buffer, s32 len) + { + return file->read(buffer,len); + } + + s32 readLong(); + f32 readFloat(); + + void readString(core::stringc &str); + void readVec3f(core::vector3df* v); + void readVec2f(core::vector2df* v); + void readColorRGB(color_rgb_t* color); + + io::IReadFile *file; + }; + + // + // The file header + // + class Header + { + public: + + enum E_CSM_VERSION + { + VERSION_4 = 4, + VERSION_4_1 = 5 + }; + + Header(){ clear(); } + + s32 getVersion() const { return version; } + void clear(){ version = 0; } + void load(BinaryFileReader* pReader) + { + version = pReader->readLong(); + } + + private: + + s32 version; + }; + + + // + // The groups + // + class Group + { + public: + + Group(){ clear(); } + ~Group(){ clear(); } + + void clear(); + void load(BinaryFileReader* pReader); + + s32 getFlags() const { return flags; } + s32 getParentGroupID() const { return parentGroup; } + const core::stringc& getProperties() const { return props; } + video::SColor getColor() const { return color.toSColor(); } + + private: + + s32 flags; + s32 parentGroup; + core::stringc props; + color_rgb_t color; + }; + + + // + // The visgroups + // + class VisGroup + { + public: + + VisGroup(){ clear(); } + ~VisGroup(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + + s32 getFlags() const{ return flags; } + const core::stringc& getName() const{ return name; } + video::SColor getColor() const{ return color.toSColor(); } + + private: + + core::stringc name; + s32 flags; + color_rgb_t color; + }; + + + // + // Lightmaps + // + class LightMap + { + public: + + LightMap() : pixelData(0){ clear(); } + ~LightMap(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + s32 getWidth() const{ return width; } + s32 getHeight() const{ return height; } + s32* getPixelData() const{ return pixelData; } + + private: + + s32 width; + s32 height; + s32* pixelData; + }; + + struct Triangle + { + s32 a,b,c; + }; + + + struct Line + { + s32 a,b; + }; + + + class Vertex + { + public: + + Vertex(){ clear(); } + ~Vertex(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + + const core::vector3df& getPosition() const { return position; } + const core::vector3df& getNormal() const { return normal; } + video::SColor getColor() const { return color.toSColor(); } + const core::vector3df& getTextureCoordinates() const { return texCoords; } + const core::vector3df& getLightMapCoordinates() const { return lmapCoords; } + + private: + + core::vector3df position; + core::vector3df normal; + color_rgb_t color; + core::vector3df texCoords; + core::vector3df lmapCoords; + }; + + + class Surface + { + public: + + Surface() { clear(); } + ~Surface(){ clear(); } + + void clear(); + void load(BinaryFileReader *pReader); + + s32 getFlags() const{ return flags; } + const core::stringc& getTextureName() const{ return textureName; } + s32 getLightMapId() const{ return lightMapId; } + const core::vector2df* getUVOffset() const{ return &uvOffset; } + const core::vector2df* getUVScale() const{ return &uvScale; } + f32 getUVRotation() const{ return uvRotation; } + + u32 getVertexCount() const{ return vertices.size(); } + const Vertex& getVertexAt(const s32 index) const{ return vertices[index]; } + + u32 getTriangleCount() const{ return triangles.size(); } + const Triangle& getTriangleAt(const s32 index) const{ return triangles[index]; } + + private: + + s32 flags; + core::stringc textureName; + s32 lightMapId; + core::vector2df uvOffset; + core::vector2df uvScale; + f32 uvRotation; + core::array vertices; + core::array triangles; + core::array lines; + }; + + class Mesh + { + public: + + Mesh(){ clear(); } + ~Mesh(){ clear(); } + + void clear(); + void load(BinaryFileReader* pReader, bool bReadVisGroups); + + s32 getFlags() const { return flags; } + s32 getGroupID() const { return groupId; } + const core::stringc& getProperties() const { return props; } + video::SColor getColor() const { return color.toSColor(); } + const core::vector3df* getPosition() const { return &position; } + s32 getVisgroupID() const { return visgroupId; } + s32 getSurfaceCount() const { return surfaces.size(); } + const Surface* getSurfaceAt(const s32 index) const { return surfaces[index]; } + + private: + + s32 flags; + s32 groupId; + core::stringc props; + color_rgb_t color; + core::vector3df position; + s32 visgroupId; + + core::array surfaces; + }; + + class Entity + { + public: + + Entity() { clear(); } + ~Entity() { clear(); } + + void clear(); + void load(BinaryFileReader* pReader); + s32 getVisgroupID() const { return visgroupId; } + s32 getGroupID() const { return groupId; } + const core::stringc& getProperties() const { return props; } + const core::vector3df* getPosition() const { return &position; } + + private: + + s32 visgroupId; + s32 groupId; + core::stringc props; + core::vector3df position; + }; + + + class CameraData + { + public: + + CameraData(){ clear(); } + ~CameraData(){ clear(); } + + void clear(); + void load(BinaryFileReader* pReader); + + const core::vector3df* getPosition(){ return &position; } + f32 getPitch(){ return pitch; } + f32 getYaw(){ return yaw; } + + private: + + core::vector3df position; + f32 pitch; + f32 yaw; + }; + + // + // A CSM File + // + class CSMFile + { + public: + + CSMFile(){ clear(); } + ~CSMFile(){ clear(); } + void clear(); + void load(BinaryFileReader* pReader); + + const Header* getHeader() const{ return &header; } + + u32 getGroupCount() const{ return groups.size(); } + const Group* getGroupAt(const s32 index) const{ return groups[index]; } + + u32 getVisGroupCount() const{ return visgroups.size(); } + const VisGroup* getVisGroupAt(const s32 index) const{ return visgroups[index]; } + + u32 getLightMapCount() const{ return lightmaps.size(); } + const LightMap* getLightMapAt(const s32 index) const { return lightmaps[index]; } + + u32 getMeshCount() const{ return meshes.size(); } + const Mesh* getMeshAt(const s32 index) const{ return meshes[index]; } + + u32 getEntityCount() const{ return entities.size(); } + const Entity* getEntityAt(const s32 index) const{ return entities[index]; } + + const CameraData* getCameraData() const{ return &cameraData; } + + private: + + Header header; + core::array groups; + core::array visgroups; + core::array lightmaps; + core::array meshes; + core::array entities; + CameraData cameraData; + }; + + CCSMLoader::CCSMLoader(scene::ISceneManager* manager, io::IFileSystem* fs) + : FileSystem(fs), SceneManager(manager) + { + + #ifdef _DEBUG + setDebugName("CCSMLoader"); + #endif + } + + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + bool CCSMLoader::isALoadableFileExtension(const io::path& filename) const + { + return core::hasFileExtension ( filename, "csm" ); + } + + + //! creates/loads an animated mesh from the file. + IAnimatedMesh* CCSMLoader::createMesh(io::IReadFile* file) + { + scene::IMesh* m = createCSMMesh(file); + + if (!m) + return 0; + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_CSM; + am->addMesh(m); + m->drop(); + + am->recalculateBoundingBox(); + return am; + } + + scene::IMesh* CCSMLoader::createCSMMesh(io::IReadFile* file) + { + if (!file) + return 0; + + BinaryFileReader reader(file); + CSMFile csmFile; + csmFile.load(&reader); + + return createIrrlichtMesh(&csmFile, + SceneManager->getParameters()->getAttributeAsString(CSM_TEXTURE_PATH), + file->getFileName()); + } + + + scene::IMesh* CCSMLoader::createIrrlichtMesh(const CSMFile* csmFile, + const core::stringc& textureRoot, const io::path& lmprefix) + { + scene::SMesh *pMesh = new scene::SMesh(); + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + for(u32 l = 0; lgetLightMapCount(); l++) + { + const LightMap* lmap = csmFile->getLightMapAt(l); + + io::path lmapName = lmprefix; + lmapName += "LMAP_"; + lmapName += io::path(l+1); + os::Printer::log("CCSMLoader loading light map", lmapName.c_str()); + + video::IImage* lmapImg = driver->createImageFromData( + video::ECF_A8R8G8B8, + core::dimension2d(lmap->getWidth(),lmap->getHeight()), + lmap->getPixelData()); + + driver->addTexture(lmapName.c_str(), lmapImg); + lmapImg->drop(); + } + + for(u32 m = 0; mgetMeshCount(); m++) + { + const Mesh* mshPtr = csmFile->getMeshAt(m); + + for(s32 s = 0; s < mshPtr->getSurfaceCount(); s++) + { + const Surface* surface = mshPtr->getSurfaceAt(s); + + core::stringc texName; + if (textureRoot.size()) + { + texName += textureRoot; + texName += "/"; + } + texName+= surface->getTextureName(); + + video::ITexture* texture = 0; + if (texName.size()) + { + if (FileSystem->existFile(texName)) + texture = driver->getTexture(texName); + else if (FileSystem->existFile(surface->getTextureName())) + texture = driver->getTexture(surface->getTextureName()); + else if (FileSystem->existFile(FileSystem->getFileBasename(surface->getTextureName()))) + texture = driver->getTexture(FileSystem->getFileBasename(surface->getTextureName())); + else if (FileSystem->existFile(FileSystem->getFileDir(lmprefix)+"/"+surface->getTextureName())) + texture = driver->getTexture(FileSystem->getFileDir(lmprefix)+"/"+surface->getTextureName()); + else + texture = driver->getTexture(FileSystem->getFileDir(lmprefix)+"/"+FileSystem->getFileBasename(surface->getTextureName())); + } + + //material + io::path lmapName = lmprefix; + lmapName += "LMAP_"; + lmapName += io::path(surface->getLightMapId()); + + scene::SMeshBufferLightMap *buffer = new scene::SMeshBufferLightMap(); + buffer->Material.setTexture(0, texture); + if (surface->getLightMapId()) + { + buffer->Material.setTexture(1, driver->getTexture(lmapName)); + buffer->Material.Lighting = false; + buffer->Material.MaterialType = video::EMT_LIGHTMAP_ADD; + } + + buffer->Vertices.reallocate(surface->getVertexCount()); + for(u32 v = 0; v < surface->getVertexCount(); ++v) + { + const Vertex& vtxPtr = surface->getVertexAt(v); + video::S3DVertex2TCoords vtx; + vtx.Pos = vtxPtr.getPosition(); + vtx.Normal = vtxPtr.getPosition(); + vtx.Color=vtxPtr.getColor(); + vtx.TCoords.set(vtxPtr.getTextureCoordinates().X, 1.f-vtxPtr.getTextureCoordinates().Y); + vtx.TCoords2.set(vtxPtr.getLightMapCoordinates().X, 1.f-vtxPtr.getLightMapCoordinates().Y); + + buffer->Vertices.push_back(vtx); + } + + buffer->Indices.reallocate(surface->getTriangleCount()*3); + for(u32 t = 0; t < surface->getTriangleCount(); ++t) + { + const Triangle& tri = surface->getTriangleAt(t); + buffer->Indices.push_back(tri.c); + buffer->Indices.push_back(tri.b); + buffer->Indices.push_back(tri.a); + } + + buffer->recalculateBoundingBox(); + pMesh->addMeshBuffer(buffer); + buffer->drop(); + } + } + + pMesh->recalculateBoundingBox(); + return pMesh; + } + + void Group::clear() + { + color.clear(); + flags = 0; + parentGroup = 0; + props = ""; + } + + void Group::load(BinaryFileReader* pReader) + { + flags = pReader->readLong(); + parentGroup = pReader->readLong(); + pReader->readString(props); + pReader->readColorRGB(&color); + } + + void VisGroup::clear() + { + color.clear(); + flags = 0; + name = ""; + } + + void VisGroup::load(BinaryFileReader* pReader) + { + pReader->readString(name); + flags = pReader->readLong(); + pReader->readColorRGB(&color); + } + + void LightMap::clear() + { + delete[] pixelData; + pixelData = 0; + width = height = 0; + } + + void LightMap::load(BinaryFileReader* pReader) + { + width = pReader->readLong(); + height = pReader->readLong(); + pixelData = new s32[width * height]; + pReader->readBuffer(pixelData, width * height * sizeof(s32)); + } + + void Mesh::clear() + { + flags = 0; + groupId = 0; + visgroupId = 0; + props = ""; + color.clear(); + position.set(0,0,0); + + for(u32 s = 0; s < surfaces.size(); s++) + { + delete surfaces[s]; + } + surfaces.clear(); + } + + void Mesh::load(BinaryFileReader* pReader, bool bReadVisGroups) + { + flags = pReader->readLong(); + groupId = pReader->readLong(); + pReader->readString(props); + pReader->readColorRGB(&color); + pReader->readVec3f(&position); + if(bReadVisGroups) + visgroupId = pReader->readLong(); + else + visgroupId = 0; + + s32 count = pReader->readLong(); + + for(s32 i = 0; i < count; i++) + { + Surface* surf = new Surface(); + surf->load(pReader); + surfaces.push_back(surf); + } + } + + void Surface::clear() + { + flags = 0; + lightMapId = 0; + textureName = ""; + uvOffset.set(0.0f,0.0f); + uvScale.set(0.0f,0.0f); + uvRotation = 0.0f; + triangles.clear(); + lines.clear(); + vertices.clear(); + } + + void Surface::load(BinaryFileReader* pReader) + { + flags = pReader->readLong(); + pReader->readString(textureName); + textureName.replace('\\', '/'); + + lightMapId = pReader->readLong(); + pReader->readVec2f(&uvOffset); + pReader->readVec2f(&uvScale); + uvRotation = pReader->readFloat(); + s32 vtxCount = pReader->readLong(); + s32 triCount = pReader->readLong(); + s32 lineCount = pReader->readLong(); + + for(s32 v = 0; v < vtxCount; v++) + { + vertices.push_back(Vertex()); + vertices.getLast().load(pReader); + } + + for(s32 t = 0; t < triCount; t++) + { + Triangle tri; + pReader->readBuffer(&tri, sizeof(tri)); + triangles.push_back(tri); + } + + for(s32 l = 0; l < lineCount; l++) + { + Line line; + pReader->readBuffer(&line,sizeof(line)); + lines.push_back(line); + + } + + } + + void Vertex::clear() + { + position.set(0,0,0); + normal.set(0,0,0); + color.clear(); + texCoords.set(0,0,0); + lmapCoords.set(0,0,0); + } + + void Vertex::load(BinaryFileReader* pReader) + { + pReader->readVec3f(&position); + pReader->readVec3f(&normal); + pReader->readColorRGB(&color); + pReader->readVec3f(&texCoords); + pReader->readVec3f(&lmapCoords); + } + + void Entity::clear() + { + visgroupId = groupId = 0; + props = ""; + position.set(0,0,0); + } + + void Entity::load(BinaryFileReader* pReader) + { + visgroupId = pReader->readLong(); + groupId = pReader->readLong(); + pReader->readString(props); + pReader->readVec3f(&position); + } + + void CameraData::clear() + { + position.set(0,0,0); + pitch = 0; + yaw = 0; + } + + void CameraData::load(BinaryFileReader* pReader) + { + pReader->readVec3f(&position); + pitch = pReader->readFloat(); + yaw = pReader->readFloat(); + } + + void CSMFile::clear() + { + header.clear(); + cameraData.clear(); + + u32 x =0; + for( x= 0; x < groups.size(); x++) + delete groups[x]; + + groups.clear(); + + for(x= 0; x < visgroups.size(); x++) + delete visgroups[x]; + + visgroups.clear(); + + for(x= 0; x < lightmaps.size(); x++) + delete lightmaps[x]; + + lightmaps.clear(); + + for(x= 0; x < meshes.size(); x++) + delete meshes[x]; + + meshes.clear(); + + for(x= 0; x < entities.size(); x++) + delete entities[x]; + + entities.clear(); + } + + void CSMFile::load(BinaryFileReader* pReader) + { + clear(); + + header.load(pReader); + + //groups + { + const s32 count = pReader->readLong(); +#ifdef _IRR_DEBUG_CSM_LOADER_ + os::Printer::log("CSM Version", core::stringc(header.getVersion()).c_str()); + os::Printer::log("Loading groups. Count", core::stringc(count)); +#endif + + groups.reallocate(count); + for (s32 i = 0; i < count; i++) + { + Group* grp = new Group(); + grp->load(pReader); + groups.push_back(grp); + } + } + const bool bHasVGroups = (header.getVersion() == Header::VERSION_4_1); + + if (bHasVGroups) + { + //visgroups + const s32 count = pReader->readLong(); +#ifdef _IRR_DEBUG_CSM_LOADER_ + os::Printer::log("Loading visgroups. Count", core::stringc(count)); +#endif + + visgroups.reallocate(count); + for (s32 i = 0; i < count; i++) + { + VisGroup* grp = new VisGroup(); + grp->load(pReader); + visgroups.push_back(grp); + } + } + + //lightmaps + { + const s32 count = pReader->readLong(); +#ifdef _IRR_DEBUG_CSM_LOADER_ + os::Printer::log("Loading lightmaps. Count", core::stringc(count)); +#endif + + lightmaps.reallocate(count); + for(s32 i = 0; i < count; i++) + { + LightMap* lm = new LightMap(); + lm->load(pReader); + lightmaps.push_back(lm); + } + } + + //meshes + { + const s32 count = pReader->readLong(); +#ifdef _IRR_DEBUG_CSM_LOADER_ + os::Printer::log("Loading meshes. Count", core::stringc(count)); +#endif + + meshes.reallocate(count); + for(s32 i = 0; i < count; i++) + { + Mesh* mesh = new Mesh(); + mesh->load(pReader,bHasVGroups); + meshes.push_back(mesh); + } + } + + //entities + { + const s32 count = pReader->readLong(); +#ifdef _IRR_DEBUG_CSM_LOADER_ + os::Printer::log("Loading entitites. Count", core::stringc(count)); +#endif + + entities.reallocate(count); + for(s32 i = 0; i < count; i++) + { + Entity* ent = new Entity(); + ent->load(pReader); + entities.push_back(ent); + } + } + + //camera data +#ifdef _IRR_DEBUG_CSM_LOADER_ + os::Printer::log("Loading camera data."); +#endif + cameraData.load(pReader); + } + + s32 BinaryFileReader::readLong() + { + int ret = 0; + readBuffer(&ret,sizeof(int)); +#ifdef __BIG_ENDIAN__ + ret = os::Byteswap::byteswap(ret); +#endif + return ret; + } + + f32 BinaryFileReader::readFloat() + { + float ret = 0; + readBuffer(&ret,sizeof(float)); +#ifdef __BIG_ENDIAN__ + ret = os::Byteswap::byteswap(ret); +#endif + return ret; + } + + void BinaryFileReader::readString(core::stringc &str) + { + str = ""; + c8 c; + readBuffer(&c,sizeof(char)); + while(c != 0) + { + str += c; + readBuffer(&c,sizeof(char)); + } + } + + void BinaryFileReader::readVec3f(core::vector3df* v) + { + v->X = readFloat(); + v->Y = readFloat(); + v->Z = readFloat(); + } + + void BinaryFileReader::readVec2f(core::vector2df* v) + { + v->X = readFloat(); + v->Y = readFloat(); + } + + void BinaryFileReader::readColorRGB(color_rgb_t* color) + { + readBuffer(color,sizeof(color_rgb_t)); + } + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_CSM_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.h new file mode 100644 index 0000000..5e850c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCSMLoader.h @@ -0,0 +1,82 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This Loader has been originally written by Saurav Mohapatra. I (Nikolaus Gebhardt) +// modified some minor things and integrated it into Irrlicht 0.9. Thanks a lot +// to Saurav Mohapatra for his work on this and that he gave me his permission to +// add it into Irrlicht. +// I did some changes to Saurav Mohapatra's loader, so I'm writing this down here: +// - Replaced all dependencies to STL and stdio with irr:: methods/constructs. +// - Moved everything into namespace irr::scene +// - Replaced logging with Irrlicht's internal logger. +// - Removed dependency to IrrlichtDevice +// - Moved all internal structures into CCSMLoader.cpp +// - Made the texture root parameter dependent on a ISceneManager string parameter +// - removed exceptions +// - Implemented CCCSMLoader as IMeshLoader +// - Fixed some problems with memory leaks +// - Fixed bounding box calculation +// +// The original readme of this file looks like this: +// +// This component provides a loader for the Cartography shop 4.x .csm maps for Irrlicht Engine. +// This is a part of the M_TRIX Project. +// This is licensed under the ZLib/LibPNG license +// The IrrCSM library is written by Saurav Mohapatra. +// +// Features +// +// The IrrCSM library features the following capabilities +// +// * Loads the .csm 4.0 and 4.1 files transparently +// * Presents the loaded file as irr::scene::IAnimatedMesh for easy creation of IOctreeSceneNode +// * Loads the textures given the correct texture root. hence map and textures can be in separate directories +// +// For more informations go to http://www.geocities.com/standard_template/irrcsm/downloads.html + +#ifndef __CSM_LOADER_H_INCLUDED__ +#define __CSM_LOADER_H_INCLUDED__ + +#include "irrArray.h" +#include "IMesh.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "IMeshLoader.h" + +namespace irr +{ +namespace scene +{ + class CSMFile; + class ISceneManager; + + class CCSMLoader : public scene::IMeshLoader + { + public: + + CCSMLoader(ISceneManager* manager, io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + private: + + scene::IMesh* createCSMMesh(io::IReadFile* file); + + scene::IMesh* createIrrlichtMesh(const CSMFile* csmFile, + const core::stringc& textureRoot, const io::path& lmprefix); + + io::IFileSystem* FileSystem; + scene::ISceneManager* SceneManager; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp new file mode 100644 index 0000000..370b893 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.cpp @@ -0,0 +1,385 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CCameraSceneNode.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& lookat) + : ICameraSceneNode(parent, mgr, id, position), + Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f), + InputReceiverEnabled(true), TargetAndRotationAreBound(false) +{ + #ifdef _DEBUG + setDebugName("CCameraSceneNode"); + #endif + + // set default projection + Fovy = core::PI / 2.5f; // Field of view, in radians. + + const video::IVideoDriver* const d = mgr?mgr->getVideoDriver():0; + if (d) + Aspect = (f32)d->getCurrentRenderTargetSize().Width / + (f32)d->getCurrentRenderTargetSize().Height; + else + Aspect = 4.0f / 3.0f; // Aspect ratio. + + recalculateProjectionMatrix(); + recalculateViewArea(); +} + + +//! Disables or enables the camera to get key or mouse inputs. +void CCameraSceneNode::setInputReceiverEnabled(bool enabled) +{ + InputReceiverEnabled = enabled; +} + + +//! Returns if the input receiver of the camera is currently enabled. +bool CCameraSceneNode::isInputReceiverEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return InputReceiverEnabled; +} + + +//! Sets the projection matrix of the camera. +/** The core::matrix4 class has some methods +to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH +\param projection: The new projection matrix of the camera. */ +void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal) +{ + IsOrthogonal = isOrthogonal; + ViewArea.getTransform ( video::ETS_PROJECTION ) = projection; +} + + +//! Gets the current projection matrix of the camera +//! \return Returns the current projection matrix of the camera. +const core::matrix4& CCameraSceneNode::getProjectionMatrix() const +{ + return ViewArea.getTransform ( video::ETS_PROJECTION ); +} + + +//! Gets the current view matrix of the camera +//! \return Returns the current view matrix of the camera. +const core::matrix4& CCameraSceneNode::getViewMatrix() const +{ + return ViewArea.getTransform ( video::ETS_VIEW ); +} + + +//! Sets a custom view matrix affector. The matrix passed here, will be +//! multiplied with the view matrix when it gets updated. +//! This allows for custom camera setups like, for example, a reflection camera. +/** \param affector: The affector matrix. */ +void CCameraSceneNode::setViewMatrixAffector(const core::matrix4& affector) +{ + Affector = affector; +} + + +//! Gets the custom view matrix affector. +const core::matrix4& CCameraSceneNode::getViewMatrixAffector() const +{ + return Affector; +} + + +//! It is possible to send mouse and key events to the camera. Most cameras +//! may ignore this input, but camera scene nodes which are created for +//! example with scene::ISceneManager::addMayaCameraSceneNode or +//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input +//! for changing their position, look at target or whatever. +bool CCameraSceneNode::OnEvent(const SEvent& event) +{ + if (!InputReceiverEnabled) + return false; + + // send events to event receiving animators + + ISceneNodeAnimatorList::Iterator ait = Animators.begin(); + + for (; ait != Animators.end(); ++ait) + if ((*ait)->isEventReceiverEnabled() && (*ait)->OnEvent(event)) + return true; + + // if nobody processed the event, return false + return false; +} + + +//! sets the look at target of the camera +//! \param pos: Look at target of the camera. +void CCameraSceneNode::setTarget(const core::vector3df& pos) +{ + Target = pos; + + if(TargetAndRotationAreBound) + { + const core::vector3df toTarget = Target - getAbsolutePosition(); + ISceneNode::setRotation(toTarget.getHorizontalAngle()); + } +} + + +//! Sets the rotation of the node. +/** This only modifies the relative rotation of the node. +If the camera's target and rotation are bound ( @see bindTargetAndRotation() ) +then calling this will also change the camera's target to match the rotation. +\param rotation New rotation of the node in degrees. */ +void CCameraSceneNode::setRotation(const core::vector3df& rotation) +{ + if(TargetAndRotationAreBound) + Target = getAbsolutePosition() + rotation.rotationToDirection(); + + ISceneNode::setRotation(rotation); +} + + +//! Gets the current look at target of the camera +//! \return Returns the current look at target of the camera +const core::vector3df& CCameraSceneNode::getTarget() const +{ + return Target; +} + + +//! sets the up vector of the camera +//! \param pos: New upvector of the camera. +void CCameraSceneNode::setUpVector(const core::vector3df& pos) +{ + UpVector = pos; +} + + +//! Gets the up vector of the camera. +//! \return Returns the up vector of the camera. +const core::vector3df& CCameraSceneNode::getUpVector() const +{ + return UpVector; +} + + +f32 CCameraSceneNode::getNearValue() const +{ + return ZNear; +} + + +f32 CCameraSceneNode::getFarValue() const +{ + return ZFar; +} + + +f32 CCameraSceneNode::getAspectRatio() const +{ + return Aspect; +} + + +f32 CCameraSceneNode::getFOV() const +{ + return Fovy; +} + + +void CCameraSceneNode::setNearValue(f32 f) +{ + ZNear = f; + recalculateProjectionMatrix(); +} + + +void CCameraSceneNode::setFarValue(f32 f) +{ + ZFar = f; + recalculateProjectionMatrix(); +} + + +void CCameraSceneNode::setAspectRatio(f32 f) +{ + Aspect = f; + recalculateProjectionMatrix(); +} + + +void CCameraSceneNode::setFOV(f32 f) +{ + Fovy = f; + recalculateProjectionMatrix(); +} + + +void CCameraSceneNode::recalculateProjectionMatrix() +{ + ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar); +} + + +//! prerender +void CCameraSceneNode::OnRegisterSceneNode() +{ + if ( SceneManager->getActiveCamera () == this ) + SceneManager->registerNodeForRendering(this, ESNRP_CAMERA); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! render +void CCameraSceneNode::render() +{ + core::vector3df pos = getAbsolutePosition(); + core::vector3df tgtv = Target - pos; + tgtv.normalize(); + + // if upvector and vector to the target are the same, we have a + // problem. so solve this problem: + core::vector3df up = UpVector; + up.normalize(); + + f32 dp = tgtv.dotProduct(up); + + if ( core::equals(core::abs_(dp), 1.f) ) + { + up.X += 0.5f; + } + + ViewArea.getTransform(video::ETS_VIEW).buildCameraLookAtMatrixLH(pos, Target, up); + ViewArea.getTransform(video::ETS_VIEW) *= Affector; + recalculateViewArea(); + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if ( driver) + { + driver->setTransform(video::ETS_PROJECTION, ViewArea.getTransform ( video::ETS_PROJECTION) ); + driver->setTransform(video::ETS_VIEW, ViewArea.getTransform ( video::ETS_VIEW) ); + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CCameraSceneNode::getBoundingBox() const +{ + return ViewArea.getBoundingBox(); +} + + +//! returns the view frustum. needed sometimes by bsp or lod render nodes. +const SViewFrustum* CCameraSceneNode::getViewFrustum() const +{ + return &ViewArea; +} + + +void CCameraSceneNode::recalculateViewArea() +{ + ViewArea.cameraPosition = getAbsolutePosition(); + + core::matrix4 m(core::matrix4::EM4CONST_NOTHING); + m.setbyproduct_nocheck(ViewArea.getTransform(video::ETS_PROJECTION), + ViewArea.getTransform(video::ETS_VIEW)); + ViewArea.setFrom(m); +} + + +//! Writes attributes of the scene node. +void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ICameraSceneNode::serializeAttributes(out, options); + + out->addVector3d("Target", Target); + out->addVector3d("UpVector", UpVector); + out->addFloat("Fovy", Fovy); + out->addFloat("Aspect", Aspect); + out->addFloat("ZNear", ZNear); + out->addFloat("ZFar", ZFar); + out->addBool("Binding", TargetAndRotationAreBound); + out->addBool("ReceiveInput", InputReceiverEnabled); +} + +//! Reads attributes of the scene node. +void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + ICameraSceneNode::deserializeAttributes(in, options); + + Target = in->getAttributeAsVector3d("Target"); + UpVector = in->getAttributeAsVector3d("UpVector"); + Fovy = in->getAttributeAsFloat("Fovy"); + Aspect = in->getAttributeAsFloat("Aspect"); + ZNear = in->getAttributeAsFloat("ZNear"); + ZFar = in->getAttributeAsFloat("ZFar"); + TargetAndRotationAreBound = in->getAttributeAsBool("Binding"); + if ( in->findAttribute("ReceiveInput") ) + InputReceiverEnabled = in->getAttributeAsBool("InputReceiverEnabled"); + + recalculateProjectionMatrix(); + recalculateViewArea(); +} + + +//! Set the binding between the camera's rotation adn target. +void CCameraSceneNode::bindTargetAndRotation(bool bound) +{ + TargetAndRotationAreBound = bound; +} + + +//! Gets the binding between the camera's rotation and target. +bool CCameraSceneNode::getTargetAndRotationBinding(void) const +{ + return TargetAndRotationAreBound; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CCameraSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + ICameraSceneNode::clone(newParent, newManager); + + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CCameraSceneNode* nb = new CCameraSceneNode(newParent, + newManager, ID, RelativeTranslation, Target); + + nb->ISceneNode::cloneMembers(this, newManager); + nb->ICameraSceneNode::cloneMembers(this); + + nb->Target = Target; + nb->UpVector = UpVector; + nb->Fovy = Fovy; + nb->Aspect = Aspect; + nb->ZNear = ZNear; + nb->ZFar = ZFar; + nb->ViewArea = ViewArea; + nb->Affector = Affector; + nb->InputReceiverEnabled = InputReceiverEnabled; + nb->TargetAndRotationAreBound = TargetAndRotationAreBound; + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace +} // end namespace + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.h new file mode 100644 index 0000000..ce75408 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCameraSceneNode.h @@ -0,0 +1,172 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_CAMERA_SCENE_NODE_H_INCLUDED__ +#define __C_CAMERA_SCENE_NODE_H_INCLUDED__ + +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" + +namespace irr +{ +namespace scene +{ + + class CCameraSceneNode : public ICameraSceneNode + { + public: + + //! constructor + CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& lookat = core::vector3df(0,0,100)); + + //! Sets the projection matrix of the camera. + /** The core::matrix4 class has some methods + to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspectiveFovLH. + Note that the matrix will only stay as set by this method until one of + the following Methods are called: setNearValue, setFarValue, setAspectRatio, setFOV. + \param projection The new projection matrix of the camera. + \param isOrthogonal Set this to true if the matrix is an orthogonal one (e.g. + from matrix4::buildProjectionMatrixOrthoLH(). */ + virtual void setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal = false); + + //! Gets the current projection matrix of the camera + //! \return Returns the current projection matrix of the camera. + virtual const core::matrix4& getProjectionMatrix() const; + + //! Gets the current view matrix of the camera + //! \return Returns the current view matrix of the camera. + virtual const core::matrix4& getViewMatrix() const; + + //! Sets a custom view matrix affector. + /** \param affector: The affector matrix. */ + virtual void setViewMatrixAffector(const core::matrix4& affector); + + //! Gets the custom view matrix affector. + virtual const core::matrix4& getViewMatrixAffector() const; + + //! It is possible to send mouse and key events to the camera. Most cameras + //! may ignore this input, but camera scene nodes which are created for + //! example with scene::ISceneManager::addMayaCameraSceneNode or + //! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input + //! for changing their position, look at target or whatever. + virtual bool OnEvent(const SEvent& event); + + //! Sets the look at target of the camera + /** If the camera's target and rotation are bound ( @see bindTargetAndRotation() ) + then calling this will also change the camera's scene node rotation to match the target. + \param pos: Look at target of the camera. */ + virtual void setTarget(const core::vector3df& pos); + + //! Sets the rotation of the node. + /** This only modifies the relative rotation of the node. + If the camera's target and rotation are bound ( @see bindTargetAndRotation() ) + then calling this will also change the camera's target to match the rotation. + \param rotation New rotation of the node in degrees. */ + virtual void setRotation(const core::vector3df& rotation); + + //! Gets the current look at target of the camera + /** \return The current look at target of the camera */ + virtual const core::vector3df& getTarget() const; + + //! Sets the up vector of the camera. + //! \param pos: New upvector of the camera. + virtual void setUpVector(const core::vector3df& pos); + + //! Gets the up vector of the camera. + //! \return Returns the up vector of the camera. + virtual const core::vector3df& getUpVector() const; + + //! Gets distance from the camera to the near plane. + //! \return Value of the near plane of the camera. + virtual f32 getNearValue() const; + + //! Gets the distance from the camera to the far plane. + //! \return Value of the far plane of the camera. + virtual f32 getFarValue() const; + + //! Get the aspect ratio of the camera. + //! \return The aspect ratio of the camera. + virtual f32 getAspectRatio() const; + + //! Gets the field of view of the camera. + //! \return Field of view of the camera + virtual f32 getFOV() const; + + //! Sets the value of the near clipping plane. (default: 1.0f) + virtual void setNearValue(f32 zn); + + //! Sets the value of the far clipping plane (default: 2000.0f) + virtual void setFarValue(f32 zf); + + //! Sets the aspect ratio (default: 4.0f / 3.0f) + virtual void setAspectRatio(f32 aspect); + + //! Sets the field of view (Default: PI / 3.5f) + virtual void setFOV(f32 fovy); + + //! PreRender event + virtual void OnRegisterSceneNode(); + + //! Render + virtual void render(); + + //! Returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns the view area. Sometimes needed by bsp or lod render nodes. + virtual const SViewFrustum* getViewFrustum() const; + + //! Disables or enables the camera to get key or mouse inputs. + //! If this is set to true, the camera will respond to key inputs + //! otherwise not. + virtual void setInputReceiverEnabled(bool enabled); + + //! Returns if the input receiver of the camera is currently enabled. + virtual bool isInputReceiverEnabled() const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA; } + + //! Binds the camera scene node's rotation to its target position and vice vera, or unbinds them. + virtual void bindTargetAndRotation(bool bound); + + //! Queries if the camera scene node's rotation and its target position are bound together. + virtual bool getTargetAndRotationBinding(void) const; + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + protected: + + void recalculateProjectionMatrix(); + void recalculateViewArea(); + + core::vector3df Target; + core::vector3df UpVector; + + f32 Fovy; // Field of view, in radians. + f32 Aspect; // Aspect ratio. + f32 ZNear; // value of the near view-plane. + f32 ZFar; // Z-value of the far view-plane. + + SViewFrustum ViewArea; + core::matrix4 Affector; + + bool InputReceiverEnabled; + bool TargetAndRotationAreBound; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.cpp new file mode 100644 index 0000000..a5e4937 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.cpp @@ -0,0 +1,361 @@ +// Copyright (C) 2012 Patryk Nadrowski +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_CG_ + +#include "CCgMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +CCgUniform::CCgUniform(const CGparameter& parameter, bool global) : Parameter(parameter), Type(CG_UNKNOWN_TYPE) +{ + Name = cgGetParameterName(Parameter); + + if(global) + Space = CG_GLOBAL; + else + Space = CG_PROGRAM; +} + +const core::stringc& CCgUniform::getName() const +{ + return Name; +} + +const CGparameter& CCgUniform::getParameter() const +{ + return Parameter; +} + +CGenum CCgUniform::getSpace() const +{ + return Space; +} + +CGtype CCgUniform::getType() const +{ + return Type; +} + +CCgUniform1f::CCgUniform1f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_FLOAT; +} + +void CCgUniform1f::update(const void* data, const SMaterial& material) const +{ + f32* Data = (f32*)data; + cgSetParameter1f(Parameter, *Data); +} + +CCgUniform2f::CCgUniform2f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_FLOAT2; +} + +void CCgUniform2f::update(const void* data, const SMaterial& material) const +{ + f32* Data = (f32*)data; + cgSetParameter2f(Parameter, *Data, *(Data+1)); +} + +CCgUniform3f::CCgUniform3f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_FLOAT3; +} + +void CCgUniform3f::update(const void* data, const SMaterial& material) const +{ + f32* Data = (f32*)data; + cgSetParameter3f(Parameter, *Data, *(Data+1), *(Data+2)); +} + +CCgUniform4f::CCgUniform4f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_FLOAT4; +} + +void CCgUniform4f::update(const void* data, const SMaterial& material) const +{ + f32* Data = (f32*)data; + cgSetParameter4f(Parameter, *Data, *(Data+1), *(Data+2), *(Data+3)); +} + +CCgUniform1i::CCgUniform1i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_INT; +} + +void CCgUniform1i::update(const void* data, const SMaterial& material) const +{ + s32* Data = (s32*)data; + cgSetParameter1i(Parameter, *Data); +} + +CCgUniform2i::CCgUniform2i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_INT2; +} + +void CCgUniform2i::update(const void* data, const SMaterial& material) const +{ + s32* Data = (s32*)data; + cgSetParameter2i(Parameter, *Data, *(Data+1)); +} + +CCgUniform3i::CCgUniform3i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_INT3; +} + +void CCgUniform3i::update(const void* data, const SMaterial& material) const +{ + s32* Data = (s32*)data; + cgSetParameter3i(Parameter, *Data, *(Data+1), *(Data+2)); +} + +CCgUniform4i::CCgUniform4i(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_INT4; +} + +void CCgUniform4i::update(const void* data, const SMaterial& material) const +{ + s32* Data = (s32*)data; + cgSetParameter4i(Parameter, *Data, *(Data+1), *(Data+2), *(Data+3)); +} + +CCgUniform4x4f::CCgUniform4x4f(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_FLOAT4x4; +} + +void CCgUniform4x4f::update(const void* data, const SMaterial& material) const +{ + f32* Data = (f32*)data; + cgSetMatrixParameterfr(Parameter, Data); +} + +CCgUniformSampler2D::CCgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_SAMPLER2D; +} + +void CCgUniformSampler2D::update(const void* data, const SMaterial& material) const +{ +} + +CCgMaterialRenderer::CCgMaterialRenderer(IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) : + CallBack(callback), BaseMaterial(baseMaterial), UserData(userData), + VertexProgram(0), FragmentProgram(0), GeometryProgram(0), VertexProfile(CG_PROFILE_UNKNOWN), FragmentProfile(CG_PROFILE_UNKNOWN), GeometryProfile(CG_PROFILE_UNKNOWN), + Material(IdentityMaterial), Error(CG_NO_ERROR) +{ + #ifdef _DEBUG + setDebugName("CCgMaterialRenderer"); + #endif + + if(BaseMaterial) + BaseMaterial->grab(); + + if(CallBack) + CallBack->grab(); +} + +CCgMaterialRenderer::~CCgMaterialRenderer() +{ + if(CallBack) + CallBack->drop(); + + if(BaseMaterial) + BaseMaterial->drop(); + + for(unsigned int i = 0; i < UniformInfo.size(); ++i) + delete UniformInfo[i]; + + UniformInfo.clear(); +} + +bool CCgMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + +void CCgMaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING); +} + +bool CCgMaterialRenderer::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + return setPixelShaderConstant(name, floats, count); +} + +bool CCgMaterialRenderer::setVertexShaderConstant(const c8* name, const bool* bools, int count) +{ + return setPixelShaderConstant(name, bools, count); +} + +bool CCgMaterialRenderer::setVertexShaderConstant(const c8* name, const s32* ints, int count) +{ + return setPixelShaderConstant(name, ints, count); +} + +void CCgMaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING); +} + +bool CCgMaterialRenderer::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + bool Status = false; + + for(unsigned int i = 0; i < UniformInfo.size(); ++i) + { + if(UniformInfo[i]->getName() == name) + { + UniformInfo[i]->update(floats, Material); + + Status = true; + } + } + + return Status; +} + +bool CCgMaterialRenderer::setPixelShaderConstant(const c8* name, const s32* ints, int count) +{ + bool Status = false; + + for(unsigned int i = 0; i < UniformInfo.size(); ++i) + { + if(UniformInfo[i]->getName() == name) + { + UniformInfo[i]->update(ints, Material); + + Status = true; + } + } + + return Status; +} + +bool CCgMaterialRenderer::setPixelShaderConstant(const c8* name, const bool* bools, int count) +{ + bool Status = false; + + for(unsigned int i = 0; i < UniformInfo.size(); ++i) + { + if(UniformInfo[i]->getName() == name) + { + UniformInfo[i]->update(bools, Material); + + Status = true; + } + } + + return Status; +} + +void CCgMaterialRenderer::getUniformList() +{ + for(unsigned int i = 0; i < UniformInfo.size(); ++i) + delete UniformInfo[i]; + + UniformInfo.clear(); + + for(unsigned int i = 0; i < 2; ++i) + { + CGenum Space = CG_GLOBAL; + bool IsGlobal = 1; + + if(i == 1) + { + Space = CG_PROGRAM; + IsGlobal = 0; + } + + for(unsigned int j = 0; j < 3; ++j) + { + CGprogram* Program = 0; + + switch(j) + { + case 0: + Program = &VertexProgram; + break; + case 1: + Program = &FragmentProgram; + break; + case 2: + Program = &GeometryProgram; + break; + } + + if(*Program) + { + CGparameter Parameter = cgGetFirstParameter(*Program, Space); + + while(Parameter) + { + if(cgGetParameterVariability(Parameter) == CG_UNIFORM && cgGetParameterDirection(Parameter) == CG_IN) + { + CCgUniform* Uniform = 0; + + CGtype Type = cgGetParameterType(Parameter); + + switch(Type) + { + case CG_FLOAT: + case CG_FLOAT1: + Uniform = new CCgUniform1f(Parameter, IsGlobal); + break; + case CG_FLOAT2: + Uniform = new CCgUniform2f(Parameter, IsGlobal); + break; + case CG_FLOAT3: + Uniform = new CCgUniform3f(Parameter, IsGlobal); + break; + case CG_FLOAT4: + Uniform = new CCgUniform4f(Parameter, IsGlobal); + break; + case CG_INT: + case CG_INT1: + Uniform = new CCgUniform1i(Parameter, IsGlobal); + break; + case CG_INT2: + Uniform = new CCgUniform2i(Parameter, IsGlobal); + break; + case CG_INT3: + Uniform = new CCgUniform3i(Parameter, IsGlobal); + break; + case CG_INT4: + Uniform = new CCgUniform4i(Parameter, IsGlobal); + break; + case CG_FLOAT4x4: + Uniform = new CCgUniform4x4f(Parameter, IsGlobal); + break; + case CG_SAMPLER2D: + Uniform = new CCgUniformSampler2D(Parameter, IsGlobal); + break; + } + + if(Uniform) + UniformInfo.push_back(Uniform); + } + + Parameter = cgGetNextParameter(Parameter); + } + } + } + } +} + +} +} + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.h new file mode 100644 index 0000000..8213f78 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCgMaterialRenderer.h @@ -0,0 +1,176 @@ +// Copyright (C) 2012 Patryk Nadrowski +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_CG_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_CG_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_CG_ + +#include "IMaterialRenderer.h" +#include "IMaterialRendererServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IGPUProgrammingServices.h" +#include "irrArray.h" +#include "irrString.h" +#include "IVideoDriver.h" +#include "os.h" +#include "Cg/cg.h" + +#ifdef _MSC_VER + #pragma comment(lib, "cg.lib") +#endif + +namespace irr +{ +namespace video +{ + +class CCgUniform +{ +public: + CCgUniform(const CGparameter& parameter, bool global); + + const core::stringc& getName() const; + const CGparameter& getParameter() const; + CGenum getSpace() const; + CGtype getType() const; + + virtual void update(const void* data, const SMaterial& material) const = 0; + +protected: + core::stringc Name; + CGparameter Parameter; + CGenum Space; + CGtype Type; +}; + +class CCgUniform1f : public CCgUniform +{ +public: + CCgUniform1f(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform2f : public CCgUniform +{ +public: + CCgUniform2f(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform3f : public CCgUniform +{ +public: + CCgUniform3f(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform4f : public CCgUniform +{ +public: + CCgUniform4f(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform1i : public CCgUniform +{ +public: + CCgUniform1i(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform2i : public CCgUniform +{ +public: + CCgUniform2i(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform3i : public CCgUniform +{ +public: + CCgUniform3i(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform4i : public CCgUniform +{ +public: + CCgUniform4i(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniform4x4f : public CCgUniform +{ +public: + CCgUniform4x4f(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgUniformSampler2D : public CCgUniform +{ +public: + CCgUniformSampler2D(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CCgMaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices +{ +public: + CCgMaterialRenderer(IShaderConstantSetCallBack* callback = 0, IMaterialRenderer* baseMaterial = 0, s32 userData = 0); + virtual ~CCgMaterialRenderer(); + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services) = 0; + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) = 0; + virtual void OnUnsetMaterial() = 0; + + virtual bool isTransparent() const; + + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) = 0; + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); + virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); + virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + virtual IVideoDriver* getVideoDriver() = 0; + +protected: + void getUniformList(); + + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + s32 UserData; + + core::array UniformInfo; + + CGprogram VertexProgram; + CGprogram FragmentProgram; + CGprogram GeometryProgram; + CGprofile VertexProfile; + CGprofile FragmentProfile; + CGprofile GeometryProfile; + + SMaterial Material; + CGerror Error; +}; + +} +} + +#endif +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.cpp new file mode 100644 index 0000000..6509812 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.cpp @@ -0,0 +1,2957 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ + +#include "CColladaFileLoader.h" +#include "os.h" +#include "IXMLReader.h" +#include "IDummyTransformationSceneNode.h" +#include "SAnimatedMesh.h" +#include "fast_atof.h" +#include "quaternion.h" +#include "ILightSceneNode.h" +#include "ICameraSceneNode.h" +#include "IMeshManipulator.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "IMeshCache.h" +#include "IMeshSceneNode.h" +#include "SMeshBufferLightMap.h" +#include "irrMap.h" + +#ifdef _DEBUG +#define COLLADA_READER_DEBUG +#endif +namespace irr +{ +namespace scene +{ +namespace +{ + // currently supported COLLADA tag names + const core::stringc colladaSectionName = "COLLADA"; + const core::stringc librarySectionName = "library"; + const core::stringc libraryNodesSectionName = "library_nodes"; + const core::stringc libraryGeometriesSectionName = "library_geometries"; + const core::stringc libraryMaterialsSectionName = "library_materials"; + const core::stringc libraryImagesSectionName = "library_images"; + const core::stringc libraryVisualScenesSectionName = "library_visual_scenes"; + const core::stringc libraryCamerasSectionName = "library_cameras"; + const core::stringc libraryLightsSectionName = "library_lights"; + const core::stringc libraryEffectsSectionName = "library_effects"; + const core::stringc assetSectionName = "asset"; + const core::stringc sceneSectionName = "scene"; + const core::stringc visualSceneSectionName = "visual_scene"; + + const core::stringc lightPrefabName = "light"; + const core::stringc cameraPrefabName = "camera"; + const core::stringc materialSectionName = "material"; + const core::stringc geometrySectionName = "geometry"; + const core::stringc imageSectionName = "image"; + const core::stringc textureSectionName = "texture"; + const core::stringc effectSectionName = "effect"; + + const core::stringc pointSectionName = "point"; + const core::stringc directionalSectionName ="directional"; + const core::stringc spotSectionName = "spot"; + const core::stringc ambientSectionName = "ambient"; + const core::stringc meshSectionName = "mesh"; + const core::stringc sourceSectionName = "source"; + const core::stringc arraySectionName = "array"; + const core::stringc floatArraySectionName ="float_array"; + const core::stringc intArraySectionName = "int_array"; + const core::stringc techniqueCommonSectionName = "technique_common"; + const core::stringc accessorSectionName = "accessor"; + const core::stringc verticesSectionName = "vertices"; + const core::stringc inputTagName = "input"; + const core::stringc polylistSectionName = "polylist"; + const core::stringc trianglesSectionName = "triangles"; + const core::stringc polygonsSectionName = "polygons"; + const core::stringc primitivesName = "p"; + const core::stringc vcountName = "vcount"; + + const core::stringc upAxisNodeName = "up_axis"; + const core::stringc nodeSectionName = "node"; + const core::stringc lookatNodeName = "lookat"; + const core::stringc matrixNodeName = "matrix"; + const core::stringc perspectiveNodeName = "perspective"; + const core::stringc rotateNodeName = "rotate"; + const core::stringc scaleNodeName = "scale"; + const core::stringc translateNodeName = "translate"; + const core::stringc skewNodeName = "skew"; + const core::stringc bboxNodeName = "boundingbox"; + const core::stringc minNodeName = "min"; + const core::stringc maxNodeName = "max"; + const core::stringc instanceName = "instance"; + const core::stringc instanceGeometryName = "instance_geometry"; + const core::stringc instanceSceneName = "instance_visual_scene"; + const core::stringc instanceEffectName = "instance_effect"; + const core::stringc instanceMaterialName = "instance_material"; + const core::stringc instanceLightName = "instance_light"; + const core::stringc instanceNodeName = "instance_node"; + const core::stringc bindMaterialName = "bind_material"; + const core::stringc extraNodeName = "extra"; + const core::stringc techniqueNodeName = "technique"; + const core::stringc colorNodeName = "color"; + const core::stringc floatNodeName = "float"; + const core::stringc float2NodeName = "float2"; + const core::stringc float3NodeName = "float3"; + + const core::stringc newParamName = "newparam"; + const core::stringc paramTagName = "param"; + const core::stringc initFromName = "init_from"; + const core::stringc dataName = "data"; + const core::stringc wrapsName = "wrap_s"; + const core::stringc wraptName = "wrap_t"; + const core::stringc minfilterName = "minfilter"; + const core::stringc magfilterName = "magfilter"; + const core::stringc mipfilterName = "mipfilter"; + + const core::stringc textureNodeName = "texture"; + const core::stringc doubleSidedNodeName = "double_sided"; + const core::stringc constantAttenuationNodeName = "constant_attenuation"; + const core::stringc linearAttenuationNodeName = "linear_attenuation"; + const core::stringc quadraticAttenuationNodeName = "quadratic_attenuation"; + const core::stringc falloffAngleNodeName = "falloff_angle"; + const core::stringc falloffExponentNodeName = "falloff_exponent"; + + const core::stringc profileCOMMONSectionName = "profile_COMMON"; + const core::stringc profileCOMMONAttributeName = "COMMON"; + + const char* const inputSemanticNames[] = {"POSITION", "VERTEX", "NORMAL", "TEXCOORD", + "UV", "TANGENT", "IMAGE", "TEXTURE", 0}; + + // We have to read ambient lights like other light types here, so we need a type for it + const video::E_LIGHT_TYPE ELT_AMBIENT = video::E_LIGHT_TYPE(video::ELT_COUNT+1); +} + + //! following class is for holding and creating instances of library + //! objects, named prefabs in this loader. + class CPrefab : public IColladaPrefab + { + public: + + CPrefab(const core::stringc& id) : Id(id) + { + } + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + // empty implementation + return 0; + } + + //! returns id of this prefab + virtual const core::stringc& getId() + { + return Id; + } + + protected: + + core::stringc Id; + }; + + + //! prefab for a light scene node + class CLightPrefab : public CPrefab + { + public: + + CLightPrefab(const core::stringc& id) : CPrefab(id) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: loaded light prefab", Id.c_str(), ELL_DEBUG); + #endif + } + + video::SLight LightData; // publically accessible + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing light instance", Id.c_str(), ELL_DEBUG); + #endif + + if ( LightData.Type == ELT_AMBIENT ) + { + mgr->setAmbientLight( LightData.DiffuseColor ); + return 0; + } + + scene::ILightSceneNode* l = mgr->addLightSceneNode(parent); + if (l) + { + l->setLightData ( LightData ); + l->setName(getId()); + } + return l; + } + }; + + + //! prefab for a mesh scene node + class CGeometryPrefab : public CPrefab + { + public: + + CGeometryPrefab(const core::stringc& id) : CPrefab(id) + { + } + + scene::IMesh* Mesh; + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing mesh instance", Id.c_str(), ELL_DEBUG); + #endif + + scene::ISceneNode* m = mgr->addMeshSceneNode(Mesh, parent); + if (m) + { + m->setName(getId()); +// m->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false); +// m->setDebugDataVisible(scene::EDS_FULL); + } + return m; + } + }; + + + //! prefab for a camera scene node + class CCameraPrefab : public CPrefab + { + public: + + CCameraPrefab(const core::stringc& id) + : CPrefab(id), YFov(core::PI / 2.5f), ZNear(1.0f), ZFar(3000.0f) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: loaded camera prefab", Id.c_str(), ELL_DEBUG); + #endif + } + + // publicly accessible data + f32 YFov; + f32 ZNear; + f32 ZFar; + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing camera instance", Id.c_str(), ELL_DEBUG); + #endif + + scene::ICameraSceneNode* c = mgr->addCameraSceneNode(parent); + if (c) + { + c->setFOV(YFov); + c->setNearValue(ZNear); + c->setFarValue(ZFar); + c->setName(getId()); + } + return c; + } + }; + + + //! prefab for a container scene node + //! Collects other prefabs and instantiates them upon instantiation + //! Uses a dummy scene node to return the children as one scene node + class CScenePrefab : public CPrefab + { + public: + CScenePrefab(const core::stringc& id) : CPrefab(id) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: loaded scene prefab", Id.c_str(), ELL_DEBUG); + #endif + } + + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Constructing scene instance", Id.c_str(), ELL_DEBUG); + #endif + + if (Children.size()==0) + return 0; + + scene::IDummyTransformationSceneNode* s = mgr->addDummyTransformationSceneNode(parent); + if (s) + { + s->setName(getId()); + s->getRelativeTransformationMatrix() = Transformation; + s->updateAbsolutePosition(); + core::stringc t; + for (u32 i=0; i<16; ++i) + { + t+=core::stringc((double)Transformation[i]); + t+=" "; + } + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA: Transformation", t.c_str(), ELL_DEBUG); + #endif + + for (u32 i=0; iaddInstance(s, mgr); + } + + return s; + } + + core::array Children; + core::matrix4 Transformation; + }; + + +//! Constructor +CColladaFileLoader::CColladaFileLoader(scene::ISceneManager* smgr, + io::IFileSystem* fs) +: SceneManager(smgr), FileSystem(fs), DummyMesh(0), + FirstLoadedMesh(0), LoadedMeshCount(0), CreateInstances(false) +{ + #ifdef _DEBUG + setDebugName("CColladaFileLoader"); + #endif +} + + +//! destructor +CColladaFileLoader::~CColladaFileLoader() +{ + if (DummyMesh) + DummyMesh->drop(); + + if (FirstLoadedMesh) + FirstLoadedMesh->drop(); +} + + +//! Returns true if the file maybe is able to be loaded by this class. +/** This decision should be based only on the file extension (e.g. ".cob") */ +bool CColladaFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "xml", "dae" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CColladaFileLoader::createMesh(io::IReadFile* file) +{ + io::IXMLReaderUTF8* reader = FileSystem->createXMLReaderUTF8(file); + if (!reader) + return 0; + + CurrentlyLoadingMesh = file->getFileName(); + CreateInstances = SceneManager->getParameters()->getAttributeAsBool( + scene::COLLADA_CREATE_SCENE_INSTANCES); + Version = 0; + FlipAxis = false; + + // read until COLLADA section, skip other parts + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (colladaSectionName == reader->getNodeName()) + readColladaSection(reader); + else + skipSection(reader, true); // unknown section + } + } + + reader->drop(); + if (!Version) + return 0; + + // because this loader loads and creates a complete scene instead of + // a single mesh, return an empty dummy mesh to make the scene manager + // know that everything went well. + if (!DummyMesh) + DummyMesh = new SAnimatedMesh(); + scene::IAnimatedMesh* returnMesh = DummyMesh; + + if (Version < 10400) + instantiateNode(SceneManager->getRootSceneNode()); + + // add the first loaded mesh into the mesh cache too, if more than one + // meshes have been loaded from the file + if (LoadedMeshCount>1 && FirstLoadedMesh) + { + os::Printer::log("Added COLLADA mesh", FirstLoadedMeshName.c_str()); + SceneManager->getMeshCache()->addMesh(FirstLoadedMeshName.c_str(), FirstLoadedMesh); + } + + // clean up temporary loaded data + clearData(); + + returnMesh->grab(); // store until this loader is destroyed + + DummyMesh->drop(); + DummyMesh = 0; + + if (FirstLoadedMesh) + FirstLoadedMesh->drop(); + FirstLoadedMesh = 0; + LoadedMeshCount = 0; + + return returnMesh; +} + + +//! skips an (unknown) section in the collada document +void CColladaFileLoader::skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping) +{ + #ifndef COLLADA_READER_DEBUG + if (reportSkipping) // always report in COLLADA_READER_DEBUG mode + #endif + os::Printer::log("COLLADA skipping section", core::stringc(reader->getNodeName()).c_str(), ELL_DEBUG); + + // skip if this element is empty anyway. + if (reader->isEmptyElement()) + return; + + // read until we've reached the last element in this section + u32 tagCounter = 1; + + while(tagCounter && reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + !reader->isEmptyElement()) + { + #ifdef COLLADA_READER_DEBUG + if (reportSkipping) + os::Printer::log("Skipping COLLADA unknown element", core::stringc(reader->getNodeName()).c_str(), ELL_DEBUG); + #endif + + ++tagCounter; + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + --tagCounter; + } +} + + +//! reads the section and its content +void CColladaFileLoader::readColladaSection(io::IXMLReaderUTF8* reader) +{ + if (reader->isEmptyElement()) + return; + + // todo: patch level needs to be handled + const f32 version = core::fast_atof(core::stringc(reader->getAttributeValue("version")).c_str()); + Version = core::floor32(version)*10000+core::round32(core::fract(version)*1000.0f); + // Version 1.4 can be checked for by if (Version >= 10400) + + while(reader->read()) + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (assetSectionName == reader->getNodeName()) + readAssetSection(reader); + else + if (librarySectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryNodesSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryGeometriesSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryMaterialsSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryEffectsSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryImagesSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryCamerasSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryLightsSectionName == reader->getNodeName()) + readLibrarySection(reader); + else + if (libraryVisualScenesSectionName == reader->getNodeName()) + readVisualScene(reader); + else + if (assetSectionName == reader->getNodeName()) + readAssetSection(reader); + else + if (sceneSectionName == reader->getNodeName()) + readSceneSection(reader); + else + { + os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING); + skipSection(reader, true); // unknown section + } + } +} + + +//! reads a section and its content +void CColladaFileLoader::readLibrarySection(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading library", ELL_DEBUG); + #endif + + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + // animation section tbd + if (cameraPrefabName == reader->getNodeName()) + readCameraPrefab(reader); + else + // code section tbd + // controller section tbd + if (geometrySectionName == reader->getNodeName()) + readGeometry(reader); + else + if (imageSectionName == reader->getNodeName()) + readImage(reader); + else + if (lightPrefabName == reader->getNodeName()) + readLightPrefab(reader); + else + if (materialSectionName == reader->getNodeName()) + readMaterial(reader); + else + if (nodeSectionName == reader->getNodeName()) + { + CScenePrefab p(""); + + readNodeSection(reader, SceneManager->getRootSceneNode(), &p); + } + else + if (effectSectionName == reader->getNodeName()) + readEffect(reader); + else + // program section tbd + if (textureSectionName == reader->getNodeName()) + readTexture(reader); + else + skipSection(reader, true); // unknown section, not all allowed supported yet + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (librarySectionName == reader->getNodeName()) + break; // end reading. + if (libraryNodesSectionName == reader->getNodeName()) + break; // end reading. + if (libraryGeometriesSectionName == reader->getNodeName()) + break; // end reading. + if (libraryMaterialsSectionName == reader->getNodeName()) + break; // end reading. + if (libraryEffectsSectionName == reader->getNodeName()) + break; // end reading. + if (libraryImagesSectionName == reader->getNodeName()) + break; // end reading. + if (libraryLightsSectionName == reader->getNodeName()) + break; // end reading. + if (libraryCamerasSectionName == reader->getNodeName()) + break; // end reading. + } + } +} + + +//! reads a element and stores it as a prefab +void CColladaFileLoader::readVisualScene(io::IXMLReaderUTF8* reader) +{ + CScenePrefab* p = 0; + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (visualSceneSectionName == reader->getNodeName()) + p = new CScenePrefab(readId(reader)); + else + if (p && nodeSectionName == reader->getNodeName()) // as a child of visual_scene + readNodeSection(reader, SceneManager->getRootSceneNode(), p); + else + if (assetSectionName == reader->getNodeName()) + readAssetSection(reader); + else + if (extraNodeName == reader->getNodeName()) + skipSection(reader, false); // ignore all other sections + else + { + os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING); + skipSection(reader, true); // ignore all other sections + } + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (libraryVisualScenesSectionName == reader->getNodeName()) + return; + else + if ((visualSceneSectionName == reader->getNodeName()) && p) + { + Prefabs.push_back(p); + p = 0; + } + } + } +} + + +//! reads a section and its content +void CColladaFileLoader::readSceneSection(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading scene", ELL_DEBUG); + #endif + + if (reader->isEmptyElement()) + return; + + // read the scene + + core::matrix4 transform; // transformation of this node + core::aabbox3df bbox; + scene::IDummyTransformationSceneNode* node = 0; + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (lookatNodeName == reader->getNodeName()) + transform *= readLookAtNode(reader); + else + if (matrixNodeName == reader->getNodeName()) + transform *= readMatrixNode(reader); + else + if (perspectiveNodeName == reader->getNodeName()) + transform *= readPerspectiveNode(reader); + else + if (rotateNodeName == reader->getNodeName()) + transform *= readRotateNode(reader); + else + if (scaleNodeName == reader->getNodeName()) + transform *= readScaleNode(reader); + else + if (skewNodeName == reader->getNodeName()) + transform *= readSkewNode(reader); + else + if (translateNodeName == reader->getNodeName()) + transform *= readTranslateNode(reader); + else + if (bboxNodeName == reader->getNodeName()) + readBboxNode(reader, bbox); + else + if (nodeSectionName == reader->getNodeName()) + { + // create dummy node if there is none yet. + if (!node) + node = SceneManager->addDummyTransformationSceneNode(SceneManager->getRootSceneNode()); + + readNodeSection(reader, node); + } + else + if ((instanceSceneName == reader->getNodeName())) + readInstanceNode(reader, SceneManager->getRootSceneNode(), 0, 0,instanceSceneName); + else + if (extraNodeName == reader->getNodeName()) + skipSection(reader, false); + else + { + os::Printer::log("COLLADA loader warning: Wrong tag usage found", reader->getNodeName(), ELL_WARNING); + skipSection(reader, true); // ignore all other sections + } + } + else + if ((reader->getNodeType() == io::EXN_ELEMENT_END) && + (sceneSectionName == reader->getNodeName())) + return; + } + if (node) + node->getRelativeTransformationMatrix() = transform; +} + + +//! reads a section and its content +void CColladaFileLoader::readAssetSection(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading asset", ELL_DEBUG); + #endif + + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (upAxisNodeName == reader->getNodeName()) + { + reader->read(); + FlipAxis = (core::stringc("Z_UP") == reader->getNodeData()); + } + } + else + if ((reader->getNodeType() == io::EXN_ELEMENT_END) && + (assetSectionName == reader->getNodeName())) + return; + } +} + + +//! reads a section and its content +void CColladaFileLoader::readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, CScenePrefab* p) +{ + if (reader->isEmptyElement()) + { + return; + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading empty node", ELL_DEBUG); + #endif + } + + core::stringc name = readId(reader); + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading node", name, ELL_DEBUG); + #endif + + core::matrix4 transform; // transformation of this node + core::aabbox3df bbox; + scene::ISceneNode* node = 0; // instance + CScenePrefab* nodeprefab = 0; // prefab for library_nodes usage + + if (p) + { + nodeprefab = new CScenePrefab(readId(reader)); + p->Children.push_back(nodeprefab); + Prefabs.push_back(nodeprefab); // in order to delete them later on + } + + // read the node + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (assetSectionName == reader->getNodeName()) + readAssetSection(reader); + else + if (lookatNodeName == reader->getNodeName()) + transform *= readLookAtNode(reader); + else + if (matrixNodeName == reader->getNodeName()) + transform *= readMatrixNode(reader); + else + if (perspectiveNodeName == reader->getNodeName()) + transform *= readPerspectiveNode(reader); + else + if (rotateNodeName == reader->getNodeName()) + transform *= readRotateNode(reader); + else + if (scaleNodeName == reader->getNodeName()) + transform *= readScaleNode(reader); + else + if (skewNodeName == reader->getNodeName()) + transform *= readSkewNode(reader); + else + if (translateNodeName == reader->getNodeName()) + transform *= readTranslateNode(reader); + else + if (bboxNodeName == reader->getNodeName()) + readBboxNode(reader, bbox); + else + if ((instanceName == reader->getNodeName()) || + (instanceNodeName == reader->getNodeName()) || + (instanceGeometryName == reader->getNodeName()) || + (instanceLightName == reader->getNodeName())) + { + scene::ISceneNode* newnode = 0; + readInstanceNode(reader, parent, &newnode, nodeprefab, reader->getNodeName()); + + if (node && newnode) + { + // move children from dummy to new node + ISceneNodeList::ConstIterator it = node->getChildren().begin(); + for (; it != node->getChildren().end(); it = node->getChildren().begin()) + (*it)->setParent(newnode); + + // remove previous dummy node + node->remove(); + node = newnode; + } + } + else + if (nodeSectionName == reader->getNodeName()) + { + // create dummy node if there is none yet. + if (CreateInstances && !node) + { + scene::IDummyTransformationSceneNode* dummy = + SceneManager->addDummyTransformationSceneNode(parent); + dummy->getRelativeTransformationMatrix() = transform; + node = dummy; + } + else + node = parent; + + // read and add child + readNodeSection(reader, node, nodeprefab); + } + else + if (extraNodeName == reader->getNodeName()) + skipSection(reader, false); + else + skipSection(reader, true); // ignore all other sections + + } // end if node + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (nodeSectionName == reader->getNodeName()) + break; + } + } + + if (nodeprefab) + nodeprefab->Transformation = transform; + else + if (node) + { + // set transformation correctly into node. + node->setPosition(transform.getTranslation()); + node->setRotation(transform.getRotationDegrees()); + node->setScale(transform.getScale()); + node->updateAbsolutePosition(); + + node->setName(name); + } +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readLookAtNode(io::IXMLReaderUTF8* reader) +{ + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading look at node", ELL_DEBUG); + #endif + + f32 floats[9]; + readFloatsInsideElement(reader, floats, 9); + + mat.buildCameraLookAtMatrixLH( + core::vector3df(floats[0], floats[1], floats[2]), + core::vector3df(floats[3], floats[4], floats[5]), + core::vector3df(floats[6], floats[7], floats[8])); + + return mat; +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readSkewNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading skew node", ELL_DEBUG); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[7]; // angle rotation-axis translation-axis + readFloatsInsideElement(reader, floats, 7); + + // build skew matrix from these 7 floats + core::quaternion q; + q.fromAngleAxis(floats[0]*core::DEGTORAD, core::vector3df(floats[1], floats[2], floats[3])); + mat = q.getMatrix(); + + if (floats[4]==1.f) // along x-axis + { + mat[4]=0.f; + mat[6]=0.f; + mat[8]=0.f; + mat[9]=0.f; + } + else + if (floats[5]==1.f) // along y-axis + { + mat[1]=0.f; + mat[2]=0.f; + mat[8]=0.f; + mat[9]=0.f; + } + else + if (floats[6]==1.f) // along z-axis + { + mat[1]=0.f; + mat[2]=0.f; + mat[4]=0.f; + mat[6]=0.f; + } + + return mat; +} + + +//! reads a element and its content and stores it in bbox +void CColladaFileLoader::readBboxNode(io::IXMLReaderUTF8* reader, + core::aabbox3df& bbox) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading boundingbox node", ELL_DEBUG); + #endif + + bbox.reset(core::aabbox3df()); + + if (reader->isEmptyElement()) + return; + + f32 floats[3]; + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (minNodeName == reader->getNodeName()) + { + readFloatsInsideElement(reader, floats, 3); + bbox.MinEdge.set(floats[0], floats[1], floats[2]); + } + else + if (maxNodeName == reader->getNodeName()) + { + readFloatsInsideElement(reader, floats, 3); + bbox.MaxEdge.set(floats[0], floats[1], floats[2]); + } + else + skipSection(reader, true); // ignore all other sections + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (bboxNodeName == reader->getNodeName()) + break; + } + } +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readMatrixNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading matrix node", ELL_DEBUG); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + readFloatsInsideElement(reader, mat.pointer(), 16); + // put translation into the correct place + if (FlipAxis) + { + core::matrix4 mat2(mat, core::matrix4::EM4CONST_TRANSPOSED); + mat2[1]=mat[8]; + mat2[2]=mat[4]; + mat2[4]=mat[2]; + mat2[5]=mat[10]; + mat2[6]=mat[6]; + mat2[8]=mat[1]; + mat2[9]=mat[9]; + mat2[10]=mat[5]; + mat2[12]=mat[3]; + mat2[13]=mat[11]; + mat2[14]=mat[7]; + return mat2; + } + else + return core::matrix4(mat, core::matrix4::EM4CONST_TRANSPOSED); +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readPerspectiveNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading perspective node", ELL_DEBUG); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[1]; + readFloatsInsideElement(reader, floats, 1); + + // TODO: build perspecitve matrix from this float + + os::Printer::log("COLLADA loader warning: not implemented yet.", ELL_WARNING); + + return mat; +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readRotateNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading rotate node", ELL_DEBUG); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[4]; + readFloatsInsideElement(reader, floats, 4); + + if (!core::iszero(floats[3])) + { + core::quaternion q; + if (FlipAxis) + q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[2], floats[1])); + else + q.fromAngleAxis(floats[3]*core::DEGTORAD, core::vector3df(floats[0], floats[1], floats[2])); + return q.getMatrix(); + } + else + return core::IdentityMatrix; +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readScaleNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading scale node", ELL_DEBUG); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[3]; + readFloatsInsideElement(reader, floats, 3); + + if (FlipAxis) + mat.setScale(core::vector3df(floats[0], floats[2], floats[1])); + else + mat.setScale(core::vector3df(floats[0], floats[1], floats[2])); + + return mat; +} + + +//! reads a element and its content and creates a matrix from it +core::matrix4 CColladaFileLoader::readTranslateNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading translate node", ELL_DEBUG); + #endif + + core::matrix4 mat; + if (reader->isEmptyElement()) + return mat; + + f32 floats[3]; + readFloatsInsideElement(reader, floats, 3); + + if (FlipAxis) + mat.setTranslation(core::vector3df(floats[0], floats[2], floats[1])); + else + mat.setTranslation(core::vector3df(floats[0], floats[1], floats[2])); + + return mat; +} + + +//! reads any kind of node +void CColladaFileLoader::readInstanceNode(io::IXMLReaderUTF8* reader, + scene::ISceneNode* parent, scene::ISceneNode** outNode, + CScenePrefab* p, const core::stringc& type) +{ + // find prefab of the specified id + core::stringc url = reader->getAttributeValue("url"); + uriToId(url); + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading instance", url, ELL_DEBUG); + #endif + + if (!reader->isEmptyElement()) + { + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (bindMaterialName == reader->getNodeName()) + readBindMaterialSection(reader,url); + else + if (extraNodeName == reader->getNodeName()) + skipSection(reader, false); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + break; + } + } + instantiateNode(parent, outNode, p, url, type); +} + + +void CColladaFileLoader::instantiateNode(scene::ISceneNode* parent, + scene::ISceneNode** outNode, CScenePrefab* p, const core::stringc& url, + const core::stringc& type) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA instantiate node", ELL_DEBUG); + #endif + + for (u32 i=0; igetId()) + { + if (p) + p->Children.push_back(Prefabs[i]); + else + if (CreateInstances) + { + scene::ISceneNode * newNode + = Prefabs[i]->addInstance(parent, SceneManager); + if (outNode) + { + *outNode = newNode; + if (*outNode) + (*outNode)->setName(url); + } + } + return; + } + } + if (p) + { + if (instanceGeometryName==type) + { + Prefabs.push_back(new CGeometryPrefab(url)); + p->Children.push_back(Prefabs.getLast()); + } + } +} + + +//! reads a element and stores it as prefab +void CColladaFileLoader::readCameraPrefab(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading camera prefab", ELL_DEBUG); + #endif + + CCameraPrefab* prefab = new CCameraPrefab(readId(reader)); + + if (!reader->isEmptyElement()) + { + // read techniques optics and imager (the latter is completely ignored, though) + readColladaParameters(reader, cameraPrefabName); + + SColladaParam* p; + + // XFOV not yet supported + p = getColladaParameter(ECPN_YFOV); + if (p && p->Type == ECPT_FLOAT) + prefab->YFov = p->Floats[0]; + + p = getColladaParameter(ECPN_ZNEAR); + if (p && p->Type == ECPT_FLOAT) + prefab->ZNear = p->Floats[0]; + + p = getColladaParameter(ECPN_ZFAR); + if (p && p->Type == ECPT_FLOAT) + prefab->ZFar = p->Floats[0]; + // orthographic camera uses LEFT, RIGHT, TOP, and BOTTOM + } + + Prefabs.push_back(prefab); +} + + +//! reads a element and stores it in the image section +void CColladaFileLoader::readImage(io::IXMLReaderUTF8* reader) +{ + // add image to list of loaded images. + Images.push_back(SColladaImage()); + SColladaImage& image=Images.getLast(); + + image.Id = readId(reader); + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading image", core::stringc(image.Id), ELL_DEBUG); + #endif + image.Dimension.Height = (u32)reader->getAttributeValueAsInt("height"); + image.Dimension.Width = (u32)reader->getAttributeValueAsInt("width"); + + if (Version >= 10400) // start with 1.4 + { + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (assetSectionName == reader->getNodeName()) + skipSection(reader, false); + else + if (initFromName == reader->getNodeName()) + { + reader->read(); + image.Source = reader->getNodeData(); + image.Source.trim(); + image.SourceIsFilename=true; + } + else + if (dataName == reader->getNodeName()) + { + reader->read(); + image.Source = reader->getNodeData(); + image.Source.trim(); + image.SourceIsFilename=false; + } + else + if (extraNodeName == reader->getNodeName()) + skipSection(reader, false); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (initFromName == reader->getNodeName()) + return; + } + } + } + else + { + image.Source = reader->getAttributeValue("source"); + image.Source.trim(); + image.SourceIsFilename=false; + } +} + + +//! reads a element and stores it in the texture section +void CColladaFileLoader::readTexture(io::IXMLReaderUTF8* reader) +{ + // add texture to list of loaded textures. + Textures.push_back(SColladaTexture()); + SColladaTexture& texture=Textures.getLast(); + + texture.Id = readId(reader); + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading texture", core::stringc(texture.Id), ELL_DEBUG); + #endif + + if (!reader->isEmptyElement()) + { + readColladaInputs(reader, textureSectionName); + SColladaInput* input = getColladaInput(ECIS_IMAGE); + if (input) + { + const core::stringc imageName = input->Source; + texture.Texture = getTextureFromImage(imageName, NULL); + } + } +} + + +//! reads a element and stores it in the material section +void CColladaFileLoader::readMaterial(io::IXMLReaderUTF8* reader) +{ + // add material to list of loaded materials. + Materials.push_back(SColladaMaterial()); + + SColladaMaterial& material = Materials.getLast(); + material.Id = readId(reader); + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading material", core::stringc(material.Id), ELL_DEBUG); + #endif + + if (Version >= 10400) + { + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + instanceEffectName == reader->getNodeName()) + { + material.InstanceEffectId = reader->getAttributeValue("url"); + uriToId(material.InstanceEffectId); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END && + materialSectionName == reader->getNodeName()) + { + break; + } + } // end while reader->read(); + } + else + { + if (!reader->isEmptyElement()) + { + readColladaInputs(reader, materialSectionName); + SColladaInput* input = getColladaInput(ECIS_TEXTURE); + if (input) + { + core::stringc textureName = input->Source; + uriToId(textureName); + for (u32 i=0; iType == ECPT_FLOAT3) + material.Mat.AmbientColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); + p = getColladaParameter(ECPN_DIFFUSE); + if (p && p->Type == ECPT_FLOAT3) + material.Mat.DiffuseColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); + p = getColladaParameter(ECPN_SPECULAR); + if (p && p->Type == ECPT_FLOAT3) + material.Mat.DiffuseColor = video::SColorf(p->Floats[0],p->Floats[1],p->Floats[2]).toSColor(); + p = getColladaParameter(ECPN_SHININESS); + if (p && p->Type == ECPT_FLOAT) + material.Mat.Shininess = p->Floats[0]; +#endif + } + } +} + +void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * effect) +{ + static const core::stringc constantNode("constant"); + static const core::stringc lambertNode("lambert"); + static const core::stringc phongNode("phong"); + static const core::stringc blinnNode("blinn"); + static const core::stringc emissionNode("emission"); + static const core::stringc ambientNode("ambient"); + static const core::stringc diffuseNode("diffuse"); + static const core::stringc specularNode("specular"); + static const core::stringc shininessNode("shininess"); + static const core::stringc reflectiveNode("reflective"); + static const core::stringc reflectivityNode("reflectivity"); + static const core::stringc transparentNode("transparent"); + static const core::stringc transparencyNode("transparency"); + static const core::stringc indexOfRefractionNode("index_of_refraction"); + + if (!effect) + { + Effects.push_back(SColladaEffect()); + effect = &Effects.getLast(); + effect->Parameters = new io::CAttributes(); + effect->Id = readId(reader); + effect->Transparency = 1.f; + effect->Mat.Lighting=true; + effect->Mat.NormalizeNormals=true; + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading effect", core::stringc(effect->Id), ELL_DEBUG); + #endif + } + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + // first come the tags we descend, but ignore the top-levels + if (!reader->isEmptyElement() && ((profileCOMMONSectionName == reader->getNodeName()) || + (techniqueNodeName == reader->getNodeName()))) + readEffect(reader,effect); + else + if (newParamName == reader->getNodeName()) + readParameter(reader, effect->Parameters); + else + // these are the actual materials inside technique + if (constantNode == reader->getNodeName() || + lambertNode == reader->getNodeName() || + phongNode == reader->getNodeName() || + blinnNode == reader->getNodeName()) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading effect part", reader->getNodeName(), ELL_DEBUG); + #endif + effect->Mat.setFlag(irr::video::EMF_GOURAUD_SHADING, + phongNode == reader->getNodeName() || + blinnNode == reader->getNodeName()); + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const core::stringc node = reader->getNodeName(); + if (emissionNode == node || ambientNode == node || + diffuseNode == node || specularNode == node || + reflectiveNode == node || transparentNode == node ) + { + // color or texture types + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + colorNodeName == reader->getNodeName()) + { + const video::SColorf colorf = readColorNode(reader); + const video::SColor color = colorf.toSColor(); + if (emissionNode == node) + effect->Mat.EmissiveColor = color; + else + if (ambientNode == node) + effect->Mat.AmbientColor = color; + else + if (diffuseNode == node) + effect->Mat.DiffuseColor = color; + else + if (specularNode == node) + effect->Mat.SpecularColor = color; + else + if (transparentNode == node) + effect->Transparency = colorf.getAlpha(); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT && + textureNodeName == reader->getNodeName()) + { + effect->Textures.push_back(reader->getAttributeValue("texture")); + break; + } + else + if (reader->getNodeType() == io::EXN_ELEMENT) + skipSection(reader, false); + else + if (reader->getNodeType() == io::EXN_ELEMENT_END && + node == reader->getNodeName()) + break; + } + } + else + if (shininessNode == node || reflectivityNode == node || + transparencyNode == node || indexOfRefractionNode == node ) + { + // float or param types + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + floatNodeName == reader->getNodeName()) + { + f32 f = readFloatNode(reader); + if (shininessNode == node) + effect->Mat.Shininess = f; + else + if (transparencyNode == node) + effect->Transparency *= f; + } + else + if (reader->getNodeType() == io::EXN_ELEMENT) + skipSection(reader, false); + else + if (reader->getNodeType() == io::EXN_ELEMENT_END && + node == reader->getNodeName()) + break; + } + } + else + skipSection(reader, true); // ignore all other nodes + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END && ( + constantNode == reader->getNodeName() || + lambertNode == reader->getNodeName() || + phongNode == reader->getNodeName() || + blinnNode == reader->getNodeName() + )) + break; + } + } + else + if (!reader->isEmptyElement() && (extraNodeName == reader->getNodeName())) + readEffect(reader,effect); + else + if (doubleSidedNodeName == reader->getNodeName()) + { + // read the GoogleEarth extra flag for double sided polys + s32 doubleSided = 0; + readIntsInsideElement(reader,&doubleSided,1); + if (doubleSided) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Setting double sided flag for effect.", ELL_DEBUG); + #endif + + effect->Mat.setFlag(irr::video::EMF_BACK_FACE_CULLING,false); + } + } + else + skipSection(reader, true); // ignore all other sections + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (effectSectionName == reader->getNodeName()) + break; + else + if (profileCOMMONSectionName == reader->getNodeName()) + break; + else + if (techniqueNodeName == reader->getNodeName()) + break; + else + if (extraNodeName == reader->getNodeName()) + break; + } + } + + if (effect->Mat.AmbientColor == video::SColor(0) && + effect->Mat.DiffuseColor != video::SColor(0)) + effect->Mat.AmbientColor = effect->Mat.DiffuseColor; + if (effect->Mat.DiffuseColor == video::SColor(0) && + effect->Mat.AmbientColor != video::SColor(0)) + effect->Mat.DiffuseColor = effect->Mat.AmbientColor; + if ((effect->Transparency != 0.0f) && (effect->Transparency != 1.0f)) + { + effect->Mat.MaterialType = irr::video::EMT_TRANSPARENT_VERTEX_ALPHA; + effect->Mat.ZWriteEnable = false; + } + + video::E_TEXTURE_CLAMP twu = video::ETC_REPEAT; + s32 idx = effect->Parameters->findAttribute(wrapsName.c_str()); + if ( idx >= 0 ) + twu = (video::E_TEXTURE_CLAMP)(effect->Parameters->getAttributeAsInt(idx)); + video::E_TEXTURE_CLAMP twv = video::ETC_REPEAT; + idx = effect->Parameters->findAttribute(wraptName.c_str()); + if ( idx >= 0 ) + twv = (video::E_TEXTURE_CLAMP)(effect->Parameters->getAttributeAsInt(idx)); + + for (u32 i=0; iMat.TextureLayer[i].TextureWrapU = twu; + effect->Mat.TextureLayer[i].TextureWrapV = twv; + } + + effect->Mat.setFlag(video::EMF_BILINEAR_FILTER, effect->Parameters->getAttributeAsBool("bilinear")); + effect->Mat.setFlag(video::EMF_TRILINEAR_FILTER, effect->Parameters->getAttributeAsBool("trilinear")); + effect->Mat.setFlag(video::EMF_ANISOTROPIC_FILTER, effect->Parameters->getAttributeAsBool("anisotropic")); +} + + +const SColladaMaterial* CColladaFileLoader::findMaterial(const core::stringc& materialName) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA find material", materialName, ELL_DEBUG); + #endif + + // do a quick lookup in the materials + SColladaMaterial matToFind; + matToFind.Id = materialName; + s32 mat = Materials.binary_search(matToFind); + if (mat == -1) + return 0; + // instantiate the material effect if needed + if (Materials[mat].InstanceEffectId.size() != 0) + { + // do a quick lookup in the effects + SColladaEffect effectToFind; + effectToFind.Id = Materials[mat].InstanceEffectId; + s32 effect = Effects.binary_search(effectToFind); + if (effect != -1) + { + // found the effect, instantiate by copying into the material + Materials[mat].Mat = Effects[effect].Mat; + if (Effects[effect].Textures.size()) + Materials[mat].Mat.setTexture(0, getTextureFromImage(Effects[effect].Textures[0], &(Effects[effect]))); + Materials[mat].Transparency = Effects[effect].Transparency; + // and indicate the material is instantiated by removing the effect ref + Materials[mat].InstanceEffectId = ""; + } + else + return 0; + } + return &Materials[mat]; +} + + +void CColladaFileLoader::readBindMaterialSection(io::IXMLReaderUTF8* reader, const core::stringc & id) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading bind material", ELL_DEBUG); + #endif + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (instanceMaterialName == reader->getNodeName()) + { + // the symbol to retarget, and the target material + core::stringc meshbufferReference = reader->getAttributeValue("symbol"); + if (meshbufferReference.size()==0) + continue; + core::stringc target = reader->getAttributeValue("target"); + uriToId(target); + if (target.size()==0) + continue; + const SColladaMaterial * material = findMaterial(target); + if (!material) + continue; + // bind any pending materials for this node + meshbufferReference = id+"/"+meshbufferReference; +#ifdef COLLADA_READER_DEBUG + os::Printer::log((core::stringc("Material binding: ")+meshbufferReference+" "+target).c_str(), ELL_DEBUG); +#endif + if (MaterialsToBind.find(meshbufferReference)) + { + core::array & toBind + = MeshesToBind[MaterialsToBind[meshbufferReference]]; +#ifdef COLLADA_READER_DEBUG + os::Printer::log("Material binding now ",material->Id.c_str(), ELL_DEBUG); + os::Printer::log("#meshbuffers",core::stringc(toBind.size()).c_str(), ELL_DEBUG); +#endif + SMesh tmpmesh; + for (u32 i = 0; i < toBind.size(); ++i) + { + toBind[i]->getMaterial() = material->Mat; + tmpmesh.addMeshBuffer(toBind[i]); + + if ((material->Transparency!=0.0f) && (material->Transparency!=1.0f)) + { + toBind[i]->getMaterial().MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + toBind[i]->getMaterial().ZWriteEnable = false; + } + } + SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,material->Mat.DiffuseColor); + if ((material->Transparency!=0.0f) && (material->Transparency!=1.0f)) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA found transparency material", core::stringc(material->Transparency).c_str(), ELL_DEBUG); + #endif + SceneManager->getMeshManipulator()->setVertexColorAlpha(&tmpmesh, core::floor32(material->Transparency*255.0f)); + } + } + } + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END && + bindMaterialName == reader->getNodeName()) + break; + } +} + + +//! reads a element and stores it as mesh if possible +void CColladaFileLoader::readGeometry(io::IXMLReaderUTF8* reader) +{ + core::stringc id = readId(reader); + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading geometry", id, ELL_DEBUG); + #endif + + SAnimatedMesh* amesh = new SAnimatedMesh(); + scene::SMesh* mesh = new SMesh(); + amesh->addMesh(mesh); + core::array sources; + bool okToReadArray = false; + + // handles geometry node and the mesh children in this loop + // read sources with arrays and accessor for each mesh + if (!reader->isEmptyElement()) + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const char* nodeName = reader->getNodeName(); + if (meshSectionName == nodeName) + { + // inside a mesh section. Don't have to do anything here. + } + else + if (sourceSectionName == nodeName) + { + // create a new source + sources.push_back(SSource()); + sources.getLast().Id = readId(reader); + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Reading source", sources.getLast().Id.c_str(), ELL_DEBUG); + #endif + } + else + if (arraySectionName == nodeName || floatArraySectionName == nodeName || intArraySectionName == nodeName) + { + // create a new array and read it. + if (!sources.empty()) + { + sources.getLast().Array.Name = readId(reader); + + int count = reader->getAttributeValueAsInt("count"); + sources.getLast().Array.Data.set_used(count); // pre allocate + + // check if type of array is ok + const char* type = reader->getAttributeValue("type"); + okToReadArray = (type && (!strcmp("float", type) || !strcmp("int", type))) || floatArraySectionName == nodeName || intArraySectionName == nodeName; + + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Read array", sources.getLast().Array.Name.c_str(), ELL_DEBUG); + #endif + } + #ifdef COLLADA_READER_DEBUG + else + os::Printer::log("Warning, array outside source found", + readId(reader).c_str(), ELL_DEBUG); + #endif + + } + else + if (accessorSectionName == nodeName) // child of source (below a technique tag) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Reading accessor", ELL_DEBUG); + #endif + SAccessor accessor; + accessor.Count = reader->getAttributeValueAsInt("count"); + accessor.Offset = reader->getAttributeValueAsInt("offset"); + accessor.Stride = reader->getAttributeValueAsInt("stride"); + if (accessor.Stride == 0) + accessor.Stride = 1; + + // the accessor contains some information on how to access (boi!) the array, + // the info is stored in collada style parameters, so just read them. + readColladaParameters(reader, accessorSectionName); + if (!sources.empty()) + { + sources.getLast().Accessors.push_back(accessor); + sources.getLast().Accessors.getLast().Parameters = ColladaParameters; + } + } + else + if (verticesSectionName == nodeName) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Reading vertices", ELL_DEBUG); + #endif + // read vertex input position source + readColladaInputs(reader, verticesSectionName); + } + else + // lines and linestrips missing + if (polygonsSectionName == nodeName || + polylistSectionName == nodeName || + trianglesSectionName == nodeName) + { + // read polygons section + readPolygonSection(reader, sources, mesh, id); + } + else + // trifans, and tristrips missing + if (doubleSidedNodeName == reader->getNodeName()) + { + // read the extra flag for double sided polys + s32 doubleSided = 0; + readIntsInsideElement(reader,&doubleSided,1); + if (doubleSided) + { + #ifdef COLLADA_READER_DEBUG + os::Printer::log("Setting double sided flag for mesh.", ELL_DEBUG); + #endif + amesh->setMaterialFlag(irr::video::EMF_BACK_FACE_CULLING,false); + } + } + else + // techniqueCommon or 'technique profile=common' must not be skipped + if ((techniqueCommonSectionName != nodeName) // Collada 1.2/1.3 + && (techniqueNodeName != nodeName) // Collada 1.4+ + && (extraNodeName != nodeName)) + { + os::Printer::log("COLLADA loader warning: Wrong tag usage found in geometry", reader->getNodeName(), ELL_WARNING); + skipSection(reader, true); // ignore all other sections + } + } // end if node type is element + else + if (reader->getNodeType() == io::EXN_TEXT) + { + // read array data + if (okToReadArray && !sources.empty()) + { + core::array& a = sources.getLast().Array.Data; + core::stringc data = reader->getNodeData(); + data.trim(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + { + if (geometrySectionName == reader->getNodeName()) + { + // end of geometry section reached, cancel out + break; + } + } + } // end while reader->read(); + + // add mesh as geometry + + mesh->recalculateBoundingBox(); + amesh->recalculateBoundingBox(); + + // create virtual file name + io::path filename = CurrentlyLoadingMesh; + filename += '#'; + filename += id; + + // add to scene manager + if (LoadedMeshCount) + { + SceneManager->getMeshCache()->addMesh(filename.c_str(), amesh); + os::Printer::log("Added COLLADA mesh", filename.c_str(), ELL_DEBUG); + } + else + { + FirstLoadedMeshName = filename; + FirstLoadedMesh = amesh; + FirstLoadedMesh->grab(); + } + + ++LoadedMeshCount; + mesh->drop(); + amesh->drop(); + + // create geometry prefab + u32 i; + for (i=0; igetId()==id) + { + ((CGeometryPrefab*)Prefabs[i])->Mesh=mesh; + break; + } + } + if (i==Prefabs.size()) + { + CGeometryPrefab* prefab = new CGeometryPrefab(id); + prefab->Mesh = mesh; + Prefabs.push_back(prefab); + } + + // store as dummy mesh if no instances will be created + if (!CreateInstances && !DummyMesh) + { + DummyMesh = amesh; + DummyMesh->grab(); + } +} + + +struct SPolygon +{ + core::array Indices; +}; + +//! reads a polygons section and creates a mesh from it +void CColladaFileLoader::readPolygonSection(io::IXMLReaderUTF8* reader, + core::array& sources, scene::SMesh* mesh, + const core::stringc& geometryId) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading polygon section", ELL_DEBUG); + #endif + + core::stringc materialName = reader->getAttributeValue("material"); + + core::stringc polygonType = reader->getNodeName(); + const int polygonCount = reader->getAttributeValueAsInt("count"); // Not useful because it only determines the number of primitives, which have arbitrary vertices in case of polygon + core::array polygons; + if (polygonType == polygonsSectionName) + polygons.reallocate(polygonCount); + core::array vCounts; + bool parsePolygonOK = false; + bool parseVcountOK = false; + u32 inputSemanticCount = 0; + bool unresolvedInput=false; + u32 maxOffset = 0; + core::array localInputs; + + // read all and primitives + if (!reader->isEmptyElement()) + while(reader->read()) + { + const char* nodeName = reader->getNodeName(); + + if (reader->getNodeType() == io::EXN_ELEMENT) + { + // polygon node may contain params + if (inputTagName == nodeName) + { + // read input tag + readColladaInput(reader, localInputs); + + // resolve input source + SColladaInput& inp = localInputs.getLast(); + + // get input source array id, if it is a vertex input, take + // the -source attribute. + if (inp.Semantic == ECIS_VERTEX) + { + inp.Source = Inputs[0].Source; + for (u32 i=1; igetNodeType() == io::EXN_ELEMENT_END) + { + if (primitivesName == nodeName) + parsePolygonOK = false; // end parsing a polygon + else + if (vcountName == nodeName) + parseVcountOK = false; // end parsing vcounts + else + if (polygonType == nodeName) + break; // cancel out and create mesh + + } // end is element end + else + if (reader->getNodeType() == io::EXN_TEXT) + { + if (parseVcountOK) + { + core::stringc data = reader->getNodeData(); + data.trim(); + const c8* p = &data[0]; + while(*p) + { + findNextNoneWhiteSpace(&p); + if (*p) + vCounts.push_back(readInt(&p)); + } + parseVcountOK = false; + } + else + if (parsePolygonOK && polygons.size()) + { + core::stringc data = reader->getNodeData(); + data.trim(); + const c8* p = &data[0]; + SPolygon& poly = polygons.getLast(); + if (polygonType == polygonsSectionName) + poly.Indices.reallocate((maxOffset+1)*3); + else + poly.Indices.reallocate(polygonCount*(maxOffset+1)*3); + + if (vCounts.empty()) + { + while(*p) + { + findNextNoneWhiteSpace(&p); + poly.Indices.push_back(readInt(&p)); + } + } + else + { + for (u32 i = 0; i < vCounts.size(); i++) + { + const int polyVCount = vCounts[i]; + core::array polyCorners; + + for (u32 j = 0; j < polyVCount * inputSemanticCount; j++) + { + if (!*p) + break; + findNextNoneWhiteSpace(&p); + polyCorners.push_back(readInt(&p)); + } + + while (polyCorners.size() >= 3 * inputSemanticCount) + { + // add one triangle's worth of indices + for (u32 k = 0; k < inputSemanticCount * 3; ++k) + { + poly.Indices.push_back(polyCorners[k]); + } + + // remove one corner from our poly + polyCorners.erase(inputSemanticCount,inputSemanticCount); + } + polyCorners.clear(); + } + vCounts.clear(); + } + parsePolygonOK = false; + } + } + } // end while reader->read() + + // find source array (we'll ignore accessors for this implementation) + for (u32 i=0; i vertMap; + + for (u32 i=0; i indices; + const u32 vertexCount = polygons[i].Indices.size() / maxOffset; + mbuffer->Vertices.reallocate(mbuffer->Vertices.size()+vertexCount); + + // for all index/semantic groups + for (u32 v=0; v::Node* n = vertMap.find(vtx); + if (n) + { + indices.push_back(n->getValue()); + } + else + { + indices.push_back(mbuffer->getVertexCount()); + mbuffer->Vertices.push_back(vtx); + vertMap.insert(vtx, mbuffer->getVertexCount()-1); + } + } // end for all vertices + + if (polygonsSectionName == polygonType && + indices.size() > 3) + { + // need to tesselate for polygons of 4 or more vertices + // for now we naively turn interpret it as a triangle fan + // as full tesselation is problematic + if (FlipAxis) + { + for (u32 ind = indices.size()-3; ind>0 ; --ind) + { + mbuffer->Indices.push_back(indices[0]); + mbuffer->Indices.push_back(indices[ind+2]); + mbuffer->Indices.push_back(indices[ind+1]); + } + } + else + { + for (u32 ind = 0; ind+2 < indices.size(); ++ind) + { + mbuffer->Indices.push_back(indices[0]); + mbuffer->Indices.push_back(indices[ind+1]); + mbuffer->Indices.push_back(indices[ind+2]); + } + } + } + else + { + // it's just triangles + for (u32 ind = 0; ind < indices.size(); ind+=3) + { + if (FlipAxis) + { + mbuffer->Indices.push_back(indices[ind+2]); + mbuffer->Indices.push_back(indices[ind+1]); + mbuffer->Indices.push_back(indices[ind+0]); + } + else + { + mbuffer->Indices.push_back(indices[ind+0]); + mbuffer->Indices.push_back(indices[ind+1]); + mbuffer->Indices.push_back(indices[ind+2]); + } + } + } + + } // end for all polygons + } + else + { + // lightmap mesh buffer + + scene::SMeshBufferLightMap* mbuffer = new SMeshBufferLightMap(); + buffer = mbuffer; + + for (u32 i=0; iVertices.reallocate(mbuffer->Vertices.size()+vertexCount); + // for all vertices in array + for (u32 v=0; vVertices.push_back(vtx); + + } // end for all vertices + + // add vertex indices + const u32 oldVertexCount = mbuffer->Vertices.size() - vertexCount; + for (u32 face=0; faceIndices.push_back(oldVertexCount + 0); + mbuffer->Indices.push_back(oldVertexCount + 1 + face); + mbuffer->Indices.push_back(oldVertexCount + 2 + face); + } + + } // end for all polygons + } + + const SColladaMaterial* m = findMaterial(materialName); + if (m) + { + buffer->getMaterial() = m->Mat; + SMesh tmpmesh; + tmpmesh.addMeshBuffer(buffer); + SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,m->Mat.DiffuseColor); + if (m->Transparency != 1.0f) + SceneManager->getMeshManipulator()->setVertexColorAlpha(&tmpmesh,core::floor32(m->Transparency*255.0f)); + } + // add future bind reference for the material + core::stringc meshbufferReference = geometryId+"/"+materialName; + if (!MaterialsToBind.find(meshbufferReference)) + { + MaterialsToBind[meshbufferReference] = MeshesToBind.size(); + MeshesToBind.push_back(core::array()); + } + MeshesToBind[MaterialsToBind[meshbufferReference]].push_back(buffer); + + // calculate normals if there is no slot for it + + if (!normalSlotCount) + SceneManager->getMeshManipulator()->recalculateNormals(buffer, true); + + // recalculate bounding box + buffer->recalculateBoundingBox(); + + // add mesh buffer + mesh->addMeshBuffer(buffer); + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA added meshbuffer", core::stringc(buffer->getVertexCount())+" vertices, "+core::stringc(buffer->getIndexCount())+" indices.", ELL_DEBUG); + #endif + + buffer->drop(); +} + + +//! reads a element and stores it as prefab +void CColladaFileLoader::readLightPrefab(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading light prefab", ELL_DEBUG); + #endif + + CLightPrefab* prefab = new CLightPrefab(readId(reader)); + + if (!reader->isEmptyElement()) + { + if (Version >= 10400) // start with 1.4 + { + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (pointSectionName == reader->getNodeName()) + prefab->LightData.Type=video::ELT_POINT; + else + if (directionalSectionName == reader->getNodeName()) + prefab->LightData.Type=video::ELT_DIRECTIONAL; + else + if (spotSectionName == reader->getNodeName()) + prefab->LightData.Type=video::ELT_SPOT; + else + if (ambientSectionName == reader->getNodeName()) + prefab->LightData.Type=ELT_AMBIENT; + else + if (colorNodeName == reader->getNodeName()) + prefab->LightData.DiffuseColor=readColorNode(reader); + else + if (constantAttenuationNodeName == reader->getNodeName()) + readFloatsInsideElement(reader,&prefab->LightData.Attenuation.X,1); + else + if (linearAttenuationNodeName == reader->getNodeName()) + readFloatsInsideElement(reader,&prefab->LightData.Attenuation.Y,1); + else + if (quadraticAttenuationNodeName == reader->getNodeName()) + readFloatsInsideElement(reader,&prefab->LightData.Attenuation.Z,1); + else + if (falloffAngleNodeName == reader->getNodeName()) + { + readFloatsInsideElement(reader,&prefab->LightData.OuterCone,1); + prefab->LightData.OuterCone *= core::DEGTORAD; + } + else + if (falloffExponentNodeName == reader->getNodeName()) + readFloatsInsideElement(reader,&prefab->LightData.Falloff,1); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if ((pointSectionName == reader->getNodeName()) || + (directionalSectionName == reader->getNodeName()) || + (spotSectionName == reader->getNodeName()) || + (ambientSectionName == reader->getNodeName())) + break; + } + } + } + else + { + readColladaParameters(reader, lightPrefabName); + + SColladaParam* p = getColladaParameter(ECPN_COLOR); + if (p && p->Type == ECPT_FLOAT3) + prefab->LightData.DiffuseColor.set(p->Floats[0], p->Floats[1], p->Floats[2]); + } + } + + Prefabs.push_back(prefab); +} + + +//! returns a collada parameter or none if not found +SColladaParam* CColladaFileLoader::getColladaParameter(ECOLLADA_PARAM_NAME name) +{ + for (u32 i=0; i& inputs) +{ + // parse param + SColladaInput p; + + // get type + core::stringc semanticName = reader->getAttributeValue("semantic"); + for (u32 i=0; inputSemanticNames[i]; ++i) + { + if (semanticName == inputSemanticNames[i]) + { + p.Semantic = (ECOLLADA_INPUT_SEMANTIC)i; + break; + } + } + + // get source + p.Source = reader->getAttributeValue("source"); + if (reader->getAttributeValue("offset")) // Collada 1.4+ + p.Offset = (u32)reader->getAttributeValueAsInt("offset"); + else // Collada 1.2/1.3 + p.Offset = (u32)reader->getAttributeValueAsInt("idx"); + p.Set = (u32)reader->getAttributeValueAsInt("set"); + + // add input + inputs.push_back(p); +} + +//! parses all collada inputs inside an element and stores them in Inputs +void CColladaFileLoader::readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName) +{ + Inputs.clear(); + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + inputTagName == reader->getNodeName()) + { + readColladaInput(reader, Inputs); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (parentName == reader->getNodeName()) + return; // end of parent reached + } + + } // end while reader->read(); +} + +//! parses all collada parameters inside an element and stores them in ColladaParameters +void CColladaFileLoader::readColladaParameters(io::IXMLReaderUTF8* reader, + const core::stringc& parentName) +{ + ColladaParameters.clear(); + + const char* const paramNames[] = {"COLOR", "AMBIENT", "DIFFUSE", + "SPECULAR", "SHININESS", "YFOV", "ZNEAR", "ZFAR", 0}; + + const char* const typeNames[] = {"float", "float2", "float3", 0}; + + while(reader->read()) + { + const char* nodeName = reader->getNodeName(); + if (reader->getNodeType() == io::EXN_ELEMENT && + paramTagName == nodeName) + { + // parse param + SColladaParam p; + + // get type + u32 i; + core::stringc typeName = reader->getAttributeValue("type"); + for (i=0; typeNames[i]; ++i) + if (typeName == typeNames[i]) + { + p.Type = (ECOLLADA_PARAM_TYPE)i; + break; + } + + // get name + core::stringc nameName = reader->getAttributeValue("name"); + for (i=0; typeNames[i]; ++i) + if (nameName == paramNames[i]) + { + p.Name = (ECOLLADA_PARAM_NAME)i; + break; + } + + // read parameter data inside parameter tags + switch(p.Type) + { + case ECPT_FLOAT: + case ECPT_FLOAT2: + case ECPT_FLOAT3: + case ECPT_FLOAT4: + readFloatsInsideElement(reader, p.Floats, p.Type - ECPT_FLOAT + 1); + break; + + // TODO: other types of data (ints, bools or whatever) + default: + break; + } + + // add param + ColladaParameters.push_back(p); + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (parentName == reader->getNodeName()) + return; // end of parent reached + } + + } // end while reader->read(); +} + + +//! parses a float from a char pointer and moves the pointer +//! to the end of the parsed float +inline f32 CColladaFileLoader::readFloat(const c8** p) +{ + f32 ftmp; + *p = core::fast_atof_move(*p, ftmp); + return ftmp; +} + + +//! parses an int from a char pointer and moves the pointer to +//! the end of the parsed float +inline s32 CColladaFileLoader::readInt(const c8** p) +{ + return (s32)readFloat(p); +} + + +//! places pointer to next begin of a token +void CColladaFileLoader::findNextNoneWhiteSpace(const c8** start) +{ + const c8* p = *start; + + while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) + ++p; + + // TODO: skip comments + + *start = p; +} + + +//! reads floats from inside of xml element until end of xml element +void CColladaFileLoader::readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count) +{ + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + // TODO: check for comments inside the element + // and ignore them. + + if (reader->getNodeType() == io::EXN_TEXT) + { + // parse float data + core::stringc data = reader->getNodeData(); + data.trim(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + break; // end parsing text + } +} + + +//! reads ints from inside of xml element until end of xml element +void CColladaFileLoader::readIntsInsideElement(io::IXMLReaderUTF8* reader, s32* ints, u32 count) +{ + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + // TODO: check for comments inside the element + // and ignore them. + + if (reader->getNodeType() == io::EXN_TEXT) + { + // parse float data + core::stringc data = reader->getNodeData(); + data.trim(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + break; // end parsing text + } +} + + +video::SColorf CColladaFileLoader::readColorNode(io::IXMLReaderUTF8* reader) +{ + if (reader->getNodeType() == io::EXN_ELEMENT && + colorNodeName == reader->getNodeName()) + { + f32 color[4]; + readFloatsInsideElement(reader,color,4); + return video::SColorf(color[0], color[1], color[2], color[3]); + } + + return video::SColorf(); +} + + +f32 CColladaFileLoader::readFloatNode(io::IXMLReaderUTF8* reader) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading ", ELL_DEBUG); + #endif + + f32 result = 0.0f; + if (reader->getNodeType() == io::EXN_ELEMENT && + floatNodeName == reader->getNodeName()) + { + readFloatsInsideElement(reader,&result,1); + } + + return result; +} + + +//! clears all loaded data +void CColladaFileLoader::clearData() +{ + // delete all prefabs + + for (u32 i=0; idrop(); + + Prefabs.clear(); + + // clear all parameters + ColladaParameters.clear(); + + // clear all materials + Images.clear(); + + // clear all materials + Textures.clear(); + + // clear all materials + Materials.clear(); + + // clear all inputs + Inputs.clear(); + + // clear all effects + for ( u32 i=0; idrop(); + Effects.clear(); + + // clear all the materials to bind + MaterialsToBind.clear(); + MeshesToBind.clear(); +} + + +//! changes the XML URI into an internal id +void CColladaFileLoader::uriToId(core::stringc& str) +{ + // currently, we only remove the # from the begin if there + // because we simply don't support referencing other files. + if (!str.size()) + return; + + if (str[0] == '#') + str.erase(0); +} + + +//! read Collada Id, uses id or name if id is missing +core::stringc CColladaFileLoader::readId(io::IXMLReaderUTF8* reader) +{ + core::stringc id = reader->getAttributeValue("id"); + if (id.size()==0) + id = reader->getAttributeValue("name"); + return id; +} + + +//! create an Irrlicht texture from the reference +video::ITexture* CColladaFileLoader::getTextureFromImage(core::stringc uri, SColladaEffect * effect) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA searching texture", uri, ELL_DEBUG); + #endif + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + for (;;) + { + uriToId(uri); + for (u32 i=0; iexistFile(Images[i].Source)) + return driver->getTexture(Images[i].Source); + return driver->getTexture((FileSystem->getFileDir(CurrentlyLoadingMesh)+"/"+Images[i].Source)); + } + else + if (Images[i].Source.size()) + { + //const u32 size = Images[i].Dimension.getArea(); + const u32 size = Images[i].Dimension.Width * Images[i].Dimension.Height;; + u32* data = new u32[size]; // we assume RGBA + u32* ptrdest = data; + const c8* ptrsrc = Images[i].Source.c_str(); + for (u32 j=0; jcreateImageFromData(video::ECF_A8R8G8B8, Images[i].Dimension, data, true, true); + video::ITexture* tex = driver->addTexture((CurrentlyLoadingMesh+"#"+Images[i].Id).c_str(), img); + img->drop(); + return tex; + } + break; + } + } + if (effect && effect->Parameters->getAttributeType(uri.c_str())==io::EAT_STRING) + { + uri = effect->Parameters->getAttributeAsString(uri.c_str()); +#ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA now searching texture", uri.c_str(), ELL_DEBUG); +#endif + } + else + break; + } + return 0; +} + + +//! read a parameter and value +void CColladaFileLoader::readParameter(io::IXMLReaderUTF8* reader, io::IAttributes* parameters) +{ + #ifdef COLLADA_READER_DEBUG + os::Printer::log("COLLADA reading parameter", ELL_DEBUG); + #endif + + if ( !parameters ) + return; + + const core::stringc name = reader->getAttributeValue("sid"); + if (!reader->isEmptyElement()) + { + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (floatNodeName == reader->getNodeName()) + { + const f32 f = readFloatNode(reader); + parameters->addFloat(name.c_str(), f); + } + else + if (float2NodeName == reader->getNodeName()) + { + f32 f[2]; + readFloatsInsideElement(reader, f, 2); +// Parameters.addVector2d(name.c_str(), core::vector2df(f[0],f[1])); + } + else + if (float3NodeName == reader->getNodeName()) + { + f32 f[3]; + readFloatsInsideElement(reader, f, 3); + parameters->addVector3d(name.c_str(), core::vector3df(f[0],f[1],f[2])); + } + else + if ((initFromName == reader->getNodeName()) || + (sourceSectionName == reader->getNodeName())) + { + reader->read(); + parameters->addString(name.c_str(), reader->getNodeData()); + } + else + if (wrapsName == reader->getNodeName()) + { + reader->read(); + const core::stringc val = reader->getNodeData(); + if (val == "WRAP") + parameters->addInt(wrapsName.c_str(), (int)video::ETC_REPEAT); + else if ( val== "MIRROR") + parameters->addInt(wrapsName.c_str(), (int)video::ETC_MIRROR); + else if ( val== "CLAMP") + parameters->addInt(wrapsName.c_str(), (int)video::ETC_CLAMP_TO_EDGE); + else if ( val== "BORDER") + parameters->addInt(wrapsName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); + else if ( val== "NONE") + parameters->addInt(wrapsName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); + } + else + if (wraptName == reader->getNodeName()) + { + reader->read(); + const core::stringc val = reader->getNodeData(); + if (val == "WRAP") + parameters->addInt(wraptName.c_str(), (int)video::ETC_REPEAT); + else if ( val== "MIRROR") + parameters->addInt(wraptName.c_str(), (int)video::ETC_MIRROR); + else if ( val== "CLAMP") + parameters->addInt(wraptName.c_str(), (int)video::ETC_CLAMP_TO_EDGE); + else if ( val== "BORDER") + parameters->addInt(wraptName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); + else if ( val== "NONE") + parameters->addInt(wraptName.c_str(), (int)video::ETC_CLAMP_TO_BORDER); + } + else + if (minfilterName == reader->getNodeName()) + { + reader->read(); + const core::stringc val = reader->getNodeData(); + if (val == "LINEAR_MIPMAP_LINEAR") + parameters->addBool("trilinear", true); + else + if (val == "LINEAR_MIPMAP_NEAREST") + parameters->addBool("bilinear", true); + } + else + if (magfilterName == reader->getNodeName()) + { + reader->read(); + const core::stringc val = reader->getNodeData(); + if (val != "LINEAR") + { + parameters->addBool("bilinear", false); + parameters->addBool("trilinear", false); + } + } + else + if (mipfilterName == reader->getNodeName()) + { + parameters->addBool("anisotropic", true); + } + } + else + if(reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (newParamName == reader->getNodeName()) + break; + } + } + } +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_COLLADA_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.h new file mode 100644 index 0000000..df1a551 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaFileLoader.h @@ -0,0 +1,389 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "ISceneManager.h" +#include "irrMap.h" +#include "CAttributes.h" + +namespace irr +{ +namespace scene +{ + +#ifdef _DEBUG +//#define COLLADA_READER_DEBUG +#endif + +class IColladaPrefab; + +enum ECOLLADA_PARAM_NAME +{ + ECPN_COLOR = 0, + ECPN_AMBIENT, + ECPN_DIFFUSE, + ECPN_SPECULAR, + ECPN_SHININESS, + ECPN_TRANSPARENCY, + ECPN_YFOV, + ECPN_ZNEAR, + ECPN_ZFAR, + + ECPN_COUNT +}; + +enum ECOLLADA_PARAM_TYPE +{ + ECPT_FLOAT = 0, + ECPT_FLOAT2, + ECPT_FLOAT3, + ECPT_FLOAT4, + + ECPT_COUNT +}; + +//! Collada Parameter +struct SColladaParam +{ + SColladaParam() + : Name(ECPN_COUNT), Type(ECPT_COUNT) + { + for (int i=0; i<4; ++i) Floats[i] = 0; + } + + ECOLLADA_PARAM_NAME Name; + ECOLLADA_PARAM_TYPE Type; + + f32 Floats[4]; +}; + +enum ECOLLADA_INPUT_SEMANTIC +{ + ECIS_POSITION = 0, + ECIS_VERTEX, + ECIS_NORMAL, + ECIS_TEXCOORD, + ECIS_UV, + ECIS_TANGENT, + ECIS_IMAGE, + ECIS_TEXTURE, + + ECIS_COUNT +}; + +//! Collada Input +struct SColladaInput +{ + SColladaInput() + : Semantic(ECIS_COUNT), Data(0), Offset(0), Set(0), Stride(1) + { + } + + ECOLLADA_INPUT_SEMANTIC Semantic; + core::stringc Source; + f32* Data; + u32 Offset; + u32 Set; + u32 Stride; +}; + +//! Collada images +struct SColladaImage +{ + core::stringc Id; + core::stringc Source; + core::dimension2du Dimension; + bool SourceIsFilename; +}; + + +//! Collada texture +struct SColladaTexture +{ + video::ITexture* Texture; + core::stringc Id; +}; + + +//! Collada material +struct SColladaMaterial +{ + video::SMaterial Mat; + core::stringc Id; + core::stringc InstanceEffectId; + f32 Transparency; + + inline bool operator< (const SColladaMaterial & other) const + { + return Id < other.Id; + } +}; + +//! Collada effect (materials, shaders, and programs) +struct SColladaEffect +{ + core::stringc Id; + f32 Transparency; + core::array Textures; + video::SMaterial Mat; + // TODO: Parameters looks somewhat lazy workaround, I think we should really read all parameters correct. + io::IAttributes * Parameters; + + inline bool operator< (const SColladaEffect & other) const + { + return Id < other.Id; + } +}; + + +struct SNumberArray // for storing float and int arrays +{ + core::stringc Name; + core::array Data; +}; + +struct SAccessor +{ + SAccessor() + : Count(0), Offset(0), Stride(1) {} + // I don't store the source of the accessor here because I assume + // it to use the array of the source this accessor is located in. + + int Count; + int Offset; + int Stride; + + core::array Parameters; // parameters defining the accessor +}; + +struct SSource +{ + core::stringc Id; + SNumberArray Array; + core::array Accessors; +}; + +class CScenePrefab; + +//! Meshloader capable of loading COLLADA meshes and scene descriptions into Irrlicht. +class CColladaFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CColladaFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~CColladaFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + //! skips an (unknown) section in the collada document + void skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping); + + //! reads the section and its content + void readColladaSection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readLibrarySection(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it as a prefab + void readVisualScene(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readSceneSection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + void readAssetSection(io::IXMLReaderUTF8* reader); + + //! reads a section and its content + //! if a prefab pointer is passed the nodes are created as scene prefabs children of that prefab + void readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, CScenePrefab* p=0); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readLookAtNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readMatrixNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readPerspectiveNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readRotateNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readSkewNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and stores it in bbox + void readBboxNode(io::IXMLReaderUTF8* reader, core::aabbox3df& bbox); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader); + + //! reads a element and its content and creates a matrix from it + core::matrix4 readTranslateNode(io::IXMLReaderUTF8* reader); + + //! reads a element + video::SColorf readColorNode(io::IXMLReaderUTF8* reader); + + //! reads a element + f32 readFloatNode(io::IXMLReaderUTF8* reader); + + //! reads a node + void readInstanceNode(io::IXMLReaderUTF8* reader, + scene::ISceneNode* parent, scene::ISceneNode** outNode, + CScenePrefab* p=0, const core::stringc& type=core::stringc()); + + //! creates a scene node from Prefabs (with name given in 'url') + void instantiateNode(scene::ISceneNode* parent, scene::ISceneNode** outNode=0, + CScenePrefab* p=0, const core::stringc& url="", + const core::stringc& type=core::stringc()); + + //! reads a element and stores it as prefab + void readLightPrefab(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it as prefab + void readCameraPrefab(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the image section + void readImage(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the texture section + void readTexture(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the material section + void readMaterial(io::IXMLReaderUTF8* reader); + + //! reads a element and stores it in the effects section + void readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * effect = 0); + + //! reads a element and stores it as mesh if possible + void readGeometry(io::IXMLReaderUTF8* reader); + + //! parses a float from a char pointer and moves the pointer to + //! the end of the parsed float + inline f32 readFloat(const c8** p); + + //! parses an int from a char pointer and moves the pointer to + //! the end of the parsed float + inline s32 readInt(const c8** p); + + //! places pointer to next begin of a token + void findNextNoneWhiteSpace(const c8** p); + + //! reads floats from inside of xml element until end of xml element + void readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count); + + //! reads ints from inside of xml element until end of xml element + void readIntsInsideElement(io::IXMLReaderUTF8* reader, s32* ints, u32 count); + + //! clears all loaded data + void clearData(); + + //! parses all collada parameters inside an element and stores them in ColladaParameters + void readColladaParameters(io::IXMLReaderUTF8* reader, const core::stringc& parentName); + + //! returns a collada parameter or none if not found + SColladaParam* getColladaParameter(ECOLLADA_PARAM_NAME name); + + //! parses all collada inputs inside an element and stores them in Inputs. Reads + //! until first tag which is not an input tag or the end of the parent is reached + void readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName); + + //! reads a collada input tag and adds it to the input parameter + void readColladaInput(io::IXMLReaderUTF8* reader, core::array& inputs); + + //! returns a collada input or none if not found + SColladaInput* getColladaInput(ECOLLADA_INPUT_SEMANTIC input); + + //! read Collada Id, uses id or name if id is missing + core::stringc readId(io::IXMLReaderUTF8* reader); + + //! changes the XML URI into an internal id + void uriToId(core::stringc& str); + + //! reads a polygons section and creates a mesh from it + void readPolygonSection(io::IXMLReaderUTF8* reader, + core::array& sources, scene::SMesh* mesh, + const core::stringc& geometryId); + + //! finds a material, possible instancing it + const SColladaMaterial * findMaterial(const core::stringc & materialName); + + //! reads and bind materials as given by the symbol->target bind mapping + void readBindMaterialSection(io::IXMLReaderUTF8* reader, const core::stringc & id); + + //! create an Irrlicht texture from the SColladaImage + video::ITexture* getTextureFromImage(core::stringc uri, SColladaEffect * effect); + + //! read a parameter and value + void readParameter(io::IXMLReaderUTF8* reader, io::IAttributes* parameters); + + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + + scene::IAnimatedMesh* DummyMesh; + core::stringc CurrentlyLoadingMesh; + + scene::IAnimatedMesh* FirstLoadedMesh; + io::path FirstLoadedMeshName; + s32 LoadedMeshCount; + u32 Version; + bool FlipAxis; + + core::array Prefabs; + core::array ColladaParameters; + core::array Images; + core::array Textures; + core::array Materials; + core::array Inputs; + core::array Effects; + //! meshbuffer reference ("geomid/matname") -> index into MeshesToBind + core::map MaterialsToBind; + //! Array of buffers for each material binding + core::array< core::array > MeshesToBind; + + bool CreateInstances; +}; + + + +//! following class is for holding and createing instances of library objects, +//! named prefabs in this loader. +class IColladaPrefab : public virtual IReferenceCounted +{ +public: + //! creates an instance of this prefab + virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent, + scene::ISceneManager* mgr) = 0; + + //! returns id of this prefab + virtual const core::stringc& getId() = 0; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.cpp new file mode 100644 index 0000000..e5b6df5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.cpp @@ -0,0 +1,2245 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// TODO: second UV-coordinates currently ignored in textures + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_ + +#include "CColladaMeshWriter.h" +#include "os.h" +#include "IFileSystem.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" +#include "IMesh.h" +#include "IAttributes.h" +#include "IAnimatedMeshSceneNode.h" +#include "IMeshSceneNode.h" +#include "ITerrainSceneNode.h" +#include "ILightSceneNode.h" +#include "ICameraSceneNode.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! Which lighting model should be used in the technique (FX) section when exporting effects (materials) +E_COLLADA_TECHNIQUE_FX CColladaMeshWriterProperties::getTechniqueFx(const video::SMaterial& material) const +{ + return ECTF_BLINN; +} + +//! Which texture index should be used when writing the texture of the given sampler color. +s32 CColladaMeshWriterProperties::getTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const +{ + // So far we just export in a way which is similar to how we import colladas. + // There might be better ways to do this, but I suppose it depends a lot for which target + // application we export, so in most cases it will have to be done in user-code anyway. + switch ( cs ) + { + case ECCS_DIFFUSE: + return 2; + case ECCS_AMBIENT: + return 1; + case ECCS_EMISSIVE: + return 0; + case ECCS_SPECULAR: + return 3; + case ECCS_TRANSPARENT: + return -1; + case ECCS_REFLECTIVE: + return -1; + }; + return -1; +} + +E_COLLADA_IRR_COLOR CColladaMeshWriterProperties::getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const +{ + switch ( cs ) + { + case ECCS_DIFFUSE: + return ECIC_DIFFUSE; + case ECCS_AMBIENT: + return ECIC_AMBIENT; + case ECCS_EMISSIVE: + return ECIC_EMISSIVE; + case ECCS_SPECULAR: + return ECIC_SPECULAR; + case ECCS_TRANSPARENT: + return ECIC_NONE; + case ECCS_REFLECTIVE: + return ECIC_CUSTOM; + }; + + return ECIC_NONE; +} + +//! Return custom colors for certain color types requested by collada. +video::SColor CColladaMeshWriterProperties::getCustomColor(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const +{ + return video::SColor(255, 0, 0, 0); +} + + +//! Return the settings for transparence +E_COLLADA_TRANSPARENT_FX CColladaMeshWriterProperties::getTransparentFx(const video::SMaterial& material) const +{ + // TODO: figure out best default mapping + return ECOF_A_ONE; +} + +//! Transparency value for the material. +f32 CColladaMeshWriterProperties::getTransparency(const video::SMaterial& material) const +{ + // TODO: figure out best default mapping + return -1.f; +} + +//! Reflectivity value for that material +f32 CColladaMeshWriterProperties::getReflectivity(const video::SMaterial& material) const +{ + // TODO: figure out best default mapping + return 0.f; +} + +//! Return index of refraction for that material +f32 CColladaMeshWriterProperties::getIndexOfRefraction(const video::SMaterial& material) const +{ + return -1.f; +} + +bool CColladaMeshWriterProperties::isExportable(const irr::scene::ISceneNode * node) const +{ + return node && node->isVisible(); +} + +IMesh* CColladaMeshWriterProperties::getMesh(irr::scene::ISceneNode * node) +{ + if ( !node ) + return 0; + if ( node->getType() == ESNT_ANIMATED_MESH ) + return static_cast(node)->getMesh()->getMesh(0); + // TODO: we need some ISceneNode::hasType() function to get rid of those checks + if ( node->getType() == ESNT_MESH + || node->getType() == ESNT_CUBE + || node->getType() == ESNT_SPHERE + || node->getType() == ESNT_WATER_SURFACE + || node->getType() == ESNT_Q3SHADER_SCENE_NODE + ) + return static_cast(node)->getMesh(); + if ( node->getType() == ESNT_TERRAIN ) + return static_cast(node)->getMesh(); + return 0; +} + +// Check if the node has it's own material overwriting the mesh-materials +bool CColladaMeshWriterProperties::useNodeMaterial(const scene::ISceneNode* node) const +{ + if ( !node ) + return false; + + // TODO: we need some ISceneNode::hasType() function to get rid of those checks + bool useMeshMaterial = ( (node->getType() == ESNT_MESH || + node->getType() == ESNT_CUBE || + node->getType() == ESNT_SPHERE || + node->getType() == ESNT_WATER_SURFACE || + node->getType() == ESNT_Q3SHADER_SCENE_NODE) + && static_cast(node)->isReadOnlyMaterials()) + + || (node->getType() == ESNT_ANIMATED_MESH + && static_cast(node)->isReadOnlyMaterials() ); + + return !useMeshMaterial; +} + + + +CColladaMeshWriterNames::CColladaMeshWriterNames(IColladaMeshWriter * writer) + : ColladaMeshWriter(writer) +{ +} + +irr::core::stringw CColladaMeshWriterNames::nameForMesh(const scene::IMesh* mesh, int instance) +{ + irr::core::stringw name(L"mesh"); + name += nameForPtr(mesh); + if ( instance > 0 ) + { + name += L"i"; + name += irr::core::stringw(instance); + } + return ColladaMeshWriter->toNCName(name); +} + +irr::core::stringw CColladaMeshWriterNames::nameForNode(const scene::ISceneNode* node) +{ + irr::core::stringw name; + // Prefix, because xs::ID can't start with a number, also nicer name + if ( node && node->getType() == ESNT_LIGHT ) + name = L"light"; + else + name = L"node"; + name += nameForPtr(node); + if ( node ) + { + name += irr::core::stringw(node->getName()); + } + return ColladaMeshWriter->toNCName(name); +} + +irr::core::stringw CColladaMeshWriterNames::nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) +{ + core::stringw strMat(L"mat"); + + bool nodeMaterial = ColladaMeshWriter->getProperties()->useNodeMaterial(node); + if ( nodeMaterial ) + { + strMat += L"node"; + strMat += nameForPtr(node); + strMat += irr::core::stringw(node->getName()); + } + strMat += L"mesh"; + strMat += nameForPtr(mesh); + strMat += materialId; + return ColladaMeshWriter->toNCName(strMat); +} + +irr::core::stringw CColladaMeshWriterNames::nameForPtr(const void* ptr) const +{ + wchar_t buf[32]; + swprintf(buf, 32, L"%p", ptr); + return irr::core::stringw(buf); +} + + + +CColladaMeshWriter::CColladaMeshWriter( ISceneManager * smgr, video::IVideoDriver* driver, + io::IFileSystem* fs) + : FileSystem(fs), VideoDriver(driver), Writer(0) +{ + + #ifdef _DEBUG + setDebugName("CColladaMeshWriter"); + #endif + + if (VideoDriver) + VideoDriver->grab(); + + if (FileSystem) + FileSystem->grab(); + + if ( smgr ) + setAmbientLight( smgr->getAmbientLight() ); + + CColladaMeshWriterProperties * p = new CColladaMeshWriterProperties(); + setDefaultProperties(p); + setProperties(p); + p->drop(); + + CColladaMeshWriterNames * nameGenerator = new CColladaMeshWriterNames(this); + setDefaultNameGenerator(nameGenerator); + setNameGenerator(nameGenerator); + nameGenerator->drop(); +} + + +CColladaMeshWriter::~CColladaMeshWriter() +{ + if (VideoDriver) + VideoDriver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + +void CColladaMeshWriter::reset() +{ + LibraryImages.clear(); + Meshes.clear(); + LightNodes.clear(); + CameraNodes.clear(); + MaterialsWritten.clear(); + EffectsWritten.clear(); + MaterialNameCache.clear(); +} + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CColladaMeshWriter::getType() const +{ + return EMWT_COLLADA; +} + +//! writes a scene starting with the given node +bool CColladaMeshWriter::writeScene(io::IWriteFile* file, scene::ISceneNode* root) +{ + if (!file || !root) + return false; + + reset(); + + Writer = FileSystem->createXMLWriter(file); + + if (!Writer) + { + os::Printer::log("Could not write file", file->getFileName()); + return false; + } + + Directory = FileSystem->getFileDir(FileSystem->getAbsolutePath( file->getFileName() )); + + // make names for all nodes with exportable meshes + makeMeshNames(root); + + os::Printer::log("Writing scene", file->getFileName()); + + // write COLLADA header + + Writer->writeXMLHeader(); + + Writer->writeElement(L"COLLADA", false, + L"xmlns", L"http://www.collada.org/2005/11/COLLADASchema", + L"version", L"1.4.1"); + Writer->writeLineBreak(); + + // write asset data + writeAsset(); + + // write all materials + Writer->writeElement(L"library_materials", false); + Writer->writeLineBreak(); + writeNodeMaterials(root); + Writer->writeClosingTag(L"library_materials"); + Writer->writeLineBreak(); + + Writer->writeElement(L"library_effects", false); + Writer->writeLineBreak(); + writeNodeEffects(root); + Writer->writeClosingTag(L"library_effects"); + Writer->writeLineBreak(); + + + // images + writeLibraryImages(); + + // lights + Writer->writeElement(L"library_lights", false); + Writer->writeLineBreak(); + + writeAmbientLightElement( getAmbientLight() ); + writeNodeLights(root); + + Writer->writeClosingTag(L"library_lights"); + Writer->writeLineBreak(); + + // cameras + Writer->writeElement(L"library_cameras", false); + Writer->writeLineBreak(); + writeNodeCameras(root); + Writer->writeClosingTag(L"library_cameras"); + Writer->writeLineBreak(); + + // write meshes + Writer->writeElement(L"library_geometries", false); + Writer->writeLineBreak(); + writeAllMeshGeometries(); + Writer->writeClosingTag(L"library_geometries"); + Writer->writeLineBreak(); + + // write scene + Writer->writeElement(L"library_visual_scenes", false); + Writer->writeLineBreak(); + Writer->writeElement(L"visual_scene", false, L"id", L"default_scene"); + Writer->writeLineBreak(); + + // ambient light (instance_light also needs a node as parent so we have to create one) + Writer->writeElement(L"node", false); + Writer->writeLineBreak(); + Writer->writeElement(L"instance_light", true, L"url", L"#ambientlight"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"node"); + Writer->writeLineBreak(); + + // Write the scenegraph. + if ( root->getType() != ESNT_SCENE_MANAGER ) + { + // TODO: Not certain if we should really write the root or if we should just always only write the children. + // For now writing root to keep backward compatibility for this case, but if anyone needs to _not_ write + // that root-node we can add a parameter for this later on in writeScene. + writeSceneNode(root); + } + else + { + // The visual_scene element is identical to our scenemanager and acts as root, + // so we do not write the root itself if it points to the scenemanager. + const core::list& rootChildren = root->getChildren(); + for ( core::list::ConstIterator it = rootChildren.begin(); + it != rootChildren.end(); + ++ it ) + { + writeSceneNode(*it); + } + } + + + Writer->writeClosingTag(L"visual_scene"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"library_visual_scenes"); + Writer->writeLineBreak(); + + + // instance scene + Writer->writeElement(L"scene", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"instance_visual_scene", true, L"url", L"#default_scene"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"scene"); + Writer->writeLineBreak(); + + + // close everything + + Writer->writeClosingTag(L"COLLADA"); + Writer->drop(); + + return true; +} + +void CColladaMeshWriter::makeMeshNames(irr::scene::ISceneNode * node) +{ + if ( !node || !getProperties() || !getProperties()->isExportable(node) || !getNameGenerator()) + return; + + IMesh* mesh = getProperties()->getMesh(node); + if ( mesh ) + { + if ( !Meshes.find(mesh) ) + { + SColladaMesh cm; + cm.Name = nameForMesh(mesh, 0); + Meshes.insert(mesh, cm); + } + } + + const core::list& children = node->getChildren(); + for ( core::list::ConstIterator it = children.begin(); it != children.end(); ++it ) + { + makeMeshNames(*it); + } +} + +void CColladaMeshWriter::writeNodeMaterials(irr::scene::ISceneNode * node) +{ + if ( !node || !getProperties() || !getProperties()->isExportable(node) ) + return; + + core::array materialNames; + + IMesh* mesh = getProperties()->getMesh(node); + if ( mesh ) + { + MeshNode * n = Meshes.find(mesh); + if ( !getProperties()->useNodeMaterial(node) ) + { + // no material overrides - write mesh materials + if ( n && !n->getValue().MaterialsWritten ) + { + writeMeshMaterials(mesh, getGeometryWriting() == ECGI_PER_MESH_AND_MATERIAL ? &materialNames : NULL); + n->getValue().MaterialsWritten = true; + } + } + else + { + // write node materials + for (u32 i=0; igetMaterialCount(); ++i) + { + video::SMaterial & material = node->getMaterial(i); + core::stringw strMat(nameForMaterial(material, i, mesh, node)); + writeMaterial(strMat); + if ( getGeometryWriting() == ECGI_PER_MESH_AND_MATERIAL ) + materialNames.push_back(strMat); + } + } + + // When we write another mesh-geometry for each new material-list we have + // to figure out here if we need another geometry copy and create a new name here. + if ( n && getGeometryWriting() == ECGI_PER_MESH_AND_MATERIAL ) + { + SGeometryMeshMaterials * geomMat = n->getValue().findGeometryMeshMaterials(materialNames); + if ( geomMat ) + geomMat->MaterialOwners.push_back(node); + else + { + SGeometryMeshMaterials gmm; + if ( n->getValue().GeometryMeshMaterials.empty() ) + gmm.GeometryName = n->getValue().Name; // first one can use the original name + else + gmm.GeometryName = nameForMesh(mesh, n->getValue().GeometryMeshMaterials.size()); + gmm.MaterialNames = materialNames; + gmm.MaterialOwners.push_back(node); + n->getValue().GeometryMeshMaterials.push_back(gmm); + } + } + } + + const core::list& children = node->getChildren(); + for ( core::list::ConstIterator it = children.begin(); it != children.end(); ++it ) + { + writeNodeMaterials( *it ); + } +} + +void CColladaMeshWriter::writeMaterial(const irr::core::stringw& materialname) +{ + if ( MaterialsWritten.find(materialname) ) + return; + MaterialsWritten.insert(materialname, true); + + Writer->writeElement(L"material", false, + L"id", materialname.c_str(), + L"name", materialname.c_str()); + Writer->writeLineBreak(); + + // We don't make a difference between material and effect on export. + // Every material is just using an instance of an effect. + core::stringw strFx(materialname); + strFx += L"-fx"; + Writer->writeElement(L"instance_effect", true, + L"url", (core::stringw(L"#") + strFx).c_str()); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"material"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeNodeEffects(irr::scene::ISceneNode * node) +{ + if ( !node || !getProperties() || !getProperties()->isExportable(node) || !getNameGenerator() ) + return; + + IMesh* mesh = getProperties()->getMesh(node); + if ( mesh ) + { + if ( !getProperties()->useNodeMaterial(node) ) + { + // no material overrides - write mesh materials + MeshNode * n = Meshes.find(mesh); + if ( n && !n->getValue().EffectsWritten ) + { + writeMeshEffects(mesh); + n->getValue().EffectsWritten = true; + } + } + else + { + // write node materials + for (u32 i=0; igetMaterialCount(); ++i) + { + video::SMaterial & material = node->getMaterial(i); + irr::core::stringw materialfxname(nameForMaterial(material, i, mesh, node)); + materialfxname += L"-fx"; + writeMaterialEffect(materialfxname, material); + } + } + } + + const core::list& children = node->getChildren(); + for ( core::list::ConstIterator it = children.begin(); it != children.end(); ++it ) + { + writeNodeEffects( *it ); + } +} + +void CColladaMeshWriter::writeNodeLights(irr::scene::ISceneNode * node) +{ + if ( !node || !getProperties() || !getProperties()->isExportable(node)) + return; + + if ( node->getType() == ESNT_LIGHT ) + { + ILightSceneNode * lightNode = static_cast(node); + const video::SLight& lightData = lightNode->getLightData(); + + SColladaLight cLight; + cLight.Name = nameForNode(node); + LightNodes.insert(node, cLight); + + Writer->writeElement(L"light", false, L"id", cLight.Name.c_str()); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + switch ( lightNode->getLightType() ) + { + case video::ELT_POINT: + Writer->writeElement(L"point", false); + Writer->writeLineBreak(); + + writeColorElement(lightData.DiffuseColor, false); + writeNode(L"constant_attenuation ", core::stringw(lightData.Attenuation.X).c_str()); + writeNode(L"linear_attenuation ", core::stringw(lightData.Attenuation.Y).c_str()); + writeNode(L"quadratic_attenuation", core::stringw(lightData.Attenuation.Z).c_str()); + + Writer->writeClosingTag(L"point"); + Writer->writeLineBreak(); + break; + + case video::ELT_SPOT: + Writer->writeElement(L"spot", false); + Writer->writeLineBreak(); + + writeColorElement(lightData.DiffuseColor, false); + + writeNode(L"constant_attenuation ", core::stringw(lightData.Attenuation.X).c_str()); + writeNode(L"linear_attenuation ", core::stringw(lightData.Attenuation.Y).c_str()); + writeNode(L"quadratic_attenuation", core::stringw(lightData.Attenuation.Z).c_str()); + + writeNode(L"falloff_angle", core::stringw(lightData.OuterCone * core::RADTODEG).c_str()); + writeNode(L"falloff_exponent", core::stringw(lightData.Falloff).c_str()); + + Writer->writeClosingTag(L"spot"); + Writer->writeLineBreak(); + break; + + case video::ELT_DIRECTIONAL: + Writer->writeElement(L"directional", false); + Writer->writeLineBreak(); + + writeColorElement(lightData.DiffuseColor, false); + + Writer->writeClosingTag(L"directional"); + Writer->writeLineBreak(); + break; + default: + break; + } + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"light"); + Writer->writeLineBreak(); + + } + + const core::list& children = node->getChildren(); + for ( core::list::ConstIterator it = children.begin(); it != children.end(); ++it ) + { + writeNodeLights( *it ); + } +} + +void CColladaMeshWriter::writeNodeCameras(irr::scene::ISceneNode * node) +{ + if ( !node || !getProperties() || !getProperties()->isExportable(node) ) + return; + + if ( isCamera(node) ) + { + ICameraSceneNode * cameraNode = static_cast(node); + irr::core::stringw name = nameForNode(node); + CameraNodes.insert(cameraNode, name); + + Writer->writeElement(L"camera", false, L"id", name.c_str()); + Writer->writeLineBreak(); + + Writer->writeElement(L"optics", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + if ( cameraNode->isOrthogonal() ) + { + Writer->writeElement(L"orthographic", false); + Writer->writeLineBreak(); + +// writeNode(L"xmag", core::stringw("1.0").c_str()); // TODO: do we need xmag, ymag? +// writeNode(L"ymag", core::stringw("1.0").c_str()); + writeNode(L"aspect_ratio", core::stringw(cameraNode->getAspectRatio()).c_str()); + writeNode(L"znear", core::stringw(cameraNode->getNearValue()).c_str()); + writeNode(L"zfar", core::stringw(cameraNode->getFarValue()).c_str()); + + Writer->writeClosingTag(L"orthographic"); + Writer->writeLineBreak(); + } + else + { + Writer->writeElement(L"perspective", false); + Writer->writeLineBreak(); + + writeNode(L"yfov", core::stringw(cameraNode->getFOV()*core::RADTODEG).c_str()); + writeNode(L"aspect_ratio", core::stringw(cameraNode->getAspectRatio()).c_str()); + writeNode(L"znear", core::stringw(cameraNode->getNearValue()).c_str()); + writeNode(L"zfar", core::stringw(cameraNode->getFarValue()).c_str()); + + Writer->writeClosingTag(L"perspective"); + Writer->writeLineBreak(); + } + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"optics"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"camera"); + Writer->writeLineBreak(); + } + + const core::list& children = node->getChildren(); + for ( core::list::ConstIterator it = children.begin(); it != children.end(); ++it ) + { + writeNodeCameras( *it ); + } +} + +void CColladaMeshWriter::writeAllMeshGeometries() +{ + core::map::ConstIterator it = Meshes.getConstIterator(); + for(; !it.atEnd(); it++ ) + { + IMesh* mesh = it->getKey(); + const SColladaMesh& colladaMesh = it->getValue(); + + if ( getGeometryWriting() == ECGI_PER_MESH_AND_MATERIAL && colladaMesh.GeometryMeshMaterials.size() > 1 ) + { + for ( u32 i=0; iisExportable(node) ) + return; + + // Collada doesn't require to set the id, but some other tools have problems if none exists, so we just add it. + irr::core::stringw nameId(nameForNode(node)); + Writer->writeElement(L"node", false, L"id", nameId.c_str()); + Writer->writeLineBreak(); + + // DummyTransformationSceneNode don't have rotation, position, scale information + // But also don't always export the transformation matrix as that forces us creating + // new DummyTransformationSceneNode's on import. + if ( node->getType() == ESNT_DUMMY_TRANSFORMATION ) + { + writeMatrixElement(node->getRelativeTransformation()); + } + else + { + irr::core::vector3df rot(node->getRotation()); + if ( isCamera(node) && !static_cast(node)->getTargetAndRotationBinding() ) + { + ICameraSceneNode * camNode = static_cast(node); + const core::vector3df toTarget = camNode->getTarget() - camNode->getAbsolutePosition(); + rot = toTarget.getHorizontalAngle(); + } + + writeTranslateElement( node->getPosition() ); + writeRotateElement( irr::core::vector3df(1.f, 0.f, 0.f), rot.X ); + writeRotateElement( irr::core::vector3df(0.f, 1.f, 0.f), rot.Y ); + writeRotateElement( irr::core::vector3df(0.f, 0.f, 1.f), rot.Z ); + writeScaleElement( node->getScale() ); + } + + // instance geometry + IMesh* mesh = getProperties()->getMesh(node); + if ( mesh ) + { + MeshNode * n = Meshes.find(mesh); + if ( n ) + { + const SColladaMesh& colladaMesh = n->getValue(); + writeMeshInstanceGeometry(colladaMesh.findGeometryNameForNode(node), mesh, node); + } + } + + // instance light + if ( node->getType() == ESNT_LIGHT ) + { + LightNode * n = LightNodes.find(node); + if ( n ) + writeLightInstance(n->getValue().Name); + } + + // instance camera + if ( isCamera(node) ) + { + CameraNode * camNode = CameraNodes.find(node); + if ( camNode ) + writeCameraInstance(camNode->getValue()); + } + + const core::list& children = node->getChildren(); + for ( core::list::ConstIterator it = children.begin(); it != children.end(); ++it ) + { + writeSceneNode( *it ); + } + + Writer->writeClosingTag(L"node"); + Writer->writeLineBreak(); +} + +//! writes a mesh +bool CColladaMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + reset(); + + Writer = FileSystem->createXMLWriter(file); + + if (!Writer) + { + os::Printer::log("Could not write file", file->getFileName()); + return false; + } + + Directory = FileSystem->getFileDir(FileSystem->getAbsolutePath( file->getFileName() )); + + os::Printer::log("Writing mesh", file->getFileName()); + + // write COLLADA header + + Writer->writeXMLHeader(); + + Writer->writeElement(L"COLLADA", false, + L"xmlns", L"http://www.collada.org/2005/11/COLLADASchema", + L"version", L"1.4.1"); + Writer->writeLineBreak(); + + // write asset data + writeAsset(); + + // write all materials + + Writer->writeElement(L"library_materials", false); + Writer->writeLineBreak(); + + writeMeshMaterials(mesh); + + Writer->writeClosingTag(L"library_materials"); + Writer->writeLineBreak(); + + Writer->writeElement(L"library_effects", false); + Writer->writeLineBreak(); + + writeMeshEffects(mesh); + + Writer->writeClosingTag(L"library_effects"); + Writer->writeLineBreak(); + + // images + writeLibraryImages(); + + // write mesh + + Writer->writeElement(L"library_geometries", false); + Writer->writeLineBreak(); + + irr::core::stringw meshname(nameForMesh(mesh, 0)); + writeMeshGeometry(meshname, mesh); + + Writer->writeClosingTag(L"library_geometries"); + Writer->writeLineBreak(); + + // write scene_library + if ( getWriteDefaultScene() ) + { + Writer->writeElement(L"library_visual_scenes", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"visual_scene", false, L"id", L"default_scene"); + Writer->writeLineBreak(); + + Writer->writeElement(L"node", false); + Writer->writeLineBreak(); + + writeMeshInstanceGeometry(meshname, mesh); + + Writer->writeClosingTag(L"node"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"visual_scene"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"library_visual_scenes"); + Writer->writeLineBreak(); + + + // write scene + Writer->writeElement(L"scene", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"instance_visual_scene", true, L"url", L"#default_scene"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"scene"); + Writer->writeLineBreak(); + } + + + // close everything + + Writer->writeClosingTag(L"COLLADA"); + Writer->drop(); + + return true; +} + +void CColladaMeshWriter::writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh, scene::ISceneNode* node) +{ + // + Writer->writeElement(L"instance_geometry", false, L"url", toRef(meshname).c_str()); + Writer->writeLineBreak(); + + Writer->writeElement(L"bind_material", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + // instance materials + // + bool useNodeMaterials = node && node->getMaterialCount() == mesh->getMeshBufferCount(); + for (u32 i=0; igetMeshBufferCount(); ++i) + { + irr::core::stringw strMatSymbol(nameForMaterialSymbol(mesh, i)); + core::stringw strMatTarget = "#"; + video::SMaterial & material = useNodeMaterials ? node->getMaterial(i) : mesh->getMeshBuffer(i)->getMaterial(); + strMatTarget += nameForMaterial(material, i, mesh, node); + Writer->writeElement(L"instance_material", false, L"symbol", strMatSymbol.c_str(), L"target", strMatTarget.c_str()); + Writer->writeLineBreak(); + + // TODO: need to handle second UV-set + // + Writer->writeElement(L"bind_vertex_input", true, L"semantic", L"uv", L"input_semantic", L"TEXCOORD", L"input_set", L"0" ); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"instance_material"); + Writer->writeLineBreak(); + } + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"bind_material"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"instance_geometry"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeLightInstance(const irr::core::stringw& lightName) +{ + Writer->writeElement(L"instance_light", true, L"url", toRef(lightName).c_str()); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeCameraInstance(const irr::core::stringw& cameraName) +{ + Writer->writeElement(L"instance_camera", true, L"url", toRef(cameraName).c_str()); + Writer->writeLineBreak(); +} + +bool CColladaMeshWriter::hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const +{ + return type == video::EVT_2TCOORDS; +} + +void CColladaMeshWriter::writeVector(const irr::core::vector3df& vec) +{ + wchar_t tmpbuf[255]; + swprintf(tmpbuf, 255, L"%f %f %f", vec.X, vec.Y, vec.Z); + + Writer->writeText(tmpbuf); +} + +void CColladaMeshWriter::writeUv(const irr::core::vector2df& vec) +{ + // change handedness + wchar_t tmpbuf[255]; + swprintf(tmpbuf, 255, L"%f %f", vec.X, 1.f-vec.Y); + + Writer->writeText(tmpbuf); +} + +void CColladaMeshWriter::writeVector(const irr::core::vector2df& vec) +{ + wchar_t tmpbuf[255]; + swprintf(tmpbuf, 255, L"%f %f", vec.X, vec.Y); + + Writer->writeText(tmpbuf); +} + +void CColladaMeshWriter::writeColor(const irr::video::SColorf& colorf, bool writeAlpha) +{ + wchar_t tmpbuf[255]; + if ( writeAlpha ) + swprintf(tmpbuf, 255, L"%f %f %f %f", colorf.getRed(), colorf.getGreen(), colorf.getBlue(), colorf.getAlpha()); + else + swprintf(tmpbuf, 255, L"%f %f %f", colorf.getRed(), colorf.getGreen(), colorf.getBlue()); + + Writer->writeText(tmpbuf); +} + +irr::core::stringw CColladaMeshWriter::toString(const irr::video::ECOLOR_FORMAT format) const +{ + switch ( format ) + { + case video::ECF_A1R5G5B5: return irr::core::stringw(L"A1R5G5B5"); + case video::ECF_R5G6B5: return irr::core::stringw(L"R5G6B5"); + case video::ECF_R8G8B8: return irr::core::stringw(L"R8G8B8"); + case video::ECF_A8R8G8B8: return irr::core::stringw(L"A8R8G8B8"); + default: return irr::core::stringw(L""); + } +} + +irr::core::stringw CColladaMeshWriter::toString(const irr::video::E_TEXTURE_CLAMP clamp) const +{ + switch ( clamp ) + { + case video::ETC_REPEAT: + return core::stringw(L"WRAP"); + case video::ETC_CLAMP: + case video::ETC_CLAMP_TO_EDGE: + return core::stringw(L"CLAMP"); + case video::ETC_CLAMP_TO_BORDER: + return core::stringw(L"BORDER"); + case video::ETC_MIRROR: + case video::ETC_MIRROR_CLAMP: + case video::ETC_MIRROR_CLAMP_TO_EDGE: + case video::ETC_MIRROR_CLAMP_TO_BORDER: + return core::stringw(L"MIRROR"); + } + return core::stringw(L"NONE"); +} + +irr::core::stringw CColladaMeshWriter::toString(const irr::scene::E_COLLADA_TRANSPARENT_FX transparent) const +{ + if ( transparent & ECOF_RGB_ZERO ) + return core::stringw(L"RGB_ZERO"); + else + return core::stringw(L"A_ONE"); +} + +irr::core::stringw CColladaMeshWriter::toRef(const irr::core::stringw& source) const +{ + irr::core::stringw ref(L"#"); + ref += source; + return ref; +} + +bool CColladaMeshWriter::isCamera(const scene::ISceneNode* node) const +{ + // TODO: we need some ISceneNode::hasType() function to get rid of those checks + if ( node->getType() == ESNT_CAMERA + || node->getType() == ESNT_CAMERA_MAYA + || node->getType() == ESNT_CAMERA_FPS ) + return true; + return false; +} + +irr::core::stringw CColladaMeshWriter::nameForMesh(const scene::IMesh* mesh, int instance) const +{ + IColladaMeshWriterNames * nameGenerator = getNameGenerator(); + if ( nameGenerator ) + { + return nameGenerator->nameForMesh(mesh, instance); + } + return irr::core::stringw(L"missing_name_generator"); +} + +irr::core::stringw CColladaMeshWriter::nameForNode(const scene::ISceneNode* node) const +{ + IColladaMeshWriterNames * nameGenerator = getNameGenerator(); + if ( nameGenerator ) + { + return nameGenerator->nameForNode(node); + } + return irr::core::stringw(L"missing_name_generator"); +} + +irr::core::stringw CColladaMeshWriter::nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) +{ + irr::core::stringw matName; + if ( getExportSMaterialsOnlyOnce() ) + { + matName = findCachedMaterialName(material); + if ( !matName.empty() ) + return matName; + } + + IColladaMeshWriterNames * nameGenerator = getNameGenerator(); + if ( nameGenerator ) + { + matName = nameGenerator->nameForMaterial(material, materialId, mesh, node); + } + else + matName = irr::core::stringw(L"missing_name_generator"); + + if ( getExportSMaterialsOnlyOnce() ) + MaterialNameCache.push_back (MaterialName(material, matName)); + return matName; +} + +// Each mesh-material has one symbol which is replaced on instantiation +irr::core::stringw CColladaMeshWriter::nameForMaterialSymbol(const scene::IMesh* mesh, int materialId) const +{ + wchar_t buf[100]; + swprintf(buf, 100, L"mat_symb_%p_%d", mesh, materialId); + return irr::core::stringw(buf); +} + +irr::core::stringw CColladaMeshWriter::findCachedMaterialName(const irr::video::SMaterial& material) const +{ + for ( u32 i=0; i= 'A' && c <= 'Z') + || c == L'_' + || (c >= 'a' && c <= 'z') + || (c >= 0xC0 && c <= 0xD6) + || (c >= 0xD8 && c <= 0xF6) + || (c >= 0xF8 && c <= 0x2FF) + || (c >= 0x370 && c <= 0x37D) + || (c >= 0x37F && c <= 0x1FFF) + || (c >= 0x200C && c <= 0x200D) + || (c >= 0x2070 && c <= 0x218F) + || (c >= 0x2C00 && c <= 0x2FEF) + || (c >= 0x3001 && c <= 0xD7FF) + || (c >= 0xF900 && c <= 0xFDCF) + || (c >= 0xFDF0 && c <= 0xFFFD) +#if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000 + || (c >= 0x10000 && c <= 0xEFFFF) +#endif + ; +} + +bool CColladaMeshWriter::isXmlNameChar(wchar_t c) const +{ + return isXmlNameStartChar(c) + || c == L'-' + || c == L'.' + || (c >= '0' && c <= '9') + || c == 0xB7 + || (c >= 0x0300 && c <= 0x036F) + || (c >= 0x203F && c <= 0x2040); +} + +// Restrict the characters to a set of allowed characters in xs::NCName. +irr::core::stringw CColladaMeshWriter::toNCName(const irr::core::stringw& oldString, const irr::core::stringw& prefix) const +{ + irr::core::stringw result(prefix); // help to ensure id starts with a valid char and reduce chance of name-conflicts + if ( oldString.empty() ) + return result; + + result.append( oldString ); + + // We replace all characters not allowed by a replacement char + const wchar_t REPLACMENT = L'-'; + for ( irr::u32 i=1; i < result.size(); ++i ) + { + if ( result[i] == L':' || !isXmlNameChar(result[i]) ) + { + result[i] = REPLACMENT; + } + } + return result; +} + +// Restrict the characters to a set of allowed characters in xs::NCName. +irr::core::stringw CColladaMeshWriter::pathToURI(const irr::io::path& path) const +{ + irr::core::stringw result; + + // is this a relative path? + if ( path.size() > 1 + && path[0] != _IRR_TEXT('/') + && path[0] != _IRR_TEXT('\\') + && path[1] != _IRR_TEXT(':') ) + { + // not already starting with "./" ? + if ( path[0] != _IRR_TEXT('.') + || path[1] != _IRR_TEXT('/') ) + { + result.append(L"./"); + } + } + result.append(path); + + // TODO: make correct URI (without whitespaces) + + return result; +} + +void CColladaMeshWriter::writeAsset() +{ + Writer->writeElement(L"asset", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"contributor", false); + Writer->writeLineBreak(); + Writer->writeElement(L"authoring_tool", false); + Writer->writeText(L"Irrlicht Engine / irrEdit"); // this code has originated from irrEdit 0.7 + Writer->writeClosingTag(L"authoring_tool"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"contributor"); + Writer->writeLineBreak(); + + // The next two are required + Writer->writeElement(L"created", false); + Writer->writeText(L"2008-01-31T00:00:00Z"); + Writer->writeClosingTag(L"created"); + Writer->writeLineBreak(); + + Writer->writeElement(L"modified", false); + Writer->writeText(L"2008-01-31T00:00:00Z"); + Writer->writeClosingTag(L"modified"); + Writer->writeLineBreak(); + + Writer->writeElement(L"revision", false); + Writer->writeText(L"1.0"); + Writer->writeClosingTag(L"revision"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"asset"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeMeshMaterials(scene::IMesh* mesh, irr::core::array * materialNamesOut) +{ + u32 i; + for (i=0; igetMeshBufferCount(); ++i) + { + video::SMaterial & material = mesh->getMeshBuffer(i)->getMaterial(); + core::stringw strMat(nameForMaterial(material, i, mesh, NULL)); + writeMaterial(strMat); + if ( materialNamesOut ) + materialNamesOut->push_back(strMat); + } +} + +void CColladaMeshWriter::writeMaterialEffect(const irr::core::stringw& materialfxname, const video::SMaterial & material) +{ + if ( EffectsWritten.find(materialfxname) ) + return; + EffectsWritten.insert(materialfxname, true); + + Writer->writeElement(L"effect", false, + L"id", materialfxname.c_str(), + L"name", materialfxname.c_str()); + Writer->writeLineBreak(); + Writer->writeElement(L"profile_COMMON", false); + Writer->writeLineBreak(); + + int numTextures = 0; + if ( getWriteTextures() ) + { + // write texture surfaces and samplers and buffer all used imagess + for ( int t=0; t<4; ++t ) + { + const video::SMaterialLayer& layer = material.TextureLayer[t]; + if ( !layer.Texture ) + break; + ++numTextures; + + if ( LibraryImages.linear_search(layer.Texture) < 0 ) + LibraryImages.push_back( layer.Texture ); + + irr::core::stringw texName("tex"); + texName += irr::core::stringw(t); + + // write texture surface + // + irr::core::stringw texSurface(texName); + texSurface += L"-surface"; + Writer->writeElement(L"newparam", false, L"sid", texSurface.c_str()); + Writer->writeLineBreak(); + // + Writer->writeElement(L"surface", false, L"type", L"2D"); + Writer->writeLineBreak(); + + // internal_texturename + Writer->writeElement(L"init_from", false); + irr::io::path p(FileSystem->getRelativeFilename(layer.Texture->getName().getPath(), Directory)); + Writer->writeText(toNCName(irr::core::stringw(p)).c_str()); + Writer->writeClosingTag(L"init_from"); + Writer->writeLineBreak(); + + // A8R8G8B8 + Writer->writeElement(L"format", false); + video::ECOLOR_FORMAT format = layer.Texture->getColorFormat(); + Writer->writeText(toString(format).c_str()); + Writer->writeClosingTag(L"format"); + Writer->writeLineBreak(); + // + Writer->writeClosingTag(L"surface"); + Writer->writeLineBreak(); + // + Writer->writeClosingTag(L"newparam"); + Writer->writeLineBreak(); + + // write texture sampler + // + irr::core::stringw texSampler(texName); + texSampler += L"-sampler"; + Writer->writeElement(L"newparam", false, L"sid", texSampler.c_str()); + Writer->writeLineBreak(); + // + Writer->writeElement(L"sampler2D", false); + Writer->writeLineBreak(); + + // tex0-surface + Writer->writeElement(L"source", false); + Writer->writeText(texSurface.c_str()); + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // WRAP + Writer->writeElement(L"wrap_s", false); + Writer->writeText(toString((video::E_TEXTURE_CLAMP)layer.TextureWrapU).c_str()); + Writer->writeClosingTag(L"wrap_s"); + Writer->writeLineBreak(); + + // WRAP + Writer->writeElement(L"wrap_t", false); + Writer->writeText(toString((video::E_TEXTURE_CLAMP)layer.TextureWrapV).c_str()); + Writer->writeClosingTag(L"wrap_t"); + Writer->writeLineBreak(); + + // LINEAR_MIPMAP_LINEAR + Writer->writeElement(L"minfilter", false); + Writer->writeText(minTexfilterToString(layer.BilinearFilter, layer.TrilinearFilter).c_str()); + Writer->writeClosingTag(L"minfilter"); + Writer->writeLineBreak(); + + // LINEAR + Writer->writeElement(L"magfilter", false); + Writer->writeText(magTexfilterToString(layer.BilinearFilter, layer.TrilinearFilter).c_str()); + Writer->writeClosingTag(L"magfilter"); + Writer->writeLineBreak(); + + // TBD - actually not sure how anisotropic should be written, so for now it writes in a way + // that works with the way the loader reads it again. + if ( layer.AnisotropicFilter ) + { + // LINEAR_MIPMAP_LINEAR + Writer->writeElement(L"mipfilter", false); + Writer->writeText(L"LINEAR_MIPMAP_LINEAR"); + Writer->writeClosingTag(L"mipfilter"); + Writer->writeLineBreak(); + } + + // + Writer->writeClosingTag(L"sampler2D"); + Writer->writeLineBreak(); + // + Writer->writeClosingTag(L"newparam"); + Writer->writeLineBreak(); + } + } + + Writer->writeElement(L"technique", false, L"sid", L"common"); + Writer->writeLineBreak(); + + E_COLLADA_TECHNIQUE_FX techFx = getProperties() ? getProperties()->getTechniqueFx(material) : ECTF_BLINN; + writeFxElement(material, techFx); + + Writer->writeClosingTag(L"technique"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"profile_COMMON"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"effect"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeMeshEffects(scene::IMesh* mesh) +{ + for (u32 i=0; igetMeshBufferCount(); ++i) + { + video::SMaterial & material = mesh->getMeshBuffer(i)->getMaterial(); + irr::core::stringw materialfxname(nameForMaterial(material, i, mesh, NULL)); + materialfxname += L"-fx"; + writeMaterialEffect(materialfxname, material); + } +} + +void CColladaMeshWriter::writeMeshGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh) +{ + core::stringw meshId(meshname); + + Writer->writeElement(L"geometry", false, L"id", meshId.c_str(), L"name", meshId.c_str()); + Writer->writeLineBreak(); + Writer->writeElement(L"mesh"); + Writer->writeLineBreak(); + + // do some statistics for the mesh to know which stuff needs to be saved into + // the file: + // - count vertices + // - check for the need of a second texture coordinate + // - count amount of second texture coordinates + // - check for the need of tangents (TODO) + + u32 totalVertexCount = 0; + u32 totalTCoords2Count = 0; + bool needsTangents = false; // TODO: tangents not supported here yet + u32 i=0; + for (i=0; igetMeshBufferCount(); ++i) + { + totalVertexCount += mesh->getMeshBuffer(i)->getVertexCount(); + + if (hasSecondTextureCoordinates(mesh->getMeshBuffer(i)->getVertexType())) + totalTCoords2Count += mesh->getMeshBuffer(i)->getVertexCount(); + + if (!needsTangents) + needsTangents = mesh->getMeshBuffer(i)->getVertexType() == video::EVT_TANGENTS; + } + + SComponentGlobalStartPos* globalIndices = new SComponentGlobalStartPos[mesh->getMeshBufferCount()]; + + // write positions + core::stringw meshPosId(meshId); + meshPosId += L"-Pos"; + Writer->writeElement(L"source", false, L"id", meshPosId.c_str()); + Writer->writeLineBreak(); + + core::stringw vertexCountStr(totalVertexCount*3); + core::stringw meshPosArrayId(meshPosId); + meshPosArrayId += L"-array"; + Writer->writeElement(L"float_array", false, L"id", meshPosArrayId.c_str(), + L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + globalIndices[i].PosStartIndex = 0; + + if (i!=0) + globalIndices[i].PosStartIndex = globalIndices[i-1].PosLastIndex + 1; + + globalIndices[i].PosLastIndex = globalIndices[i].PosStartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + } + } + + Writer->writeClosingTag(L"float_array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalVertexCount); + + Writer->writeElement(L"accessor", false, L"source", toRef(meshPosArrayId).c_str(), + L"count", vertexCountStr.c_str(), L"stride", L"3"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // write texture coordinates + + core::stringw meshTexCoord0Id(meshId); + meshTexCoord0Id += L"-TexCoord0"; + Writer->writeElement(L"source", false, L"id", meshTexCoord0Id.c_str()); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalVertexCount*2); + core::stringw meshTexCoordArrayId(meshTexCoord0Id); + meshTexCoordArrayId += L"-array"; + Writer->writeElement(L"float_array", false, L"id", meshTexCoordArrayId.c_str(), + L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + globalIndices[i].TCoord0StartIndex = 0; + + if (i!=0) + globalIndices[i].TCoord0StartIndex = globalIndices[i-1].TCoord0LastIndex + 1; + + globalIndices[i].TCoord0LastIndex = globalIndices[i].TCoord0StartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + } + } + + Writer->writeClosingTag(L"float_array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalVertexCount); + + Writer->writeElement(L"accessor", false, L"source", toRef(meshTexCoordArrayId).c_str(), + L"count", vertexCountStr.c_str(), L"stride", L"2"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // write normals + core::stringw meshNormalId(meshId); + meshNormalId += L"-Normal"; + Writer->writeElement(L"source", false, L"id", meshNormalId.c_str()); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalVertexCount*3); + core::stringw meshNormalArrayId(meshNormalId); + meshNormalArrayId += L"-array"; + Writer->writeElement(L"float_array", false, L"id", meshNormalArrayId.c_str(), + L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + globalIndices[i].NormalStartIndex = 0; + + if (i!=0) + globalIndices[i].NormalStartIndex = globalIndices[i-1].NormalLastIndex + 1; + + globalIndices[i].NormalLastIndex = globalIndices[i].NormalStartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + } + } + + Writer->writeClosingTag(L"float_array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalVertexCount); + + Writer->writeElement(L"accessor", false, L"source", toRef(meshNormalArrayId).c_str(), + L"count", vertexCountStr.c_str(), L"stride", L"3"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"X", L"type", L"float"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Y", L"type", L"float"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"Z", L"type", L"float"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + + // write second set of texture coordinates + core::stringw meshTexCoord1Id(meshId); + meshTexCoord1Id += L"-TexCoord1"; + if (totalTCoords2Count) + { + Writer->writeElement(L"source", false, L"id", meshTexCoord1Id.c_str()); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalTCoords2Count*2); + core::stringw meshTexCoord1ArrayId(meshTexCoord1Id); + meshTexCoord1ArrayId += L"-array"; + Writer->writeElement(L"float_array", false, L"id", meshTexCoord1ArrayId.c_str(), + L"count", vertexCountStr.c_str()); + Writer->writeLineBreak(); + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + video::E_VERTEX_TYPE vtxType = buffer->getVertexType(); + u32 vertexCount = buffer->getVertexCount(); + + if (hasSecondTextureCoordinates(vtxType)) + { + globalIndices[i].TCoord1StartIndex = 0; + + if (i!=0 && globalIndices[i-1].TCoord1LastIndex != -1) + globalIndices[i].TCoord1StartIndex = globalIndices[i-1].TCoord1LastIndex + 1; + + globalIndices[i].TCoord1LastIndex = globalIndices[i].TCoord1StartIndex + vertexCount - 1; + + switch(vtxType) + { + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteLineBreak(); + } + } + break; + default: + break; + } + } // end this buffer has 2 texture coordinates + } + + Writer->writeClosingTag(L"float_array"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + vertexCountStr = core::stringw(totalTCoords2Count); + + Writer->writeElement(L"accessor", false, L"source", toRef(meshTexCoord1ArrayId).c_str(), + L"count", vertexCountStr.c_str(), L"stride", L"2"); + Writer->writeLineBreak(); + + Writer->writeElement(L"param", true, L"name", L"U", L"type", L"float"); + Writer->writeLineBreak(); + Writer->writeElement(L"param", true, L"name", L"V", L"type", L"float"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"accessor"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"source"); + Writer->writeLineBreak(); + } + + // write tangents + + // TODO + + // write vertices + core::stringw meshVtxId(meshId); + meshVtxId += L"-Vtx"; + Writer->writeElement(L"vertices", false, L"id", meshVtxId.c_str()); + Writer->writeLineBreak(); + + Writer->writeElement(L"input", true, L"semantic", L"POSITION", L"source", toRef(meshPosId).c_str()); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"vertices"); + Writer->writeLineBreak(); + + // write polygons + + for (i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + + const u32 polyCount = buffer->getIndexCount() / 3; + core::stringw strPolyCount(polyCount); + irr::core::stringw strMat(nameForMaterialSymbol(mesh, i)); + + Writer->writeElement(L"triangles", false, L"count", strPolyCount.c_str(), + L"material", strMat.c_str()); + Writer->writeLineBreak(); + + Writer->writeElement(L"input", true, L"semantic", L"VERTEX", L"source", toRef(meshVtxId).c_str(), L"offset", L"0"); + Writer->writeLineBreak(); + Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", toRef(meshTexCoord0Id).c_str(), L"offset", L"1", L"set", L"0"); + Writer->writeLineBreak(); + Writer->writeElement(L"input", true, L"semantic", L"NORMAL", L"source", toRef(meshNormalId).c_str(), L"offset", L"2"); + Writer->writeLineBreak(); + + bool has2ndTexCoords = hasSecondTextureCoordinates(buffer->getVertexType()); + if (has2ndTexCoords) + { + // TODO: when working on second uv-set - my suspicion is that this one should be called "TEXCOORD2" + // to allow bind_vertex_input to differentiate the uv-sets. + Writer->writeElement(L"input", true, L"semantic", L"TEXCOORD", L"source", toRef(meshTexCoord1Id).c_str(), L"idx", L"3"); + Writer->writeLineBreak(); + } + + // write indices now + + s32 posIdx = globalIndices[i].PosStartIndex; + s32 tCoordIdx = globalIndices[i].TCoord0StartIndex; + s32 normalIdx = globalIndices[i].NormalStartIndex; + s32 tCoord2Idx = globalIndices[i].TCoord1StartIndex; + + Writer->writeElement(L"p", false); + + core::stringw strP; + strP.reserve(100); + for (u32 p=0; pgetIndices()[(p*3) + 0] + posIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 0] + tCoordIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 0] + normalIdx; + strP += " "; + if (has2ndTexCoords) + { + strP += buffer->getIndices()[(p*3) + 0] + tCoord2Idx; + strP += " "; + } + + strP += buffer->getIndices()[(p*3) + 1] + posIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 1] + tCoordIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 1] + normalIdx; + strP += " "; + if (has2ndTexCoords) + { + strP += buffer->getIndices()[(p*3) + 1] + tCoord2Idx; + strP += " "; + } + + strP += buffer->getIndices()[(p*3) + 2] + posIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 2] + tCoordIdx; + strP += " "; + strP += buffer->getIndices()[(p*3) + 2] + normalIdx; + if (has2ndTexCoords) + { + strP += " "; + strP += buffer->getIndices()[(p*3) + 2] + tCoord2Idx; + } + strP += " "; + + Writer->writeText(strP.c_str()); + } + + Writer->writeClosingTag(L"p"); + Writer->writeLineBreak(); + + // close index buffer section + + Writer->writeClosingTag(L"triangles"); + Writer->writeLineBreak(); + } + + // close mesh and geometry + delete [] globalIndices; + Writer->writeClosingTag(L"mesh"); + Writer->writeLineBreak(); + Writer->writeClosingTag(L"geometry"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeLibraryImages() +{ + if ( getWriteTextures() && !LibraryImages.empty() ) + { + Writer->writeElement(L"library_images", false); + Writer->writeLineBreak(); + + for ( irr::u32 i=0; igetRelativeFilename(LibraryImages[i]->getName().getPath(), Directory)); + // + irr::core::stringw ncname( toNCName(irr::core::stringw(p)) ); + Writer->writeElement(L"image", false, L"id", ncname.c_str(), L"name", ncname.c_str()); + Writer->writeLineBreak(); + // ../flowers/rose01.jpg + Writer->writeElement(L"init_from", false); + Writer->writeText(pathToURI(p).c_str()); + Writer->writeClosingTag(L"init_from"); + Writer->writeLineBreak(); + // + Writer->writeClosingTag(L"image"); + Writer->writeLineBreak(); + } + + Writer->writeClosingTag(L"library_images"); + Writer->writeLineBreak(); + } +} + +void CColladaMeshWriter::writeColorElement(const video::SColorf & col, bool writeAlpha) +{ + Writer->writeElement(L"color", false); + + writeColor(col, writeAlpha); + + Writer->writeClosingTag(L"color"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeColorElement(const video::SColor & col, bool writeAlpha) +{ + writeColorElement( video::SColorf(col), writeAlpha ); +} + +void CColladaMeshWriter::writeAmbientLightElement(const video::SColorf & col) +{ + Writer->writeElement(L"light", false, L"id", L"ambientlight"); + Writer->writeLineBreak(); + + Writer->writeElement(L"technique_common", false); + Writer->writeLineBreak(); + + Writer->writeElement(L"ambient", false); + Writer->writeLineBreak(); + + writeColorElement(col, false); + + Writer->writeClosingTag(L"ambient"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"technique_common"); + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"light"); + Writer->writeLineBreak(); +} + +s32 CColladaMeshWriter::getCheckedTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) +{ + if ( !getWriteTextures() + || !getProperties() ) + return -1; + + s32 idx = getProperties()->getTextureIdx(material, cs); + if ( idx >= 0 && !material.TextureLayer[idx].Texture ) + return -1; + + return idx; +} + +video::SColor CColladaMeshWriter::getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs, E_COLLADA_IRR_COLOR colType) +{ + switch ( colType ) + { + case ECIC_NONE: + return video::SColor(255, 0, 0, 0); + + case ECIC_CUSTOM: + return getProperties()->getCustomColor(material, cs); + + case ECIC_DIFFUSE: + return material.DiffuseColor; + + case ECIC_AMBIENT: + return material.AmbientColor; + + case ECIC_EMISSIVE: + return material.EmissiveColor; + + case ECIC_SPECULAR: + return material.SpecularColor; + } + return video::SColor(255, 0, 0, 0); +} + +void CColladaMeshWriter::writeTextureSampler(s32 textureIdx) +{ + irr::core::stringw sampler(L"tex"); + sampler += irr::core::stringw(textureIdx); + sampler += L"-sampler"; + + // + Writer->writeElement(L"texture", true, L"texture", sampler.c_str(), L"texcoord", L"uv" ); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeFxElement(const video::SMaterial & material, E_COLLADA_TECHNIQUE_FX techFx) +{ + core::stringw fxLabel; + bool writeEmission = true; + bool writeAmbient = true; + bool writeDiffuse = true; + bool writeSpecular = true; + bool writeShininess = true; + bool writeReflective = true; + bool writeReflectivity = true; + bool writeTransparent = true; + bool writeTransparency = true; + bool writeIndexOfRefraction = true; + switch ( techFx ) + { + case ECTF_BLINN: + fxLabel = L"blinn"; + break; + case ECTF_PHONG: + fxLabel = L"phong"; + break; + case ECTF_LAMBERT: + fxLabel = L"lambert"; + writeSpecular = false; + writeShininess = false; + break; + case ECTF_CONSTANT: + fxLabel = L"constant"; + writeAmbient = false; + writeDiffuse = false; + writeSpecular = false; + writeShininess = false; + break; + } + + Writer->writeElement(fxLabel.c_str(), false); + Writer->writeLineBreak(); + + // write all interesting material parameters + // attributes must be written in fixed order + if ( getProperties() ) + { + if ( writeEmission ) + { + writeColorFx(material, L"emission", ECCS_EMISSIVE); + } + + if ( writeAmbient ) + { + writeColorFx(material, L"ambient", ECCS_AMBIENT); + } + + if ( writeDiffuse ) + { + writeColorFx(material, L"diffuse", ECCS_DIFFUSE); + } + + if ( writeSpecular ) + { + writeColorFx(material, L"specular", ECCS_SPECULAR); + } + + if ( writeShininess ) + { + Writer->writeElement(L"shininess", false); + Writer->writeLineBreak(); + writeFloatElement(material.Shininess); + Writer->writeClosingTag(L"shininess"); + Writer->writeLineBreak(); + } + + if ( writeReflective ) + { + writeColorFx(material, L"reflective", ECCS_REFLECTIVE); + } + + if ( writeReflectivity ) + { + f32 t = getProperties()->getReflectivity(material); + if ( t >= 0.f ) + { + // 1.000000 + Writer->writeElement(L"reflectivity", false); + Writer->writeLineBreak(); + writeFloatElement(t); + Writer->writeClosingTag(L"reflectivity"); + Writer->writeLineBreak(); + } + } + + if ( writeTransparent ) + { + E_COLLADA_TRANSPARENT_FX transparentFx = getProperties()->getTransparentFx(material); + writeColorFx(material, L"transparent", ECCS_TRANSPARENT, L"opaque", toString(transparentFx).c_str()); + } + + if ( writeTransparency ) + { + f32 t = getProperties()->getTransparency(material); + if ( t >= 0.f ) + { + // 1.000000 + Writer->writeElement(L"transparency", false); + Writer->writeLineBreak(); + writeFloatElement(t); + Writer->writeClosingTag(L"transparency"); + Writer->writeLineBreak(); + } + } + + if ( writeIndexOfRefraction ) + { + f32 t = getProperties()->getIndexOfRefraction(material); + if ( t >= 0.f ) + { + Writer->writeElement(L"index_of_refraction", false); + Writer->writeLineBreak(); + writeFloatElement(t); + Writer->writeClosingTag(L"index_of_refraction"); + Writer->writeLineBreak(); + } + } + } + + + Writer->writeClosingTag(fxLabel.c_str()); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeColorFx(const video::SMaterial & material, const wchar_t * colorname, E_COLLADA_COLOR_SAMPLER cs, const wchar_t* attr1Name, const wchar_t* attr1Value) +{ + irr::s32 idx = getCheckedTextureIdx(material, cs); + E_COLLADA_IRR_COLOR colType = idx < 0 ? getProperties()->getColorMapping(material, cs) : ECIC_NONE; + if ( idx >= 0 || colType != ECIC_NONE ) + { + Writer->writeElement(colorname, false, attr1Name, attr1Value); + Writer->writeLineBreak(); + if ( idx >= 0 ) + writeTextureSampler(idx); + else + writeColorElement(getColorMapping(material, cs, colType)); + Writer->writeClosingTag(colorname); + Writer->writeLineBreak(); + } +} + +void CColladaMeshWriter::writeNode(const wchar_t * nodeName, const wchar_t * content) +{ + Writer->writeElement(nodeName, false); + Writer->writeText(content); + Writer->writeClosingTag(nodeName); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeFloatElement(irr::f32 value) +{ + Writer->writeElement(L"float", false); + Writer->writeText(core::stringw((double)value).c_str()); + Writer->writeClosingTag(L"float"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeRotateElement(const irr::core::vector3df& axis, irr::f32 angle) +{ + Writer->writeElement(L"rotate", false); + irr::core::stringw txt(axis.X); + txt += L" "; + txt += irr::core::stringw(axis.Y); + txt += L" "; + txt += irr::core::stringw(axis.Z); + txt += L" "; + txt += irr::core::stringw((double)angle); + Writer->writeText(txt.c_str()); + Writer->writeClosingTag(L"rotate"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeScaleElement(const irr::core::vector3df& scale) +{ + Writer->writeElement(L"scale", false); + irr::core::stringw txt(scale.X); + txt += L" "; + txt += irr::core::stringw(scale.Y); + txt += L" "; + txt += irr::core::stringw(scale.Z); + Writer->writeText(txt.c_str()); + Writer->writeClosingTag(L"scale"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeTranslateElement(const irr::core::vector3df& translate) +{ + Writer->writeElement(L"translate", false); + irr::core::stringw txt(translate.X); + txt += L" "; + txt += irr::core::stringw(translate.Y); + txt += L" "; + txt += irr::core::stringw(translate.Z); + Writer->writeText(txt.c_str()); + Writer->writeClosingTag(L"translate"); + Writer->writeLineBreak(); +} + +void CColladaMeshWriter::writeMatrixElement(const irr::core::matrix4& matrix) +{ + Writer->writeElement(L"matrix", false); + Writer->writeLineBreak(); + + for ( int a=0; a<4; ++a ) + { + irr::core::stringw txt; + for ( int b=0; b<4; ++b ) + { + if ( b > 0 ) + txt += " "; + // row-column switched compared to Irrlicht + txt += irr::core::stringw(matrix[b*4+a]); + } + Writer->writeText(txt.c_str()); + Writer->writeLineBreak(); + } + + Writer->writeClosingTag(L"matrix"); + Writer->writeLineBreak(); +} + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.h new file mode 100644 index 0000000..61f2a27 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CColladaMeshWriter.h @@ -0,0 +1,271 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_C_COLLADA_MESH_WRITER_H_INCLUDED__ +#define __IRR_C_COLLADA_MESH_WRITER_H_INCLUDED__ + +#include "IColladaMeshWriter.h" +#include "S3DVertex.h" +#include "irrMap.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; + class IFileSystem; +} + +namespace scene +{ + //! Callback interface for properties which can be used to influence collada writing + // (Implementer note: keep namespace labels here to make it easier for users copying this one) + class CColladaMeshWriterProperties : public virtual IColladaMeshWriterProperties + { + public: + //! Which lighting model should be used in the technique (FX) section when exporting effects (materials) + virtual irr::scene::E_COLLADA_TECHNIQUE_FX getTechniqueFx(const irr::video::SMaterial& material) const; + + //! Which texture index should be used when writing the texture of the given sampler color. + virtual irr::s32 getTextureIdx(const irr::video::SMaterial & material, irr::scene::E_COLLADA_COLOR_SAMPLER cs) const; + + //! Return which color from Irrlicht should be used for the color requested by collada + virtual irr::scene::E_COLLADA_IRR_COLOR getColorMapping(const irr::video::SMaterial & material, irr::scene::E_COLLADA_COLOR_SAMPLER cs) const; + + //! Return custom colors for certain color types requested by collada. + virtual irr::video::SColor getCustomColor(const irr::video::SMaterial & material, irr::scene::E_COLLADA_COLOR_SAMPLER cs) const; + + //! Return the settings for transparence + virtual irr::scene::E_COLLADA_TRANSPARENT_FX getTransparentFx(const irr::video::SMaterial& material) const; + + //! Transparency value for that material. + virtual irr::f32 getTransparency(const irr::video::SMaterial& material) const; + + //! Reflectivity value for that material + virtual irr::f32 getReflectivity(const irr::video::SMaterial& material) const; + + //! Return index of refraction for that material + virtual irr::f32 getIndexOfRefraction(const irr::video::SMaterial& material) const; + + //! Should node be used in scene export? By default all visible nodes are exported. + virtual bool isExportable(const irr::scene::ISceneNode * node) const; + + //! Return the mesh for the given nod. If it has no mesh or shouldn't export it's mesh return 0. + virtual irr::scene::IMesh* getMesh(irr::scene::ISceneNode * node); + + //! Return if the node has it's own material overwriting the mesh-materials + virtual bool useNodeMaterial(const scene::ISceneNode* node) const; + }; + + class CColladaMeshWriterNames : public virtual IColladaMeshWriterNames + { + public: + CColladaMeshWriterNames(IColladaMeshWriter * writer); + virtual irr::core::stringw nameForMesh(const scene::IMesh* mesh, int instance); + virtual irr::core::stringw nameForNode(const scene::ISceneNode* node); + virtual irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node); + protected: + irr::core::stringw nameForPtr(const void* ptr) const; + private: + IColladaMeshWriter * ColladaMeshWriter; + }; + + + +//! class to write meshes, implementing a COLLADA (.dae, .xml) writer +/** This writer implementation has been originally developed for irrEdit and then +merged out to the Irrlicht Engine */ +class CColladaMeshWriter : public IColladaMeshWriter +{ +public: + + CColladaMeshWriter(ISceneManager * smgr, video::IVideoDriver* driver, io::IFileSystem* fs); + virtual ~CColladaMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a scene starting with the given node + virtual bool writeScene(io::IWriteFile* file, scene::ISceneNode* root); + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + // Restrict the characters of oldString a set of allowed characters in xs::NCName and add the prefix. + virtual irr::core::stringw toNCName(const irr::core::stringw& oldString, const irr::core::stringw& prefix=irr::core::stringw(L"_NC_")) const; + +protected: + + void reset(); + bool hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const; + void writeUv(const irr::core::vector2df& vec); + void writeVector(const irr::core::vector2df& vec); + void writeVector(const irr::core::vector3df& vec); + void writeColor(const irr::video::SColorf& colorf, bool writeAlpha=true); + inline irr::core::stringw toString(const irr::video::ECOLOR_FORMAT format) const; + inline irr::core::stringw toString(const irr::video::E_TEXTURE_CLAMP clamp) const; + inline irr::core::stringw toString(const irr::scene::E_COLLADA_TRANSPARENT_FX opaque) const; + inline irr::core::stringw toRef(const irr::core::stringw& source) const; + bool isCamera(const scene::ISceneNode* node) const; + irr::core::stringw nameForMesh(const scene::IMesh* mesh, int instance) const; + irr::core::stringw nameForNode(const scene::ISceneNode* node) const; + irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node); + irr::core::stringw nameForMaterialSymbol(const scene::IMesh* mesh, int materialId) const; + irr::core::stringw findCachedMaterialName(const irr::video::SMaterial& material) const; + irr::core::stringw minTexfilterToString(bool bilinear, bool trilinear) const; + irr::core::stringw magTexfilterToString(bool bilinear, bool trilinear) const; + irr::core::stringw pathToURI(const irr::io::path& path) const; + inline bool isXmlNameStartChar(wchar_t c) const; + inline bool isXmlNameChar(wchar_t c) const; + s32 getCheckedTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs); + video::SColor getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs, E_COLLADA_IRR_COLOR colType); + void writeAsset(); + void makeMeshNames(irr::scene::ISceneNode * node); + void writeNodeMaterials(irr::scene::ISceneNode * node); + void writeNodeEffects(irr::scene::ISceneNode * node); + void writeNodeLights(irr::scene::ISceneNode * node); + void writeNodeCameras(irr::scene::ISceneNode * node); + void writeAllMeshGeometries(); + void writeSceneNode(irr::scene::ISceneNode * node); + void writeMeshMaterials(scene::IMesh* mesh, irr::core::array * materialNamesOut=0); + void writeMeshEffects(scene::IMesh* mesh); + void writeMaterialEffect(const irr::core::stringw& materialname, const video::SMaterial & material); + void writeMeshGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh); + void writeMeshInstanceGeometry(const irr::core::stringw& meshname, scene::IMesh* mesh, scene::ISceneNode* node=0); + void writeMaterial(const irr::core::stringw& materialname); + void writeLightInstance(const irr::core::stringw& lightName); + void writeCameraInstance(const irr::core::stringw& cameraName); + void writeLibraryImages(); + void writeColorFx(const video::SMaterial & material, const wchar_t * colorname, E_COLLADA_COLOR_SAMPLER cs, const wchar_t* attr1Name=0, const wchar_t* attr1Value=0); + void writeAmbientLightElement(const video::SColorf & col); + void writeColorElement(const video::SColor & col, bool writeAlpha=true); + void writeColorElement(const video::SColorf & col, bool writeAlpha=true); + void writeTextureSampler(s32 textureIdx); + void writeFxElement(const video::SMaterial & material, E_COLLADA_TECHNIQUE_FX techFx); + void writeNode(const wchar_t * nodeName, const wchar_t * content); + void writeFloatElement(irr::f32 value); + void writeRotateElement(const irr::core::vector3df& axis, irr::f32 angle); + void writeScaleElement(const irr::core::vector3df& scale); + void writeTranslateElement(const irr::core::vector3df& translate); + void writeMatrixElement(const irr::core::matrix4& matrix); + + struct SComponentGlobalStartPos + { + SComponentGlobalStartPos() : PosStartIndex(-1), PosLastIndex(-1), + NormalStartIndex(-1), NormalLastIndex(-1), + TCoord0StartIndex(-1), TCoord0LastIndex(-1), + TCoord1StartIndex(-1), TCoord1LastIndex(-1) + { } + + s32 PosStartIndex; + s32 PosLastIndex; + + s32 NormalStartIndex; + s32 NormalLastIndex; + + s32 TCoord0StartIndex; + s32 TCoord0LastIndex; + + s32 TCoord1StartIndex; + s32 TCoord1LastIndex; + }; + + io::IFileSystem* FileSystem; + video::IVideoDriver* VideoDriver; + io::IXMLWriter* Writer; + core::array LibraryImages; + io::path Directory; + + // Helper struct for creating geometry copies for the ECGI_PER_MESH_AND_MATERIAL settings. + struct SGeometryMeshMaterials + { + bool equals(const core::array& names) const + { + if ( names.size() != MaterialNames.size() ) + return false; + for ( irr::u32 i=0; i MaterialNames; // Material names exported for this instance + core::array MaterialOwners; // Nodes using this specific mesh-material combination + }; + + // Check per mesh-ptr if stuff has been written for this mesh already + struct SColladaMesh + { + SColladaMesh() : MaterialsWritten(false), EffectsWritten(false) + { + } + + SGeometryMeshMaterials * findGeometryMeshMaterials(const irr::core::array materialNames) + { + for ( irr::u32 i=0; i= 0 ) + return GeometryMeshMaterials[i].GeometryName; + } + return Name; // (shouldn't get here usually) + } + + irr::core::stringw Name; + bool MaterialsWritten; // just an optimization doing that here in addition to the MaterialsWritten map + bool EffectsWritten; // just an optimization doing that here in addition to the EffectsWritten map + + core::array GeometryMeshMaterials; + }; + typedef core::map::Node MeshNode; + core::map Meshes; + + // structure for the lights library + struct SColladaLight + { + SColladaLight() {} + irr::core::stringw Name; + }; + typedef core::map::Node LightNode; + core::map LightNodes; + + // structure for the camera library + typedef core::map::Node CameraNode; + core::map CameraNodes; + + // Check per name if stuff has been written already + // TODO: second parameter not needed, we just don't have a core::set class yet in Irrlicht + core::map MaterialsWritten; + core::map EffectsWritten; + + // Cache material names + struct MaterialName + { + MaterialName(const irr::video::SMaterial & material, const irr::core::stringw& name) + : Material(material), Name(name) + {} + irr::video::SMaterial Material; + irr::core::stringw Name; + }; + irr::core::array< MaterialName > MaterialNameCache; +}; + + +} // end namespace +} // end namespace + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.cpp new file mode 100644 index 0000000..abc2c33 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.cpp @@ -0,0 +1,705 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CColorConverter.h" +#include "SColor.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +//! converts a monochrome bitmap to A1R5G5B5 data +void CColorConverter::convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad, bool flip) +{ + if (!in || !out) + return; + + if (flip) + out += width * height; + + for (s32 y=0; y>shift & 0x01 ? (s16)0xffff : (s16)0x8000; + + if ((--shift)<0) // 8 pixel done + { + shift=7; + ++in; + } + } + + if (shift != 7) // width did not fill last byte + ++in; + + if (!flip) + out += width; + in += linepad; + } +} + + + +//! converts a 4 bit palettized image to A1R5G5B5 +void CColorConverter::convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip) +{ + if (!in || !out || !palette) + return; + + if (flip) + out += width*height; + + for (s32 y=0; y> shift) & 0xf)]); + + if (shift==0) + { + shift = 4; + ++in; + } + else + shift = 0; + } + + if (shift == 0) // odd width + ++in; + + if (!flip) + out += width; + in += linepad; + } +} + + + +//! converts a 8 bit palettized image into A1R5G5B5 +void CColorConverter::convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad, bool flip) +{ + if (!in || !out || !palette) + return; + + if (flip) + out += width * height; + + for (s32 y=0; y> 15)&0x1)<<31) | (((t >> 10)&0x1F)<<19) | + (((t >> 5)&0x1F)<<11) | (t&0x1F)<<3; + out[(s32)(y*newWidth + x)] = t; + + sy+=sourceYStep; + } + } +} + + + +//! copies X8R8G8B8 32 bit data +void CColorConverter::convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip) +{ + if (!in || !out) + return; + + if (flip) + out += width * height; + + for (s32 y=0; y> 7; + dB[1] = (*sB & 0x03e0) >> 2; + dB[0] = (*sB & 0x1f) << 3; + + sB += 1; + dB += 3; + } +} + +void CColorConverter::convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u8 * dB = (u8 *)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[0] = (*sB & 0x7c00) >> 7; + dB[1] = (*sB & 0x03e0) >> 2; + dB[2] = (*sB & 0x1f) << 3; + + sB += 1; + dB += 3; + } +} + +void CColorConverter::convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = A1R5G5B5toA8R8G8B8(*sB++); +} + +void CColorConverter::convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 2); +} + +void CColorConverter::convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = A1R5G5B5toR5G6B5(*sB++); +} + +void CColorConverter::convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + // sB[3] is alpha + dB[0] = sB[2]; + dB[1] = sB[1]; + dB[2] = sB[0]; + + sB += 4; + dB += 3; + } +} + +void CColorConverter::convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + // sB[3] is alpha + dB[0] = sB[0]; + dB[1] = sB[1]; + dB[2] = sB[2]; + + sB += 4; + dB += 3; + } +} + +void CColorConverter::convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 4); +} + +void CColorConverter::convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + u32* sB = (u32*)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = A8R8G8B8toA1R5G5B5(*sB++); +} + +void CColorConverter::convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP) +{ + u8 * sB = (u8 *)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + { + s32 r = sB[2] >> 3; + s32 g = sB[1] >> 2; + s32 b = sB[0] >> 3; + + dB[0] = (r << 11) | (g << 5) | (b); + + sB += 4; + dB += 1; + } +} + +void CColorConverter::convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + u8 r = sB[2] & 0xe0; + u8 g = (sB[1] & 0xe0) >> 3; + u8 b = (sB[0] & 0xc0) >> 6; + + dB[0] = (r | g | b); + + sB += 4; + dB += 1; + } +} + +void CColorConverter::convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 3); +} + +void CColorConverter::convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8* )sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + { + *dB = 0xff000000 | (sB[0]<<16) | (sB[1]<<8) | sB[2]; + + sB += 3; + ++dB; + } +} + +void CColorConverter::convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + u8 * sB = (u8 *)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + { + s32 r = sB[0] >> 3; + s32 g = sB[1] >> 3; + s32 b = sB[2] >> 3; + + dB[0] = (0x8000) | (r << 10) | (g << 5) | (b); + + sB += 3; + dB += 1; + } +} + +void CColorConverter::convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8* )sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + { + *dB = 0xff000000 | (sB[2]<<16) | (sB[1]<<8) | sB[0]; + + sB += 3; + ++dB; + } +} + +void CColorConverter::convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u8* sB = (u8*)sP; + u8* dB = (u8*)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[0] = sB[3]; + dB[1] = sB[2]; + dB[2] = sB[1]; + dB[3] = sB[0]; + + sB += 4; + dB += 4; + } + +} + +void CColorConverter::convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP) +{ + u8 * sB = (u8 *)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + { + s32 r = sB[0] >> 3; + s32 g = sB[1] >> 2; + s32 b = sB[2] >> 3; + + dB[0] = (r << 11) | (g << 5) | (b); + + sB += 3; + dB += 1; + } +} + +void CColorConverter::convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP) +{ + memcpy(dP, sP, sN * 2); +} + +void CColorConverter::convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u8 * dB = (u8 *)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[0] = (*sB & 0xf800) >> 8; + dB[1] = (*sB & 0x07e0) >> 3; + dB[2] = (*sB & 0x001f) << 3; + + sB += 1; + dB += 3; + } +} + +void CColorConverter::convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u8 * dB = (u8 *)dP; + + for (s32 x = 0; x < sN; ++x) + { + dB[2] = (*sB & 0xf800) >> 8; + dB[1] = (*sB & 0x07e0) >> 3; + dB[0] = (*sB & 0x001f) << 3; + + sB += 1; + dB += 3; + } +} + +void CColorConverter::convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u32* dB = (u32*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = R5G6B5toA8R8G8B8(*sB++); +} + +void CColorConverter::convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP) +{ + u16* sB = (u16*)sP; + u16* dB = (u16*)dP; + + for (s32 x = 0; x < sN; ++x) + *dB++ = R5G6B5toA1R5G5B5(*sB++); +} + + +void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF) +{ + switch (sF) + { + case ECF_A1R5G5B5: + switch (dF) + { + case ECF_A1R5G5B5: + convert_A1R5G5B5toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_A1R5G5B5toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_A1R5G5B5toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_A1R5G5B5toR8G8B8(sP, sN, dP); + break; +#ifndef _DEBUG + default: + break; +#endif + } + break; + case ECF_R5G6B5: + switch (dF) + { + case ECF_A1R5G5B5: + convert_R5G6B5toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_R5G6B5toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_R5G6B5toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_R5G6B5toR8G8B8(sP, sN, dP); + break; +#ifndef _DEBUG + default: + break; +#endif + } + break; + case ECF_A8R8G8B8: + switch (dF) + { + case ECF_A1R5G5B5: + convert_A8R8G8B8toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_A8R8G8B8toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_A8R8G8B8toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_A8R8G8B8toR8G8B8(sP, sN, dP); + break; +#ifndef _DEBUG + default: + break; +#endif + } + break; + case ECF_R8G8B8: + switch (dF) + { + case ECF_A1R5G5B5: + convert_R8G8B8toA1R5G5B5(sP, sN, dP); + break; + case ECF_R5G6B5: + convert_R8G8B8toR5G6B5(sP, sN, dP); + break; + case ECF_A8R8G8B8: + convert_R8G8B8toA8R8G8B8(sP, sN, dP); + break; + case ECF_R8G8B8: + convert_R8G8B8toR8G8B8(sP, sN, dP); + break; +#ifndef _DEBUG + default: + break; +#endif + } + break; + } +} + + +} // end namespace video +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.h new file mode 100644 index 0000000..b3da9ad --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CColorConverter.h @@ -0,0 +1,92 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_COLOR_CONVERTER_H_INCLUDED__ +#define __C_COLOR_CONVERTER_H_INCLUDED__ + +#include "irrTypes.h" +#include "IImage.h" + +namespace irr +{ +namespace video +{ + +class CColorConverter +{ +public: + + //! converts a monochrome bitmap to A1R5G5B5 + static void convert1BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false); + + //! converts a 4 bit palettized image to A1R5G5B5 + static void convert4BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false); + + //! converts a 8 bit palettized image to A1R5G5B5 + static void convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false); + + //! converts a 8 bit palettized or non palettized image (A8) into R8G8B8 + static void convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false); + + //! converts a 8 bit palettized or non palettized image (A8) into A8R8G8B8 + static void convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false); + + //! converts R8G8B8 16 bit data to A1R5G5B5 data + static void convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false); + + //! copies R8G8B8 24 bit data to 24 data, and flips and + //! mirrors the image during the process. + static void convert24BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, s32 linepad=0, bool flip=false, bool bgr=false); + + //! Resizes the surface to a new size and converts it at the same time + //! to an A8R8G8B8 format, returning the pointer to the new buffer. + static void convert16bitToA8R8G8B8andResize(const s16* in, s32* out, s32 newWidth, s32 newHeight, s32 currentWidth, s32 currentHeight); + + //! copies X8R8G8B8 32 bit data, and flips and + //! mirrors the image during the process. + static void convert32BitTo32Bit(const s32* in, s32* out, s32 width, s32 height, s32 linepad, bool flip=false); + + + //! functions for converting one image format to another efficiently + //! and hopefully correctly. + //! + //! \param sP pointer to source pixel data + //! \param sN number of source pixels to copy + //! \param dP pointer to destination data buffer. must be big enough + //! to hold sN pixels in the output format. + static void convert_A1R5G5B5toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toB8G8R8(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_A1R5G5B5toR5G6B5(const void* sP, s32 sN, void* dP); + + static void convert_A8R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toB8G8R8(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_A8R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP); + + static void convert_A8R8G8B8toR3G3B2(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_R8G8B8toR5G6B5(const void* sP, s32 sN, void* dP); + static void convert_B8G8R8toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_B8G8R8A8toA8R8G8B8(const void* sP, s32 sN, void* dP); + + static void convert_R5G6B5toR5G6B5(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toR8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toB8G8R8(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toA8R8G8B8(const void* sP, s32 sN, void* dP); + static void convert_R5G6B5toA1R5G5B5(const void* sP, s32 sN, void* dP); + static void convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF); +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.cpp new file mode 100644 index 0000000..e3eaecc --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.cpp @@ -0,0 +1,235 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CCubeSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "SMeshBuffer.h" +#include "os.h" +#include "CShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + + /* + 011 111 + /6,8------/5 y + / | / | ^ z + / | / | | / + 010 3,9-------2 | |/ + | 7- - -10,4 101 *---->x + | / | / + |/ | / + 0------11,1/ + 000 100 + */ + +//! constructor +CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr, + s32 id, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) + : IMeshSceneNode(parent, mgr, id, position, rotation, scale), + Mesh(0), Shadow(0), Size(size) +{ + #ifdef _DEBUG + setDebugName("CCubeSceneNode"); + #endif + + setSize(); +} + + +CCubeSceneNode::~CCubeSceneNode() +{ + if (Shadow) + Shadow->drop(); + if (Mesh) + Mesh->drop(); +} + + +void CCubeSceneNode::setSize() +{ + if (Mesh) + Mesh->drop(); + Mesh = SceneManager->getGeometryCreator()->createCubeMesh(core::vector3df(Size)); +} + + +//! renders the node. +void CCubeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + if (Shadow) + Shadow->updateShadowVolumes(); + + // for debug purposes only: + video::SMaterial mat = Mesh->getMeshBuffer(0)->getMaterial(); + + // overwrite half transparency + if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) + mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; + driver->setMaterial(mat); + driver->drawMeshBuffer(Mesh->getMeshBuffer(0)); + + // for debug purposes only: + if (DebugDataVisible) + { + video::SMaterial m; + m.Lighting = false; + m.AntiAliasing=0; + driver->setMaterial(m); + + if (DebugDataVisible & scene::EDS_BBOX) + { + driver->draw3DBox(Mesh->getMeshBuffer(0)->getBoundingBox(), video::SColor(255,255,255,255)); + } + if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) + { + driver->draw3DBox(Mesh->getMeshBuffer(0)->getBoundingBox(), + video::SColor(255,190,128,128)); + } + if (DebugDataVisible & scene::EDS_NORMALS) + { + // draw normals + const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); + const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); + const u32 count = Mesh->getMeshBufferCount(); + + for (u32 i=0; i != count; ++i) + { + driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor); + } + } + + // show mesh + if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) + { + m.Wireframe = true; + driver->setMaterial(m); + + driver->drawMeshBuffer(Mesh->getMeshBuffer(0)); + } + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CCubeSceneNode::getBoundingBox() const +{ + return Mesh->getMeshBuffer(0)->getBoundingBox(); +} + + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool CCubeSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + } + + return ISceneNode::removeChild(child); +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* CCubeSceneNode::addShadowVolumeSceneNode( + const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (!shadowMesh) + shadowMesh = Mesh; // if null is given, use the mesh of node + + if (Shadow) + Shadow->drop(); + + Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + + +void CCubeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. +video::SMaterial& CCubeSceneNode::getMaterial(u32 i) +{ + return Mesh->getMeshBuffer(0)->getMaterial(); +} + + +//! returns amount of materials used by this scene node. +u32 CCubeSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Writes attributes of the scene node. +void CCubeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addFloat("Size", Size); +} + + +//! Reads attributes of the scene node. +void CCubeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + f32 newSize = in->getAttributeAsFloat("Size"); + newSize = core::max_(newSize, 0.0001f); + if (newSize != Size) + { + Size = newSize; + setSize(); + } + + ISceneNode::deserializeAttributes(in, options); +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CCubeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CCubeSceneNode* nb = new CCubeSceneNode(Size, newParent, + newManager, ID, RelativeTranslation); + + nb->cloneMembers(this, newManager); + nb->getMaterial(0) = getMaterial(0); + nb->Shadow = Shadow; + if ( nb->Shadow ) + nb->Shadow->grab(); + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.h new file mode 100644 index 0000000..b676938 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CCubeSceneNode.h @@ -0,0 +1,93 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_CUBE_SCENE_NODE_H_INCLUDED__ +#define __C_CUBE_SCENE_NODE_H_INCLUDED__ + +#include "IMeshSceneNode.h" +#include "SMesh.h" + +namespace irr +{ +namespace scene +{ + class CCubeSceneNode : public IMeshSceneNode + { + public: + + //! constructor + CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + virtual ~CCubeSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_CUBE; } + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh, + s32 id, bool zfailmethod=true, f32 infinity=10000.0f); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + //! Sets a new mesh to display + virtual void setMesh(IMesh* mesh) {} + + //! Returns the current mesh + virtual IMesh* getMesh(void) { return Mesh; } + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly) {} + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const { return false; } + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + + private: + void setSize(); + + IMesh* Mesh; + IShadowVolumeSceneNode* Shadow; + f32 Size; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.cpp new file mode 100644 index 0000000..9886b37 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.cpp @@ -0,0 +1,2455 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D8Driver.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "os.h" +#include "S3DVertex.h" +#include "CD3D8Texture.h" +#include "CD3D8MaterialRenderer.h" +#include "CD3D8ShaderMaterialRenderer.h" +#include "CD3D8NormalMapRenderer.h" +#include "CD3D8ParallaxMapRenderer.h" +#include "SIrrCreationParameters.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CD3D8Driver::CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) + : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), + ResetRenderStates(true), Transformation3DChanged(false), + D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), + WindowId(0), SceneSourceRect(0), + LastVertexType((video::E_VERTEX_TYPE)-1), + MaxTextureUnits(0), MaxUserClipPlanes(0), + MaxLightDistance(0), LastSetLight(-1), DeviceLost(false), + DriverWasReset(true), Params(params) +{ + #ifdef _DEBUG + setDebugName("CD3D8Driver"); + #endif + + printVersion(); + + for (u32 i=0; iRelease(); + + if (pID3D) + pID3D->Release(); +} + + +void CD3D8Driver::createMaterialRenderers() +{ + // create D3D8 material renderers + + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); + + // add the same renderer for all lightmap types + CD3D8MaterialRenderer_LIGHTMAP* lmr = new CD3D8MaterialRenderer_LIGHTMAP(pID3DDevice, this); + addMaterialRenderer(lmr); // for EMT_LIGHTMAP: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: + lmr->drop(); + + // add remaining material renderers + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); + + // add normal map renderers + s32 tmp = 0; + video::IMaterialRenderer* renderer = 0; + + renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add parallax map renderers + + renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add basic 1 texture blending + addAndDropMaterialRenderer(new CD3D8MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); +} + + +//! initialises the Direct3D API +bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware) +{ + HRESULT hr; + typedef IDirect3D8 * (__stdcall *D3DCREATETYPE)(UINT); + +#if defined( _IRR_XBOX_PLATFORM_) + D3DCREATETYPE d3dCreate = (D3DCREATETYPE) &Direct3DCreate8; +#else + D3DLibrary = LoadLibrary( __TEXT("d3d8.dll") ); + + if (!D3DLibrary) + { + os::Printer::log("Error, could not load d3d8.dll.", ELL_ERROR); + return false; + } + + D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate8"); + + if (!d3dCreate) + { + os::Printer::log("Error, could not get proc adress of Direct3DCreate8.", ELL_ERROR); + return false; + } +#endif + + //just like pID3D = Direct3DCreate8(D3D_SDK_VERSION); + pID3D = (*d3dCreate)(D3D_SDK_VERSION); + + if (!pID3D) + { + os::Printer::log("Error initializing D3D.", ELL_ERROR); + return false; + } + + // print device information + D3DADAPTER_IDENTIFIER8 dai; + if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, D3DENUM_NO_WHQL_LEVEL, &dai))) + { + char tmp[512]; + + s32 Product = HIWORD(dai.DriverVersion.HighPart); + s32 Version = LOWORD(dai.DriverVersion.HighPart); + s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); + s32 Build = LOWORD(dai.DriverVersion.LowPart); + + sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, + SubVersion, Build); + os::Printer::log(tmp, ELL_INFORMATION); + } + + D3DDISPLAYMODE d3ddm; + hr = pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm); + if (FAILED(hr)) + { + os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); + return false; + } + + ZeroMemory(&present, sizeof(present)); + + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + present.Windowed = TRUE; + present.BackBufferFormat = d3ddm.Format; + present.EnableAutoDepthStencil = TRUE; + + if (Params.Fullscreen) + { + present.SwapEffect = D3DSWAPEFFECT_FLIP; + present.Windowed = FALSE; + present.BackBufferWidth = Params.WindowSize.Width; + present.BackBufferHeight = Params.WindowSize.Height; + present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + + if (Params.Vsync) + present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else + present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + if (Params.Bits == 32) + present.BackBufferFormat = D3DFMT_X8R8G8B8; + else + present.BackBufferFormat = D3DFMT_R5G6B5; + } + + D3DDEVTYPE devtype = D3DDEVTYPE_HAL; + #ifndef _IRR_D3D_NO_SHADER_DEBUGGING + devtype = D3DDEVTYPE_REF; + #endif + + // enable anti alias if possible and whished + if (Params.AntiAlias > 0) + { + if(Params.AntiAlias > 16) + Params.AntiAlias = 16; + + while(Params.AntiAlias > 0) + { + if(!FAILED(pID3D->CheckDeviceMultiSampleType(Params.DisplayAdapter, + devtype , present.BackBufferFormat, !Params.Fullscreen, + (D3DMULTISAMPLE_TYPE)Params.AntiAlias))) + { + present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + break; + } + --Params.AntiAlias; + } + + if(Params.AntiAlias==0) + os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); + } + + // check stencil buffer compatibility + if (Params.Stencilbuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D24S8; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { +#if !defined( _IRR_XBOX_PLATFORM_) + present.AutoDepthStencilFormat = D3DFMT_D24X4S4; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D15S1; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); + Params.Stencilbuffer = false; + } + } +#endif + } + else + if(FAILED(pID3D->CheckDepthStencilMatch(Params.DisplayAdapter, devtype, + present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) + { + os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); + Params.Stencilbuffer = false; + } + } + // do not use else here to cope with flag change in previous block + if (!Params.Stencilbuffer) + { +#if !defined( _IRR_XBOX_PLATFORM_) + present.AutoDepthStencilFormat = D3DFMT_D32; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X8; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D16; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); + return false; + } + } + } +#else + present.AutoDepthStencilFormat = D3DFMT_D16; + if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); + return false; + } +#endif + } + + // create device +#if defined( _IRR_XBOX_PLATFORM_) + DWORD fpuPrecision = 0; +#else + DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; + DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; +#endif + if (pureSoftware) + { + hr = pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd, + fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D8 software device.", ELL_ERROR); + } + else + { + hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, + fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if(FAILED(hr)) + hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, + fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); + if(FAILED(hr)) + hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, + fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); + } + + if (!pID3DDevice) + { + os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); + return false; + } + + // get caps + pID3DDevice->GetDeviceCaps(&Caps); + + if (Params.Stencilbuffer && + (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) + { + os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); + Params.Stencilbuffer = false; + } + + // set default vertex shader + setVertexShader(EVT_STANDARD); + + // enable antialiasing + if (Params.AntiAlias>0) + pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + + // set fog mode + setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); + + // set exposed data + ExposedData.D3D8.D3D8 = pID3D; + ExposedData.D3D8.D3DDev8 = pID3DDevice; + ExposedData.D3D8.HWnd = hwnd; + + ResetRenderStates = true; + + // create materials + createMaterialRenderers(); + + MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); + MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; + + DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); + DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); + DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); + DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); + DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); + DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); + DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); + DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); + DriverAttributes->setAttribute("Version", 800); + DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100); + DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); + + // set the renderstates + setRenderStates3DMode(); + + // so far so good. + return true; +} + + +//! applications must call this method before performing any rendering. returns false if failed. +bool CD3D8Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, + const SExposedVideoData& videoData, core::rect* sourceRect) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); + WindowId = (HWND)videoData.D3D8.HWnd; + SceneSourceRect = sourceRect; + + if (!pID3DDevice) + return false; + + HRESULT hr; + if (DeviceLost) + { +#ifndef _IRR_XBOX_PLATFORM_ + if(FAILED(hr = pID3DDevice->TestCooperativeLevel())) + { + if (hr == D3DERR_DEVICELOST) + { + Sleep(100); + hr = pID3DDevice->TestCooperativeLevel(); + if (hr == D3DERR_DEVICELOST) + return false; + } + + if ((hr == D3DERR_DEVICENOTRESET) && !reset()) + return false; + } +#endif + } + + DWORD flags = 0; + + if (backBuffer) + flags |= D3DCLEAR_TARGET; + + if (zBuffer) + flags |= D3DCLEAR_ZBUFFER; + + if (Params.Stencilbuffer) + flags |= D3DCLEAR_STENCIL; + + if (flags) + { + hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); + if (FAILED(hr)) + os::Printer::log("Direct3D8 clear failed.", ELL_WARNING); + } + + hr = pID3DDevice->BeginScene(); + if (FAILED(hr)) + { + os::Printer::log("Direct3D8 begin scene failed.", ELL_WARNING); + return false; + } + + return true; +} + + +//! applications must call this method after performing any rendering. returns false if failed. +bool CD3D8Driver::endScene() +{ + CNullDriver::endScene(); + DriverWasReset=false; + + HRESULT hr = pID3DDevice->EndScene(); + if (FAILED(hr)) + { + os::Printer::log("DIRECT3D8 end scene failed.", ELL_WARNING); + return false; + } + + RECT* srcRct = 0; + RECT sourceRectData; + if ( SceneSourceRect) + { + srcRct = &sourceRectData; + sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; + sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; + sourceRectData.right = SceneSourceRect->LowerRightCorner.X; + sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; + } + + hr = pID3DDevice->Present(srcRct, NULL, WindowId, NULL); + + if (SUCCEEDED(hr)) + return true; + + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("DIRECT3D8 device lost.", ELL_WARNING); + } + else + os::Printer::log("DIRECT3D8 present failed.", ELL_WARNING); + return false; +} + + +//! resets the device +bool CD3D8Driver::reset() +{ + u32 i; + os::Printer::log("Resetting D3D8 device.", ELL_INFORMATION); + + for (i=0; iisRenderTarget()) + { + IDirect3DTexture8* tex = ((CD3D8Texture*)(Textures[i].Surface))->getDX8Texture(); + if (tex) + tex->Release(); + } + } + DriverWasReset=true; + + HRESULT hr = pID3DDevice->Reset(&present); + + for (i=0; iisRenderTarget()) + ((CD3D8Texture*)(Textures[i].Surface))->createRenderTarget(); + } + + if (FAILED(hr)) + { + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); + } + else + os::Printer::log("Resetting failed.", ELL_WARNING); + return false; + } + + DeviceLost = false; + ResetRenderStates = true; + LastVertexType = (E_VERTEX_TYPE)-1; + + for (i=0; i= D3DVS_VERSION(1,1); + case EVDF_VERTEX_SHADER_2_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); + case EVDF_VERTEX_SHADER_3_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); + case EVDF_PIXEL_SHADER_1_1: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); + case EVDF_PIXEL_SHADER_1_2: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); + case EVDF_PIXEL_SHADER_1_3: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); + case EVDF_PIXEL_SHADER_1_4: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); + case EVDF_PIXEL_SHADER_2_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); + case EVDF_PIXEL_SHADER_3_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); + case EVDF_TEXTURE_NSQUARE: + return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; + case EVDF_TEXTURE_NPOT: + return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; + case EVDF_COLOR_MASK: + return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; + case EVDF_BLEND_OPERATIONS: + case EVDF_TEXTURE_MATRIX: + return true; + default: + return false; + }; +} + + +//! sets transformation +void CD3D8Driver::setTransform(E_TRANSFORMATION_STATE state, + const core::matrix4& mat) +{ + switch(state) + { + case ETS_VIEW: + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + Transformation3DChanged = true; + break; + case ETS_WORLD: + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + Transformation3DChanged = true; + break; + case ETS_PROJECTION: + pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + Transformation3DChanged = true; + break; + case ETS_COUNT: + return; + default: + if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) + { + pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), + (D3DMATRIX*)((void*)mat.pointer())); + } + break; + } + + Matrices[state] = mat; +} + + +//! sets the current Texture +bool CD3D8Driver::setActiveTexture(u32 stage, const video::ITexture* texture) +{ + if (CurrentTexture[stage] == texture) + return true; + + if (texture && (texture->getDriverType() != EDT_DIRECT3D8)) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + CurrentTexture[stage] = texture; + + if (!texture) + { + pID3DDevice->SetTexture(stage, 0); + pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + } + else + { + pID3DDevice->SetTexture(stage, ((const CD3D8Texture*)texture)->getDX8Texture()); + } + return true; +} + + +//! sets a material +void CD3D8Driver::setMaterial(const SMaterial& material) +{ + Material = material; + OverrideMaterial.apply(Material); + + for (u32 i=0; igetDriverType() != EDT_DIRECT3D8) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + // check for valid render target + + CD3D8Texture* tex = (CD3D8Texture*)texture; + + if (texture && !tex->isRenderTarget()) + { + os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); + return false; + } + + if (texture && (tex->getSize().Width > ScreenSize.Width || + tex->getSize().Height > ScreenSize.Height )) + { + os::Printer::log("Error: Tried to set a render target texture which is bigger than the screen.", ELL_ERROR); + return false; + } + + // check if we should set the previous RT back + + bool ret = true; + + if (tex == 0) + { + if (PrevRenderTarget) + { + IDirect3DSurface8* dss = 0; + pID3DDevice->GetDepthStencilSurface(&dss); + + if (FAILED(pID3DDevice->SetRenderTarget(PrevRenderTarget, dss))) + { + os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); + ret = false; + } + + if (dss) + dss->Release(); + + CurrentRendertargetSize = core::dimension2d(0,0); + PrevRenderTarget->Release(); + PrevRenderTarget = 0; + } + } + else + { + // we want to set a new target. so do this. + + // store previous target + + if (!PrevRenderTarget && (FAILED(pID3DDevice->GetRenderTarget(&PrevRenderTarget)))) + { + os::Printer::log("Could not get previous render target.", ELL_ERROR); + return false; + } + + // set new render target + + IDirect3DSurface8* dss = 0; + pID3DDevice->GetDepthStencilSurface(&dss); + + if (FAILED(pID3DDevice->SetRenderTarget(tex->getRenderTargetSurface(), dss))) + { + os::Printer::log("Error: Could not set render target.", ELL_ERROR); + ret = false; + } + + if (dss) + dss->Release(); + + CurrentRendertargetSize = tex->getSize(); + } + Transformation3DChanged = true; + + if (clearBackBuffer || clearZBuffer) + { + DWORD flags = 0; + + if (clearBackBuffer) + flags |= D3DCLEAR_TARGET; + + if (clearZBuffer) + flags |= D3DCLEAR_ZBUFFER; + + pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); + } + + return ret; +} + + +//! Creates a render target texture. +ITexture* CD3D8Driver::addRenderTargetTexture( + const core::dimension2d& size, const io::path& name, + const ECOLOR_FORMAT format) +{ + CD3D8Texture* tex = new CD3D8Texture(this, size, name); + if (tex) + { + if (!tex->Texture) + { + tex->drop(); + return 0; + } + addTexture(tex); + tex->drop(); + } + return tex; +} + + +//! sets a viewport +void CD3D8Driver::setViewPort(const core::rect& area) +{ + core::rect vp(area); + core::rect rendert(0,0, ScreenSize.Width, ScreenSize.Height); + vp.clipAgainst(rendert); + + D3DVIEWPORT8 viewPort; + viewPort.X = vp.UpperLeftCorner.X; + viewPort.Y = vp.UpperLeftCorner.Y; + viewPort.Width = vp.getWidth(); + viewPort.Height = vp.getHeight(); + viewPort.MinZ = 0.0f; + viewPort.MaxZ = 1.0f; + + HRESULT hr = D3DERR_INVALIDCALL; + if (vp.getHeight()>0 && vp.getWidth()>0) + hr = pID3DDevice->SetViewport(&viewPort); + + if (FAILED(hr)) + os::Printer::log("Failed setting the viewport.", ELL_WARNING); + + ViewPort = vp; +} + + +//! gets the area of the current viewport +const core::rect& CD3D8Driver::getViewPort() const +{ + return ViewPort; +} + + +//! draws a vertex primitive list +void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); + + if (!vertexCount || !primitiveCount) + return; + + draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, + vType, pType, iType, true); +} + + +//! draws a vertex primitive list in 2d +void CD3D8Driver::draw2DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); + + if (!vertexCount || !primitiveCount) + return; + + draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, + vType, pType, iType, false); +} + + +void CD3D8Driver::draw2D3DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType, bool is3D) +{ + setVertexShader(vType); + + const u32 stride = getVertexPitchFromType(vType); + + D3DFORMAT indexType=D3DFMT_UNKNOWN; + switch (iType) + { + case (EIT_16BIT): + { + indexType=D3DFMT_INDEX16; + break; + } + case (EIT_32BIT): + { + indexType=D3DFMT_INDEX32; + break; + } + } + + if (is3D) + { + if (!setRenderStates3DMode()) + return; + } + else + { + if (Material.MaterialType==EMT_ONETEXTURE_BLEND) + { + E_BLEND_FACTOR srcFact; + E_BLEND_FACTOR dstFact; + E_MODULATE_FUNC modulo; + u32 alphaSource; + unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); + setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); + } + else + setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); + } + + switch (pType) + { + case scene::EPT_POINT_SPRITES: + case scene::EPT_POINTS: + { + f32 tmp=Material.Thickness/getScreenSize().Height; + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&tmp)); + tmp=1.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); + tmp=0.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); + } + break; + case scene::EPT_LINE_STRIP: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + case scene::EPT_LINE_LOOP: + { + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount - 1, indexList, indexType, vertices, stride); + u16 tmpIndices[] = {primitiveCount - 1, 0}; + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + 1, tmpIndices, indexType, vertices, stride); + } + break; + case scene::EPT_LINES: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + case scene::EPT_TRIANGLE_STRIP: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + case scene::EPT_TRIANGLE_FAN: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + case scene::EPT_TRIANGLES: + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + } +} + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CD3D8Driver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!sourceRect.isValid()) + return; + + if (!setActiveTexture(0, texture)) + return; + + core::position2d targetPos = pos; + core::position2d sourcePos = sourceRect.UpperLeftCorner; + // This needs to be signed as it may go negative. + core::dimension2d sourceSize(sourceRect.getSize()); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + return; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + return; + } + + // ok, we've clipped everything. + // now draw it. + + core::rect tcoords; + tcoords.UpperLeftCorner.X = (f32)sourcePos.X / texture->getOriginalSize().Width ; + tcoords.UpperLeftCorner.Y = (f32)sourcePos.Y / texture->getOriginalSize().Height; + tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + (f32)sourceSize.Width / texture->getOriginalSize().Width; + tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + (f32)sourceSize.Height / texture->getOriginalSize().Height; + + const core::rect poss(targetPos, sourceSize); + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, + (f32)poss.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, + (f32)poss.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, + (f32)poss.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, + (f32)poss.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + const s16 indices[6] = {0,1,2,0,2,3}; + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); +} + + +void CD3D8Driver::draw2DImage(const video::ITexture* texture, + const core::rect& destRect, + const core::rect& sourceRect, + const core::rect* clipRect, + const video::SColor* const colors, + bool useAlphaChannelOfTexture) +{ + if(!texture) + return; + + const core::dimension2d& ss = texture->getOriginalSize(); + core::rect tcoords; + tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; + tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; + tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; + tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; + + core::rect clippedRect(destRect); + if (clipRect) + { + clippedRect.clipAgainst(*clipRect); + + //tcoords must be clipped by the same factors + const f32 tcWidth = tcoords.getWidth(); + const f32 tcHeight = tcoords.getHeight(); + + const f32 invDestRectWidth = 1.f / (f32)(destRect.getWidth()); + f32 scale = (f32)(clippedRect.UpperLeftCorner.X - destRect.UpperLeftCorner.X) * invDestRectWidth; + tcoords.UpperLeftCorner.X += scale * tcWidth; + scale = (f32)(destRect.LowerRightCorner.X - clippedRect.LowerRightCorner.X) * invDestRectWidth; + tcoords.LowerRightCorner.X -= scale * tcWidth; + + const f32 invDestRectHeight = 1.f / (f32)(destRect.getHeight()); + scale = (f32)(clippedRect.UpperLeftCorner.Y - destRect.UpperLeftCorner.Y) * invDestRectHeight; + tcoords.UpperLeftCorner.Y += scale * tcHeight; + scale = (f32)(destRect.LowerRightCorner.Y - clippedRect.LowerRightCorner.Y) * invDestRectHeight; + tcoords.LowerRightCorner.Y -= scale * tcHeight; + } + + const video::SColor temp[4] = + { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF + }; + + const video::SColor* const useColor = colors ? colors : temp; + + S3DVertex vtx[4]; // clock wise + vtx[0] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[0], + tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[3], + tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[2], + tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[1], + tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + const s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || + useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, + true, useAlphaChannelOfTexture); + + setActiveTexture(0, texture); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); +} + + +//!Draws an 2d rectangle with a gradient. +void CD3D8Driver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, + SColor colorRightDown, const core::rect* clip) +{ + core::rect pos(position); + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); + vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); + vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); + vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); + + const s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode( + colorLeftUp.getAlpha() < 255 || + colorRightUp.getAlpha() < 255 || + colorLeftDown.getAlpha() < 255 || + colorRightDown.getAlpha() < 255, false, false); + + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); +} + + +//! Draws a 2d line. +void CD3D8Driver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + if (start==end) + drawPixel(start.X, start.Y, color); + else + { + // thanks to Vash TheStampede who sent in his implementation + S3DVertex vtx[2]; + vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, + 0.0f, 0.0f, 0.0f, // normal + color, 0.0f, 0.0f); // texture + + vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, + 0.0f, 0.0f, 0.0f, + color, 0.0f, 0.0f); + + setRenderStates2DMode(color.getAlpha() < 255, false, false); + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex)); + } +} + + +//! Draws a pixel +void CD3D8Driver::drawPixel(u32 x, u32 y, const SColor & color) +{ + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) + return; + + setRenderStates2DMode(color.getAlpha() < 255, false, false); + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); + + pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); +} + + +//! sets right vertex shader +void CD3D8Driver::setVertexShader(E_VERTEX_TYPE newType) +{ + // Because we don't know if a vertex shader was set in a material instead of a + // fvf, this call cannot be prevented in D3D8. + //if (newType != LastVertexType) + { + LastVertexType = newType; + HRESULT hr = 0; + + switch(newType) + { + case EVT_STANDARD: + hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); + break; + case EVT_2TCOORDS: + hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); + break; + case EVT_TANGENTS: + hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | + D3DFVF_TEXCOORDSIZE2(0) | // real texture coord + D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent + D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal + ); + break; + } + + if (FAILED(hr)) + { + os::Printer::log("Could not set vertex Shader.", ELL_ERROR); + return; + } + } +} + + +//! sets the needed renderstates +bool CD3D8Driver::setRenderStates3DMode() +{ + if (!pID3DDevice) + return false; + + if (CurrentRenderMode != ERM_3D) + { + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + + ResetRenderStates = true; + } + + if (ResetRenderStates || LastMaterial != Material) + { + // unset old material + + if (CurrentRenderMode == ERM_3D && + LastMaterial.MaterialType != Material.MaterialType && + LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + + // set new material. + + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( + Material, LastMaterial, ResetRenderStates, this); + } + + bool shaderOK = true; + + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); + + LastMaterial = Material; + + ResetRenderStates = false; + + CurrentRenderMode = ERM_3D; + + return shaderOK; +} + + +//! Map Irrlicht texture wrap mode to native values +D3DTEXTUREADDRESS CD3D8Driver::getTextureWrapMode(const u8 clamp) +{ + switch (clamp) + { + case ETC_REPEAT: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) + return D3DTADDRESS_WRAP; + case ETC_CLAMP: + case ETC_CLAMP_TO_EDGE: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) + return D3DTADDRESS_CLAMP; + case ETC_MIRROR: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) + return D3DTADDRESS_MIRROR; + case ETC_CLAMP_TO_BORDER: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) + return D3DTADDRESS_BORDER; + else + return D3DTADDRESS_CLAMP; + case ETC_MIRROR_CLAMP: + case ETC_MIRROR_CLAMP_TO_EDGE: + case ETC_MIRROR_CLAMP_TO_BORDER: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) + return D3DTADDRESS_MIRRORONCE; + else + return D3DTADDRESS_CLAMP; + default: + return D3DTADDRESS_WRAP; + } +} + + +//! Can be called by an IMaterialRenderer to make its work easier. +void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderstates) +{ + if (resetAllRenderstates || + lastmaterial.AmbientColor != material.AmbientColor || + lastmaterial.DiffuseColor != material.DiffuseColor || + lastmaterial.SpecularColor != material.SpecularColor || + lastmaterial.EmissiveColor != material.EmissiveColor || + lastmaterial.Shininess != material.Shininess) + { + D3DMATERIAL8 mat; + mat.Diffuse = colorToD3D(material.DiffuseColor); + mat.Ambient = colorToD3D(material.AmbientColor); + mat.Specular = colorToD3D(material.SpecularColor); + mat.Emissive = colorToD3D(material.EmissiveColor); + mat.Power = material.Shininess; + pID3DDevice->SetMaterial(&mat); + } + + if (lastmaterial.ColorMaterial != material.ColorMaterial) + { + pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); + pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, + ((material.ColorMaterial == ECM_DIFFUSE)|| + (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); + pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, + ((material.ColorMaterial == ECM_AMBIENT)|| + (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); + pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, + (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, + (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + } + + // fillmode + if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) + { + if (material.Wireframe) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + else + if (material.PointCloud) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); + else + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + } + + // shademode + if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) + { + if (material.GouraudShading) + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + else + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } + + // lighting + if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) + { + if (material.Lighting) + pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); + else + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + } + + // zbuffer + if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) + { + switch (material.ZBuffer) + { + case ECFN_NEVER: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + break; + case ECFN_LESSEQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + break; + case ECFN_EQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + break; + case ECFN_LESS: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + break; + case ECFN_NOTEQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); + break; + case ECFN_GREATEREQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); + break; + case ECFN_GREATER: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); + break; + case ECFN_ALWAYS: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + break; + } + } + + // zwrite +// if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) + { + if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); + else + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); + } + + // back face culling + if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) + { +// if (material.FrontfaceCulling && material.BackfaceCulling) +// pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); +// else + if (material.FrontfaceCulling) + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + else + if (material.BackfaceCulling) + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + else + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } + + // fog + if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) + { + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); + } + + // specular highlights + if (resetAllRenderstates || !core::equals(lastmaterial.Shininess, material.Shininess)) + { + bool enable = (material.Shininess!=0); + pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); + pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); + } + + // normalization + if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) + { + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); + } + + // Color Mask + if (queryFeature(EVDF_COLOR_MASK) && + (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) + { + const DWORD flag = + ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | + ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | + ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | + ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); + pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); + } + + if (queryFeature(EVDF_BLEND_OPERATIONS) && + (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) + { + if (material.BlendOperation==EBO_NONE) + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + switch (material.BlendOperation) + { + case EBO_MAX: + case EBO_MAX_FACTOR: + case EBO_MAX_ALPHA: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); + break; + case EBO_MIN: + case EBO_MIN_FACTOR: + case EBO_MIN_ALPHA: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); + break; + case EBO_SUBTRACT: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); + break; + case EBO_REVSUBTRACT: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); + break; + default: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + break; + } + } + } + + // Polygon offset + if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || + lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || + lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) + { + pID3DDevice->SetRenderState(D3DRS_ZBIAS, material.PolygonOffsetFactor); + } + + // thickness + if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) + { + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); + } + + // texture address mode + for (u32 st=0; stSetTextureStageState(st, D3DTSS_MIPMAPLODBIAS, *(DWORD*)(&tmp)); + } + + if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) + pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); + // If separate UV not supported reuse U for V + if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) + pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); + else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) + pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); + + // Bilinear and/or trilinear + if (resetAllRenderstates || + lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || + lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || + lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || + lastmaterial.UseMipMaps != material.UseMipMaps) + { + if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter>1) + { + const D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && + material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + const D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && + material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + const D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; + + if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) + pID3DDevice->SetTextureStageState(st, D3DTSS_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); + pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, tftMag); + pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, tftMin); + pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, tftMip); + } + else + { + pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, D3DTEXF_POINT); + pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, D3DTEXF_NONE); + pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, D3DTEXF_POINT); + } + } + } +} + + +//! sets the needed renderstates +void CD3D8Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) +{ + if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && + CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || + Transformation3DChanged) + { + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + static_cast(Material.MaterialType) < MaterialRenderers.size()) + { + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + ResetRenderStates = true; + } + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + Transformation3DChanged = false; + + setActiveTexture(0,0); + setActiveTexture(1,0); + setActiveTexture(2,0); + setActiveTexture(3,0); + + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + + pID3DDevice->SetVertexShader(D3DFVF_XYZ); + LastVertexType = (video::E_VERTEX_TYPE)(-1); + + pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + + pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); + pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); + pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); + if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) + pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + } + + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) + { + // USE THE ZPASS METHOD + pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); + } + else + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) + { + // USE THE ZFAIL METHOD + pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); + } + + CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; +} + + +//! sets the needed renderstates +void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) +{ + if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) + { + pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D8); + pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); + pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D8); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1 ); + pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); + //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); + pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); + pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); + + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); + + Transformation3DChanged = false; + + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + CurrentRenderMode = ERM_STENCIL_FILL; +} + + +//! sets the needed renderstates +void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) +{ + if (!pID3DDevice) + return; + + if (CurrentRenderMode != ERM_2D || Transformation3DChanged) + { + // unset last 3d material + if (CurrentRenderMode == ERM_3D) + { + if (static_cast(LastMaterial.MaterialType) < MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + } + if (!OverrideMaterial2DEnabled) + { + setBasicRenderStates(InitMaterial2D, LastMaterial, true); + LastMaterial=InitMaterial2D; + + // fix everything that is wrongly set by SMaterial default + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); + + } + pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); + core::matrix4 m; + m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); + m.setTranslation(core::vector3df(-1,1,0)); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); + + Transformation3DChanged = false; + } + if (OverrideMaterial2DEnabled) + { + OverrideMaterial2D.Lighting=false; + setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); + LastMaterial = OverrideMaterial2D; + } + + // no alphaChannel without texture + alphaChannel &= texture; + + if (alpha || alphaChannel) + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + else + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + if (texture) + { + setTransform(ETS_TEXTURE_0, core::IdentityMatrix); + // Due to the transformation change, the previous line would call a reset each frame + // but we can safely reset the variable as it was false before + Transformation3DChanged=false; + } + if (alphaChannel) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + } + + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + } + } + + CurrentRenderMode = ERM_2D; +} + + +//! deletes all dynamic lights there are +void CD3D8Driver::deleteAllDynamicLights() +{ + for (s32 i=0; iLightEnable(i, false); + + LastSetLight = -1; + + CNullDriver::deleteAllDynamicLights(); +} + + +//! adds a dynamic light +s32 CD3D8Driver::addDynamicLight(const SLight& dl) +{ + CNullDriver::addDynamicLight(dl); + + D3DLIGHT8 light; + + switch (dl.Type) + { + case ELT_POINT: + light.Type = D3DLIGHT_POINT; + break; + case ELT_SPOT: + light.Type = D3DLIGHT_SPOT; + break; + case ELT_DIRECTIONAL: + light.Type = D3DLIGHT_DIRECTIONAL; + break; + } + + light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); + light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); + + light.Range = core::min_(dl.Radius, MaxLightDistance); + light.Falloff = dl.Falloff; + + light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); + light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); + light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); + + light.Attenuation0 = dl.Attenuation.X; + light.Attenuation1 = dl.Attenuation.Y; + light.Attenuation2 = dl.Attenuation.Z; + + light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; + light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; + + ++LastSetLight; + + if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) + { + // I don't care if this succeeds + (void)pID3DDevice->LightEnable(LastSetLight, true); + return LastSetLight; + } + + return -1; +} + + +void CD3D8Driver::turnLightOn(s32 lightIndex, bool turnOn) +{ + if(lightIndex < 0 || lightIndex > LastSetLight) + return; + + (void)pID3DDevice->LightEnable(lightIndex, turnOn); +} + + +//! returns the maximal amount of dynamic lights the device can handle +u32 CD3D8Driver::getMaximalDynamicLightAmount() const +{ + return Caps.MaxActiveLights; +} + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CD3D8Driver::setAmbientLight(const SColorf& color) +{ + if (!pID3DDevice) + return; + + AmbientLight = color; + D3DCOLOR col = color.toSColor().color; + pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); +} + + +//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 +//! driver, it would return "Direct3D8.1". +const wchar_t* CD3D8Driver::getName() const +{ + return L"Direct3D 8.1"; +} + + +//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do +//! this: First, draw all geometry. Then use this method, to draw the shadow +//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CD3D8Driver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) +{ + const u32 count = triangles.size(); + if (!Params.Stencilbuffer || !count) + return; + + setRenderStatesStencilShadowMode(zfail, debugDataVisible); + + if (!zfail) + { + // ZPASS Method + + // Draw front-side of shadow volume in stencil only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW ); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); + pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + } + else + { + // ZFAIL Method + + // Draw front-side of shadow volume in stencil only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT ); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT ); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + } +} + + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CD3D8Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!Params.Stencilbuffer) + return; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); + vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); + vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); + vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); + + const s16 indices[6] = {0,1,2,1,3,2}; + + setRenderStatesStencilFillMode( + leftUpEdge.getAlpha() < 255 || + rightUpEdge.getAlpha() < 255 || + leftDownEdge.getAlpha() < 255 || + rightDownEdge.getAlpha() < 255); + + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); + + if (clearStencilBuffer) + pID3DDevice->Clear(0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CD3D8Driver::getMaximalPrimitiveCount() const +{ + return Caps.MaxPrimitiveCount; +} + + +//! Sets the fog mode. +void CD3D8Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); + + if (!pID3DDevice) + return; + + pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); + + pID3DDevice->SetRenderState( +#if defined( _IRR_XBOX_PLATFORM_) + D3DRS_FOGTABLEMODE, +#else + pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, +#endif + (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); + + if (fogType==EFT_FOG_LINEAR) + { + pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); + pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); + } + else + pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); + + if(!pixelFog) + pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); +} + + +//! Draws a 3d line. +void CD3D8Driver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + setVertexShader(EVT_STANDARD); + setRenderStates3DMode(); + video::S3DVertex v[2]; + v[0].Color = color; + v[1].Color = color; + v[0].Pos = start; + v[1].Pos = end; + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); +} + + +void CD3D8Driver::OnResize(const core::dimension2d& size) +{ + if (!pID3DDevice) + return; + + CNullDriver::OnResize(size); + reset(); +} + + +//! Returns type of video driver +E_DRIVER_TYPE CD3D8Driver::getDriverType() const +{ + return EDT_DIRECT3D8; +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CD3D8Driver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Matrices[state]; +} + + +//! Sets a vertex shader constant. +void CD3D8Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetVertexShaderConstant(startRegister, data, constantAmount); +} + + +//! Sets a pixel shader constant. +void CD3D8Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetPixelShaderConstant(startRegister, data, constantAmount); +} + + +//! Sets a constant for the vertex shader based on a name. +bool CD3D8Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + + +//! Bool interface for the above. +bool CD3D8Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + + +//! Int interface for the above. +bool CD3D8Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + + +//! Sets a constant for the pixel shader based on a name. +bool CD3D8Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + + +//! Bool interface for the above. +bool CD3D8Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + + +//! Int interface for the above. +bool CD3D8Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) +{ + os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); + return false; +} + + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 CD3D8Driver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData) +{ + s32 nr = -1; + CD3D8ShaderMaterialRenderer* r = new CD3D8ShaderMaterialRenderer( + pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, + callback, getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + + +//! Returns a pointer to the IVideoDriver interface. (Implementation for +//! IMaterialRendererServices) +IVideoDriver* CD3D8Driver::getVideoDriver() +{ + return this; +} + + +//! Clears the ZBuffer. +void CD3D8Driver::clearZBuffer() +{ + const HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); + + if (FAILED(hr)) + os::Printer::log("CD3D8Driver clearZBuffer() failed.", ELL_WARNING); +} + + +//! Returns an image created from the last rendered frame. +IImage* CD3D8Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) +{ +#if defined( _IRR_XBOX_PLATFORM_) + return 0; +#else + if (target != video::ERT_FRAME_BUFFER) + return 0; + + // query the screen dimensions of the current adapter + D3DDISPLAYMODE displayMode; + pID3DDevice->GetDisplayMode(&displayMode); + + if (format==video::ECF_UNKNOWN) + format=video::ECF_A8R8G8B8; + + // create the image surface to store the front buffer image [always A8R8G8B8] + HRESULT hr; + LPDIRECT3DSURFACE8 lpSurface; + if (FAILED(hr = pID3DDevice->CreateImageSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, &lpSurface))) + return 0; + + // read the front buffer into the image surface + if (FAILED(hr = pID3DDevice->GetFrontBuffer(lpSurface))) + { + lpSurface->Release(); + return 0; + } + + RECT clientRect; + { + POINT clientPoint; + clientPoint.x = 0; + clientPoint.y = 0; + + ClientToScreen( (HWND)getExposedVideoData().D3D8.HWnd, &clientPoint ); + + clientRect.left = clientPoint.x; + clientRect.top = clientPoint.y; + clientRect.right = clientRect.left + ScreenSize.Width; + clientRect.bottom = clientRect.top + ScreenSize.Height; + + // window can be off-screen partly, we can't take screenshots from that + clientRect.left = core::max_(clientRect.left, 0l); + clientRect.top = core::max_(clientRect.top, 0l); + clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); + clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); + } + + // lock our area of the surface + D3DLOCKED_RECT lockedRect; + if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) + { + lpSurface->Release(); + return 0; + } + + irr::core::dimension2d shotSize; + shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); + shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); + + // this could throw, but we aren't going to worry about that case very much + IImage* newImage = createImage(format, shotSize); + + if (newImage) + { + // d3d pads the image, so we need to copy the correct number of bytes + u32* dP = (u32*)newImage->lock(); + u8 * sP = (u8 *)lockedRect.pBits; + + // If the display mode format doesn't promise anything about the Alpha value + // and it appears that it's not presenting 255, then we should manually + // set each pixel alpha value to 255. + if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) + { + for (u32 y = 0; y < shotSize.Height; ++y) + { + for(u32 x = 0; x < shotSize.Width; ++x) + { + newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); + sP += 4; + } + + sP += lockedRect.Pitch - (4 * shotSize.Width); + } + } + else + { + for (u32 y = 0; y < shotSize.Height; ++y) + { + convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); + sP += lockedRect.Pitch; + dP += shotSize.Width; + } + } + + newImage->unlock(); + } + + // we can unlock and release the surface + lpSurface->UnlockRect(); + + // release the image surface + lpSurface->Release(); + + // return status of save operation to caller + return newImage; +#endif +} + + +// returns the current size of the screen or rendertarget +const core::dimension2d& CD3D8Driver::getCurrentRenderTargetSize() const +{ + if ( CurrentRendertargetSize.Width == 0 ) + return ScreenSize; + else + return CurrentRendertargetSize; +} + + +// Set/unset a clipping plane. +bool CD3D8Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ +#if defined( _IRR_XBOX_PLATFORM_) + return false; +#else + if (index >= MaxUserClipPlanes) + return false; + pID3DDevice->SetClipPlane(index, (const float*)&plane); + enableClipPlane(index, enable); + return true; +#endif +} + + +// Enable/disable a clipping plane. +void CD3D8Driver::enableClipPlane(u32 index, bool enable) +{ +#if defined( _IRR_XBOX_PLATFORM_) + return; +#else + if (index >= MaxUserClipPlanes) + return; + DWORD renderstate; + pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); + if (enable) + renderstate |= (1 << index); + else + renderstate &= ~(1 << index); + pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); +#endif +} + + +core::dimension2du CD3D8Driver::getMaxTextureSize() const +{ + return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +//! creates a video driver +IVideoDriver* createDirectX8Driver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window) +{ + const bool pureSoftware = false; + CD3D8Driver* dx8 = new CD3D8Driver(params, io); + + if (!dx8->initDriver(window, pureSoftware)) + { + dx8->drop(); + dx8 = 0; + } + + return dx8; +} +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +} // end namespace video +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.h new file mode 100644 index 0000000..e9428a9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Driver.h @@ -0,0 +1,341 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_DIRECTX_8_H_INCLUDED__ +#define __C_VIDEO_DIRECTX_8_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#ifdef _IRR_WINDOWS_ + #define WIN32_LEAN_AND_MEAN + #include +#endif + +#include "SIrrCreationParameters.h" +// always included for static createDriver function +#include "CNullDriver.h" +#include "IMaterialRendererServices.h" + +#include + +namespace irr +{ +namespace video +{ + class CD3D8Driver : public CNullDriver, IMaterialRendererServices + { + friend class CD3D8Texture; + + public: + + //! constructor + CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io); + + //! destructor + virtual ~CD3D8Driver(); + + //! applications must call this method before performing any rendering. returns false if failed. + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect* sourceRect=0); + + //! applications must call this method after performing any rendering. returns false if failed. + virtual bool endScene(); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + //! sets a render target + virtual bool setRenderTarget(video::ITexture* texture, + bool clearBackBuffer=true, bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! gets the area of the current viewport + virtual const core::rect& getViewPort() const; + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType); + + //! draws a vertex primitive list in 2d + virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a pixel. + virtual void drawPixel(u32 x, u32 y, const SColor & color); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! initialises the Direct3D API + bool initDriver(HWND hwnd, bool pureSoftware); + + //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light, returning an index to the light + //! \param light: the light data to use to create the light + //! \return An index to the light, or -1 if an error occurs + virtual s32 addDynamicLight(const SLight& light); + + //! Turns a dynamic light on or off + //! \param lightIndex: the index returned by addDynamicLight + //! \param turnOn: true to turn the light on, false to turn it off + virtual void turnLightOn(s32 lightIndex, bool turnOn); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do + //! this: Frist, draw all geometry. Then use this method, to draw the shadow + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail=true, u32 debugDataVisible=0); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Enables or disables a texture creation flag. + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); + + //! Sets the fog mode. + virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Can be called by an IMaterialRenderer to make its work easier. + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates); + + //! Sets a vertex shader constant. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a pixel shader constant. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a constant for the vertex shader based on a name. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); + + //! Sets a constant for the pixel shader based on a name. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); + + //! Returns a pointer to the IVideoDriver interface. (Implementation for + //! IMaterialRendererServices) + virtual IVideoDriver* getVideoDriver(); + + //! Creates a render target texture. + virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + //! Returns the maximum texture size supported. + virtual core::dimension2du getMaxTextureSize() const; + + virtual bool checkDriverReset() {return DriverWasReset;} + private: + + // enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. + enum E_RENDER_MODE + { + ERM_NONE = 0, // no render state has been set yet. + ERM_2D, // 2d drawing rendermode + ERM_3D, // 3d rendering mode + ERM_STENCIL_FILL, // stencil fill mode + ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode + ERM_SHADOW_VOLUME_ZPASS // stencil volume draw mode + }; + + //! sets right vertex shader + void setVertexShader(video::E_VERTEX_TYPE newType); + + //! sets the needed renderstates + bool setRenderStates3DMode(); + + //! sets the needed renderstates + void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); + + //! sets the needed renderstates + void setRenderStatesStencilFillMode(bool alpha); + + //! sets the needed renderstates + void setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible); + + //! sets the current Texture + bool setActiveTexture(u32 stage, const video::ITexture* texture); + + //! resets the device + bool reset(); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); + + // returns the current size of the screen or rendertarget + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData); + + void createMaterialRenderers(); + + void draw2D3DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType, bool is3D); + + D3DTEXTUREADDRESS getTextureWrapMode(const u8 clamp); + + inline D3DCOLORVALUE colorToD3D(const SColor& col) + { + const f32 f = 1.0f / 255.0f; + D3DCOLORVALUE v; + v.r = col.getRed() * f; + v.g = col.getGreen() * f; + v.b = col.getBlue() * f; + v.a = col.getAlpha() * f; + return v; + } + + E_RENDER_MODE CurrentRenderMode; + D3DPRESENT_PARAMETERS present; + + SMaterial Material, LastMaterial; + bool ResetRenderStates; // bool to make all renderstates be reseted if set. + bool Transformation3DChanged; + const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; + core::matrix4 Matrices[ETS_COUNT]; // matrices of the 3d mode we need to restore when we switch back from the 2d mode. + + HINSTANCE D3DLibrary; + IDirect3D8* pID3D; + IDirect3DDevice8* pID3DDevice; + + IDirect3DSurface8* PrevRenderTarget; + core::dimension2d CurrentRendertargetSize; + + HWND WindowId; + core::rect* SceneSourceRect; + + D3DCAPS8 Caps; + + E_VERTEX_TYPE LastVertexType; + + D3DMATRIX UnitMatrix; + + u32 MaxTextureUnits; + u32 MaxUserClipPlanes; + f32 MaxLightDistance; + s32 LastSetLight; + bool DeviceLost; + bool DriverWasReset; + + SColorf AmbientLight; + + SIrrlichtCreationParameters Params; + }; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +#endif // __C_VIDEO_DIRECTX_8_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8MaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8MaterialRenderer.h new file mode 100644 index 0000000..5eb883c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8MaterialRenderer.h @@ -0,0 +1,581 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +namespace +{ +D3DMATRIX UnitMatrixD3D8; +D3DMATRIX SphereMapMatrixD3D8; +inline void setTextureColorStage(IDirect3DDevice8* dev, DWORD i, + DWORD arg1, DWORD op, DWORD arg2) +{ + dev->SetTextureStageState(i, D3DTSS_COLOROP, op); + dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); + dev->SetTextureStageState(i, D3DTSS_COLORARG2, arg2); +} +inline void setTextureColorStage(IDirect3DDevice8* dev, DWORD i, DWORD arg1) +{ + dev->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); +} + +inline void setTextureAlphaStage(IDirect3DDevice8* dev, DWORD i, + DWORD arg1, DWORD op, DWORD arg2) +{ + dev->SetTextureStageState(i, D3DTSS_ALPHAOP, op); + dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); + dev->SetTextureStageState(i, D3DTSS_ALPHAARG2, arg2); +} +inline void setTextureAlphaStage(IDirect3DDevice8* dev, DWORD i, DWORD arg1) +{ + dev->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); +} +} // anonymous namespace + +//! Base class for all internal D3D8 material renderers +class CD3D8MaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + CD3D8MaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver) + : pID3DDevice(d3ddev), Driver(driver) + { + } + +protected: + + IDirect3DDevice8* pID3DDevice; + video::IVideoDriver* Driver; +}; + + +//! Solid material renderer +class CD3D8MaterialRenderer_SOLID : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_SOLID(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } +}; + +//! Generic Texture Blend +class CD3D8MaterialRenderer_ONETEXTURE_BLEND : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || + material.MaterialTypeParam != lastMaterial.MaterialTypeParam || + resetAllRenderstates) + { + + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + u32 alphaSource; + unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam ); + + if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO) + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) ); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) ); + } + + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE); + + if ( alphaSource && (textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) )) + { + if (alphaSource==EAS_VERTEX_COLOR) + { + setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); + } + else if (alphaSource==EAS_TEXTURE) + { + setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); + } + else + { + setTextureAlphaStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + } + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + } + } + + //! Returns if the material is transparent. + /** The scene management needs to know this for being able to sort the + materials by opaque and transparent. + The return value could be optimized, but we'd need to know the + MaterialTypeParam for it. */ + virtual bool isTransparent() const + { + return true; + } + + private: + + u32 getD3DBlend ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_ZERO: r = D3DBLEND_ZERO; break; + case EBF_ONE: r = D3DBLEND_ONE; break; + case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break; + case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break; + case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break; + case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break; + case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break; + case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break; + case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break; + case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break; + } + return r; + } + + u32 getD3DModulate ( E_MODULATE_FUNC func ) const + { + u32 r = D3DTOP_MODULATE; + switch ( func ) + { + case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break; + case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break; + case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break; + } + return r; + } + +}; + + +//! Solid 2 layer material renderer +class CD3D8MaterialRenderer_SOLID_2_LAYER : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } +}; + + +//! Transparent add color material renderer +class CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); + } + } + + //! Returns if the material is transparent. The scene management needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent vertex alpha material renderer +class CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates + || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + + pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f)); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + // 127 is required by EMT_TRANSPARENT_ALPHA_CHANNEL_REF + pID3DDevice->SetRenderState(D3DRS_ALPHAREF, 127); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return false; // this material is not really transparent because it does no blending. + } +}; + + +//! material renderer for all kinds of lightmaps +class CD3D8MaterialRenderer_LIGHTMAP : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_LIGHTMAP(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING) + { + // with lighting + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + } + else + { + setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, + (material.MaterialType == EMT_LIGHTMAP_ADD)? + D3DTOP_ADD: + (material.MaterialType == EMT_LIGHTMAP_M4 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M4)? + D3DTOP_MODULATE4X: + (material.MaterialType == EMT_LIGHTMAP_M2 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M2)? + D3DTOP_MODULATE2X: + D3DTOP_MODULATE, + D3DTA_CURRENT); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } +}; + + +//! material renderer for detail maps +class CD3D8MaterialRenderer_DETAIL_MAP : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_DETAIL_MAP(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, D3DTOP_ADDSIGNED, D3DTA_CURRENT); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } +}; + + +//! sphere map material renderer +class CD3D8MaterialRenderer_SPHERE_MAP : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_SPHERE_MAP(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D8 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL ); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D8 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D8MaterialRenderer_REFLECTION_2_LAYER : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D8 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D8 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D8MaterialRenderer +{ +public: + + CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) + : CD3D8MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + setTextureAlphaStage(pID3DDevice, 1, D3DTA_CURRENT); + + pID3DDevice->SetTransform(D3DTS_TEXTURE1, &SphereMapMatrixD3D8 ); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D8); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.cpp new file mode 100644 index 0000000..c5e039d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.cpp @@ -0,0 +1,248 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "CD3D8NormalMapRenderer.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "SLight.h" + +namespace irr +{ +namespace video +{ + + // 1.1 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D8 render path normal map vertex shader + const char D3D8_NORMAL_MAP_VSH[] = + ";Irrlicht Engine 0.8 D3D8 render path normal map vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "\n"\ + "; v0 - position \n"\ + "; v1 - normal \n"\ + "; v2 - color \n"\ + "; v3 - texture coord \n"\ + "; v4 - tangent \n"\ + "; v5 - binormal \n"\ + "\n"\ + "vs.1.1\n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - lightpos1\n"\ + "add r3, c14, -r4 ; vtxpos - lightpos2\n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light vector 1 with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light vector 2 with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + // Irrlicht Engine D3D8 render path normal map pixel shader + const char D3D8_NORMAL_MAP_PSH[] = + ";Irrlicht Engine 0.8 D3D8 render path normal map pixel shader\n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + "ps.1.1 \n"\ + "tex t0 ; sample color map \n"\ + "tex t1 ; sample normal map\n"\ + "texcoord t2 ; fetch light vector 1\n"\ + "texcoord t3 ; fetch light vector 2\n"\ + "\n"\ + "dp3_sat r0, t1_bx2, t2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1)\n"\ + "mul r0, r0, v0 ; luminance1 * light color 1 \n"\ + "\n"\ + "dp3_sat r1, t1_bx2, t3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1)\n"\ + "mad r0, r1, v1, r0 ; (luminance2 * light color 2) + luminance 1 \n"\ + "\n"\ + "mul r0, t0, r0 ; total luminance * base color\n"\ + "mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ + "\n"\ + ""; + + CD3D8NormalMapRenderer::CD3D8NormalMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D8ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), + CompiledShaders(true) + { + + #ifdef _DEBUG + setDebugName("CD3D8NormalMapRenderer"); + #endif + + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D8NormalMapRenderer* nmr = (video::CD3D8NormalMapRenderer*)renderer; + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, D3D8_NORMAL_MAP_VSH, D3D8_NORMAL_MAP_PSH, EVT_TANGENTS); + } + // something failed, use base material + if (-1==outMaterialTypeNr) + driver->addMaterialRenderer(this); + } + + + CD3D8NormalMapRenderer::~CD3D8NormalMapRenderer() + { + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader = 0; + } + } + + + bool CD3D8NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D8ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + //! Returns the render capability of the material. + s32 CD3D8NormalMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + void CD3D8NormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the + // driver and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.h new file mode 100644 index 0000000..e53ab65 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8NormalMapRenderer.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include + +#include "CD3D8ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for normal maps +class CD3D8NormalMapRenderer : public CD3D8ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D8NormalMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + ~CD3D8NormalMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +private: + + //! stores if this shader compiled the shaders and is + //! allowed to delete them again. D3D8 lacks reference counting + //! support for shaders. + bool CompiledShaders; + +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp new file mode 100644 index 0000000..ca30966 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp @@ -0,0 +1,318 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "CD3D8ParallaxMapRenderer.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "SLight.h" + +namespace irr +{ +namespace video +{ + // 1.1/1.4 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D8 render path normal map vertex shader + const char D3D8_PARALLAX_MAP_VSH[] = + ";Irrlicht Engine 0.10 D3D8 render path parallax mapping vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c4: Eye position \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "vs.1.1\n"\ + "; v0 ; position \n"\ + "; v1 ; normal \n"\ + "; v2 ; color \n"\ + "; v3 ; texture coord \n"\ + "; v4 ; tangent \n"\ + "; v5 ; binormal \n"\ + "\n"\ + "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ + "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - light1 pos\n"\ + "add r3, c14, -r4 ; vtxpos - light2 pos\n"\ + "add r1, -c4, r4 ; eye - vtxpos \n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light1 vector with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light2 vector with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "dp3 r10.x, r5, r1 ; transform the eye vector with U, V, W\n"\ + "dp3 r10.y, r6, r1 \n"\ + "dp3 r10.z, r7, r1 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + ";mul r8, r8, c96 \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + ";mul r9, r9, c96 \n"\ + "dp3 r10.w, r10, r10 ; normalize eye vector (r10)\n"\ + "rsq r10.w, r10.w \n"\ + "mul r10, r10, r10.w \n"\ + "mul r10, r10, c96 \n"\ + "\n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "mad oT4.xyz, r10.xyz, c95, c95 ; move eye vector from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + + // Irrlicht Engine D3D8 render path normal map pixel shader version 1.4 + const char D3D8_PARALLAX_MAP_PSH[] = + ";Irrlicht Engine 0.10 D3D8 render path parallax mapping pixel shader \n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";t4: eye vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + " \n"\ + "ps.1.4 \n"\ + " \n"\ + ";def c6, 0.02f, 0.02f, 0.02f, 0.0f ; scale factor, now set in callback \n"\ + " \n"\ + "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ + "texcrd r4.xyz, t4 ; fetch eye vector \n"\ + "texcrd r0.xyz, t0 ; color map \n"\ + " \n"\ + "; original parallax mapping: \n"\ + ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ + ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "; modified parallax mapping to reduce swimming effect: \n"\ + "mul r3, r1_bx2.wwww, r1_bx2.zzzz ; (nh,nh,nh,nh) = (h,h,h,h) * (n.z,n.z,n.z,n.z,) \n"\ + "mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ + "mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "phase \n"\ + " \n"\ + "texld r0, r2 ; load diffuse texture with new tex coord \n"\ + "texld r1, r2 ; sample normal map \n"\ + "texcrd r2.xyz, t2 ; fetch light vector 1 \n"\ + "texcrd r3.xyz, t3 ; fetch light vector 2 \n"\ + " \n"\ + "dp3_sat r2, r1_bx2, r2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ + "mul r2, r2, v0 ; luminance1 * light color 1 \n"\ + " \n"\ + "dp3_sat r3, r1_bx2, r3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ + "mad r3, r3, v1, r2 ; (luminance2 * light color 2) + luminance1 \n"\ + " \n"\ + "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ + "+mov r0.a, v0.a ; write original alpha value \n"\ + "\n"; + + + CD3D8ParallaxMapRenderer::CD3D8ParallaxMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D8ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), + CompiledShaders(true), CurrentScale(0.0f) + { + + #ifdef _DEBUG + setDebugName("CD3D8ParallaxMapRenderer"); + #endif + + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled parallax map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D8ParallaxMapRenderer* nmr = (video::CD3D8ParallaxMapRenderer*)renderer; + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, D3D8_PARALLAX_MAP_VSH, D3D8_PARALLAX_MAP_PSH, EVT_TANGENTS); + } + // something failed, use base material + if (-1==outMaterialTypeNr) + driver->addMaterialRenderer(this); + } + + + CD3D8ParallaxMapRenderer::~CD3D8ParallaxMapRenderer() + { + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader = 0; + } + } + + + bool CD3D8ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D8ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + + void CD3D8ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) + { + CD3D8ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, + resetAllRenderstates, services); + + CurrentScale = material.MaterialTypeParam; + } + + + //! Returns the render capability of the material. + s32 CD3D8ParallaxMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants + //! for an material renderer should be set. + void CD3D8ParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set eye position + + // The viewpoint is at (0., 0., 0.) in eye space. + // Turning this into a vector [0 0 0 1] and multiply it by + // the inverse of the view matrix, the resulting vector is the + // object space location of the camera. + + f32 floats[4] = {0,0,0,1}; + core::matrix4 minv(driver->getTransform(video::ETS_VIEW)); + minv.makeInverse(); + minv.multiplyWith1x4Matrix(floats); + services->setVertexShaderConstant(floats, 4, 1); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the driver + // and set them as constants + + const u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // this is not really necessary in d3d9 (used a def instruction), but to be sure: + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + f32 c96[] = {-1, 1, 1, 1}; + services->setVertexShaderConstant(c96, 96, 1); + + // set scale factor + f32 factor = 0.02f; // default value + if (CurrentScale != 0) + factor = CurrentScale; + + f32 c6[] = {factor, factor, factor, 0}; + services->setPixelShaderConstant(c6, 6, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.h new file mode 100644 index 0000000..4543ab7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ParallaxMapRenderer.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include + +#include "CD3D8ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for parallax maps +class CD3D8ParallaxMapRenderer : public CD3D8ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D8ParallaxMapRenderer( + IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + ~CD3D8ParallaxMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + virtual void OnSetMaterial(const SMaterial& material) { } + virtual void OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +private: + + //! stores if this shader compiled the shaders and is + //! allowed to delete them again. D3D8 lacks reference counting + //! support for shaders. + bool CompiledShaders; + + f32 CurrentScale; +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp new file mode 100644 index 0000000..f46d583 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp @@ -0,0 +1,332 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CD3D8ShaderMaterialRenderer.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include +#include +#pragma comment (lib, "d3dx8.lib") + +#include "IShaderConstantSetCallBack.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" + +#ifndef _IRR_D3D_NO_SHADER_DEBUGGING +#include +#endif + +namespace irr +{ +namespace video +{ + +//! Public constructor +CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) +: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) +{ + + #ifdef _DEBUG + setDebugName("CD3D8ShaderMaterialRenderer"); + #endif + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, EVT_STANDARD); +} + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData) +: pID3DDevice(d3ddev), Driver(driver), BaseMaterial(baseMaterial), CallBack(callback), + VertexShader(0), PixelShader(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + + +//! Destructor +CD3D8ShaderMaterialRenderer::~CD3D8ShaderMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (VertexShader) + pID3DDevice->DeleteVertexShader(VertexShader); + + if (PixelShader) + pID3DDevice->DeletePixelShader(PixelShader); + + if (BaseMaterial) + BaseMaterial->drop (); +} + + +void CD3D8ShaderMaterialRenderer::init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* pixelShaderProgram, E_VERTEX_TYPE type) +{ + outMaterialTypeNr = -1; + + // create vertex shader + if (!createVertexShader(vertexShaderProgram, type)) + return; + + // create pixel shader + if (!createPixelShader(pixelShaderProgram)) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + +bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (VertexShader || PixelShader)) + CallBack->OnSetConstants(service, UserData); + + return true; +} + + +void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexShader) + { + // We do not need to save and reset the old vertex shader, because + // in D3D8, this is mixed up with the fvf, and this is set by the driver + // every time. + //pID3DDevice->GetVertexShader(&OldVertexShader); + + // set new vertex shader + if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) + os::Printer::log("Could not set vertex shader.", ELL_ERROR); + } + + // set new pixel shader + if (PixelShader) + { + if (FAILED(pID3DDevice->SetPixelShader(PixelShader))) + os::Printer::log("Could not set pixel shader.", ELL_ERROR); + } + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, services); + } + + //let callback know used material + if (CallBack) + CallBack->OnSetMaterial(material); + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +void CD3D8ShaderMaterialRenderer::OnUnsetMaterial() +{ + // We do not need to save and reset the old vertex shader, because + // in D3D8, this is mixed up with the fvf, and this is set by the driver + // every time. + // if (VertexShader) + // pID3DDevice->SetVertexShader(OldVertexShader); + + if (PixelShader) + pID3DDevice->SetPixelShader(0); + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + + +//! Returns if the material is transparent. The scene managment needs to know this +//! for being able to sort the materials by opaque and transparent. +bool CD3D8ShaderMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + +bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh) +{ + if (!pxsh) + return true; + +#if defined( _IRR_XBOX_PLATFORM_) + return false; +#else + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + D3DXAssembleShader(pxsh, (UINT)strlen(pxsh), 0, 0, &code, &errors); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(pxsh, strlen(pxsh), 1, f); + fflush(f); + fclose(f); + + D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); + #endif + if (errors) + { + // print out compilation errors. + os::Printer::log("Pixel shader compilation failed:", ELL_ERROR); + os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader))) + { + os::Printer::log("Could not create pixel shader.", ELL_ERROR); + code->Release(); + return false; + } + + code->Release(); + return true; +#endif + +} + + + +bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX_TYPE type) +{ + if (!vtxsh) + return true; + + // compile shader +#if defined( _IRR_XBOX_PLATFORM_) + return false; +#else + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + D3DXAssembleShader(vtxsh, (UINT)strlen(vtxsh), 0, 0, &code, &errors); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(vtxsh, strlen(vtxsh), 1, f); + fflush(f); + fclose(f); + + D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); + + #endif + + + if (errors) + { + // print out compilation errors. + os::Printer::log("Vertex shader compilation failed:", ELL_ERROR); + os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + DWORD* decl = 0; + + DWORD dwStdDecl[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0, D3DVSDT_FLOAT3), // position 0 + D3DVSD_REG(1, D3DVSDT_FLOAT3), // normal 1 + D3DVSD_REG(2, D3DVSDT_D3DCOLOR ),// color 2 + D3DVSD_REG(3, D3DVSDT_FLOAT2 ), // tex1 3 + D3DVSD_REG(4, D3DVSDT_FLOAT2 ), // tex2 4 + D3DVSD_END() + }; + + DWORD dwTngtDecl[] = + { + D3DVSD_STREAM(0), + D3DVSD_REG(0 , D3DVSDT_FLOAT3), // position 0 + D3DVSD_REG(1 , D3DVSDT_FLOAT3), // normal 1 + D3DVSD_REG(2 , D3DVSDT_D3DCOLOR ),// color 2 + D3DVSD_REG(3 , D3DVSDT_FLOAT2 ), // tex1 3 + D3DVSD_REG(4, D3DVSDT_FLOAT3 ), // tangent 4 + D3DVSD_REG(5, D3DVSDT_FLOAT3 ), // binormal 5 + D3DVSD_END() + }; + + if (type == EVT_TANGENTS) + decl = dwTngtDecl; + else + decl = dwStdDecl; + + if (FAILED(pID3DDevice->CreateVertexShader(decl, + (DWORD*)code->GetBufferPointer(), &VertexShader, 0))) + { + os::Printer::log("Could not create vertex shader.", ELL_ERROR); + code->Release(); + return false; + } + + code->Release(); + return true; +#endif +} + + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.h new file mode 100644 index 0000000..02156a1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8ShaderMaterialRenderer.h @@ -0,0 +1,82 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D8_SHADER_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D8_SHADER_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_API_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ +#include +#include + +#include "IMaterialRenderer.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders with D3D8 +class CD3D8ShaderMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Public constructor + CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); + + //! Destructor + ~CD3D8ShaderMaterialRenderer(); + + virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + virtual void OnUnsetMaterial(); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData=0); + + void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + E_VERTEX_TYPE type); + bool createPixelShader(const c8* pxsh); + bool createVertexShader(const char* vtxsh, E_VERTEX_TYPE type); + + IDirect3DDevice8* pID3DDevice; + video::IVideoDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + DWORD VertexShader; + DWORD OldVertexShader; + DWORD PixelShader; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.cpp new file mode 100644 index 0000000..990efbe --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.cpp @@ -0,0 +1,659 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D8Texture.h" +#include "CD3D8Driver.h" +#include "os.h" + + +#ifndef _IRR_COMPILE_WITH_DIRECT3D_9_ +// The D3DXFilterTexture function seems to get linked wrong when +// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. +// So mipmapgeneration is replaced with my own bad generation in d3d 8 when +// compiling with both D3D 8 and 9. +//#define _IRR_USE_D3DXFilterTexture_ +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include + +#ifdef _IRR_USE_D3DXFilterTexture_ +#pragma comment (lib, "d3dx8.lib") +#endif // _IRR_USE_D3DXFilterTexture_ + +namespace irr +{ +namespace video +{ + +//! rendertarget constructor +CD3D8Texture::CD3D8Texture(CD3D8Driver* driver, const core::dimension2d& size, const io::path& name) +: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), + TextureSize(size), ImageSize(size), Pitch(0), + HasMipMaps(false), IsRenderTarget(true) +{ + #ifdef _DEBUG + setDebugName("CD3D8Texture"); + #endif + + Device=driver->getExposedVideoData().D3D8.D3DDev8; + if (Device) + Device->AddRef(); + + createRenderTarget(); +} + + +//! constructor +CD3D8Texture::CD3D8Texture(IImage* image, CD3D8Driver* driver, + u32 flags, const io::path& name, void* mipmapData) +: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), +TextureSize(0,0), ImageSize(0,0), Pitch(0), +HasMipMaps(false), IsRenderTarget(false) +{ + #ifdef _DEBUG + setDebugName("CD3D8Texture"); + #endif + + HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + Device=driver->getExposedVideoData().D3D8.D3DDev8; + if (Device) + Device->AddRef(); + + if (image) + { + if (createTexture(flags, image)) + { + if (copyTexture(image)) + { + regenerateMipMapLevels(mipmapData); + } + } + else + os::Printer::log("Could not create DIRECT3D8 Texture.", ELL_WARNING); + } +} + + +//! destructor +CD3D8Texture::~CD3D8Texture() +{ + if (Texture) + Texture->Release(); + + if (RTTSurface) + RTTSurface->Release(); + + if (Device) + Device->Release(); +} + + +//! creates the hardware texture +bool CD3D8Texture::createTexture(u32 flags, video::IImage* image) +{ + ImageSize = image->getDimension(); + + core::dimension2d optSize = ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); + + D3DFORMAT format = D3DFMT_A1R5G5B5; + switch(getTextureFormatFromFlags(flags)) + { + case ETCF_ALWAYS_16_BIT: + format = D3DFMT_A1R5G5B5; break; + case ETCF_ALWAYS_32_BIT: + format = D3DFMT_A8R8G8B8; break; + case ETCF_OPTIMIZED_FOR_QUALITY: + { + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + case ECF_A8R8G8B8: + format = D3DFMT_A8R8G8B8; break; + case ECF_A1R5G5B5: + case ECF_R5G6B5: + format = D3DFMT_A1R5G5B5; break; + } + } + break; + case ETCF_OPTIMIZED_FOR_SPEED: + format = D3DFMT_A1R5G5B5; break; + } + + if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) + { + if (format == D3DFMT_A8R8G8B8) + +#ifdef _IRR_XBOX_PLATFORM_ + format = D3DFMT_X8R8G8B8; +#else + format = D3DFMT_R8G8B8; +#endif + + else if (format == D3DFMT_A1R5G5B5) + format = D3DFMT_R5G6B5; + } + + const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + HRESULT hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + 0, format, D3DPOOL_MANAGED, &Texture); + + if (FAILED(hr)) + { + // try brute force 16 bit + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_A1R5G5B5; +#ifdef _IRR_XBOX_PLATFORM_ + else if (format == D3DFMT_X8R8G8B8) + format = D3DFMT_R5G6B5; +#else + else if (format == D3DFMT_R8G8B8) + format = D3DFMT_R5G6B5; +#endif + else + return false; + + hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + 0, format, D3DPOOL_MANAGED, &Texture); + } + + ColorFormat = getColorFormatFromD3DFormat(format); + return (SUCCEEDED(hr)); +} + + +//! copies the image to the texture +bool CD3D8Texture::copyTexture(video::IImage* image) +{ + if (Texture && image) + { + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + + TextureSize.Width = desc.Width; + TextureSize.Height = desc.Height; + + D3DLOCKED_RECT rect; + HRESULT hr = Texture->LockRect(0, &rect, 0, 0); + if (FAILED(hr)) + { + os::Printer::log("Could not lock D3D8 Texture.", ELL_ERROR); + return false; + } + + Pitch = rect.Pitch; + image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); + + hr = Texture->UnlockRect(0); + if (FAILED(hr)) + { + os::Printer::log("Could not unlock D3D8 Texture.", ELL_ERROR); + return false; + } + } + + return true; +} + + +//! lock function +void* CD3D8Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) +{ + if (!Texture) + return 0; + + MipLevelLocked=mipmapLevel; + HRESULT hr; + D3DLOCKED_RECT rect; + if(!IsRenderTarget) + { + hr = Texture->LockRect(mipmapLevel, &rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + } + else + { + if (!RTTSurface) + { + // Make RTT surface large enough for all miplevels (including 0) + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); + return 0; + } + } + + IDirect3DSurface8 *surface = 0; + hr = Texture->GetSurfaceLevel(mipmapLevel, &surface); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", "Could not get surface.", ELL_ERROR); + return 0; + } + hr = Device->CopyRects(surface, 0, 0, RTTSurface, 0); + surface->Release(); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", "Data copy failed.", ELL_ERROR); + return 0; + } + hr = RTTSurface->LockRect(&rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D8 Texture.", "LockRect failed.", ELL_ERROR); + return 0; + } + } + return rect.pBits; +} + + +//! unlock function +void CD3D8Texture::unlock() +{ + if (!Texture) + return; + + if (!IsRenderTarget) + Texture->UnlockRect(MipLevelLocked); + else if (RTTSurface) + RTTSurface->UnlockRect(); +} + + +//! Returns original size of the texture. +const core::dimension2d& CD3D8Texture::getOriginalSize() const +{ + return ImageSize; +} + + +//! Returns (=size) of the texture. +const core::dimension2d& CD3D8Texture::getSize() const +{ + return TextureSize; +} + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE CD3D8Texture::getDriverType() const +{ + return EDT_DIRECT3D8; +} + + +//! returns color format of texture +ECOLOR_FORMAT CD3D8Texture::getColorFormat() const +{ + return ColorFormat; +} + + +//! returns pitch of texture (in bytes) +u32 CD3D8Texture::getPitch() const +{ + return Pitch; +} + + +//! returns the DIRECT3D8 Texture +IDirect3DTexture8* CD3D8Texture::getDX8Texture() const +{ + return Texture; +} + + +//! returns if texture has mipmap levels +bool CD3D8Texture::hasMipMaps() const +{ + return HasMipMaps; +} + + +// The D3DXFilterTexture function seems to get linked wrong when +// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. +// So mipmapgeneration is replaced with my own bad generation in d3d 8 when +// compiling with both D3D 8 and 9. +bool CD3D8Texture::createMipMaps(u32 level) +{ + if (level==0) + return true; + + IDirect3DSurface8* upperSurface = 0; + IDirect3DSurface8* lowerSurface = 0; + + // get upper level + HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); + if (FAILED(hr) || !upperSurface) + { + os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); + return false; + } + + // get lower level + hr = Texture->GetSurfaceLevel(level, &lowerSurface); + if (FAILED(hr) || !lowerSurface) + { + os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); + upperSurface->Release(); + return false; + } + + D3DSURFACE_DESC upperDesc, lowerDesc; + upperSurface->GetDesc(&upperDesc); + lowerSurface->GetDesc(&lowerDesc); + + D3DLOCKED_RECT upperlr; + D3DLOCKED_RECT lowerlr; + + // lock upper surface + if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) + { + os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); + upperSurface->Release(); + lowerSurface->Release(); + return false; + } + + // lock lower surface + if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) + { + os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); + upperSurface->UnlockRect(); + upperSurface->Release(); + lowerSurface->Release(); + return false; + } + + if (upperDesc.Format != lowerDesc.Format) + { + os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); + } + else + { + if (upperDesc.Format == D3DFMT_A1R5G5B5) + copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + if (upperDesc.Format == D3DFMT_A8R8G8B8) + copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); + } + + bool result=true; + // unlock + if (FAILED(upperSurface->UnlockRect())) + result=false; + if (FAILED(lowerSurface->UnlockRect())) + result=false; + + // release + upperSurface->Release(); + lowerSurface->Release(); + + if (!result || upperDesc.Width < 3 || upperDesc.Height < 3) + return result; // stop generating levels + + // generate next level + return createMipMaps(level+1); +} + + +ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format) +{ + switch(format) + { + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + Pitch = TextureSize.Width * 2; + return ECF_A1R5G5B5; + break; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + Pitch = TextureSize.Width * 4; + return ECF_A8R8G8B8; + break; + case D3DFMT_R5G6B5: + Pitch = TextureSize.Width * 2; + return ECF_R5G6B5; + break; + default: + return (ECOLOR_FORMAT)0; + }; +} + + + +void CD3D8Texture::copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, + s32 pitchsrc, s32 pitchtgt) const +{ + u16 c; + + for (int x=0; x>= 2; + r >>= 2; + g >>= 2; + b >>= 2; + + c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff); + *(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color; + } + } +} + + +void CD3D8Texture::createRenderTarget() +{ + TextureSize = TextureSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); + + // get backbuffer format to create the render target in the + // same format + + IDirect3DSurface8* bb; + D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8; + + if (!FAILED(Device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &bb))) + { + D3DSURFACE_DESC desc; + bb->GetDesc(&desc); + d3DFormat = desc.Format; + + if (d3DFormat == D3DFMT_X8R8G8B8) + d3DFormat = D3DFMT_A8R8G8B8; + + bb->Release(); + } + else + { + os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.", + ELL_WARNING); + return; + } + + // create texture + HRESULT hr; + + hr = Device->CreateTexture( + TextureSize.Width, + TextureSize.Height, + 1, // mip map level count, we don't want mipmaps here + D3DUSAGE_RENDERTARGET, + d3DFormat, + D3DPOOL_DEFAULT, + &Texture); + + // get irrlicht format from D3D format + ColorFormat = getColorFormatFromD3DFormat(d3DFormat); + + if (FAILED(hr)) + os::Printer::log("Could not create render target texture"); +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void CD3D8Texture::regenerateMipMapLevels(void* mipmapData) +{ + if (mipmapData) + { + core::dimension2du size = TextureSize; + u32 level=0; + do + { + if (size.Width>1) + size.Width /=2; + if (size.Height>1) + size.Height /=2; + ++level; + IDirect3DSurface8* mipSurface = 0; + HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); + if (FAILED(hr) || !mipSurface) + { + os::Printer::log("Could not get mipmap level", ELL_WARNING); + return; + } + D3DSURFACE_DESC mipDesc; + mipSurface->GetDesc(&mipDesc); + D3DLOCKED_RECT miplr; + + // lock mipmap surface + if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) + { + mipSurface->Release(); + os::Printer::log("Could not lock texture", ELL_WARNING); + return; + } + + memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); + mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; + // unlock + mipSurface->UnlockRect(); + // release + mipSurface->Release(); + } while (size.Width != 1 || size.Height != 1); + } + else if (HasMipMaps) + { + // create mip maps. +#ifndef _IRR_USE_D3DXFilterTexture_ + // The D3DXFilterTexture function seems to get linked wrong when + // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. + // So mipmapgeneration is replaced with my own bad generation in d3d 8 when + // compiling with both D3D 8 and 9. + HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT ); + if (FAILED(hr)) +#endif + createMipMaps(); + } +} + + +//! returns if it is a render target +bool CD3D8Texture::isRenderTarget() const +{ + return IsRenderTarget; +} + + +//! Returns pointer to the render target surface +IDirect3DSurface8* CD3D8Texture::getRenderTargetSurface() +{ + if (!IsRenderTarget) + return 0; + + IDirect3DSurface8 *pRTTSurface = 0; + if (Texture) + Texture->GetSurfaceLevel(0, &pRTTSurface); + + if (pRTTSurface) + pRTTSurface->Release(); + + return pRTTSurface; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.h new file mode 100644 index 0000000..4a73c54 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D8Texture.h @@ -0,0 +1,120 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DIRECTX8_TEXTURE_H_INCLUDED__ +#define __C_DIRECTX8_TEXTURE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + +#include "ITexture.h" +#include "IImage.h" + +#include + +namespace irr +{ +namespace video +{ + +class CD3D8Driver; + +/*! + interface for a Video Driver dependent Texture. +*/ +class CD3D8Texture : public ITexture +{ +public: + + //! constructor + CD3D8Texture(IImage* image, CD3D8Driver* driver, + u32 flags, const io::path& name, void* mipmapData=0); + + //! rendertarget constructor + CD3D8Texture(CD3D8Driver* driver, const core::dimension2d& size, const io::path& name); + + //! destructor + virtual ~CD3D8Texture(); + + //! lock function + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! returns the DIRECT3D8 Texture + IDirect3DTexture8* getDX8Texture() const; + + //! returns if texture has mipmap levels + bool hasMipMaps() const; + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(void* mipmapData=0); + + //! returns if it is a render target + virtual bool isRenderTarget() const; + + //! Returns pointer to the render target surface + IDirect3DSurface8* getRenderTargetSurface(); + +private: + friend class CD3D8Driver; + + void createRenderTarget(); + + //! creates the hardware texture + bool createTexture(u32 flags, IImage* Image); + + //! copies the image to the texture + bool copyTexture(IImage* Image); + + //! convert color formats + ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format); + + bool createMipMaps(u32 level=1); + + void copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + void copy32BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + IDirect3DDevice8* Device; + IDirect3DTexture8* Texture; + IDirect3DSurface8* RTTSurface; + CD3D8Driver* Driver; + core::dimension2d TextureSize; + core::dimension2d ImageSize; + s32 Pitch; + u32 MipLevelLocked; + ECOLOR_FORMAT ColorFormat; + + bool HasMipMaps; + bool IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +#endif // __C_DIRECTX8_TEXTURE_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.cpp new file mode 100644 index 0000000..8220a7e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.cpp @@ -0,0 +1,222 @@ +// Copyright (C) 2012-2012 Patryk Nadrowski +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#if defined(_IRR_COMPILE_WITH_DIRECT3D_9_) && defined(_IRR_COMPILE_WITH_CG_) + +#include "CD3D9CgMaterialRenderer.h" +#include "CD3D9Driver.h" +#include "CD3D9Texture.h" + +namespace irr +{ +namespace video +{ + +CD3D9CgUniformSampler2D::CD3D9CgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_SAMPLER2D; +} + +void CD3D9CgUniformSampler2D::update(const void* data, const SMaterial& material) const +{ + s32* Data = (s32*)data; + s32 LayerID = *Data; + + if (material.TextureLayer[LayerID].Texture) + { + IDirect3DBaseTexture9* Texture = reinterpret_cast(material.TextureLayer[LayerID].Texture)->getDX9Texture(); + + cgD3D9SetTextureParameter(Parameter, Texture); + } +} + +CD3D9CgMaterialRenderer::CD3D9CgMaterialRenderer(CD3D9Driver* driver, s32& materialType, + const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, + const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, + const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) : + Driver(driver), CCgMaterialRenderer(callback, baseMaterial, userData) +{ + #ifdef _DEBUG + setDebugName("CD3D9CgMaterialRenderer"); + #endif + + init(materialType, vertexProgram, vertexEntry, vertexProfile, fragmentProgram, fragmentEntry, fragmentProfile, + geometryProgram, geometryEntry, geometryProfile, inType, outType, vertices); +} + +CD3D9CgMaterialRenderer::~CD3D9CgMaterialRenderer() +{ + if (VertexProgram) + { + cgD3D9UnloadProgram(VertexProgram); + cgDestroyProgram(VertexProgram); + } + if (FragmentProgram) + { + cgD3D9UnloadProgram(FragmentProgram); + cgDestroyProgram(FragmentProgram); + } + /*if (GeometryProgram) + { + cgD3D9UnloadProgram(GeometryProgram); + cgDestroyProgram(GeometryProgram); + }*/ +} + +void CD3D9CgMaterialRenderer::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services) +{ + Material = material; + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexProgram) + cgD3D9BindProgram(VertexProgram); + + if (FragmentProgram) + cgD3D9BindProgram(FragmentProgram); + + /*if (GeometryProgram) + cgD3D9BindProgram(GeometryProgram);*/ + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, this); + } + + if (CallBack) + CallBack->OnSetMaterial(material); + + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +bool CD3D9CgMaterialRenderer::OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype) +{ + if (CallBack && (VertexProgram || FragmentProgram || GeometryProgram)) + CallBack->OnSetConstants(this, UserData); + + return true; +} + +void CD3D9CgMaterialRenderer::OnUnsetMaterial() +{ + if (VertexProgram) + cgD3D9UnbindProgram(VertexProgram); + if (FragmentProgram) + cgD3D9UnbindProgram(FragmentProgram); + /*if (GeometryProgram) + cgD3D9UnbindProgram(GeometryProgram);*/ + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); + + Material = IdentityMaterial;; +} + +void CD3D9CgMaterialRenderer::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) +{ + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +IVideoDriver* CD3D9CgMaterialRenderer::getVideoDriver() +{ + return Driver; +} + +void CD3D9CgMaterialRenderer::init(s32& materialType, + const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, + const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, + const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices) +{ + bool Status = true; + CGerror Error = CG_NO_ERROR; + materialType = -1; + + // TODO: add profile selection + + if (vertexProgram) + { + VertexProfile = cgD3D9GetLatestVertexProfile(); + + if (VertexProfile) + VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, vertexProgram, VertexProfile, vertexEntry, 0); + + if (!VertexProgram) + { + Error = cgGetError(); + os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); + os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); + + Status = false; + } + else + cgD3D9LoadProgram(VertexProgram, 0, 0); + } + + if (fragmentProgram) + { + FragmentProfile = cgD3D9GetLatestPixelProfile(); + + if (FragmentProfile) + FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, fragmentProgram, FragmentProfile, fragmentEntry, 0); + + if (!FragmentProgram) + { + Error = cgGetError(); + os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); + os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); + + Status = false; + } + else + cgD3D9LoadProgram(FragmentProgram, 0, 0); + } + + /*if (geometryProgram) + { + GeometryProfile = cgD3D9GetLatestGeometryProfile(); + + if (GeometryProfile) + GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, geometryProgram, GeometryProfile, geometryEntry, 0); + + if (!GeometryProgram) + { + Error = cgGetError(); + os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); + os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); + + Status = false; + } + else + cgD3D9LoadProgram(GeometryProgram, 0, 0); + }*/ + + getUniformList(); + + // create D3D9 specifics sampler uniforms. + for(unsigned int i = 0; i < UniformInfo.size(); ++i) + { + if (UniformInfo[i]->getType() == CG_SAMPLER2D) + { + bool IsGlobal = true; + + if (UniformInfo[i]->getSpace() == CG_PROGRAM) + IsGlobal = false; + + CCgUniform* Uniform = new CD3D9CgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); + delete UniformInfo[i]; + UniformInfo[i] = Uniform; + } + } + + if (Status) + materialType = Driver->addMaterialRenderer(this); +} + +} +} + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.h new file mode 100644 index 0000000..7cb4b0f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9CgMaterialRenderer.h @@ -0,0 +1,83 @@ +// Copyright (C) 2012-2012 Patryk Nadrowski +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DIRECT3D_9_CG_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_DIRECT3D_9_CG_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#if defined(_IRR_COMPILE_WITH_DIRECT3D_9_) && defined(_IRR_COMPILE_WITH_CG_) + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include "CCgMaterialRenderer.h" +#include "Cg/cgD3D9.h" + +#ifdef _MSC_VER + #pragma comment(lib, "cgD3D9.lib") +#endif + +namespace irr +{ +namespace video +{ + +class CD3D9Driver; +class IShaderConstantSetCallBack; + +class CD3D9CgUniformSampler2D : public CCgUniform +{ +public: + CD3D9CgUniformSampler2D(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class CD3D9CgMaterialRenderer : public CCgMaterialRenderer +{ +public: + CD3D9CgMaterialRenderer(CD3D9Driver* driver, s32& materialType, + const c8* vertexProgram = 0, const c8* vertexEntry = "main", + E_VERTEX_SHADER_TYPE vertexProfile = video::EVST_VS_1_1, + const c8* fragmentProgram = 0, const c8* fragmentEntry = "main", + E_PIXEL_SHADER_TYPE fragmentProfile = video::EPST_PS_1_1, + const c8* geometryProgram = 0, const c8* geometryEntry = "main", + E_GEOMETRY_SHADER_TYPE geometryProfile = video::EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 vertices = 0, IShaderConstantSetCallBack* callback = 0, + IMaterialRenderer* baseMaterial = 0, s32 userData = 0); + + virtual ~CD3D9CgMaterialRenderer(); + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services); + virtual bool OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype); + virtual void OnUnsetMaterial(); + + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates); + virtual IVideoDriver* getVideoDriver(); + +protected: + void init(s32& materialType, + const c8* vertexProgram = 0, const c8* vertexEntry = "main", + E_VERTEX_SHADER_TYPE vertexProfile = video::EVST_VS_1_1, + const c8* fragmentProgram = 0, const c8* fragmentEntry = "main", + E_PIXEL_SHADER_TYPE fragmentProfile = video::EPST_PS_1_1, + const c8* geometryProgram = 0, const c8* geometryEntry = "main", + E_GEOMETRY_SHADER_TYPE geometryProfile = video::EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 vertices = 0); + + CD3D9Driver* Driver; +}; + +} +} + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.cpp new file mode 100644 index 0000000..7404894 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.cpp @@ -0,0 +1,3633 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D9Driver.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "os.h" +#include "S3DVertex.h" +#include "CD3D9Texture.h" +#include "CD3D9MaterialRenderer.h" +#include "CD3D9ShaderMaterialRenderer.h" +#include "CD3D9NormalMapRenderer.h" +#include "CD3D9ParallaxMapRenderer.h" +#include "CD3D9HLSLMaterialRenderer.h" +#include "CD3D9CgMaterialRenderer.h" +#include "SIrrCreationParameters.h" + +namespace irr +{ +namespace video +{ + +namespace +{ + inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); } +} + +//! constructor +CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) + : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), + ResetRenderStates(true), Transformation3DChanged(false), + D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), + WindowId(0), SceneSourceRect(0), + LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0), + MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1), + MaxLightDistance(0.f), LastSetLight(-1), + ColorFormat(ECF_A8R8G8B8), DeviceLost(false), + DriverWasReset(true), OcclusionQuerySupport(false), + AlphaToCoverageSupport(false), Params(params) +{ + #ifdef _DEBUG + setDebugName("CD3D9Driver"); + #endif + + printVersion(); + + for (u32 i=0; idrop(); + } + DepthBuffers.clear(); + + // drop d3d9 + + if (pID3DDevice) + pID3DDevice->Release(); + + if (pID3D) + pID3D->Release(); + + #ifdef _IRR_COMPILE_WITH_CG_ + cgD3D9SetDevice(0); + + if(CgContext) + { + cgDestroyContext(CgContext); + } + #endif +} + + +void CD3D9Driver::createMaterialRenderers() +{ + // create D3D9 material renderers + + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); + + // add the same renderer for all lightmap types + + CD3D9MaterialRenderer_LIGHTMAP* lmr = new CD3D9MaterialRenderer_LIGHTMAP(pID3DDevice, this); + addMaterialRenderer(lmr); // for EMT_LIGHTMAP: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: + lmr->drop(); + + // add remaining fixed function pipeline material renderers + + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); + + // add normal map renderers + + s32 tmp = 0; + video::IMaterialRenderer* renderer = 0; + + renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add parallax map renderers + + renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + + renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + + renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, + MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add basic 1 texture blending + addAndDropMaterialRenderer(new CD3D9MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); +} + + +//! initialises the Direct3D API +bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware) +{ + if (!pID3D) + { + D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") ); + + if (!D3DLibrary) + { + os::Printer::log("Error, could not load d3d9.dll.", ELL_ERROR); + return false; + } + + typedef IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT); + D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9"); + + if (!d3dCreate) + { + os::Printer::log("Error, could not get proc adress of Direct3DCreate9.", ELL_ERROR); + return false; + } + + //just like pID3D = Direct3DCreate9(D3D_SDK_VERSION); + pID3D = (*d3dCreate)(D3D_SDK_VERSION); + + if (!pID3D) + { + os::Printer::log("Error initializing D3D.", ELL_ERROR); + return false; + } + } + + // print device information + D3DADAPTER_IDENTIFIER9 dai; + if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai))) + { + char tmp[512]; + + s32 Product = HIWORD(dai.DriverVersion.HighPart); + s32 Version = LOWORD(dai.DriverVersion.HighPart); + s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); + s32 Build = LOWORD(dai.DriverVersion.LowPart); + + sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, + SubVersion, Build); + os::Printer::log(tmp, ELL_INFORMATION); + + // Assign vendor name based on vendor id. + VendorID= static_cast(dai.VendorId); + switch(dai.VendorId) + { + case 0x1002 : VendorName = "ATI Technologies Inc."; break; + case 0x10DE : VendorName = "NVIDIA Corporation"; break; + case 0x102B : VendorName = "Matrox Electronic Systems Ltd."; break; + case 0x121A : VendorName = "3dfx Interactive Inc"; break; + case 0x5333 : VendorName = "S3 Graphics Co., Ltd."; break; + case 0x8086 : VendorName = "Intel Corporation"; break; + default: VendorName = "Unknown VendorId: ";VendorName += (u32)dai.VendorId; break; + } + } + + D3DDISPLAYMODE d3ddm; + if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm))) + { + os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); + return false; + } + + ZeroMemory(&present, sizeof(present)); + + present.BackBufferCount = 1; + present.EnableAutoDepthStencil = TRUE; + if (Params.Vsync) + present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else + present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + if (Params.Fullscreen) + { + present.BackBufferWidth = Params.WindowSize.Width; + present.BackBufferHeight = Params.WindowSize.Height; + // request 32bit mode if user specified 32 bit, added by Thomas Stuefe + if (Params.Bits == 32) + present.BackBufferFormat = D3DFMT_X8R8G8B8; + else + present.BackBufferFormat = D3DFMT_R5G6B5; + present.SwapEffect = D3DSWAPEFFECT_FLIP; + present.Windowed = FALSE; + present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + } + else + { + present.BackBufferFormat = d3ddm.Format; + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + present.Windowed = TRUE; + } + + UINT adapter = Params.DisplayAdapter; + D3DDEVTYPE devtype = D3DDEVTYPE_HAL; + #ifndef _IRR_D3D_NO_SHADER_DEBUGGING + devtype = D3DDEVTYPE_REF; + #elif defined(_IRR_USE_NVIDIA_PERFHUD_) + for (UINT adapter_i = 0; adapter_i < pID3D->GetAdapterCount(); ++adapter_i) + { + D3DADAPTER_IDENTIFIER9 identifier; + pID3D->GetAdapterIdentifier(adapter_i,0,&identifier); + if (strstr(identifier.Description,"PerfHUD") != 0) + { + adapter = adapter_i; + devtype = D3DDEVTYPE_REF; + break; + } + } + #endif + + // enable anti alias if possible and desired + if (Params.AntiAlias > 0) + { + if (Params.AntiAlias > 32) + Params.AntiAlias = 32; + + DWORD qualityLevels = 0; + + while(Params.AntiAlias > 0) + { + if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter, + devtype, present.BackBufferFormat, !Params.Fullscreen, + (D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels))) + { + present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; + present.MultiSampleQuality = qualityLevels-1; + present.SwapEffect = D3DSWAPEFFECT_DISCARD; + break; + } + --Params.AntiAlias; + } + + if (Params.AntiAlias==0) + { + os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); + } + } + + // check stencil buffer compatibility + if (Params.Stencilbuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D24S8; + if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X4S4; + if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D15S1; + if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); + Params.Stencilbuffer = false; + } + } + } + else + if(FAILED(pID3D->CheckDepthStencilMatch(adapter, devtype, + present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) + { + os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); + Params.Stencilbuffer = false; + } + } + // do not use else here to cope with flag change in previous block + if (!Params.Stencilbuffer) + { + present.AutoDepthStencilFormat = D3DFMT_D32; + if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D24X8; + if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + present.AutoDepthStencilFormat = D3DFMT_D16; + if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, + present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) + { + os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); + return false; + } + } + } + } + + // create device + + DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; + DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; + if (pureSoftware) + { + if (FAILED(pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd, + fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice))) + os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR); + } + else + { + HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd, + fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if(FAILED(hr)) + hr = pID3D->CreateDevice(adapter, devtype, hwnd, + fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); + + if(FAILED(hr)) + hr = pID3D->CreateDevice(adapter, devtype, hwnd, + fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); + + if (FAILED(hr)) + os::Printer::log("Was not able to create Direct3D9 device.", ELL_ERROR); + } + + if (!pID3DDevice) + { + os::Printer::log("Was not able to create DIRECT3D9 device.", ELL_ERROR); + return false; + } + + // get caps + pID3DDevice->GetDeviceCaps(&Caps); + + os::Printer::log("Currently available Video Memory (kB)", core::stringc(pID3DDevice->GetAvailableTextureMem()/1024).c_str()); + + // disable stencilbuffer if necessary + if (Params.Stencilbuffer && + (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || + !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) + { + os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); + Params.Stencilbuffer = false; + } + + // set default vertex shader + setVertexShader(EVT_STANDARD); + + // set fog mode + setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); + + // set exposed data + ExposedData.D3D9.D3D9 = pID3D; + ExposedData.D3D9.D3DDev9 = pID3DDevice; + ExposedData.D3D9.HWnd = hwnd; + + ResetRenderStates = true; + + // create materials + createMaterialRenderers(); + + MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); + MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; + MaxMRTs = (s32)Caps.NumSimultaneousRTs; + OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK); + + if (VendorID==0x10DE)//NVidia + AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, + (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK); + else if (VendorID==0x1002)//ATI + AlphaToCoverageSupport = true; // TODO: Check unknown +#if 0 + AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, + (D3DFORMAT)MAKEFOURCC('A','2','M','1')) == S_OK); +#endif + + DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); + DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); + DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); + DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); + DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); + DriverAttributes->setAttribute("MaxMultipleRenderTargets", (s32)Caps.NumSimultaneousRTs); + DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); + DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); + DriverAttributes->setAttribute("MaxTextureLODBias", 16); + DriverAttributes->setAttribute("Version", 901); + DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)(((0x00ff00 & Caps.VertexShaderVersion)>>8)*100 + (Caps.VertexShaderVersion&0xff))); + DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); + + // set the renderstates + setRenderStates3DMode(); + + // store the screen's depth buffer + DepthBuffers.push_back(new SDepthSurface()); + if (SUCCEEDED(pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)))) + { + D3DSURFACE_DESC desc; + DepthBuffers[0]->Surface->GetDesc(&desc); + DepthBuffers[0]->Size.set(desc.Width, desc.Height); + } + else + { + os::Printer::log("Was not able to get main depth buffer.", ELL_ERROR); + return false; + } + + D3DColorFormat = D3DFMT_A8R8G8B8; + IDirect3DSurface9* bb=0; + if (SUCCEEDED(pID3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb))) + { + D3DSURFACE_DESC desc; + bb->GetDesc(&desc); + D3DColorFormat = desc.Format; + + if (D3DColorFormat == D3DFMT_X8R8G8B8) + D3DColorFormat = D3DFMT_A8R8G8B8; + + bb->Release(); + } + ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat); + + #ifdef _IRR_COMPILE_WITH_CG_ + CgContext = cgCreateContext(); + cgD3D9SetDevice(pID3DDevice); + #endif + + // so far so good. + return true; +} + + +//! applications must call this method before performing any rendering. returns false if failed. +bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, + const SExposedVideoData& videoData, core::rect* sourceRect) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); + WindowId = (HWND)videoData.D3D9.HWnd; + SceneSourceRect = sourceRect; + + if (!pID3DDevice) + return false; + + HRESULT hr; + if (DeviceLost) + { + if (FAILED(hr = pID3DDevice->TestCooperativeLevel())) + { + if (hr == D3DERR_DEVICELOST) + { + Sleep(100); + hr = pID3DDevice->TestCooperativeLevel(); + if (hr == D3DERR_DEVICELOST) + return false; + } + + if ((hr == D3DERR_DEVICENOTRESET) && !reset()) + return false; + } + } + + DWORD flags = 0; + + if (backBuffer) + flags |= D3DCLEAR_TARGET; + + if (zBuffer) + flags |= D3DCLEAR_ZBUFFER; + + if (Params.Stencilbuffer) + flags |= D3DCLEAR_STENCIL; + + if (flags) + { + hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); + if (FAILED(hr)) + os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING); + } + + hr = pID3DDevice->BeginScene(); + if (FAILED(hr)) + { + os::Printer::log("DIRECT3D9 begin scene failed.", ELL_WARNING); + return false; + } + + return true; +} + + +//! applications must call this method after performing any rendering. returns false if failed. +bool CD3D9Driver::endScene() +{ + CNullDriver::endScene(); + DriverWasReset=false; + + HRESULT hr = pID3DDevice->EndScene(); + if (FAILED(hr)) + { + os::Printer::log("DIRECT3D9 end scene failed.", ELL_WARNING); + return false; + } + + RECT* srcRct = 0; + RECT sourceRectData; + if ( SceneSourceRect ) + { + srcRct = &sourceRectData; + sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; + sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; + sourceRectData.right = SceneSourceRect->LowerRightCorner.X; + sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; + } + + IDirect3DSwapChain9* swChain; + hr = pID3DDevice->GetSwapChain(0, &swChain); + DWORD flags = (Params.HandleSRGB && (Caps.Caps3&D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION))?D3DPRESENT_LINEAR_CONTENT:0; + hr = swChain->Present(srcRct, NULL, WindowId, NULL, flags); + swChain->Release(); + + if (SUCCEEDED(hr)) + return true; + + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("Present failed", "DIRECT3D9 device lost.", ELL_WARNING); + } +#ifdef D3DERR_DEVICEREMOVED + else if (hr == D3DERR_DEVICEREMOVED) + { + os::Printer::log("Present failed", "Device removed.", ELL_WARNING); + } +#endif + else if (hr == D3DERR_INVALIDCALL) + { + os::Printer::log("Present failed", "Invalid Call", ELL_WARNING); + } + else + os::Printer::log("DIRECT3D9 present failed.", ELL_WARNING); + return false; +} + + +//! queries the features of the driver, returns true if feature is available +bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + if (!FeatureEnabled[feature]) + return false; + + switch (feature) + { + case EVDF_MULTITEXTURE: + case EVDF_BILINEAR_FILTER: + return true; + case EVDF_RENDER_TO_TARGET: + return Caps.NumSimultaneousRTs > 0; + case EVDF_HARDWARE_TL: + return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; + case EVDF_MIP_MAP: + return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; + case EVDF_MIP_MAP_AUTO_UPDATE: + // always return false because a lot of drivers claim they do + // this but actually don't do this at all. + return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0; + case EVDF_STENCIL_BUFFER: + return Params.Stencilbuffer && Caps.StencilCaps; + case EVDF_VERTEX_SHADER_1_1: + return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); + case EVDF_VERTEX_SHADER_2_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); + case EVDF_VERTEX_SHADER_3_0: + return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); + case EVDF_PIXEL_SHADER_1_1: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); + case EVDF_PIXEL_SHADER_1_2: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); + case EVDF_PIXEL_SHADER_1_3: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); + case EVDF_PIXEL_SHADER_1_4: + return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); + case EVDF_PIXEL_SHADER_2_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); + case EVDF_PIXEL_SHADER_3_0: + return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); + case EVDF_HLSL: + return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); + case EVDF_TEXTURE_NSQUARE: + return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; + case EVDF_TEXTURE_NPOT: + return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; + case EVDF_COLOR_MASK: + return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; + case EVDF_MULTIPLE_RENDER_TARGETS: + return Caps.NumSimultaneousRTs > 1; + case EVDF_MRT_COLOR_MASK: + return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_INDEPENDENTWRITEMASKS) != 0; + case EVDF_MRT_BLEND: + return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0; + case EVDF_OCCLUSION_QUERY: + return OcclusionQuerySupport; + case EVDF_POLYGON_OFFSET: + return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0; + case EVDF_BLEND_OPERATIONS: + case EVDF_TEXTURE_MATRIX: +#ifdef _IRR_COMPILE_WITH_CG_ + // available iff. define is present + case EVDF_CG: +#endif + return true; + default: + return false; + }; +} + + +//! sets transformation +void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state, + const core::matrix4& mat) +{ + Transformation3DChanged = true; + + switch(state) + { + case ETS_VIEW: + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_WORLD: + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_PROJECTION: + pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); + break; + case ETS_COUNT: + return; + default: + if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) + { + if (mat.isIdentity()) + pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + else + { + pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), + (D3DMATRIX*)((void*)mat.pointer())); + } + } + break; + } + + Matrices[state] = mat; +} + + +//! sets the current Texture +bool CD3D9Driver::setActiveTexture(u32 stage, const video::ITexture* texture) +{ + if (CurrentTexture[stage] == texture) + return true; + + if (texture && texture->getDriverType() != EDT_DIRECT3D9) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + CurrentTexture[stage] = texture; + + if (!texture) + { + pID3DDevice->SetTexture(stage, 0); + pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + } + else + { + pID3DDevice->SetTexture(stage, ((const CD3D9Texture*)texture)->getDX9Texture()); + } + return true; +} + + +//! sets a material +void CD3D9Driver::setMaterial(const SMaterial& material) +{ + Material = material; + OverrideMaterial.apply(Material); + + for (u32 i=0; igetDriverType() != EDT_DIRECT3D9) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + // check for valid render target + + if (texture && !texture->isRenderTarget()) + { + os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); + return false; + } + + CD3D9Texture* tex = static_cast(texture); + + // check if we should set the previous RT back + + bool ret = true; + + for(u32 i = 1; i < NumSetMRTs; i++) + { + // First texture handled elsewhere + pID3DDevice->SetRenderTarget(i, NULL); + } + if (tex == 0) + { + if (PrevRenderTarget) + { + if (FAILED(pID3DDevice->SetRenderTarget(0, PrevRenderTarget))) + { + os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); + ret = false; + } + if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthBuffers[0]->Surface))) + { + os::Printer::log("Error: Could not set main depth buffer.", ELL_ERROR); + } + + CurrentRendertargetSize = core::dimension2d(0,0); + PrevRenderTarget->Release(); + PrevRenderTarget = 0; + } + } + else + { + // we want to set a new target. so do this. + + // store previous target + + if (!PrevRenderTarget) + { + if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) + { + os::Printer::log("Could not get previous render target.", ELL_ERROR); + return false; + } + } + + // set new render target + + if (FAILED(pID3DDevice->SetRenderTarget(0, tex->getRenderTargetSurface()))) + { + os::Printer::log("Error: Could not set render target.", ELL_ERROR); + return false; + } + CurrentRendertargetSize = tex->getSize(); + + if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface))) + { + os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); + } + } + Transformation3DChanged=true; + + if (clearBackBuffer || clearZBuffer) + { + DWORD flags = 0; + + if (clearBackBuffer) + flags |= D3DCLEAR_TARGET; + + if (clearZBuffer) + flags |= D3DCLEAR_ZBUFFER; + + pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); + } + + return ret; +} + + +//! Sets multiple render targets +bool CD3D9Driver::setRenderTarget(const core::array& targets, + bool clearBackBuffer, bool clearZBuffer, SColor color) +{ + if (targets.size()==0) + return setRenderTarget(0, clearBackBuffer, clearZBuffer, color); + + u32 maxMultipleRTTs = core::min_(MaxMRTs, targets.size()); + + for (u32 i = 0; i < maxMultipleRTTs; ++i) + { + if (targets[i].TargetType != ERT_RENDER_TEXTURE || !targets[i].RenderTexture) + { + maxMultipleRTTs = i; + os::Printer::log("Missing texture for MRT.", ELL_WARNING); + break; + } + + // check for right driver type + + if (targets[i].RenderTexture->getDriverType() != EDT_DIRECT3D9) + { + maxMultipleRTTs = i; + os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING); + break; + } + + // check for valid render target + + if (!targets[i].RenderTexture->isRenderTarget()) + { + maxMultipleRTTs = i; + os::Printer::log("Tried to set a non render target texture as render target.", ELL_WARNING); + break; + } + + // check for valid size + + if (targets[0].RenderTexture->getSize() != targets[i].RenderTexture->getSize()) + { + maxMultipleRTTs = i; + os::Printer::log("Render target texture has wrong size.", ELL_WARNING); + break; + } + } + if (maxMultipleRTTs==0) + { + os::Printer::log("Fatal Error: No valid MRT found.", ELL_ERROR); + return false; + } + + CD3D9Texture* tex = static_cast(targets[0].RenderTexture); + + // check if we should set the previous RT back + + bool ret = true; + + // we want to set a new target. so do this. + // store previous target + + if (!PrevRenderTarget) + { + if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) + { + os::Printer::log("Could not get previous render target.", ELL_ERROR); + return false; + } + } + + // set new render target + + // In d3d9 we have at most 4 MRTs, so the following is enough + D3DRENDERSTATETYPE colorWrite[4]={D3DRS_COLORWRITEENABLE, D3DRS_COLORWRITEENABLE1, D3DRS_COLORWRITEENABLE2, D3DRS_COLORWRITEENABLE3}; + for (u32 i = 0; i < maxMultipleRTTs; ++i) + { + if (FAILED(pID3DDevice->SetRenderTarget(i, static_cast(targets[i].RenderTexture)->getRenderTargetSurface()))) + { + os::Printer::log("Error: Could not set render target.", ELL_ERROR); + return false; + } + if (i<4 && (i==0 || queryFeature(EVDF_MRT_COLOR_MASK))) + { + const DWORD flag = + ((targets[i].ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | + ((targets[i].ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | + ((targets[i].ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | + ((targets[i].ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); + pID3DDevice->SetRenderState(colorWrite[i], flag); + } + } + for(u32 i = maxMultipleRTTs; i < NumSetMRTs; i++) + { + pID3DDevice->SetRenderTarget(i, NULL); + } + NumSetMRTs=maxMultipleRTTs; + + CurrentRendertargetSize = tex->getSize(); + + if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface))) + { + os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); + } + + if (clearBackBuffer || clearZBuffer) + { + DWORD flags = 0; + + if (clearBackBuffer) + flags |= D3DCLEAR_TARGET; + + if (clearZBuffer) + flags |= D3DCLEAR_ZBUFFER; + + pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); + } + + return ret; +} + + +//! sets a viewport +void CD3D9Driver::setViewPort(const core::rect& area) +{ + core::rect vp = area; + core::rect rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); + vp.clipAgainst(rendert); + if (vp.getHeight()>0 && vp.getWidth()>0) + { + D3DVIEWPORT9 viewPort; + viewPort.X = vp.UpperLeftCorner.X; + viewPort.Y = vp.UpperLeftCorner.Y; + viewPort.Width = vp.getWidth(); + viewPort.Height = vp.getHeight(); + viewPort.MinZ = 0.0f; + viewPort.MaxZ = 1.0f; + + HRESULT hr = pID3DDevice->SetViewport(&viewPort); + if (FAILED(hr)) + os::Printer::log("Failed setting the viewport.", ELL_WARNING); + else + ViewPort = vp; + } +} + + +//! gets the area of the current viewport +const core::rect& CD3D9Driver::getViewPort() const +{ + return ViewPort; +} + + +bool CD3D9Driver::updateVertexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) +{ + if (!hwBuffer) + return false; + + const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer; + const void* vertices=mb->getVertices(); + const u32 vertexCount=mb->getVertexCount(); + const E_VERTEX_TYPE vType=mb->getVertexType(); + const u32 vertexSize = getVertexPitchFromType(vType); + const u32 bufSize = vertexSize * vertexCount; + + if (!hwBuffer->vertexBuffer || (bufSize > hwBuffer->vertexBufferSize)) + { + if (hwBuffer->vertexBuffer) + { + hwBuffer->vertexBuffer->Release(); + hwBuffer->vertexBuffer=0; + } + + DWORD FVF; + // Get the vertex sizes and cvf + switch (vType) + { + case EVT_STANDARD: + FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1; + break; + case EVT_2TCOORDS: + FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2; + break; + case EVT_TANGENTS: + FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3; + break; + default: + return false; + } + + DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY + if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC) + flags |= D3DUSAGE_DYNAMIC; + + if (FAILED(pID3DDevice->CreateVertexBuffer(bufSize, flags, FVF, D3DPOOL_DEFAULT, &hwBuffer->vertexBuffer, NULL))) + return false; + hwBuffer->vertexBufferSize = bufSize; + + flags = 0; // SIO2: Reset flags before Lock + if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC) + flags = D3DLOCK_DISCARD; + + void* lockedBuffer = 0; + hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, flags); + memcpy(lockedBuffer, vertices, bufSize); + hwBuffer->vertexBuffer->Unlock(); + } + else + { + void* lockedBuffer = 0; + hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, D3DLOCK_DISCARD); + memcpy(lockedBuffer, vertices, bufSize); + hwBuffer->vertexBuffer->Unlock(); + } + + return true; +} + + +bool CD3D9Driver::updateIndexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) +{ + if (!hwBuffer) + return false; + + const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer; + const u16* indices=mb->getIndices(); + const u32 indexCount=mb->getIndexCount(); + u32 indexSize = 2; + D3DFORMAT indexType=D3DFMT_UNKNOWN; + switch (mb->getIndexType()) + { + case EIT_16BIT: + { + indexType=D3DFMT_INDEX16; + indexSize = 2; + break; + } + case EIT_32BIT: + { + indexType=D3DFMT_INDEX32; + indexSize = 4; + break; + } + } + + const u32 bufSize = indexSize * indexCount; + if (!hwBuffer->indexBuffer || (bufSize > hwBuffer->indexBufferSize)) + { + if (hwBuffer->indexBuffer) + { + hwBuffer->indexBuffer->Release(); + hwBuffer->indexBuffer=0; + } + + DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY + if (hwBuffer->Mapped_Index != scene::EHM_STATIC) + flags |= D3DUSAGE_DYNAMIC; // SIO2: Add DYNAMIC flag for dynamic buffer data + + if (FAILED(pID3DDevice->CreateIndexBuffer(bufSize, flags, indexType, D3DPOOL_DEFAULT, &hwBuffer->indexBuffer, NULL))) + return false; + + flags = 0; // SIO2: Reset flags before Lock + if (hwBuffer->Mapped_Index != scene::EHM_STATIC) + flags = D3DLOCK_DISCARD; + + void* lockedBuffer = 0; + if (FAILED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, flags))) + return false; + + memcpy(lockedBuffer, indices, bufSize); + hwBuffer->indexBuffer->Unlock(); + + hwBuffer->indexBufferSize = bufSize; + } + else + { + void* lockedBuffer = 0; + if( SUCCEEDED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, D3DLOCK_DISCARD))) + { + memcpy(lockedBuffer, indices, bufSize); + hwBuffer->indexBuffer->Unlock(); + } + } + + return true; +} + + +//! updates hardware buffer if needed +bool CD3D9Driver::updateHardwareBuffer(SHWBufferLink *hwBuffer) +{ + if (!hwBuffer) + return false; + + if (hwBuffer->Mapped_Vertex!=scene::EHM_NEVER) + { + if (hwBuffer->ChangedID_Vertex != hwBuffer->MeshBuffer->getChangedID_Vertex() + || !((SHWBufferLink_d3d9*)hwBuffer)->vertexBuffer) + { + hwBuffer->ChangedID_Vertex = hwBuffer->MeshBuffer->getChangedID_Vertex(); + + if (!updateVertexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer)) + return false; + } + } + + if (hwBuffer->Mapped_Index!=scene::EHM_NEVER) + { + if (hwBuffer->ChangedID_Index != hwBuffer->MeshBuffer->getChangedID_Index() + || !((SHWBufferLink_d3d9*)hwBuffer)->indexBuffer) + { + hwBuffer->ChangedID_Index = hwBuffer->MeshBuffer->getChangedID_Index(); + + if (!updateIndexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer)) + return false; + } + } + + return true; +} + + +//! Create hardware buffer from meshbuffer +CD3D9Driver::SHWBufferLink *CD3D9Driver::createHardwareBuffer(const scene::IMeshBuffer* mb) +{ + // Looks like d3d does not support only partial buffering, so refuse + // in any case of NEVER + if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER || mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) + return 0; + + SHWBufferLink_d3d9 *hwBuffer=new SHWBufferLink_d3d9(mb); + + //add to map + HWBufferMap.insert(hwBuffer->MeshBuffer, hwBuffer); + + hwBuffer->ChangedID_Vertex=hwBuffer->MeshBuffer->getChangedID_Vertex(); + hwBuffer->ChangedID_Index=hwBuffer->MeshBuffer->getChangedID_Index(); + hwBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); + hwBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); + hwBuffer->LastUsed=0; + hwBuffer->vertexBuffer=0; + hwBuffer->indexBuffer=0; + hwBuffer->vertexBufferSize=0; + hwBuffer->indexBufferSize=0; + + if (!updateHardwareBuffer(hwBuffer)) + { + deleteHardwareBuffer(hwBuffer); + return 0; + } + + return hwBuffer; +} + + +void CD3D9Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) +{ + if (!_HWBuffer) + return; + + SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer; + if (HWBuffer->indexBuffer) + { + HWBuffer->indexBuffer->Release(); + HWBuffer->indexBuffer = 0; + } + + if (HWBuffer->vertexBuffer) + { + HWBuffer->vertexBuffer->Release(); + HWBuffer->vertexBuffer = 0; + } + + CNullDriver::deleteHardwareBuffer(_HWBuffer); +} + + +//! Draw hardware buffer +void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) +{ + if (!_HWBuffer) + return; + + SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer; + + updateHardwareBuffer(HWBuffer); //check if update is needed + + HWBuffer->LastUsed=0;//reset count + + const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; + const E_VERTEX_TYPE vType = mb->getVertexType(); + const u32 stride = getVertexPitchFromType(vType); + const void* vPtr = mb->getVertices(); + const void* iPtr = mb->getIndices(); + if (HWBuffer->vertexBuffer) + { + pID3DDevice->SetStreamSource(0, HWBuffer->vertexBuffer, 0, stride); + vPtr=0; + } + if (HWBuffer->indexBuffer) + { + pID3DDevice->SetIndices(HWBuffer->indexBuffer); + iPtr=0; + } + + drawVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); + + if (HWBuffer->vertexBuffer) + pID3DDevice->SetStreamSource(0, 0, 0, 0); + if (HWBuffer->indexBuffer) + pID3DDevice->SetIndices(0); +} + + +//! Create occlusion query. +/** Use node for identification and mesh for occlusion test. */ +void CD3D9Driver::addOcclusionQuery(scene::ISceneNode* node, + const scene::IMesh* mesh) +{ + if (!queryFeature(EVDF_OCCLUSION_QUERY)) + return; + CNullDriver::addOcclusionQuery(node, mesh); + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if ((index != -1) && (OcclusionQueries[index].PID == 0)) + pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast(&OcclusionQueries[index].PID)); +} + + +//! Remove occlusion query. +void CD3D9Driver::removeOcclusionQuery(scene::ISceneNode* node) +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + if (OcclusionQueries[index].PID != 0) + reinterpret_cast(OcclusionQueries[index].PID)->Release(); + CNullDriver::removeOcclusionQuery(node); + } +} + + +//! Run occlusion query. Draws mesh stored in query. +/** If the mesh shall not be rendered visible, use +overrideMaterial to disable the color and depth buffer. */ +void CD3D9Driver::runOcclusionQuery(scene::ISceneNode* node, bool visible) +{ + if (!node) + return; + + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + if (OcclusionQueries[index].PID) + reinterpret_cast(OcclusionQueries[index].PID)->Issue(D3DISSUE_BEGIN); + CNullDriver::runOcclusionQuery(node,visible); + if (OcclusionQueries[index].PID) + reinterpret_cast(OcclusionQueries[index].PID)->Issue(D3DISSUE_END); + } +} + + +//! Update occlusion query. Retrieves results from GPU. +/** If the query shall not block, set the flag to false. +Update might not occur in this case, though */ +void CD3D9Driver::updateOcclusionQuery(scene::ISceneNode* node, bool block) +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + // not yet started + if (OcclusionQueries[index].Run==u32(~0)) + return; + bool available = block?true:false; + int tmp=0; + if (!block) + available=(reinterpret_cast(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), 0)==S_OK); + else + { + do + { + HRESULT hr = reinterpret_cast(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), D3DGETDATA_FLUSH); + available = (hr == S_OK); + if (hr!=S_FALSE) + break; + } while (!available); + } + if (available) + OcclusionQueries[index].Result = tmp; + } +} + + +//! Return query result. +/** Return value is the number of visible pixels/fragments. +The value is a safe approximation, i.e. can be larger than the +actual value of pixels. */ +u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + return OcclusionQueries[index].Result; + else + return ~0; +} + + +//! draws a vertex primitive list +void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); + + if (!vertexCount || !primitiveCount) + return; + + draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, + vType, pType, iType, true); +} + + +//! draws a vertex primitive list +void CD3D9Driver::draw2DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType) +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); + + if (!vertexCount || !primitiveCount) + return; + + draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, + vType, pType, iType, false); +} + + +void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType, bool is3D) +{ + setVertexShader(vType); + + const u32 stride = getVertexPitchFromType(vType); + + D3DFORMAT indexType=D3DFMT_UNKNOWN; + switch (iType) + { + case (EIT_16BIT): + { + indexType=D3DFMT_INDEX16; + break; + } + case (EIT_32BIT): + { + indexType=D3DFMT_INDEX32; + break; + } + } + + if (is3D) + { + if (!setRenderStates3DMode()) + return; + } + else + { + if (Material.MaterialType==EMT_ONETEXTURE_BLEND) + { + E_BLEND_FACTOR srcFact; + E_BLEND_FACTOR dstFact; + E_MODULATE_FUNC modulo; + u32 alphaSource; + unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); + setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); + } + else + setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); + } + + switch (pType) + { + case scene::EPT_POINT_SPRITES: + case scene::EPT_POINTS: + { + f32 tmp=Material.Thickness/getScreenSize().Height; + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(tmp)); + tmp=1.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, F2DW(tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, F2DW(tmp)); + pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, F2DW(tmp)); + tmp=0.0f; + pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, F2DW(tmp)); + + if (!vertices) + { + pID3DDevice->DrawIndexedPrimitive(D3DPT_POINTLIST, 0, 0, vertexCount, 0, primitiveCount); + } + else + { + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + } + + pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); + if (pType==scene::EPT_POINT_SPRITES) + pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); + } + break; + case scene::EPT_LINE_STRIP: + if(!vertices) + pID3DDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 0, vertexCount, 0, primitiveCount); + else + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + case scene::EPT_LINE_LOOP: + if(!vertices) + { + // TODO: Implement proper hardware support for this primitive type. + // (No looping occurs currently because this would require a way to + // draw the hardware buffer with a custom set of indices. We may even + // need to create a new mini index buffer specifically for this + // primitive type.) + pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount); + } + else + { + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, + primitiveCount - 1, indexList, indexType, vertices, stride); + + u16 tmpIndices[] = {primitiveCount - 1, 0}; + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + 1, tmpIndices, indexType, vertices, stride); + } + break; + case scene::EPT_LINES: + if(!vertices) + pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount); + else + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + break; + case scene::EPT_TRIANGLE_STRIP: + if(!vertices) + pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, vertexCount, 0, primitiveCount); + else + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, primitiveCount, + indexList, indexType, vertices, stride); + break; + case scene::EPT_TRIANGLE_FAN: + if(!vertices) + pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 0, vertexCount, 0, primitiveCount); + else + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, primitiveCount, + indexList, indexType, vertices, stride); + break; + case scene::EPT_TRIANGLES: + if(!vertices) + { + pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertexCount, 0, primitiveCount); + } + else + { + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, + primitiveCount, indexList, indexType, vertices, stride); + } + break; + } +} + + +void CD3D9Driver::draw2DImage(const video::ITexture* texture, + const core::rect& destRect, + const core::rect& sourceRect, + const core::rect* clipRect, + const video::SColor* const colors, + bool useAlphaChannelOfTexture) +{ + if(!texture) + return; + + const core::dimension2d& ss = texture->getOriginalSize(); + core::rect tcoords; + tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; + tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; + tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; + tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + const video::SColor temp[4] = + { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF + }; + + const video::SColor* const useColor = colors ? colors : temp; + + S3DVertex vtx[4]; // clock wise + vtx[0] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[0], + tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[3], + tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[2], + tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, useColor[1], + tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + s16 indices[6] = {0,1,2,0,2,3}; + + setActiveTexture(0, const_cast(texture)); + + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || + useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, + true, useAlphaChannelOfTexture); + + setVertexShader(EVT_STANDARD); + + if (clipRect) + { + pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + RECT scissor; + scissor.left = clipRect->UpperLeftCorner.X; + scissor.top = clipRect->UpperLeftCorner.Y; + scissor.right = clipRect->LowerRightCorner.X; + scissor.bottom = clipRect->LowerRightCorner.Y; + pID3DDevice->SetScissorRect(&scissor); + } + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); + + if (clipRect) + pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); +} + + +void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture, + const core::array >& positions, + const core::array >& sourceRects, + const core::rect* clipRect, + SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!setActiveTexture(0, const_cast(texture))) + return; + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + const irr::u32 drawCount = core::min_(positions.size(), sourceRects.size()); + + core::array vtx(drawCount * 4); + core::array indices(drawCount * 6); + + for(u32 i = 0;i < drawCount;i++) + { + core::position2d targetPos = positions[i]; + core::position2d sourcePos = sourceRects[i].UpperLeftCorner; + // This needs to be signed as it may go negative. + core::dimension2d sourceSize(sourceRects[i].getSize()); + + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + continue; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + continue; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + continue; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + continue; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + continue; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + continue; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + continue; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + continue; + } + + // ok, we've clipped everything. + // now draw it. + + core::rect tcoords; + tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; + tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; + tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); + tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); + + const core::rect poss(targetPos, sourceSize); + + vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y)); + vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y)); + vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y)); + vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y)); + + const u32 curPos = vtx.size()-4; + indices.push_back(0+curPos); + indices.push_back(1+curPos); + indices.push_back(2+curPos); + + indices.push_back(0+curPos); + indices.push_back(2+curPos); + indices.push_back(3+curPos); + } + + if (vtx.size()) + { + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vtx.size(), indices.size() / 3, indices.pointer(), + D3DFMT_INDEX16,vtx.pointer(), sizeof(S3DVertex)); + } +} + + +//! draws a 2d image, using a color and the alpha channel of the texture if +//! desired. The image is drawn at pos and clipped against clipRect (if != 0). +void CD3D9Driver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!sourceRect.isValid()) + return; + + if (!setActiveTexture(0, const_cast(texture))) + return; + + core::position2d targetPos = pos; + core::position2d sourcePos = sourceRect.UpperLeftCorner; + // This needs to be signed as it may go negative. + core::dimension2d sourceSize(sourceRect.getSize()); + + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + return; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + return; + } + + // ok, we've clipped everything. + // now draw it. + + core::rect tcoords; + tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; + tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; + tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); + tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); + + const core::rect poss(targetPos, sourceSize); + + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, color, + tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + + s16 indices[6] = {0,1,2,0,2,3}; + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); +} + + +//!Draws a 2d rectangle with a gradient. +void CD3D9Driver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + core::rect pos(position); + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); + vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); + vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); + vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, + 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); + + s16 indices[6] = {0,1,2,0,2,3}; + + setRenderStates2DMode( + colorLeftUp.getAlpha() < 255 || + colorRightUp.getAlpha() < 255 || + colorLeftDown.getAlpha() < 255 || + colorRightDown.getAlpha() < 255, false, false); + + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); +} + + +//! Draws a 2d line. +void CD3D9Driver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + if (start==end) + drawPixel(start.X, start.Y, color); + else + { + // thanks to Vash TheStampede who sent in his implementation + S3DVertex vtx[2]; + vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, + 0.0f, 0.0f, 0.0f, // normal + color, 0.0f, 0.0f); // texture + + vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, + 0.0f, 0.0f, 0.0f, + color, 0.0f, 0.0f); + + setRenderStates2DMode(color.getAlpha() < 255, false, false); + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, + &vtx[0], sizeof(S3DVertex) ); + } +} + + +//! Draws a pixel +void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color) +{ + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + if(x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) + return; + + setRenderStates2DMode(color.getAlpha() < 255, false, false); + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); + + pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); +} + + +//! sets right vertex shader +void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType) +{ + if (newType != LastVertexType) + { + LastVertexType = newType; + HRESULT hr = 0; + + switch(newType) + { + case EVT_STANDARD: + hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); + break; + case EVT_2TCOORDS: + hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); + break; + case EVT_TANGENTS: + hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | + D3DFVF_TEXCOORDSIZE2(0) | // real texture coord + D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent + D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal + ); + break; + } + + if (FAILED(hr)) + { + os::Printer::log("Could not set vertex Shader.", ELL_ERROR); + return; + } + } +} + + +//! sets the needed renderstates +bool CD3D9Driver::setRenderStates3DMode() +{ + if (!pID3DDevice) + return false; + + if (CurrentRenderMode != ERM_3D) + { + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_CLIPPING, TRUE); + + ResetRenderStates = true; + } + + if (ResetRenderStates || LastMaterial != Material) + { + // unset old material + + if (CurrentRenderMode == ERM_3D && + LastMaterial.MaterialType != Material.MaterialType && + LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + + // set new material. + + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( + Material, LastMaterial, ResetRenderStates, this); + } + + bool shaderOK = true; + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); + + LastMaterial = Material; + + ResetRenderStates = false; + + CurrentRenderMode = ERM_3D; + + return shaderOK; +} + + +//! Map Irrlicht texture wrap mode to native values +D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp) +{ + switch (clamp) + { + case ETC_REPEAT: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) + return D3DTADDRESS_WRAP; + case ETC_CLAMP: + case ETC_CLAMP_TO_EDGE: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) + return D3DTADDRESS_CLAMP; + case ETC_MIRROR: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) + return D3DTADDRESS_MIRROR; + case ETC_CLAMP_TO_BORDER: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) + return D3DTADDRESS_BORDER; + else + return D3DTADDRESS_CLAMP; + case ETC_MIRROR_CLAMP: + case ETC_MIRROR_CLAMP_TO_EDGE: + case ETC_MIRROR_CLAMP_TO_BORDER: + if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) + return D3DTADDRESS_MIRRORONCE; + else + return D3DTADDRESS_CLAMP; + default: + return D3DTADDRESS_WRAP; + } +} + + +//! Can be called by an IMaterialRenderer to make its work easier. +void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderstates) +{ + // This needs only to be updated onresets + if (Params.HandleSRGB && resetAllRenderstates) + pID3DDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE); + + if (resetAllRenderstates || + lastmaterial.AmbientColor != material.AmbientColor || + lastmaterial.DiffuseColor != material.DiffuseColor || + lastmaterial.SpecularColor != material.SpecularColor || + lastmaterial.EmissiveColor != material.EmissiveColor || + lastmaterial.Shininess != material.Shininess) + { + D3DMATERIAL9 mat; + mat.Diffuse = colorToD3D(material.DiffuseColor); + mat.Ambient = colorToD3D(material.AmbientColor); + mat.Specular = colorToD3D(material.SpecularColor); + mat.Emissive = colorToD3D(material.EmissiveColor); + mat.Power = material.Shininess; + pID3DDevice->SetMaterial(&mat); + } + + if (lastmaterial.ColorMaterial != material.ColorMaterial) + { + pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); + pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, + ((material.ColorMaterial == ECM_DIFFUSE)|| + (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); + pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, + ((material.ColorMaterial == ECM_AMBIENT)|| + (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); + pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, + (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, + (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + } + + // fillmode + if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) + { + if (material.Wireframe) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + else + if (material.PointCloud) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); + else + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + } + + // shademode + + if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) + { + if (material.GouraudShading) + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + else + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } + + // lighting + + if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) + { + if (material.Lighting) + pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); + else + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + } + + // zbuffer + + if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) + { + switch (material.ZBuffer) + { + case ECFN_NEVER: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + break; + case ECFN_LESSEQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + break; + case ECFN_EQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + break; + case ECFN_LESS: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + break; + case ECFN_NOTEQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); + break; + case ECFN_GREATEREQUAL: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); + break; + case ECFN_GREATER: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); + break; + case ECFN_ALWAYS: + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + break; + } + } + + // zwrite +// if (resetAllRenderstates || (lastmaterial.ZWriteEnable != material.ZWriteEnable)) + { + if ( material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); + else + pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); + } + + // back face culling + + if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) + { +// if (material.FrontfaceCulling && material.BackfaceCulling) +// pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); +// else + if (material.FrontfaceCulling) + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + else + if (material.BackfaceCulling) + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + else + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } + + // fog + if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) + { + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); + } + + // specular highlights + if (resetAllRenderstates || !core::equals(lastmaterial.Shininess,material.Shininess)) + { + const bool enable = (material.Shininess!=0.0f); + pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); + pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); + } + + // normalization + if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) + { + pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); + } + + // Color Mask + if (queryFeature(EVDF_COLOR_MASK) && + (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) + { + const DWORD flag = + ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | + ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | + ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | + ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); + pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); + } + + if (queryFeature(EVDF_BLEND_OPERATIONS) && + (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) + { + if (material.BlendOperation==EBO_NONE) + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + switch (material.BlendOperation) + { + case EBO_SUBTRACT: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); + break; + case EBO_REVSUBTRACT: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); + break; + case EBO_MIN: + case EBO_MIN_FACTOR: + case EBO_MIN_ALPHA: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); + break; + case EBO_MAX: + case EBO_MAX_FACTOR: + case EBO_MAX_ALPHA: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); + break; + default: + pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + break; + } + } + } + + // Polygon offset + if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || + lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || + lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) + { + if (material.PolygonOffsetFactor) + { + if (material.PolygonOffsetDirection==EPO_BACK) + { + pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1.f)); + pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)material.PolygonOffsetFactor)); + } + else + { + pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(-1.f)); + pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)-material.PolygonOffsetFactor)); + } + } + else + { + pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); + pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); + } + } + + // Anti Aliasing + if (resetAllRenderstates || lastmaterial.AntiAliasing != material.AntiAliasing) + { + if (AlphaToCoverageSupport && (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)) + { + if (VendorID==0x10DE)//NVidia + pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, MAKEFOURCC('A','T','O','C')); + // SSAA could give better results on NVidia cards + else if (VendorID==0x1002)//ATI + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1')); + } + else if (AlphaToCoverageSupport && (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)) + { + if (VendorID==0x10DE) + pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN); + else if (VendorID==0x1002) + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0')); + } + + // enable antialiasing + if (Params.AntiAlias) + { + if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) + pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + else if (lastmaterial.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) + pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); + if (material.AntiAliasing & (EAAM_LINE_SMOOTH)) + pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, TRUE); + else if (lastmaterial.AntiAliasing & (EAAM_LINE_SMOOTH)) + pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); + } + } + + // thickness + if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) + { + pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(material.Thickness)); + } + + // texture address mode + for (u32 st=0; stSetSamplerState(st, D3DSAMP_SRGBTEXTURE, TRUE); + + if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) + { + const float tmp = material.TextureLayer[st].LODBias * 0.125f; + pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, F2DW(tmp)); + } + + if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) + pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); + // If separate UV not supported reuse U for V + if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) + pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); + else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) + pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); + + // Bilinear, trilinear, and anisotropic filter + if (resetAllRenderstates || + lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || + lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || + lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || + lastmaterial.UseMipMaps != material.UseMipMaps) + { + if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter) + { + D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && + material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && + material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; + D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; + + if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) + pID3DDevice->SetSamplerState(st, D3DSAMP_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); + pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, tftMag); + pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, tftMin); + pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, tftMip); + } + else + { + pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, D3DTEXF_POINT); + pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } + } + } +} + + +//! sets the needed renderstates +void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) +{ + if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && + CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || + Transformation3DChanged) + { + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + static_cast(Material.MaterialType) < MaterialRenderers.size()) + { + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + ResetRenderStates = true; + } + // switch back the matrices + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); + + Transformation3DChanged = false; + + setActiveTexture(0,0); + setActiveTexture(1,0); + setActiveTexture(2,0); + setActiveTexture(3,0); + + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + + pID3DDevice->SetFVF(D3DFVF_XYZ); + LastVertexType = (video::E_VERTEX_TYPE)(-1); + + pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + + pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); + pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); + pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); + + pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); + pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); + pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + + //if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) + // pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) + pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); + } + + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) + { + // USE THE ZPASS METHOD + pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + //pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); // does not matter, will be set later + } + else + if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) + { + // USE THE ZFAIL METHOD + pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + //pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); // does not matter, will be set later + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); + } + + CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; +} + + +//! sets the needed renderstates +void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha) +{ + if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D9); + pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D9); + pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D9); + + pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1); + pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); + //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); + pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); + pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); + + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + + Transformation3DChanged = false; + + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + if (alpha) + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + CurrentRenderMode = ERM_STENCIL_FILL; +} + + +//! Enable the 2d override material +void CD3D9Driver::enableMaterial2D(bool enable) +{ + if (!enable) + CurrentRenderMode = ERM_NONE; + CNullDriver::enableMaterial2D(enable); +} + + +//! sets the needed renderstates +void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) +{ + if (!pID3DDevice) + return; + + if (CurrentRenderMode != ERM_2D || Transformation3DChanged) + { + // unset last 3d material + if (CurrentRenderMode == ERM_3D) + { + if (static_cast(LastMaterial.MaterialType) < MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + } + if (!OverrideMaterial2DEnabled) + { + setBasicRenderStates(InitMaterial2D, LastMaterial, true); + LastMaterial=InitMaterial2D; + + // fix everything that is wrongly set by InitMaterial2D default + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + } + core::matrix4 m; +// this fixes some problems with pixel exact rendering, but also breaks nice texturing +// moreover, it would have to be tested in each call, as the texture flag can change each time +// if (!texture) +// m.setTranslation(core::vector3df(0.5f,0.5f,0)); + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)m.pointer())); + + // adjust the view such that pixel center aligns with texels + // Otherwise, subpixel artifacts will occur + m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); + pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); + m.setTranslation(core::vector3df(-1,1,0)); + pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); + + // 2d elements are clipped in software + pID3DDevice->SetRenderState(D3DRS_CLIPPING, FALSE); + + Transformation3DChanged = false; + } + if (OverrideMaterial2DEnabled) + { + OverrideMaterial2D.Lighting=false; + setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); + LastMaterial = OverrideMaterial2D; + } + + // no alphaChannel without texture + alphaChannel &= texture; + + if (alpha || alphaChannel) + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + else + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + if (texture) + { + setTransform(ETS_TEXTURE_0, core::IdentityMatrix); + // Due to the transformation change, the previous line would call a reset each frame + // but we can safely reset the variable as it was false before + Transformation3DChanged=false; + } + if (alphaChannel) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + } + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + if (alpha) + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + } + else + { + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + } + } + + CurrentRenderMode = ERM_2D; +} + + +//! deletes all dynamic lights there are +void CD3D9Driver::deleteAllDynamicLights() +{ + for (s32 i=0; iLightEnable(i, false); + + LastSetLight = -1; + + CNullDriver::deleteAllDynamicLights(); +} + + +//! adds a dynamic light +s32 CD3D9Driver::addDynamicLight(const SLight& dl) +{ + CNullDriver::addDynamicLight(dl); + + D3DLIGHT9 light; + + switch (dl.Type) + { + case ELT_POINT: + light.Type = D3DLIGHT_POINT; + break; + case ELT_SPOT: + light.Type = D3DLIGHT_SPOT; + break; + case ELT_DIRECTIONAL: + light.Type = D3DLIGHT_DIRECTIONAL; + break; + } + + light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); + light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); + + light.Range = core::min_(dl.Radius, MaxLightDistance); + light.Falloff = dl.Falloff; + + light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); + light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); + light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); + + light.Attenuation0 = dl.Attenuation.X; + light.Attenuation1 = dl.Attenuation.Y; + light.Attenuation2 = dl.Attenuation.Z; + + light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; + light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; + + ++LastSetLight; + + if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) + { + // I don't care if this succeeds + (void)pID3DDevice->LightEnable(LastSetLight, true); + return LastSetLight; + } + + return -1; +} + +//! Turns a dynamic light on or off +//! \param lightIndex: the index returned by addDynamicLight +//! \param turnOn: true to turn the light on, false to turn it off +void CD3D9Driver::turnLightOn(s32 lightIndex, bool turnOn) +{ + if(lightIndex < 0 || lightIndex > LastSetLight) + return; + + (void)pID3DDevice->LightEnable(lightIndex, turnOn); +} + + +//! returns the maximal amount of dynamic lights the device can handle +u32 CD3D9Driver::getMaximalDynamicLightAmount() const +{ + return Caps.MaxActiveLights; +} + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CD3D9Driver::setAmbientLight(const SColorf& color) +{ + if (!pID3DDevice) + return; + + AmbientLight = color; + D3DCOLOR col = color.toSColor().color; + pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); +} + + +//! \return Returns the name of the video driver. Example: In case of the DIRECT3D9 +//! driver, it would return "Direct3D9.0". +const wchar_t* CD3D9Driver::getName() const +{ + return L"Direct3D 9.0"; +} + + +//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do +//! this: First, draw all geometry. Then use this method, to draw the shadow +//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CD3D9Driver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) +{ + if (!Params.Stencilbuffer) + return; + + setRenderStatesStencilShadowMode(zfail, debugDataVisible); + + const u32 count = triangles.size(); + if (!count) + return; + + if (!zfail) + { + // ZPASS Method + + // Draw front-side of shadow volume in stencil only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + } + else + { + // ZFAIL Method + + // Draw front-side of shadow volume in stencil only + pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + + // Now reverse cull order so front sides of shadow volume are written. + pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); + pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR); + pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); + } +} + + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!Params.Stencilbuffer) + return; + + S3DVertex vtx[4]; + vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); + vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); + vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); + vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); + + s16 indices[6] = {0,1,2,1,3,2}; + + setRenderStatesStencilFillMode( + leftUpEdge.getAlpha() < 255 || + rightUpEdge.getAlpha() < 255 || + leftDownEdge.getAlpha() < 255 || + rightDownEdge.getAlpha() < 255); + + setActiveTexture(0,0); + + setVertexShader(EVT_STANDARD); + + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], + D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); + + if (clearStencilBuffer) + pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CD3D9Driver::getMaximalPrimitiveCount() const +{ + return Caps.MaxPrimitiveCount; +} + + +//! Sets the fog mode. +void CD3D9Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); + + if (!pID3DDevice) + return; + + pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); + + pID3DDevice->SetRenderState( + pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, + (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); + + if (fogType==EFT_FOG_LINEAR) + { + pID3DDevice->SetRenderState(D3DRS_FOGSTART, F2DW(start)); + pID3DDevice->SetRenderState(D3DRS_FOGEND, F2DW(end)); + } + else + pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, F2DW(density)); + + if(!pixelFog) + pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); +} + + +//! Draws a 3d line. +void CD3D9Driver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + setVertexShader(EVT_STANDARD); + setRenderStates3DMode(); + video::S3DVertex v[2]; + v[0].Color = color; + v[1].Color = color; + v[0].Pos = start; + v[1].Pos = end; + + pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); +} + + +//! resets the device +bool CD3D9Driver::reset() +{ + u32 i; + os::Printer::log("Resetting D3D9 device.", ELL_INFORMATION); + + for (i=0; iisRenderTarget()) + { + IDirect3DBaseTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture(); + if (tex) + tex->Release(); + } + } + for (i=0; iSurface) + DepthBuffers[i]->Surface->Release(); + } + for (i=0; i(OcclusionQueries[i].PID)->Release(); + OcclusionQueries[i].PID=0; + } + } + // this does not require a restore in the reset method, it's updated + // automatically in the next render cycle. + removeAllHardwareBuffers(); + + DriverWasReset=true; + + HRESULT hr = pID3DDevice->Reset(&present); + + // restore RTTs + for (i=0; iisRenderTarget()) + ((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget(); + } + + // restore screen depthbuffer + pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)); + D3DSURFACE_DESC desc; + // restore other depth buffers + // depth format is taken from main depth buffer + DepthBuffers[0]->Surface->GetDesc(&desc); + // multisampling is taken from rendertarget + D3DSURFACE_DESC desc2; + for (i=1; iDepthSurface==DepthBuffers[i]) + { + ((CD3D9Texture*)(Textures[j].Surface))->Texture->GetLevelDesc(0,&desc2); + break; + } + } + + pID3DDevice->CreateDepthStencilSurface(DepthBuffers[i]->Size.Width, + DepthBuffers[i]->Size.Height, + desc.Format, + desc2.MultiSampleType, + desc2.MultiSampleQuality, + TRUE, + &(DepthBuffers[i]->Surface), + NULL); + } + for (i=0; iCreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast(&OcclusionQueries[i].PID)); + } + + if (FAILED(hr)) + { + if (hr == D3DERR_DEVICELOST) + { + DeviceLost = true; + os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); + } +#ifdef D3DERR_DEVICEREMOVED + else if (hr == D3DERR_DEVICEREMOVED) + { + os::Printer::log("Resetting failed due to device removed.", ELL_WARNING); + } +#endif + else if (hr == D3DERR_DRIVERINTERNALERROR) + { + os::Printer::log("Resetting failed due to internal error.", ELL_WARNING); + } + else if (hr == D3DERR_OUTOFVIDEOMEMORY) + { + os::Printer::log("Resetting failed due to out of memory.", ELL_WARNING); + } + else if (hr == D3DERR_DEVICENOTRESET) + { + os::Printer::log("Resetting failed due to not reset.", ELL_WARNING); + } + else if (hr == D3DERR_INVALIDCALL) + { + os::Printer::log("Resetting failed due to invalid call", "You need to release some more surfaces.", ELL_WARNING); + } + else + { + os::Printer::log("Resetting failed due to unknown reason.", core::stringc((int)hr).c_str(), ELL_WARNING); + } + return false; + } + + DeviceLost = false; + ResetRenderStates = true; + LastVertexType = (E_VERTEX_TYPE)-1; + + for (u32 i=0; i& size) +{ + if (!pID3DDevice) + return; + + CNullDriver::OnResize(size); + present.BackBufferWidth = size.Width; + present.BackBufferHeight = size.Height; + + reset(); +} + + +//! Returns type of video driver +E_DRIVER_TYPE CD3D9Driver::getDriverType() const +{ + return EDT_DIRECT3D9; +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CD3D9Driver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Matrices[state]; +} + + +//! Sets a vertex shader constant. +void CD3D9Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetVertexShaderConstantF(startRegister, data, constantAmount); +} + + +//! Sets a pixel shader constant. +void CD3D9Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + if (data) + pID3DDevice->SetPixelShaderConstantF(startRegister, data, constantAmount); +} + + +//! Sets a constant for the vertex shader based on a name. +bool CD3D9Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(true, name, floats, count); + } + + return false; +} + + +//! Bool interface for the above. +bool CD3D9Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(true, name, bools, count); + } + + return false; +} + + +//! Int interface for the above. +bool CD3D9Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(true, name, ints, count); + } + + return false; +} + + +//! Sets a constant for the pixel shader based on a name. +bool CD3D9Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(false, name, floats, count); + } + + return false; +} + + +//! Bool interface for the above. +bool CD3D9Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(false, name, bools, count); + } + + return false; +} + + +//! Int interface for the above. +bool CD3D9Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) +{ + if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) + { + CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; + return r->setVariable(false, name, ints, count); + } + + return false; +} + + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 CD3D9Driver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData) +{ + s32 nr = -1; + CD3D9ShaderMaterialRenderer* r = new CD3D9ShaderMaterialRenderer( + pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, + callback, getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + + +//! Adds a new material renderer to the VideoDriver, based on a high level shading +//! language. +s32 CD3D9Driver::addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName, + E_GEOMETRY_SHADER_TYPE gsCompileTarget, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) +{ + s32 nr = -1; + + #ifdef _IRR_COMPILE_WITH_CG_ + if(shadingLang == EGSL_CG) + { + CD3D9CgMaterialRenderer* r = new CD3D9CgMaterialRenderer( + this, nr, + vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, + pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, + geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, + inType, outType, verticesOut, + callback,getMaterialRenderer(baseMaterial), userData); + + r->drop(); + } + else + #endif + { + CD3D9HLSLMaterialRenderer* r = new CD3D9HLSLMaterialRenderer( + pID3DDevice, this, nr, + vertexShaderProgram, + vertexShaderEntryPointName, + vsCompileTarget, + pixelShaderProgram, + pixelShaderEntryPointName, + psCompileTarget, + callback, + getMaterialRenderer(baseMaterial), + userData); + + r->drop(); + } + + return nr; +} + + +//! Returns a pointer to the IVideoDriver interface. (Implementation for +//! IMaterialRendererServices) +IVideoDriver* CD3D9Driver::getVideoDriver() +{ + return this; +} + + +//! Creates a render target texture. +ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, + const ECOLOR_FORMAT format) +{ + CD3D9Texture* tex = new CD3D9Texture(this, size, name, format); + if (tex) + { + if (!tex->Texture) + { + tex->drop(); + return 0; + } + checkDepthBuffer(tex); + addTexture(tex); + tex->drop(); + } + return tex; +} + + +//! Clears the ZBuffer. +void CD3D9Driver::clearZBuffer() +{ + HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); + + if (FAILED(hr)) + os::Printer::log("CD3D9Driver clearZBuffer() failed.", ELL_WARNING); +} + + +//! Returns an image created from the last rendered frame. +IImage* CD3D9Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) +{ + if (target != video::ERT_FRAME_BUFFER) + return 0; + + // query the screen dimensions of the current adapter + D3DDISPLAYMODE displayMode; + pID3DDevice->GetDisplayMode(0, &displayMode); + + if (format==video::ECF_UNKNOWN) + format=video::ECF_A8R8G8B8; + + // create the image surface to store the front buffer image [always A8R8G8B8] + HRESULT hr; + LPDIRECT3DSURFACE9 lpSurface; + if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0))) + return 0; + + // read the front buffer into the image surface + if (FAILED(hr = pID3DDevice->GetFrontBufferData(0, lpSurface))) + { + lpSurface->Release(); + return 0; + } + + RECT clientRect; + { + POINT clientPoint; + clientPoint.x = 0; + clientPoint.y = 0; + + ClientToScreen((HWND)getExposedVideoData().D3D9.HWnd, &clientPoint); + + clientRect.left = clientPoint.x; + clientRect.top = clientPoint.y; + clientRect.right = clientRect.left + ScreenSize.Width; + clientRect.bottom = clientRect.top + ScreenSize.Height; + + // window can be off-screen partly, we can't take screenshots from that + clientRect.left = core::max_(clientRect.left, 0l); + clientRect.top = core::max_(clientRect.top, 0l); + clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); + clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); + } + + // lock our area of the surface + D3DLOCKED_RECT lockedRect; + if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) + { + lpSurface->Release(); + return 0; + } + + irr::core::dimension2d shotSize; + shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); + shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); + + // this could throw, but we aren't going to worry about that case very much + IImage* newImage = createImage(format, shotSize); + + if (newImage) + { + // d3d pads the image, so we need to copy the correct number of bytes + u32* dP = (u32*)newImage->lock(); + u8 * sP = (u8 *)lockedRect.pBits; + + // If the display mode format doesn't promise anything about the Alpha value + // and it appears that it's not presenting 255, then we should manually + // set each pixel alpha value to 255. + if (D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) + { + for (u32 y = 0; y < shotSize.Height; ++y) + { + for (u32 x = 0; x < shotSize.Width; ++x) + { + newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); + sP += 4; + } + + sP += lockedRect.Pitch - (4 * shotSize.Width); + } + } + else + { + for (u32 y = 0; y < shotSize.Height; ++y) + { + convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); + sP += lockedRect.Pitch; + dP += shotSize.Width; + } + } + + newImage->unlock(); + } + + // we can unlock and release the surface + lpSurface->UnlockRect(); + + // release the image surface + lpSurface->Release(); + + // return status of save operation to caller + return newImage; +} + + +//! returns color format +ECOLOR_FORMAT CD3D9Driver::getColorFormat() const +{ + return ColorFormat; +} + + +//! returns color format +D3DFORMAT CD3D9Driver::getD3DColorFormat() const +{ + return D3DColorFormat; +} + + +// returns the current size of the screen or rendertarget +const core::dimension2d& CD3D9Driver::getCurrentRenderTargetSize() const +{ + if ( CurrentRendertargetSize.Width == 0 ) + return ScreenSize; + else + return CurrentRendertargetSize; +} + + +// Set/unset a clipping plane. +bool CD3D9Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ + if (index >= MaxUserClipPlanes) + return false; + + HRESULT ok = pID3DDevice->SetClipPlane(index, (const float*)&(plane.Normal.X)); + if (D3D_OK == ok) + enableClipPlane(index, enable); + return true; +} + + +// Enable/disable a clipping plane. +void CD3D9Driver::enableClipPlane(u32 index, bool enable) +{ + if (index >= MaxUserClipPlanes) + return; + DWORD renderstate; + HRESULT ok = pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); + if (S_OK == ok) + { + if (enable) + renderstate |= (1 << index); + else + renderstate &= ~(1 << index); + ok = pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); + } +} + + +D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const +{ + switch(format) + { + case ECF_A1R5G5B5: + return D3DFMT_A1R5G5B5; + case ECF_R5G6B5: + return D3DFMT_R5G6B5; + case ECF_R8G8B8: + return D3DFMT_R8G8B8; + case ECF_A8R8G8B8: + return D3DFMT_A8R8G8B8; + + // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski. + case ECF_R16F: + return D3DFMT_R16F; + case ECF_G16R16F: + return D3DFMT_G16R16F; + case ECF_A16B16G16R16F: + return D3DFMT_A16B16G16R16F; + case ECF_R32F: + return D3DFMT_R32F; + case ECF_G32R32F: + return D3DFMT_G32R32F; + case ECF_A32B32G32R32F: + return D3DFMT_A32B32G32R32F; + } + return D3DFMT_UNKNOWN; +} + + +ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const +{ + switch(format) + { + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + return ECF_A1R5G5B5; + case D3DFMT_A8B8G8R8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + return ECF_A8R8G8B8; + case D3DFMT_R5G6B5: + return ECF_R5G6B5; + case D3DFMT_R8G8B8: + return ECF_R8G8B8; + + // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski. + case D3DFMT_R16F: + return ECF_R16F; + case D3DFMT_G16R16F: + return ECF_G16R16F; + case D3DFMT_A16B16G16R16F: + return ECF_A16B16G16R16F; + case D3DFMT_R32F: + return ECF_R32F; + case D3DFMT_G32R32F: + return ECF_G32R32F; + case D3DFMT_A32B32G32R32F: + return ECF_A32B32G32R32F; + default: + return (ECOLOR_FORMAT)0; + }; +} + + +void CD3D9Driver::checkDepthBuffer(ITexture* tex) +{ + if (!tex) + return; + const core::dimension2du optSize = tex->getSize().getOptimalSize( + !queryFeature(EVDF_TEXTURE_NPOT), + !queryFeature(EVDF_TEXTURE_NSQUARE), true); + SDepthSurface* depth=0; + core::dimension2du destSize(0x7fffffff, 0x7fffffff); + for (u32 i=0; iSize.Width>=optSize.Width) && + (DepthBuffers[i]->Size.Height>=optSize.Height)) + { + if ((DepthBuffers[i]->Size.WidthSize.HeightSize; + } + } + } + if (!depth) + { + D3DSURFACE_DESC desc; + DepthBuffers[0]->Surface->GetDesc(&desc); + // the multisampling needs to match the RTT + D3DSURFACE_DESC desc2; + ((CD3D9Texture*)tex)->Texture->GetLevelDesc(0,&desc2); + DepthBuffers.push_back(new SDepthSurface()); + HRESULT hr=pID3DDevice->CreateDepthStencilSurface(optSize.Width, + optSize.Height, + desc.Format, + desc2.MultiSampleType, + desc2.MultiSampleQuality, + TRUE, + &(DepthBuffers.getLast()->Surface), + NULL); + if (SUCCEEDED(hr)) + { + depth=DepthBuffers.getLast(); + depth->Surface->GetDesc(&desc); + depth->Size.set(desc.Width, desc.Height); + } + else + { + if (hr == D3DERR_OUTOFVIDEOMEMORY) + os::Printer::log("Could not create DepthBuffer","out of video memory",ELL_ERROR); + else if( hr == E_OUTOFMEMORY ) + os::Printer::log("Could not create DepthBuffer","out of memory",ELL_ERROR); + else + { + char buffer[128]; + sprintf(buffer,"Could not create DepthBuffer of %ix%i",optSize.Width,optSize.Height); + os::Printer::log(buffer,ELL_ERROR); + } + DepthBuffers.erase(DepthBuffers.size()-1); + } + } + else + depth->grab(); + + static_cast(tex)->DepthSurface=depth; +} + + +void CD3D9Driver::removeDepthSurface(SDepthSurface* depth) +{ + for (u32 i=0; iinitDriver(window, pureSoftware)) + { + dx9->drop(); + dx9 = 0; + } + + return dx9; +} +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + +} // end namespace video +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.h new file mode 100644 index 0000000..095ae9d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Driver.h @@ -0,0 +1,496 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_DIRECTX_9_H_INCLUDED__ +#define __C_VIDEO_DIRECTX_9_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#ifdef _IRR_WINDOWS_ +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include "CNullDriver.h" +#include "SIrrCreationParameters.h" +#include "IMaterialRendererServices.h" +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#include "irrMath.h" // needed by borland for sqrtf define +#endif +#include + +#ifdef _IRR_COMPILE_WITH_CG_ +#include "Cg/cg.h" +#include "Cg/cgD3D9.h" +#endif + +namespace irr +{ +namespace video +{ + struct SDepthSurface : public IReferenceCounted + { + SDepthSurface() : Surface(0) + { + #ifdef _DEBUG + setDebugName("SDepthSurface"); + #endif + } + virtual ~SDepthSurface() + { + if (Surface) + Surface->Release(); + } + + IDirect3DSurface9* Surface; + core::dimension2du Size; + }; + + class CD3D9Driver : public CNullDriver, IMaterialRendererServices + { + public: + + friend class CD3D9Texture; + + //! constructor + CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io); + + //! destructor + virtual ~CD3D9Driver(); + + //! applications must call this method before performing any rendering. returns false if failed. + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect* sourceRect=0); + + //! applications must call this method after performing any rendering. returns false if failed. + virtual bool endScene(); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + //! sets a render target + virtual bool setRenderTarget(video::ITexture* texture, + bool clearBackBuffer=true, bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)); + + //! Sets multiple render targets + virtual bool setRenderTarget(const core::array& texture, + bool clearBackBuffer=true, bool clearZBuffer=true, + SColor color=video::SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! gets the area of the current viewport + virtual const core::rect& getViewPort() const; + + struct SHWBufferLink_d3d9 : public SHWBufferLink + { + SHWBufferLink_d3d9(const scene::IMeshBuffer *_MeshBuffer): + SHWBufferLink(_MeshBuffer), + vertexBuffer(0), indexBuffer(0), + vertexBufferSize(0), indexBufferSize(0) {} + + IDirect3DVertexBuffer9* vertexBuffer; + IDirect3DIndexBuffer9* indexBuffer; + + u32 vertexBufferSize; + u32 indexBufferSize; + }; + + bool updateVertexHardwareBuffer(SHWBufferLink_d3d9 *HWBuffer); + bool updateIndexHardwareBuffer(SHWBufferLink_d3d9 *HWBuffer); + + //! updates hardware buffer if needed + virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Create hardware buffer from mesh + virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb); + + //! Delete hardware buffer (only some drivers can) + virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Draw hardware buffer + virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Create occlusion query. + /** Use node for identification and mesh for occlusion test. */ + virtual void addOcclusionQuery(scene::ISceneNode* node, + const scene::IMesh* mesh=0); + + //! Remove occlusion query. + virtual void removeOcclusionQuery(scene::ISceneNode* node); + + //! Run occlusion query. Draws mesh stored in query. + /** If the mesh shall not be rendered visible, use + overrideMaterial to disable the color and depth buffer. */ + virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false); + + //! Update occlusion query. Retrieves results from GPU. + /** If the query shall not block, set the flag to false. + Update might not occur in this case, though */ + virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true); + + //! Return query result. + /** Return value is the number of visible pixels/fragments. + The value is a safe approximation, i.e. can be larger then the + actual value of pixels. */ + virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const; + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType); + + //! draws a vertex primitive list in 2d + virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); + + //! Draws a set of 2d images, using a color and the alpha channel of the texture. + virtual void draw2DImageBatch(const video::ITexture* texture, + const core::array >& positions, + const core::array >& sourceRects, + const core::rect* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a pixel. + virtual void drawPixel(u32 x, u32 y, const SColor & color); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! initialises the Direct3D API + bool initDriver(HWND hwnd, bool pureSoftware); + + //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light, returning an index to the light + //! \param light: the light data to use to create the light + //! \return An index to the light, or -1 if an error occurs + virtual s32 addDynamicLight(const SLight& light); + + //! Turns a dynamic light on or off + //! \param lightIndex: the index returned by addDynamicLight + //! \param turnOn: true to turn the light on, false to turn it off + virtual void turnLightOn(s32 lightIndex, bool turnOn); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! Draws a shadow volume into the stencil buffer. + virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail=true, u32 debugDataVisible=0); + + //! Fills the stencil shadow with color. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Enables or disables a texture creation flag. + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); + + //! Sets the fog mode. + virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Can be called by an IMaterialRenderer to make its work easier. + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Sets a vertex shader constant. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a pixel shader constant. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a constant for the vertex shader based on a name. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); + + //! Sets a constant for the pixel shader based on a name. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); + + //! Returns a pointer to the IVideoDriver interface. (Implementation for + //! IMaterialRendererServices) + virtual IVideoDriver* getVideoDriver(); + + //! Creates a render target texture. + virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); + + //! Set/unset a clipping plane. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + virtual void enableClipPlane(u32 index, bool enable); + + //! Returns the graphics card vendor name. + virtual core::stringc getVendorInfo() {return VendorName;} + + //! Enable the 2d override material + virtual void enableMaterial2D(bool enable=true); + + //! Check if the driver was recently reset. + virtual bool checkDriverReset() {return DriverWasReset;} + + // removes the depth struct from the DepthSurface array + void removeDepthSurface(SDepthSurface* depth); + + //! Get the current color format of the color buffer + /** \return Color format of the color buffer. */ + virtual ECOLOR_FORMAT getColorFormat() const; + + //! Returns the maximum texture size supported. + virtual core::dimension2du getMaxTextureSize() const; + + //! Get the current color format of the color buffer + /** \return Color format of the color buffer as D3D color value. */ + D3DFORMAT getD3DColorFormat() const; + + //! Get D3D color format from Irrlicht color format. + D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const; + + //! Get Irrlicht color format from D3D color format. + ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format) const; + + //! Get Cg context + #ifdef _IRR_COMPILE_WITH_CG_ + const CGcontext& getCgContext(); + #endif + + private: + + //! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. + enum E_RENDER_MODE + { + ERM_NONE = 0, // no render state has been set yet. + ERM_2D, // 2d drawing rendermode + ERM_3D, // 3d rendering mode + ERM_STENCIL_FILL, // stencil fill mode + ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode + ERM_SHADOW_VOLUME_ZPASS // stencil volume draw mode + }; + + //! sets right vertex shader + void setVertexShader(video::E_VERTEX_TYPE newType); + + //! sets the needed renderstates + bool setRenderStates3DMode(); + + //! sets the needed renderstates + void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); + + //! sets the needed renderstates + void setRenderStatesStencilFillMode(bool alpha); + + //! sets the needed renderstates + void setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible); + + //! sets the current Texture + bool setActiveTexture(u32 stage, const video::ITexture* texture); + + //! resets the device + bool reset(); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); + + //! returns the current size of the screen or rendertarget + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + //! Check if a proper depth buffer for the RTT is available, otherwise create it. + void checkDepthBuffer(ITexture* tex); + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData); + + //! Adds a new material renderer to the VideoDriver, based on a high level shading + //! language. + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT); + + void createMaterialRenderers(); + + void draw2D3DVertexPrimitiveList(const void* vertices, + u32 vertexCount, const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType, bool is3D); + + D3DTEXTUREADDRESS getTextureWrapMode(const u8 clamp); + + inline D3DCOLORVALUE colorToD3D(const SColor& col) + { + const f32 f = 1.0f / 255.0f; + D3DCOLORVALUE v; + v.r = col.getRed() * f; + v.g = col.getGreen() * f; + v.b = col.getBlue() * f; + v.a = col.getAlpha() * f; + return v; + } + + E_RENDER_MODE CurrentRenderMode; + D3DPRESENT_PARAMETERS present; + + SMaterial Material, LastMaterial; + bool ResetRenderStates; // bool to make all renderstates be reseted if set. + bool Transformation3DChanged; + const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; + bool LastTextureMipMapsAvailable[MATERIAL_MAX_TEXTURES]; + core::matrix4 Matrices[ETS_COUNT]; // matrizes of the 3d mode we need to restore when we switch back from the 2d mode. + + HINSTANCE D3DLibrary; + IDirect3D9* pID3D; + IDirect3DDevice9* pID3DDevice; + + IDirect3DSurface9* PrevRenderTarget; + core::dimension2d CurrentRendertargetSize; + + HWND WindowId; + core::rect* SceneSourceRect; + + D3DCAPS9 Caps; + + SIrrlichtCreationParameters Params; + + E_VERTEX_TYPE LastVertexType; + + SColorf AmbientLight; + + core::stringc VendorName; + u16 VendorID; + + core::array DepthBuffers; + + u32 MaxTextureUnits; + u32 MaxUserClipPlanes; + u32 MaxMRTs; + u32 NumSetMRTs; + f32 MaxLightDistance; + s32 LastSetLight; + + enum E_CACHE_2D_ATTRIBUTES + { + EC2D_ALPHA = 0x1, + EC2D_TEXTURE = 0x2, + EC2D_ALPHA_CHANNEL = 0x4 + }; + + ECOLOR_FORMAT ColorFormat; + D3DFORMAT D3DColorFormat; + bool DeviceLost; + bool DriverWasReset; + bool OcclusionQuerySupport; + bool AlphaToCoverageSupport; + + #ifdef _IRR_COMPILE_WITH_CG_ + CGcontext CgContext; + #endif + }; + + +} // end namespace video +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ +#endif // __C_VIDEO_DIRECTX_9_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp new file mode 100644 index 0000000..131bdf5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp @@ -0,0 +1,428 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9HLSLMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" +#include "irrString.h" + +#ifndef _IRR_D3D_NO_SHADER_DEBUGGING +#include +#endif + + +namespace irr +{ +namespace video +{ + + +//! Public constructor +CD3D9HLSLMaterialRenderer::CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev, + video::IVideoDriver* driver, s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData) + : CD3D9ShaderMaterialRenderer(d3ddev, driver, callback, baseMaterial, userData), + VSConstantsTable(0), PSConstantsTable(0) +{ + + #ifdef _DEBUG + setDebugName("CD3D9HLSLMaterialRenderer"); + #endif + + outMaterialTypeNr = -1; + + // now create shaders + + if (vsCompileTarget < 0 || vsCompileTarget > EVST_COUNT) + { + os::Printer::log("Invalid HLSL vertex shader compilation target", ELL_ERROR); + return; + } + + if (!createHLSLVertexShader(vertexShaderProgram, + vertexShaderEntryPointName, VERTEX_SHADER_TYPE_NAMES[vsCompileTarget])) + return; + + if (!createHLSLPixelShader(pixelShaderProgram, + pixelShaderEntryPointName, PIXEL_SHADER_TYPE_NAMES[psCompileTarget])) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + +//! Destructor +CD3D9HLSLMaterialRenderer::~CD3D9HLSLMaterialRenderer() +{ + if (VSConstantsTable) + VSConstantsTable->Release(); + + if (PSConstantsTable) + PSConstantsTable->Release(); +} + + +bool CD3D9HLSLMaterialRenderer::createHLSLVertexShader(const char* vertexShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName) +{ + if (!vertexShaderProgram) + return true; + + LPD3DXBUFFER buffer = 0; + LPD3DXBUFFER errors = 0; + +#ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile without debug info + HRESULT h = stubD3DXCompileShader( + vertexShaderProgram, + strlen(vertexShaderProgram), + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + 0, // no flags + &buffer, + &errors, + &VSConstantsTable); + +#else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_hlsl_file_nr = 0; + ++irr_dbg_hlsl_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.vsh", irr_dbg_hlsl_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(vertexShaderProgram, strlen(vertexShaderProgram), 1, f); + fflush(f); + fclose(f); + + HRESULT h = stubD3DXCompileShaderFromFile( + tmp, + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, + &buffer, + &errors, + &VSConstantsTable); + +#endif + + if (FAILED(h)) + { + os::Printer::log("HLSL vertex shader compilation failed:", ELL_ERROR); + if (errors) + { + os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); + errors->Release(); + if (buffer) + buffer->Release(); + } + return false; + } + + if (errors) + errors->Release(); + + if (buffer) + { + if (FAILED(pID3DDevice->CreateVertexShader((DWORD*)buffer->GetBufferPointer(), + &VertexShader))) + { + os::Printer::log("Could not create hlsl vertex shader.", ELL_ERROR); + buffer->Release(); + return false; + } + + buffer->Release(); + return true; + } + + return false; +} + + +bool CD3D9HLSLMaterialRenderer::createHLSLPixelShader(const char* pixelShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName) +{ + if (!pixelShaderProgram) + return true; + + LPD3DXBUFFER buffer = 0; + LPD3DXBUFFER errors = 0; + + DWORD flags = 0; + +#ifdef D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY + if (Driver->queryFeature(video::EVDF_VERTEX_SHADER_2_0) || Driver->queryFeature(video::EVDF_VERTEX_SHADER_3_0)) + // this one's for newer DX SDKs which don't support ps_1_x anymore + // instead they'll silently compile 1_x as 2_x when using this flag + flags |= D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY; +#endif +#if defined(_IRR_D3D_USE_LEGACY_HLSL_COMPILER) && defined(D3DXSHADER_USE_LEGACY_D3DX9_31_DLL) +#ifdef D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY + else +#endif + flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL; +#endif + +#ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile without debug info + HRESULT h = stubD3DXCompileShader( + pixelShaderProgram, + strlen(pixelShaderProgram), + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + flags, + &buffer, + &errors, + &PSConstantsTable); + +#else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_hlsl_file_nr = 0; + ++irr_dbg_hlsl_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.psh", irr_dbg_hlsl_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(pixelShaderProgram, strlen(pixelShaderProgram), 1, f); + fflush(f); + fclose(f); + + HRESULT h = stubD3DXCompileShaderFromFile( + tmp, + 0, // macros + 0, // no includes + shaderEntryPointName, + shaderTargetName, + flags | D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, + &buffer, + &errors, + &PSConstantsTable); + +#endif + + if (FAILED(h)) + { + os::Printer::log("HLSL pixel shader compilation failed:", ELL_ERROR); + if (errors) + { + os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); + errors->Release(); + if (buffer) + buffer->Release(); + } + return false; + } + + if (errors) + errors->Release(); + + if (buffer) + { + if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)buffer->GetBufferPointer(), + &PixelShader))) + { + os::Printer::log("Could not create hlsl pixel shader.", ELL_ERROR); + buffer->Release(); + return false; + } + + buffer->Release(); + return true; + } + + return false; +} + + +bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, + const f32* floats, int count) +{ + LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; + if (!tbl) + return false; + + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); + if (!hndl) + { + core::stringc s = "HLSL Variable to set not found: '"; + s += name; + s += "'. Available variables are:"; + os::Printer::log(s.c_str(), ELL_WARNING); + printHLSLVariables(tbl); + return false; + } + + D3DXCONSTANT_DESC Description; + UINT ucount = 1; + tbl->GetConstantDesc(hndl, &Description, &ucount); + + if(Description.RegisterSet != D3DXRS_SAMPLER) + { + HRESULT hr = tbl->SetFloatArray(pID3DDevice, hndl, floats, count); + if (FAILED(hr)) + { + os::Printer::log("Error setting float array for HLSL variable", ELL_WARNING); + return false; + } + } + + return true; +} + + +bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, + const bool* bools, int count) +{ + LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; + if (!tbl) + return false; + + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); + if (!hndl) + { + core::stringc s = "HLSL Variable to set not found: '"; + s += name; + s += "'. Available variables are:"; + os::Printer::log(s.c_str(), ELL_WARNING); + printHLSLVariables(tbl); + return false; + } + + D3DXCONSTANT_DESC Description; + UINT ucount = 1; + tbl->GetConstantDesc(hndl, &Description, &ucount); + + if(Description.RegisterSet != D3DXRS_SAMPLER) + { + HRESULT hr = tbl->SetBoolArray(pID3DDevice, hndl, (BOOL*)bools, count); + if (FAILED(hr)) + { + os::Printer::log("Error setting bool array for HLSL variable", ELL_WARNING); + return false; + } + } + + return true; +} + + +bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, + const s32* ints, int count) +{ + LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; + if (!tbl) + return false; + + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); + if (!hndl) + { + core::stringc s = "HLSL Variable to set not found: '"; + s += name; + s += "'. Available variables are:"; + os::Printer::log(s.c_str(), ELL_WARNING); + printHLSLVariables(tbl); + return false; + } + + D3DXCONSTANT_DESC Description; + UINT ucount = 1; + tbl->GetConstantDesc(hndl, &Description, &ucount); + + if(Description.RegisterSet != D3DXRS_SAMPLER) + { + HRESULT hr = tbl->SetIntArray(pID3DDevice, hndl, ints, count); + if (FAILED(hr)) + { + os::Printer::log("Error setting int array for HLSL variable", ELL_WARNING); + return false; + } + } + + return true; +} + + +bool CD3D9HLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + if (VSConstantsTable) + VSConstantsTable->SetDefaults(pID3DDevice); + + return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); +} + + +void CD3D9HLSLMaterialRenderer::printHLSLVariables(LPD3DXCONSTANTTABLE table) +{ + // currently we only support top level parameters. + // Should be enough for the beginning. (TODO) + + // print out constant names + D3DXCONSTANTTABLE_DESC tblDesc; + HRESULT hr = table->GetDesc(&tblDesc); + if (!FAILED(hr)) + { + for (int i=0; i<(int)tblDesc.Constants; ++i) + { + D3DXCONSTANT_DESC d; + UINT n = 1; + D3DXHANDLE cHndl = table->GetConstant(NULL, i); + if (!FAILED(table->GetConstantDesc(cHndl, &d, &n))) + { + core::stringc s = " '"; + s += d.Name; + s += "' Registers:[begin:"; + s += (int)d.RegisterIndex; + s += ", count:"; + s += (int)d.RegisterCount; + s += "]"; + os::Printer::log(s.c_str()); + } + } + } +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.h new file mode 100644 index 0000000..2e051b7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9HLSLMaterialRenderer.h @@ -0,0 +1,85 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_HLSL_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_HLSL_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IGPUProgrammingServices.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders via HLSL with D3D9 +class CD3D9HLSLMaterialRenderer : public CD3D9ShaderMaterialRenderer +{ +public: + + //! Public constructor + CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData); + + //! Destructor + ~CD3D9HLSLMaterialRenderer(); + + //! sets a variable in the shader. + //! \param vertexShader: True if this should be set in the vertex shader, false if + //! in the pixel shader. + //! \param name: Name of the variable + //! \param floats: Pointer to array of floats + //! \param count: Amount of floats in array. + virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setVariable(bool vertexShader, const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setVariable(bool vertexShader, const c8* name, const s32* ints, int count); + + bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + +protected: + + bool createHLSLVertexShader(const char* vertexShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName); + + bool createHLSLPixelShader(const char* pixelShaderProgram, + const char* shaderEntryPointName, + const char* shaderTargetName); + + void printHLSLVariables(LPD3DXCONSTANTTABLE table); + + LPD3DXCONSTANTTABLE VSConstantsTable; + LPD3DXCONSTANTTABLE PSConstantsTable; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9MaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9MaterialRenderer.h new file mode 100644 index 0000000..1653661 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9MaterialRenderer.h @@ -0,0 +1,615 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#include "irrMath.h" // needed by borland for sqrtf define +#endif +#include + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +namespace +{ +D3DMATRIX UnitMatrixD3D9; +D3DMATRIX SphereMapMatrixD3D9; +inline void setTextureColorStage(IDirect3DDevice9* dev, DWORD i, + DWORD arg1, DWORD op, DWORD arg2) +{ + dev->SetTextureStageState(i, D3DTSS_COLOROP, op); + dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); + dev->SetTextureStageState(i, D3DTSS_COLORARG2, arg2); +} +inline void setTextureColorStage(IDirect3DDevice9* dev, DWORD i, DWORD arg1) +{ + dev->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); +} + +inline void setTextureAlphaStage(IDirect3DDevice9* dev, DWORD i, + DWORD arg1, DWORD op, DWORD arg2) +{ + dev->SetTextureStageState(i, D3DTSS_ALPHAOP, op); + dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); + dev->SetTextureStageState(i, D3DTSS_ALPHAARG2, arg2); +} +inline void setTextureAlphaStage(IDirect3DDevice9* dev, DWORD i, DWORD arg1) +{ + dev->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); +} +} // anonymous namespace + +//! Base class for all internal D3D9 material renderers +class CD3D9MaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + CD3D9MaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver) + : pID3DDevice(d3ddev), Driver(driver) + { + } + + //! sets a variable in the shader. + //! \param vertexShader: True if this should be set in the vertex shader, false if + //! in the pixel shader. + //! \param name: Name of the variable + //! \param floats: Pointer to array of floats + //! \param count: Amount of floats in array. + virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count) + { + os::Printer::log("Invalid material to set variable in."); + return false; + } + + //! Bool interface for the above. + virtual bool setVariable(bool vertexShader, const c8* name, const bool* bools, int count) + { + os::Printer::log("Invalid material to set variable in."); + return false; + } + + //! Int interface for the above. + virtual bool setVariable(bool vertexShader, const c8* name, const s32* ints, int count) + { + os::Printer::log("Invalid material to set variable in."); + return false; + } + +protected: + + IDirect3DDevice9* pID3DDevice; + video::IVideoDriver* Driver; +}; + + +//! Solid material renderer +class CD3D9MaterialRenderer_SOLID : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_SOLID(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } +}; + +//! Generic Texture Blend +class CD3D9MaterialRenderer_ONETEXTURE_BLEND : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || + material.MaterialTypeParam != lastMaterial.MaterialTypeParam || + resetAllRenderstates) + { + + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + u32 alphaSource; + unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam ); + + if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO) + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + else + { + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) ); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) ); + } + + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE); + + if ( textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) ) + { + if (alphaSource==EAS_VERTEX_COLOR) + { + setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); + } + else if (alphaSource==EAS_TEXTURE) + { + setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); + } + else + { + setTextureAlphaStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + } + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + } + } + + //! Returns if the material is transparent. + /** The scene management needs to know this for being able to sort the + materials by opaque and transparent. + The return value could be optimized, but we'd need to know the + MaterialTypeParam for it. */ + virtual bool isTransparent() const + { + return true; + } + + private: + + u32 getD3DBlend ( E_BLEND_FACTOR factor ) const + { + u32 r = 0; + switch ( factor ) + { + case EBF_ZERO: r = D3DBLEND_ZERO; break; + case EBF_ONE: r = D3DBLEND_ONE; break; + case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break; + case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break; + case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break; + case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break; + case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break; + case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break; + case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break; + case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break; + } + return r; + } + + u32 getD3DModulate ( E_MODULATE_FUNC func ) const + { + u32 r = D3DTOP_MODULATE; + switch ( func ) + { + case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break; + case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break; + case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break; + } + return r; + } + + bool transparent; + +}; + + + +//! Solid 2 layer material renderer +class CD3D9MaterialRenderer_SOLID_2_LAYER : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } +}; + + +//! Transparent add color material renderer +class CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); + } + } + + //! Returns if the material is transparent. The scene management needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent vertex alpha material renderer +class CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates + || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + + pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f)); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + + +//! Transparent alpha channel material renderer +class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + // 127 is required by EMT_TRANSPARENT_ALPHA_CHANNEL_REF + pID3DDevice->SetRenderState(D3DRS_ALPHAREF, 127); + pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return false; // this material is not really transparent because it does no blending. + } +}; + + +//! material renderer for all kinds of lightmaps +class CD3D9MaterialRenderer_LIGHTMAP : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING) + { + // with lighting + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + } + else + { + setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); + } + + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, + (material.MaterialType == EMT_LIGHTMAP_ADD)? + D3DTOP_ADD: + (material.MaterialType == EMT_LIGHTMAP_M4 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M4)? + D3DTOP_MODULATE4X: + (material.MaterialType == EMT_LIGHTMAP_M2 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M2)? + D3DTOP_MODULATE2X: + D3DTOP_MODULATE, + D3DTA_CURRENT); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } +}; + + + +//! material renderer for detail maps +class CD3D9MaterialRenderer_DETAIL_MAP : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, D3DTOP_ADDSIGNED, D3DTA_CURRENT); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } +}; + + +//! sphere map material renderer +class CD3D9MaterialRenderer_SPHERE_MAP : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + + pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D9 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL ); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); + pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D9 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D9MaterialRenderer_REFLECTION_2_LAYER : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D9 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D9 ); + } +}; + + +//! reflection 2 layer material renderer +class CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D9MaterialRenderer +{ +public: + + CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) + : CD3D9MaterialRenderer(p, d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + setTextureColorStage(pID3DDevice, 0, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); + setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); + setTextureColorStage(pID3DDevice, 1, + D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); + setTextureAlphaStage(pID3DDevice, 1, D3DTA_CURRENT); + + pID3DDevice->SetTransform(D3DTS_TEXTURE1, &SphereMapMatrixD3D9 ); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); + + pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + } + + virtual void OnUnsetMaterial() + { + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); + pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D9); + } + + //! Returns if the material is transparent. The scene managment needs to know this + //! for being able to sort the materials by opaque and transparent. + virtual bool isTransparent() const + { + return true; + } +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.cpp new file mode 100644 index 0000000..eb6f732 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.cpp @@ -0,0 +1,306 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9NormalMapRenderer.h" +#include "IVideoDriver.h" +#include "IMaterialRendererServices.h" +#include "os.h" +#include "SLight.h" + +namespace irr +{ +namespace video +{ + + // 1.1 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D9 render path normal map vertex shader + const char D3D9_NORMAL_MAP_VSH[] = + ";Irrlicht Engine 0.8 D3D9 render path normal map vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "vs.1.1\n"\ + "dcl_position v0 ; position \n"\ + "dcl_normal v1 ; normal \n"\ + "dcl_color v2 ; color \n"\ + "dcl_texcoord0 v3 ; texture coord \n"\ + "dcl_texcoord1 v4 ; tangent \n"\ + "dcl_texcoord2 v5 ; binormal \n"\ + "\n"\ + "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - lightpos1\n"\ + "add r3, c14, -r4 ; vtxpos - lightpos2\n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light vector 1 with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light vector 2 with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + // Irrlicht Engine D3D9 render path normal map pixel shader + const char D3D9_NORMAL_MAP_PSH_1_1[] = + ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + "ps.1.1 \n"\ + "tex t0 ; sample color map \n"\ + "tex t1 ; sample normal map\n"\ + "texcoord t2 ; fetch light vector 1\n"\ + "texcoord t3 ; fetch light vector 2\n"\ + "\n"\ + "dp3_sat r0, t1_bx2, t2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1)\n"\ + "mul r0, r0, v0 ; luminance1 * light color 1 \n"\ + "\n"\ + "dp3_sat r1, t1_bx2, t3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1)\n"\ + "mad r0, r1, v1, r0 ; (luminance2 * light color 2) + luminance 1 \n"\ + "\n"\ + "mul r0.xyz, t0, r0 ; total luminance * base color\n"\ + "+mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ + "\n"\ + ""; + + // Higher-quality normal map pixel shader (requires PS 2.0) + // uses per-pixel normalization for improved accuracy + const char D3D9_NORMAL_MAP_PSH_2_0[] = + ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + + "ps_2_0 \n"\ + "def c0, 0, 0, 0, 0\n"\ + "def c1, 1.0, 1.0, 1.0, 1.0\n"\ + "def c2, 2.0, 2.0, 2.0, 2.0\n"\ + "def c3, -.5, -.5, -.5, -.5\n"\ + "dcl t0\n"\ + "dcl t1\n"\ + "dcl t2\n"\ + "dcl t3\n"\ + "dcl v1\n"\ + "dcl v0\n"\ + "dcl_2d s0\n"\ + "dcl_2d s1\n"\ + + "texld r0, t0, s0 ; sample color map into r0 \n"\ + "texld r4, t0, s1 ; sample normal map into r4\n"\ + "add r4, r4, c3 ; bias the normal vector\n"\ + "add r5, t2, c3 ; bias the light 1 vector into r5\n"\ + "add r6, t3, c3 ; bias the light 2 vector into r6\n"\ + + "nrm r1, r4 ; normalize the normal vector into r1\n"\ + "nrm r2, r5 ; normalize the light1 vector into r2\n"\ + "nrm r3, r6 ; normalize the light2 vector into r3\n"\ + + "dp3 r2, r2, r1 ; let r2 = normal DOT light 1 vector\n"\ + "max r2, r2, c0 ; clamp result to positive numbers\n"\ + "mul r2, r2, v0 ; let r2 = luminance1 * light color 1 \n"\ + + "dp3 r3, r3, r1 ; let r3 = normal DOT light 2 vector\n"\ + "max r3, r3, c0 ; clamp result to positive numbers\n"\ + + "mad r2, r3, v1, r2 ; let r2 = (luminance2 * light color 2) + (luminance2 * light color 1) \n"\ + + "mul r2, r2, r0 ; let r2 = total luminance * base color\n"\ + "mov r2.w, v0.w ; write interpolated vertex alpha value \n"\ + + "mov oC0, r2 ; copy r2 to the output register \n"\ + + "\n"\ + ""; + + CD3D9NormalMapRenderer::CD3D9NormalMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial) + { + #ifdef _DEBUG + setDebugName("CD3D9NormalMapRenderer"); + #endif + + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basically, this thing simply compiles the hardcoded shaders + // if the hardware is able to do them, otherwise it maps to the + // base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D9NormalMapRenderer* nmr = (video::CD3D9NormalMapRenderer*)renderer; + VertexShader = nmr->VertexShader; + if (VertexShader) + VertexShader->AddRef(); + + PixelShader = nmr->PixelShader; + if (PixelShader) + PixelShader->AddRef(); + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + if (driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0)) + { + init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_2_0); + } + else + { + init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_1_1); + } + } + // something failed, use base material + if (-1==outMaterialTypeNr) + driver->addMaterialRenderer(this); + } + + + CD3D9NormalMapRenderer::~CD3D9NormalMapRenderer() + { + if (CallBack == this) + CallBack = 0; + } + + + bool CD3D9NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + + //! Returns the render capability of the material. + s32 CD3D9NormalMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants + //! for an material renderer should be set. + void CD3D9NormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the + // driver and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // this is not really necessary in d3d9 (used a def instruction), but to be sure: + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.h new file mode 100644 index 0000000..70b4a5c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9NormalMapRenderer.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#include "irrMath.h" // needed by borland for sqrtf define +#endif +#include + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for normal maps +class CD3D9NormalMapRenderer : + public CD3D9ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D9NormalMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + ~CD3D9NormalMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +private: + +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp new file mode 100644 index 0000000..954a552 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp @@ -0,0 +1,410 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9ParallaxMapRenderer.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "SLight.h" + +//#define SHADER_EXTERNAL_DEBUG + +#ifdef SHADER_EXTERNAL_DEBUG +#include "CReadFile.h" +#endif + +namespace irr +{ +namespace video +{ + // 1.1/1.4 Shaders with two lights and vertex based attenuation + + // Irrlicht Engine D3D9 render path normal map vertex shader + const char D3D9_PARALLAX_MAP_VSH[] = + ";Irrlicht Engine 0.10 D3D9 render path parallax mapping vertex shader\n"\ + "; c0-3: Transposed world matrix \n"\ + "; c4: Eye position \n"\ + "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ + "; c12: Light01 position \n"\ + "; c13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\ + "; c14: Light02 position \n"\ + "; c15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\ + "vs.1.1\n"\ + "dcl_position v0 ; position \n"\ + "dcl_normal v1 ; normal \n"\ + "dcl_color v2 ; color \n"\ + "dcl_texcoord0 v3 ; texture coord \n"\ + "dcl_texcoord1 v4 ; tangent \n"\ + "dcl_texcoord2 v5 ; binormal \n"\ + "\n"\ + "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ + "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ + "\n"\ + "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ + "\n"\ + "m3x3 r5, v4, c0 ; transform tangent U\n"\ + "m3x3 r7, v1, c0 ; transform normal W\n"\ + "m3x3 r6, v5, c0 ; transform binormal V\n"\ + "\n"\ + "m4x4 r4, v0, c0 ; vertex into world position\n"\ + "add r2, c12, -r4 ; vtxpos - light1 pos\n"\ + "add r3, c14, -r4 ; vtxpos - light2 pos\n"\ + "add r1, -c4, r4 ; eye - vtxpos \n"\ + "\n"\ + "dp3 r8.x, r5, r2 ; transform the light1 vector with U, V, W\n"\ + "dp3 r8.y, r6, r2 \n"\ + "dp3 r8.z, r7, r2 \n"\ + "dp3 r9.x, r5, r3 ; transform the light2 vector with U, V, W\n"\ + "dp3 r9.y, r6, r3 \n"\ + "dp3 r9.z, r7, r3 \n"\ + "dp3 r10.x, r5, r1 ; transform the eye vector with U, V, W\n"\ + "dp3 r10.y, r6, r1 \n"\ + "dp3 r10.z, r7, r1 \n"\ + "\n"\ + "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ + "rsq r8.w, r8.w \n"\ + "mul r8, r8, r8.w \n"\ + ";mul r8, r8, c96 \n"\ + "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ + "rsq r9.w, r9.w \n"\ + "mul r9, r9, r9.w \n"\ + ";mul r9, r9, c96 \n"\ + "dp3 r10.w, r10, r10 ; normalize eye vector (r10)\n"\ + "rsq r10.w, r10.w \n"\ + "mul r10, r10, r10.w \n"\ + "mul r10, r10, c96 \n"\ + "\n"\ + "\n"\ + "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ + "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ + "mad oT4.xyz, r10.xyz, c95, c95 ; move eye vector from -1..1 into 0..1 \n"\ + "\n"\ + " ; calculate attenuation of light 1 \n"\ + "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x² + r2.y² + r2.z² \n"\ + "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ + "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + " ; calculate attenuation of light 2 \n"\ + "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x² + r3.y² + r3.z² \n"\ + "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ + "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ + "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ + "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ + "mov oD0.a, v2.a ; move out original alpha value \n"\ + "\n"; + + + // Irrlicht Engine D3D9 render path normal map pixel shader version 1.4 + const char D3D9_PARALLAX_MAP_PSH[] = + ";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\ + ";Input: \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";t4: eye vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + " \n"\ + "ps.1.4 \n"\ + " \n"\ + ";def c6, 0.02f, 0.02f, 0.02f, 0.0f ; scale factor, now set in callback \n"\ + "def c5, 0.5f, 0.5f, 0.5f, 0.0f ; for specular division \n"\ + " \n"\ + "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ + "texcrd r4.xyz, t4 ; fetch eye vector \n"\ + "texcrd r0.xyz, t0 ; color map \n"\ + " \n"\ + "; original parallax mapping: \n"\ + ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ + ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "; modified parallax mapping to reduce swimming effect: \n"\ + "mul r3, r1_bx2.wwww, r1_bx2.zzzz ; (nh,nh,nh,nh) = (h,h,h,h) * (n.z,n.z,n.z,n.z,) \n"\ + "mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ + "mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "phase \n"\ + " \n"\ + "texld r0, r2 ; load diffuse texture with new tex coord \n"\ + "texld r1, r2 ; sample normal map \n"\ + "texcrd r2.xyz, t2 ; fetch light vector 1 \n"\ + "texcrd r3.xyz, t3 ; fetch light vector 2 \n"\ + " \n"\ + "dp3_sat r5, r1_bx2, r2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ + "mul r5, r5, v0 ; luminance1 * light color 1 \n"\ + " \n"\ + "dp3_sat r3, r1_bx2, r3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ + "mad r3, r3, v1, r5 ; (luminance2 * light color 2) + luminance1 \n"\ + " \n"\ + "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ + "+mov r0.a, v0.a ; write original alpha value \n"\ + "\n"; + + // Irrlicht Engine D3D9 render path normal map pixel shader version 2.0 + const char D3D9_PARALLAX_MAP_PSH_20[] = + ";Irrlicht Engine D3D9 render path parallax mapping pixel shader \n"\ + ";Input: \n"\ + " \n"\ + ";t0: color map texture coord \n"\ + ";t1: normal map texture coords \n"\ + ";t2: light 1 vector in tangent space \n"\ + ";t4: eye vector in tangent space \n"\ + ";v0: light 1 color \n"\ + ";t3: light 2 vector in tangent space \n"\ + ";v1: light 2 color \n"\ + ";v0.a: vertex alpha value \n"\ + " \n"\ + "ps.2.0 \n"\ + " \n"\ + "dcl_2d s0 ; Declare the s0 register to be the sampler for stage 0 \n"\ + "dcl t0.xy ; Declare t0 to have 2D texture coordinates from stage 0 \n"\ + "dcl t1.xy ; Declare t0 to have 2D texture coordinates from stage 0 \n"\ + "dcl_2d s1 ; Declare the s1 register to be the sampler for stage 1 \n"\ + " \n"\ + "dcl t2.xyz ; \n"\ + "dcl t3.xyz ; \n"\ + "dcl t4.xyz ; \n"\ + "dcl v0.xyzw; \n"\ + "dcl v1.xyzw; \n"\ + " \n"\ + "def c0, -1.0f, -1.0f, -1.0f, -1.0f ; for _bx2 emulation \n"\ + "def c1, 2.0f, 2.0f, 2.0f, 2.0f ; for _bx2 emulation \n"\ + "mov r11, c1; \n"\ + " \n"\ + "texld r1, t1, s1 ; sample (normal.x, normal.y, normal.z, height) \n"\ + "mov r4.xyz, t4 ; fetch eye vector \n"\ + "mov r0.xy, t0 ; color map \n"\ + " \n"\ + "; original parallax mapping: \n"\ + "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ + "mad r1.xyz, r1, r11, c0; \n"\ + " \n"\ + "mul r3, r1.wwww, c6; ; r3 = (height, height, height) * scale \n"\ + " \n"\ + "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ + "mad r4.xyz, r4, r11, c0; \n"\ + " \n"\ + "mad r2.xy, r3, r4, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "; modified parallax mapping to avoid swimming: \n"\ + ";mul r3, r1_bx2.wwww, r1_bx2.zzzz ; r3 = (h,h,h,h) * (n.z, n.z, n.z, n.z,) \n"\ + ";mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ + ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ + " \n"\ + "texld r0, r2, s0 ; load diffuse texture with new tex coord \n"\ + "texld r1, r2, s1 ; sample normal map \n"\ + "mov r2.xyz, t2 ; fetch light vector 1 \n"\ + "mov r3.xyz, t3 ; fetch light vector 2 \n"\ + " \n"\ + "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ + "mad r1.xyz, r1, r11, c0; \n"\ + "mad r2.xyz, r2, r11, c0; \n"\ + "mad r3.xyz, r3, r11, c0; \n"\ + " \n"\ + "dp3_sat r2, r1, r2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ + "mul r2, r2, v0 ; luminance1 * light color 1 \n"\ + " \n"\ + "dp3_sat r3, r1, r3 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ + "mad r3, r3, v1, r2 ; (luminance2 * light color 2) + luminance1 \n"\ + " \n"\ + "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ + "mov r0.a, v0.a ; write original alpha value \n"\ + "mov oC0, r0; \n"\ + "\n"; + + CD3D9ParallaxMapRenderer::CD3D9ParallaxMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), + CurrentScale(0.0f) + { + + #ifdef _DEBUG + setDebugName("CD3D9ParallaxMapRenderer"); + #endif + + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basicly, this thing simply compiles these hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) || + !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled parallax map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); + if (renderer) + { + // use the already compiled shaders + video::CD3D9ParallaxMapRenderer* nmr = (video::CD3D9ParallaxMapRenderer*)renderer; + VertexShader = nmr->VertexShader; + if (VertexShader) + VertexShader->AddRef(); + + PixelShader = nmr->PixelShader; + if (PixelShader) + PixelShader->AddRef(); + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + #ifdef SHADER_EXTERNAL_DEBUG + + // quickly load shader from external file + io::CReadFile* file = new io::CReadFile("parallax.psh"); + s32 sz = file->getSize(); + char* s = new char[sz+1]; + file->read(s, sz); + s[sz] = 0; + + init(outMaterialTypeNr, D3D9_PARALLAX_MAP_VSH, s); + + delete [] s; + file->drop(); + + #else + + // compile shaders on our own + init(outMaterialTypeNr, D3D9_PARALLAX_MAP_VSH, D3D9_PARALLAX_MAP_PSH); + + #endif // SHADER_EXTERNAL_DEBUG + } + // something failed, use base material + if (-1==outMaterialTypeNr) + driver->addMaterialRenderer(this); + } + + + CD3D9ParallaxMapRenderer::~CD3D9ParallaxMapRenderer() + { + if (CallBack == this) + CallBack = 0; + } + + bool CD3D9ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + if (vtxtype != video::EVT_TANGENTS) + { + os::Printer::log("Error: Parallax map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); + return false; + } + + return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); + } + + + void CD3D9ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) + { + CD3D9ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, + resetAllRenderstates, services); + + CurrentScale = material.MaterialTypeParam; + } + + + //! Returns the render capability of the material. + s32 CD3D9ParallaxMapRenderer::getRenderCapability() const + { + if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && + Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) + return 0; + + return 1; + } + + + //! Called by the engine when the vertex and/or pixel shader constants + //! for an material renderer should be set. + void CD3D9ParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); + + // set eye position + + // The viewpoint is at (0., 0., 0.) in eye space. + // Turning this into a vector [0 0 0 1] and multiply it by + // the inverse of the view matrix, the resulting vector is the + // object space location of the camera. + + f32 floats[4] = {0,0,0,1}; + core::matrix4 minv = driver->getTransform(video::ETS_VIEW); + minv.makeInverse(); + minv.multiplyWith1x4Matrix(floats); + services->setVertexShaderConstant(floats, 4, 1); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj; + worldViewProj = driver->getTransform(video::ETS_PROJECTION); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); + + // here we've got to fetch the fixed function lights from the + // driver and set them as constants + + const u32 cnt = driver->getDynamicLightCount(); + + for (u32 i=0; i<2; ++i) + { + SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); + services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // this is not really necessary in d3d9 (used a def instruction), but to be sure: + f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; + services->setVertexShaderConstant(c95, 95, 1); + f32 c96[] = {-1, 1, 1, 1}; + services->setVertexShaderConstant(c96, 96, 1); + + // set scale factor + f32 factor = 0.02f; // default value + if (CurrentScale != 0) + factor = CurrentScale; + + f32 c6[] = {factor, factor, factor, 0}; + services->setPixelShaderConstant(c6, 6, 1); + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.h new file mode 100644 index 0000000..94010cd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ParallaxMapRenderer.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#include "irrMath.h" // needed by borland for sqrtf define +#endif +#include + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Renderer for normal maps using parallax mapping +class CD3D9ParallaxMapRenderer : + public CD3D9ShaderMaterialRenderer, IShaderConstantSetCallBack +{ +public: + + CD3D9ParallaxMapRenderer( + IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + ~CD3D9ParallaxMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + + virtual void OnSetMaterial(const SMaterial& material) { } + virtual void OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + +private: + + f32 CurrentScale; + +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp new file mode 100644 index 0000000..7d2f76e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp @@ -0,0 +1,540 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "CD3D9ShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "irrString.h" + +#ifndef _IRR_D3D_NO_SHADER_DEBUGGING +#include +#endif + + +namespace irr +{ +namespace video +{ + +//! Public constructor +CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) +: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) +{ + #ifdef _DEBUG + setDebugName("CD3D9ShaderMaterialRenderer"); + #endif + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram); +} + + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData) +: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) +{ + #ifdef _DEBUG + setDebugName("CD3D9ShaderMaterialRenderer"); + #endif + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + +void CD3D9ShaderMaterialRenderer::init(s32& outMaterialTypeNr, + const c8* vertexShaderProgram, const c8* pixelShaderProgram) +{ + outMaterialTypeNr = -1; + + // create vertex shader + if (!createVertexShader(vertexShaderProgram)) + return; + + // create pixel shader + if (!createPixelShader(pixelShaderProgram)) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + +//! Destructor +CD3D9ShaderMaterialRenderer::~CD3D9ShaderMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (VertexShader) + VertexShader->Release(); + + if (PixelShader) + PixelShader->Release(); + + if (BaseMaterial) + BaseMaterial->drop(); +} + + +bool CD3D9ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (VertexShader || PixelShader)) + CallBack->OnSetConstants(service, UserData); + + return true; +} + + +void CD3D9ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexShader) + { + // save old vertex shader + pID3DDevice->GetVertexShader(&OldVertexShader); + + // set new vertex shader + if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) + os::Printer::log("Could not set vertex shader.", ELL_WARNING); + } + + // set new pixel shader + if (PixelShader) + { + if (FAILED(pID3DDevice->SetPixelShader(PixelShader))) + os::Printer::log("Could not set pixel shader.", ELL_WARNING); + } + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, services); + } + + //let callback know used material + if (CallBack) + CallBack->OnSetMaterial(material); + + services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +void CD3D9ShaderMaterialRenderer::OnUnsetMaterial() +{ + if (VertexShader) + pID3DDevice->SetVertexShader(OldVertexShader); + + if (PixelShader) + pID3DDevice->SetPixelShader(0); + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + + +//! Returns if the material is transparent. The scene managment needs to know this +//! for being able to sort the materials by opaque and transparent. +bool CD3D9ShaderMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + + +bool CD3D9ShaderMaterialRenderer::createPixelShader(const c8* pxsh) +{ + if (!pxsh) + return true; + + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + stubD3DXAssembleShader(pxsh, (UINT)strlen(pxsh), 0, 0, 0, &code, &errors); + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_shader_%d.psh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(pxsh, strlen(pxsh), 1, f); + fflush(f); + fclose(f); + + stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors); + + #endif + + + if (errors) + { + // print out compilation errors. + os::Printer::log("Pixel shader compilation failed:", ELL_ERROR); + os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader))) + { + os::Printer::log("Could not create pixel shader.", ELL_ERROR); + code->Release(); + return false; + } + + code->Release(); + return true; +} + + +bool CD3D9ShaderMaterialRenderer::createVertexShader(const char* vtxsh) +{ + if (!vtxsh) + return true; + + // compile shader + + LPD3DXBUFFER code = 0; + LPD3DXBUFFER errors = 0; + + #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + + // compile shader without debug info + stubD3DXAssembleShader(vtxsh, (UINT)strlen(vtxsh), 0, 0, 0, &code, &errors); + + #else + + // compile shader and emitt some debug informations to + // make it possible to debug the shader in visual studio + + static int irr_dbg_file_nr = 0; + ++irr_dbg_file_nr; + char tmp[32]; + sprintf(tmp, "irr_d3d9_dbg_shader_%d.vsh", irr_dbg_file_nr); + + FILE* f = fopen(tmp, "wb"); + fwrite(vtxsh, strlen(vtxsh), 1, f); + fflush(f); + fclose(f); + + stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors); + + #endif + + if (errors) + { + // print out compilation errors. + os::Printer::log("Vertex shader compilation failed:", ELL_ERROR); + os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); + + if (code) + code->Release(); + + errors->Release(); + return false; + } + + if (!code || FAILED(pID3DDevice->CreateVertexShader((DWORD*)code->GetBufferPointer(), &VertexShader))) + { + os::Printer::log("Could not create vertex shader.", ELL_ERROR); + if (code) + code->Release(); + return false; + } + + code->Release(); + return true; +} + + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, + UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs) +{ + // Because Irrlicht needs to be able to start up even without installed d3d dlls, it + // needs to load external d3d dlls manually. examples for the dlls are: + // SDK dll name D3DX_SDK_VERSION + // Summer 2004: no dll 22 + // February 2005: d3dx9_24.dll 24 + // April 2005: d3dx9_25.dll 25 + // June 2005: d3dx9_26.dll 26 + // August 2005: d3dx9_27.dll 27 + // October 2005, + // December 2005: d3dx9_28.dll 28 + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, pInclude, + Flags, ppShader, ppErrorMsgs); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXAssembleShader signature + typedef HRESULT (WINAPI *AssembleShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, + DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + + static bool LoadFailed = false; + static AssembleShaderFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + io::path strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (AssembleShaderFunction)GetProcAddress(hMod, "D3DXAssembleShader"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXAssembleShader from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcData, SrcDataLen, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs) +{ + // wondering what I'm doing here? + // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXAssembleShaderFromFileA(pSrcFile, pDefines, pInclude, Flags, + ppShader, ppErrorMsgs); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXAssembleShaderFromFileA signature + typedef HRESULT (WINAPI *AssembleShaderFromFileFunction)(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); + + static bool LoadFailed = false; + static AssembleShaderFromFileFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + io::path strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (AssembleShaderFromFileFunction)GetProcAddress(hMod, "D3DXAssembleShaderFromFileA"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXAssembleShaderFromFileA from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcFile, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable) +{ + // wondering what I'm doing here? + // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXCompileShader(pSrcData, SrcDataLen, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXCompileShader + typedef HRESULT (WINAPI *D3DXCompileShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable); + + static bool LoadFailed = false; + static D3DXCompileShaderFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + io::path strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (D3DXCompileShaderFunction)GetProcAddress(hMod, "D3DXCompileShader"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXCompileShader from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcData, SrcDataLen, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + +HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable) +{ + // wondering what I'm doing here? + // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() + + #if ( D3DX_SDK_VERSION < 24 ) + // directly link functions, old d3d sdks didn't try to load external dlls + // when linking to the d3dx9.lib + #ifdef _MSC_VER + #pragma comment (lib, "d3dx9.lib") + #endif + + // invoke static linked function + return D3DXCompileShaderFromFileA(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + #else + { + // try to load shader functions from the dll and print error if failed. + + // D3DXCompileShaderFromFileA + typedef HRESULT (WINAPI *D3DXCompileShaderFromFileFunction)(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + static bool LoadFailed = false; + static D3DXCompileShaderFromFileFunction pFn = 0; + + if (!pFn && !LoadFailed) + { + // try to load dll + io::path strDllName = "d3dx9_"; + strDllName += (int)D3DX_SDK_VERSION; + strDllName += ".dll"; + + HMODULE hMod = LoadLibrary(strDllName.c_str()); + if (hMod) + pFn = (D3DXCompileShaderFromFileFunction)GetProcAddress(hMod, "D3DXCompileShaderFromFileA"); + + if (!pFn) + { + LoadFailed = true; + os::Printer::log("Could not load shader function D3DXCompileShaderFromFileA from dll, shaders disabled", + strDllName.c_str(), ELL_ERROR); + } + } + + if (pFn) + { + // call already loaded function + return (*pFn)(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); + } + } + #endif // D3DX_SDK_VERSION < 24 + + return 0; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.h new file mode 100644 index 0000000..2c2bb19 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9ShaderMaterialRenderer.h @@ -0,0 +1,102 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_D3D9_SHADER_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_D3D9_SHADER_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_WINDOWS_ + +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#include "irrMath.h" // needed by borland for sqrtf define +#endif +#include + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +class IVideoDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders with D3D9 +class CD3D9ShaderMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Public constructor + CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); + + //! Destructor + ~CD3D9ShaderMaterialRenderer(); + + virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + + virtual void OnUnsetMaterial(); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, + video::IVideoDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData=0); + + void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram); + bool createPixelShader(const c8* pxsh); + bool createVertexShader(const char* vtxsh); + + HRESULT stubD3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, + DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + + HRESULT stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, + CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, + LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); + + HRESULT stubD3DXCompileShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable); + + HRESULT stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, + LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + + IDirect3DDevice9* pID3DDevice; + video::IVideoDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + IDirect3DVertexShader9* VertexShader; + IDirect3DVertexShader9* OldVertexShader; + IDirect3DPixelShader9* PixelShader; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.cpp new file mode 100644 index 0000000..122ee2a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.cpp @@ -0,0 +1,699 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE +#include "CD3D9Texture.h" +#include "CD3D9Driver.h" +#include "os.h" + +#include + +#ifndef _IRR_COMPILE_WITH_DIRECT3D_8_ +// The D3DXFilterTexture function seems to get linked wrong when +// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. +// So mipmapgeneration is replaced with my own bad generation in d3d 8 when +// compiling with both D3D 8 and 9. +// #define _IRR_USE_D3DXFilterTexture_ +#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + +#ifdef _IRR_USE_D3DXFilterTexture_ +#pragma comment(lib, "d3dx9.lib") +#endif + +namespace irr +{ +namespace video +{ + +//! rendertarget constructor +CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format) +: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), + TextureSize(size), ImageSize(size), Pitch(0), ColorFormat(ECF_UNKNOWN), + HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true) +{ + #ifdef _DEBUG + setDebugName("CD3D9Texture"); + #endif + + Device=driver->getExposedVideoData().D3D9.D3DDev9; + if (Device) + Device->AddRef(); + + createRenderTarget(format); +} + + +//! constructor +CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, + u32 flags, const io::path& name, void* mipmapData) +: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), + TextureSize(0,0), ImageSize(0,0), Pitch(0), ColorFormat(ECF_UNKNOWN), + HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) +{ + #ifdef _DEBUG + setDebugName("CD3D9Texture"); + #endif + + HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + Device=driver->getExposedVideoData().D3D9.D3DDev9; + if (Device) + Device->AddRef(); + + if (image) + { + if (createTexture(flags, image)) + { + if (copyTexture(image)) + { + regenerateMipMapLevels(mipmapData); + } + } + else + os::Printer::log("Could not create DIRECT3D9 Texture.", ELL_WARNING); + } +} + + +//! destructor +CD3D9Texture::~CD3D9Texture() +{ + if (Texture) + Texture->Release(); + + if (RTTSurface) + RTTSurface->Release(); + + // if this texture was the last one using the depth buffer + // we can release the surface. We only use the value of the pointer + // hence it is safe to use the dropped pointer... + if (DepthSurface) + { + if (DepthSurface->drop()) + Driver->removeDepthSurface(DepthSurface); + } + + if (Device) + Device->Release(); +} + + +void CD3D9Texture::createRenderTarget(const ECOLOR_FORMAT format) +{ + // are texture size restrictions there ? + if(!Driver->queryFeature(EVDF_TEXTURE_NPOT)) + { + if (TextureSize != ImageSize) + os::Printer::log("RenderTarget size has to be a power of two", ELL_INFORMATION); + } + TextureSize = TextureSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); + + D3DFORMAT d3dformat = Driver->getD3DColorFormat(); + + if(ColorFormat == ECF_UNKNOWN) + { + // get irrlicht format from backbuffer + // (This will get overwritten by the custom format if it is provided, else kept.) + ColorFormat = Driver->getColorFormat(); + setPitch(d3dformat); + + // Use color format if provided. + if(format != ECF_UNKNOWN) + { + ColorFormat = format; + d3dformat = Driver->getD3DFormatFromColorFormat(format); + setPitch(d3dformat); // This will likely set pitch to 0 for now. + } + } + else + { + d3dformat = Driver->getD3DFormatFromColorFormat(ColorFormat); + } + + // create texture + HRESULT hr; + + hr = Device->CreateTexture( + TextureSize.Width, + TextureSize.Height, + 1, // mip map level count, we don't want mipmaps here + D3DUSAGE_RENDERTARGET, + d3dformat, + D3DPOOL_DEFAULT, + &Texture, + NULL); + + if (FAILED(hr)) + { + if (D3DERR_INVALIDCALL == hr) + os::Printer::log("Could not create render target texture", "Invalid Call"); + else + if (D3DERR_OUTOFVIDEOMEMORY == hr) + os::Printer::log("Could not create render target texture", "Out of Video Memory"); + else + if (E_OUTOFMEMORY == hr) + os::Printer::log("Could not create render target texture", "Out of Memory"); + else + os::Printer::log("Could not create render target texture"); + } +} + + +bool CD3D9Texture::createMipMaps(u32 level) +{ + if (level==0) + return true; + + if (HardwareMipMaps && Texture) + { + // generate mipmaps in hardware + Texture->GenerateMipSubLevels(); + return true; + } + + // manual mipmap generation + IDirect3DSurface9* upperSurface = 0; + IDirect3DSurface9* lowerSurface = 0; + + // get upper level + HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); + if (FAILED(hr) || !upperSurface) + { + os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); + return false; + } + + // get lower level + hr = Texture->GetSurfaceLevel(level, &lowerSurface); + if (FAILED(hr) || !lowerSurface) + { + os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); + upperSurface->Release(); + return false; + } + + D3DSURFACE_DESC upperDesc, lowerDesc; + upperSurface->GetDesc(&upperDesc); + lowerSurface->GetDesc(&lowerDesc); + + D3DLOCKED_RECT upperlr; + D3DLOCKED_RECT lowerlr; + + // lock upper surface + if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) + { + upperSurface->Release(); + lowerSurface->Release(); + os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); + return false; + } + + // lock lower surface + if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) + { + upperSurface->UnlockRect(); + upperSurface->Release(); + lowerSurface->Release(); + os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); + return false; + } + + if (upperDesc.Format != lowerDesc.Format) + { + os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); + } + else + { + if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5)) + copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + if (upperDesc.Format == D3DFMT_A8R8G8B8) + copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, + lowerDesc.Width, lowerDesc.Height, + upperlr.Pitch, lowerlr.Pitch); + else + os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); + } + + bool result=true; + // unlock + if (FAILED(upperSurface->UnlockRect())) + result=false; + if (FAILED(lowerSurface->UnlockRect())) + result=false; + + // release + upperSurface->Release(); + lowerSurface->Release(); + + if (!result || (upperDesc.Width <= 3 && upperDesc.Height <= 3)) + return result; // stop generating levels + + // generate next level + return createMipMaps(level+1); +} + + +//! creates the hardware texture +bool CD3D9Texture::createTexture(u32 flags, IImage * image) +{ + ImageSize = image->getDimension(); + + core::dimension2d optSize = ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); + + D3DFORMAT format = D3DFMT_A1R5G5B5; + + switch(getTextureFormatFromFlags(flags)) + { + case ETCF_ALWAYS_16_BIT: + format = D3DFMT_A1R5G5B5; break; + case ETCF_ALWAYS_32_BIT: + format = D3DFMT_A8R8G8B8; break; + case ETCF_OPTIMIZED_FOR_QUALITY: + { + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + case ECF_A8R8G8B8: + format = D3DFMT_A8R8G8B8; break; + case ECF_A1R5G5B5: + case ECF_R5G6B5: + format = D3DFMT_A1R5G5B5; break; + } + } + break; + case ETCF_OPTIMIZED_FOR_SPEED: + format = D3DFMT_A1R5G5B5; + break; + default: + break; + } + if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) + { + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_R8G8B8; + else if (format == D3DFMT_A1R5G5B5) + format = D3DFMT_R5G6B5; + } + + const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + + DWORD usage = 0; + + // This enables hardware mip map generation. + if (mipmaps && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + { + LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9; + D3DDISPLAYMODE d3ddm; + intf->GetAdapterDisplayMode(Driver->Params.DisplayAdapter, &d3ddm); + + if (D3D_OK==intf->CheckDeviceFormat(Driver->Params.DisplayAdapter,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format)) + { + usage = D3DUSAGE_AUTOGENMIPMAP; + HardwareMipMaps = true; + } + } + + HRESULT hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + usage, // usage + format, D3DPOOL_MANAGED , &Texture, NULL); + + if (FAILED(hr)) + { + // try brute force 16 bit + HardwareMipMaps = false; + if (format == D3DFMT_A8R8G8B8) + format = D3DFMT_A1R5G5B5; + else if (format == D3DFMT_R8G8B8) + format = D3DFMT_R5G6B5; + else + return false; + + hr = Device->CreateTexture(optSize.Width, optSize.Height, + mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) + 0, format, D3DPOOL_MANAGED, &Texture, NULL); + } + + ColorFormat = Driver->getColorFormatFromD3DFormat(format); + setPitch(format); + return (SUCCEEDED(hr)); +} + + +//! copies the image to the texture +bool CD3D9Texture::copyTexture(IImage * image) +{ + if (Texture && image) + { + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + + TextureSize.Width = desc.Width; + TextureSize.Height = desc.Height; + + D3DLOCKED_RECT rect; + HRESULT hr = Texture->LockRect(0, &rect, 0, 0); + if (FAILED(hr)) + { + os::Printer::log("Texture data not copied", "Could not LockRect D3D9 Texture.", ELL_ERROR); + return false; + } + + Pitch = rect.Pitch; + image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); + + hr = Texture->UnlockRect(0); + if (FAILED(hr)) + { + os::Printer::log("Texture data not copied", "Could not UnlockRect D3D9 Texture.", ELL_ERROR); + return false; + } + } + + return true; +} + + +//! lock function +void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) +{ + if (!Texture) + return 0; + + MipLevelLocked=mipmapLevel; + HRESULT hr; + D3DLOCKED_RECT rect; + if(!IsRenderTarget) + { + hr = Texture->LockRect(mipmapLevel, &rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); + return 0; + } + } + else + { + if (!RTTSurface) + { + // Make RTT surface large enough for all miplevels (including 0) + D3DSURFACE_DESC desc; + Texture->GetLevelDesc(0, &desc); + hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, 0); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture", "Offscreen surface creation failed.", ELL_ERROR); + return 0; + } + } + + IDirect3DSurface9 *surface = 0; + hr = Texture->GetSurfaceLevel(mipmapLevel, &surface); + if (FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR); + return 0; + } + hr = Device->GetRenderTargetData(surface, RTTSurface); + surface->Release(); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture", "Data copy failed.", ELL_ERROR); + return 0; + } + hr = RTTSurface->LockRect(&rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); + if(FAILED(hr)) + { + os::Printer::log("Could not lock DIRECT3D9 Texture", "LockRect failed.", ELL_ERROR); + return 0; + } + } + return rect.pBits; +} + + +//! unlock function +void CD3D9Texture::unlock() +{ + if (!Texture) + return; + + if (!IsRenderTarget) + Texture->UnlockRect(MipLevelLocked); + else if (RTTSurface) + RTTSurface->UnlockRect(); +} + + +//! Returns original size of the texture. +const core::dimension2d& CD3D9Texture::getOriginalSize() const +{ + return ImageSize; +} + + +//! Returns (=size) of the texture. +const core::dimension2d& CD3D9Texture::getSize() const +{ + return TextureSize; +} + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE CD3D9Texture::getDriverType() const +{ + return EDT_DIRECT3D9; +} + + +//! returns color format of texture +ECOLOR_FORMAT CD3D9Texture::getColorFormat() const +{ + return ColorFormat; +} + + +//! returns pitch of texture (in bytes) +u32 CD3D9Texture::getPitch() const +{ + return Pitch; +} + + +//! returns the DIRECT3D9 Texture +IDirect3DBaseTexture9* CD3D9Texture::getDX9Texture() const +{ + return Texture; +} + + +//! returns if texture has mipmap levels +bool CD3D9Texture::hasMipMaps() const +{ + return HasMipMaps; +} + + +void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, + s32 pitchsrc, s32 pitchtgt) const +{ + for (s32 y=0; y1) + size.Width /=2; + if (size.Height>1) + size.Height /=2; + ++level; + IDirect3DSurface9* mipSurface = 0; + HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); + if (FAILED(hr) || !mipSurface) + { + os::Printer::log("Could not get mipmap level", ELL_WARNING); + return; + } + D3DSURFACE_DESC mipDesc; + mipSurface->GetDesc(&mipDesc); + D3DLOCKED_RECT miplr; + + // lock mipmap surface + if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) + { + mipSurface->Release(); + os::Printer::log("Could not lock texture", ELL_WARNING); + return; + } + + memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); + mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; + // unlock + mipSurface->UnlockRect(); + // release + mipSurface->Release(); + } while (size.Width != 1 || size.Height != 1); + } + else if (HasMipMaps) + { + // create mip maps. +#ifdef _IRR_USE_D3DXFilterTexture_ + // The D3DXFilterTexture function seems to get linked wrong when + // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. + // So mipmapgeneration is replaced with my own bad generation + HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT); + if (FAILED(hr)) +#endif + createMipMaps(); + } +} + + +//! returns if it is a render target +bool CD3D9Texture::isRenderTarget() const +{ + return IsRenderTarget; +} + + +//! Returns pointer to the render target surface +IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface() +{ + if (!IsRenderTarget) + return 0; + + IDirect3DSurface9 *pRTTSurface = 0; + if (Texture) + Texture->GetSurfaceLevel(0, &pRTTSurface); + + if (pRTTSurface) + pRTTSurface->Release(); + + return pRTTSurface; +} + + +void CD3D9Texture::setPitch(D3DFORMAT d3dformat) +{ + switch(d3dformat) + { + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + Pitch = TextureSize.Width * 2; + break; + case D3DFMT_A8B8G8R8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + Pitch = TextureSize.Width * 4; + break; + case D3DFMT_R5G6B5: + Pitch = TextureSize.Width * 2; + break; + case D3DFMT_R8G8B8: + Pitch = TextureSize.Width * 3; + break; + default: + Pitch = 0; + }; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.h new file mode 100644 index 0000000..812aa71 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CD3D9Texture.h @@ -0,0 +1,130 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DIRECTX9_TEXTURE_H_INCLUDED__ +#define __C_DIRECTX9_TEXTURE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + +#include "ITexture.h" +#include "IImage.h" +#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +#include "irrMath.h" // needed by borland for sqrtf define +#endif +#include + +namespace irr +{ +namespace video +{ + +class CD3D9Driver; +// forward declaration for RTT depth buffer handling +struct SDepthSurface; +/*! + interface for a Video Driver dependent Texture. +*/ +class CD3D9Texture : public ITexture +{ +public: + + //! constructor + CD3D9Texture(IImage* image, CD3D9Driver* driver, + u32 flags, const io::path& name, void* mipmapData=0); + + //! rendertarget constructor + CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, const io::path& name, + const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! destructor + virtual ~CD3D9Texture(); + + //! lock function + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! returns the DIRECT3D9 Texture + IDirect3DBaseTexture9* getDX9Texture() const; + + //! returns if texture has mipmap levels + bool hasMipMaps() const; + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(void* mipmapData=0); + + //! returns if it is a render target + virtual bool isRenderTarget() const; + + //! Returns pointer to the render target surface + IDirect3DSurface9* getRenderTargetSurface(); + +private: + friend class CD3D9Driver; + + void createRenderTarget(const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! creates the hardware texture + bool createTexture(u32 flags, IImage * image); + + //! copies the image to the texture + bool copyTexture(IImage * image); + + //! Helper function for mipmap generation. + bool createMipMaps(u32 level=1); + + //! Helper function for mipmap generation. + void copy16BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + //! Helper function for mipmap generation. + void copy32BitMipMap(char* src, char* tgt, + s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; + + //! set Pitch based on the d3d format + void setPitch(D3DFORMAT d3dformat); + + IDirect3DDevice9* Device; + IDirect3DTexture9* Texture; + IDirect3DSurface9* RTTSurface; + CD3D9Driver* Driver; + SDepthSurface* DepthSurface; + core::dimension2d TextureSize; + core::dimension2d ImageSize; + s32 Pitch; + u32 MipLevelLocked; + ECOLOR_FORMAT ColorFormat; + + bool HasMipMaps; + bool HardwareMipMaps; + bool IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + +#endif // __C_DIRECTX9_TEXTURE_H_INCLUDED__ + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.cpp new file mode 100644 index 0000000..b6ed57b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.cpp @@ -0,0 +1,436 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by Salvatore Russo. +// I (Nikolaus Gebhardt) did some minor modifications and changes to it and +// integrated it into Irrlicht. +// Thanks a lot to Salvatore for his work on this and that he gave me +// his permission to add it into Irrlicht using the zlib license. +/* + CDMFLoader by Salvatore Russo (September 2005) + + See the header file for additional information including use and distribution rights. +*/ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_DMF_LOADER_ + +#ifdef _DEBUG +#define _IRR_DMF_DEBUG_ +#include "os.h" +#endif + +#include "CDMFLoader.h" +#include "ISceneManager.h" +#include "IAttributes.h" +#include "SAnimatedMesh.h" +#include "SSkinMeshBuffer.h" +#include "irrString.h" +#include "irrMath.h" +#include "dmfsupport.h" + +namespace irr +{ +namespace scene +{ + +/** Constructor*/ +CDMFLoader::CDMFLoader(ISceneManager* smgr, io::IFileSystem* filesys) +: SceneMgr(smgr), FileSystem(filesys) +{ + #ifdef _DEBUG + IReferenceCounted::setDebugName("CDMFLoader"); + #endif +} + + +void CDMFLoader::findFile(bool use_mat_dirs, const core::stringc& path, const core::stringc& matPath, core::stringc& filename) +{ + // path + texpath + full name + if (use_mat_dirs && FileSystem->existFile(path+matPath+filename)) + filename = path+matPath+filename; + // path + full name + else if (FileSystem->existFile(path+filename)) + filename = path+filename; + // path + texpath + base name + else if (use_mat_dirs && FileSystem->existFile(path+matPath+FileSystem->getFileBasename(filename))) + filename = path+matPath+FileSystem->getFileBasename(filename); + // path + base name + else if (FileSystem->existFile(path+FileSystem->getFileBasename(filename))) + filename = path+FileSystem->getFileBasename(filename); + // texpath + full name + else if (use_mat_dirs && FileSystem->existFile(matPath+filename)) + filename = matPath+filename; + // texpath + base name + else if (use_mat_dirs && FileSystem->existFile(matPath+FileSystem->getFileBasename(filename))) + filename = matPath+FileSystem->getFileBasename(filename); + // base name + else if (FileSystem->existFile(FileSystem->getFileBasename(filename))) + filename = FileSystem->getFileBasename(filename); +} + + +/**Creates/loads an animated mesh from the file. + \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information.*/ +IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + video::IVideoDriver* driver = SceneMgr->getVideoDriver(); + + //Load stringlist + StringList dmfRawFile; + LoadFromFile(file, dmfRawFile); + + if (dmfRawFile.size()==0) + return 0; + + SMesh * mesh = new SMesh(); + + u32 i; + + dmfHeader header; + + //load header + core::array materiali; + if (GetDMFHeader(dmfRawFile, header)) + { + //let's set ambient light + SceneMgr->setAmbientLight(header.dmfAmbient); + + //let's create the correct number of materials, vertices and faces + dmfVert *verts=new dmfVert[header.numVertices]; + dmfFace *faces=new dmfFace[header.numFaces]; + + //let's get the materials +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Loading materials", core::stringc(header.numMaterials).c_str()); +#endif + GetDMFMaterials(dmfRawFile, materiali, header.numMaterials); + + //let's get vertices and faces +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Loading geometry"); +#endif + GetDMFVerticesFaces(dmfRawFile, verts, faces); + + //create a meshbuffer for each material, then we'll remove empty ones +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Creating meshbuffers."); +#endif + for (i=0; iMaterial.MaterialType = video::EMT_LIGHTMAP_LIGHTING; + buffer->Material.Wireframe = false; + buffer->Material.Lighting = true; + mesh->addMeshBuffer(buffer); + buffer->drop(); + } + + // Build the mesh buffers +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Adding geometry to mesh."); +#endif + for (i = 0; i < header.numFaces; i++) + { +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Polygon with #vertices", core::stringc(faces[i].numVerts).c_str()); +#endif + if (faces[i].numVerts < 3) + continue; + + const core::vector3df normal = + core::triangle3df(verts[faces[i].firstVert].pos, + verts[faces[i].firstVert+1].pos, + verts[faces[i].firstVert+2].pos).getNormal().normalize(); + + SSkinMeshBuffer* meshBuffer = (SSkinMeshBuffer*)mesh->getMeshBuffer( + faces[i].materialID); + + const bool use2TCoords = meshBuffer->Vertices_2TCoords.size() || + materiali[faces[i].materialID].lightmapName.size(); + if (use2TCoords && meshBuffer->Vertices_Standard.size()) + meshBuffer->convertTo2TCoords(); + const u32 base = meshBuffer->Vertices_2TCoords.size()?meshBuffer->Vertices_2TCoords.size():meshBuffer->Vertices_Standard.size(); + + // Add this face's verts + if (use2TCoords) + { + // make sure we have the proper type set + meshBuffer->VertexType=video::EVT_2TCOORDS; + for (u32 v = 0; v < faces[i].numVerts; v++) + { + const dmfVert& vv = verts[faces[i].firstVert + v]; + video::S3DVertex2TCoords vert(vv.pos, + normal, video::SColor(255,255,255,255), vv.tc, vv.lc); + if (materiali[faces[i].materialID].textureBlend==4 && + SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES)) + { + vert.TCoords.set(vv.tc.X,-vv.tc.Y); + } + meshBuffer->Vertices_2TCoords.push_back(vert); + } + } + else + { + for (u32 v = 0; v < faces[i].numVerts; v++) + { + const dmfVert& vv = verts[faces[i].firstVert + v]; + video::S3DVertex vert(vv.pos, + normal, video::SColor(255,255,255,255), vv.tc); + if (materiali[faces[i].materialID].textureBlend==4 && + SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES)) + { + vert.TCoords.set(vv.tc.X,-vv.tc.Y); + } + meshBuffer->Vertices_Standard.push_back(vert); + } + } + + // Now add the indices + // This weird loop turns convex polygons into triangle strips. + // I do it this way instead of a simple fan because it usually + // looks a lot better in wireframe, for example. + u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center + for (u32 v = 0; v < faces[i].numVerts - 2; v++) + { + if (v & 1) // odd + c = h - 1; + else // even + c = l + 1; + + meshBuffer->Indices.push_back(base + h); + meshBuffer->Indices.push_back(base + l); + meshBuffer->Indices.push_back(base + c); + + if (v & 1) // odd + h--; + else // even + l++; + } + } + + delete [] verts; + delete [] faces; + } + + // delete all buffers without geometry in it. +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Cleaning meshbuffers."); +#endif + i = 0; + while(i < mesh->MeshBuffers.size()) + { + if (mesh->MeshBuffers[i]->getVertexCount() == 0 || + mesh->MeshBuffers[i]->getIndexCount() == 0) + { + // Meshbuffer is empty -- drop it + mesh->MeshBuffers[i]->drop(); + mesh->MeshBuffers.erase(i); + materiali.erase(i); + } + else + { + i++; + } + } + + + { + //load textures and lightmaps in materials. + //don't worry if you receive a could not load texture, cause if you don't need + //a particular material in your scene it will be loaded and then destroyed. +#ifdef _IRR_DMF_DEBUG_ + os::Printer::log("Loading textures."); +#endif + const bool use_mat_dirs=!SceneMgr->getParameters()->getAttributeAsBool(DMF_IGNORE_MATERIALS_DIRS); + + core::stringc path; + if ( SceneMgr->getParameters()->existsAttribute(DMF_TEXTURE_PATH) ) + path = SceneMgr->getParameters()->getAttributeAsString(DMF_TEXTURE_PATH); + else + path = FileSystem->getFileDir(file->getFileName()); + path += ('/'); + + for (i=0; igetMeshBufferCount(); i++) + { + //texture and lightmap + video::ITexture *tex = 0; + video::ITexture *lig = 0; + + //current buffer to apply material + video::SMaterial& mat = mesh->getMeshBuffer(i)->getMaterial(); + + //Primary texture is normal + if (materiali[i].textureFlag==0) + { + if (materiali[i].textureBlend==4) + driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true); + findFile(use_mat_dirs, path, materiali[i].pathName, materiali[i].textureName); + tex = driver->getTexture(materiali[i].textureName); + } + //Primary texture is just a color + else if(materiali[i].textureFlag==1) + { + video::SColor color(axtoi(materiali[i].textureName.c_str())); + + //just for compatibility with older Irrlicht versions + //to support transparent materials + if (color.getAlpha()!=255 && materiali[i].textureBlend==4) + driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true); + + video::IImage *immagine= driver->createImage(video::ECF_A8R8G8B8, + core::dimension2d(8,8)); + immagine->fill(color); + tex = driver->addTexture("", immagine); + immagine->drop(); + + //to support transparent materials + if (color.getAlpha()!=255 && materiali[i].textureBlend==4) + { + mat.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + mat.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f); + } + } + + //Lightmap is present + if (materiali[i].lightmapFlag == 0) + { + findFile(use_mat_dirs, path, materiali[i].pathName, materiali[i].lightmapName); + lig = driver->getTexture(materiali[i].lightmapName); + } + else //no lightmap + { + mat.MaterialType = video::EMT_SOLID; + const f32 mult = 100.0f - header.dmfShadow; + mat.AmbientColor=header.dmfAmbient.getInterpolated(video::SColor(255,0,0,0),mult/100.f); + } + + if (materiali[i].textureBlend==4) + { + mat.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + mat.MaterialTypeParam = + SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF); + } + + //if texture is present mirror vertically owing to DeleD representation + if (tex && header.dmfVersion<1.1) + { + const core::dimension2d texsize = tex->getSize(); + void* pp = tex->lock(); + if (pp) + { + const video::ECOLOR_FORMAT format = tex->getColorFormat(); + if (format == video::ECF_A1R5G5B5) + { + s16* p = (s16*)pp; + s16 tmp=0; + for (u32 x=0; xunlock(); + tex->regenerateMipMapLevels(); + } + + //if lightmap is present mirror vertically owing to DeleD rapresentation + if (lig && header.dmfVersion<1.1) + { + const core::dimension2d ligsize=lig->getSize(); + void* pp = lig->lock(); + if (pp) + { + video::ECOLOR_FORMAT format = lig->getColorFormat(); + if (format == video::ECF_A1R5G5B5) + { + s16* p = (s16*)pp; + s16 tmp=0; + for (u32 x=0; xunlock(); + lig->regenerateMipMapLevels(); + } + + mat.setTexture(0, tex); + mat.setTexture(1, lig); + } + } + + // create bounding box + for (i = 0; i < mesh->MeshBuffers.size(); ++i) + { + mesh->MeshBuffers[i]->recalculateBoundingBox(); + } + mesh->recalculateBoundingBox(); + + // Set up an animated mesh to hold the mesh + SAnimatedMesh* AMesh = new SAnimatedMesh(); + AMesh->Type = EAMT_UNKNOWN; + AMesh->addMesh(mesh); + AMesh->recalculateBoundingBox(); + mesh->drop(); + + return AMesh; +} + + +/** \brief Tell us if this file is able to be loaded by this class + based on the file extension (e.g. ".bsp") + \return true if file is loadable.*/ +bool CDMFLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "dmf" ); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_DMF_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.h new file mode 100644 index 0000000..a314913 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDMFLoader.h @@ -0,0 +1,91 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by Salvatore Russo. +// I (Nikolaus Gebhardt) did some minor modifications changes to it and integrated +// it into Irrlicht: +// - removed STL dependency +// - removed log file and replaced it with irrlicht logging +// - adapted code formatting a bit to Irrlicht style +// - removed memory leaks +// Thanks a lot to Salvatore for his work on this and that he gave me +// his permission to add it into Irrlicht. + +/* + CDMFLoader by Salvatore Russo + Version 1.3 + + This loader is used to load DMF files in Irrlicht. + Look at the documentation for a sample application. + + Parts of this code are from Murphy McCauley COCTLoader just like + GetFaceNormal() or indexes creation routines and a routine to add faces. So + please refer to COCTLoader.h to know more about rights granted. + + You can use this software as you wish but you must not remove these notes about license nor + credits to others for parts of this code. +*/ + +#ifndef __C_DMF_LOADER_H_INCLUDED__ +#define __C_DMF_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IReadFile.h" +#include "IFileSystem.h" +#include "SMesh.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "SAnimatedMesh.h" + +namespace irr +{ +namespace scene +{ + /** A class to load DeleD mesh files.*/ + class CDMFLoader : public IMeshLoader + { + public: + + /** constructor*/ + CDMFLoader(ISceneManager* smgr, io::IFileSystem* filesys); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + /** creates/loads an animated mesh from the file. + \return Pointer to the created mesh. Returns 0 if loading failed. + If you no longer need the mesh, you should call IAnimatedMesh::drop(). + See IReferenceCounted::drop() for more information.*/ + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + /** loads dynamic lights present in this scene. + Note that loaded lights from DeleD must have the suffix \b dynamic_ and must be \b pointlight. + Irrlicht correctly loads specular color, diffuse color , position and distance of object affected by light. + \return number of lights loaded or 0 if loading failed.*/ + int loadLights(const c8 * filename, ISceneManager* smgr, + ISceneNode* parent = 0, s32 base_id = 1000); + + /** loads water plains present in this scene. + Note that loaded water plains from DeleD must have the suffix \b water_ and must be \b rectangle (with just 1 rectangular face). + Irrlicht correctly loads position and rotation of water plain as well as texture layers. + \return number of water plains loaded or 0 if loading failed.*/ + int loadWaterPlains(const c8 *filename, + ISceneManager* smgr, + ISceneNode * parent = 0, + s32 base_id = 2000, + bool mode = true); + + private: + void findFile(bool use_mat_dirs, const core::stringc& path, const core::stringc& matPath, core::stringc& filename); + + ISceneManager* SceneMgr; + io::IFileSystem* FileSystem; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultGUIElementFactory.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultGUIElementFactory.cpp new file mode 100644 index 0000000..c10f18f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDefaultGUIElementFactory.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CDefaultGUIElementFactory.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" + +#include "IGUIButton.h" +#include "IGUICheckBox.h" +#include "IGUIColorSelectDialog.h" +#include "IGUIComboBox.h" +#include "IGUIContextMenu.h" +#include "IGUIEditBox.h" +#include "IGUIFileOpenDialog.h" +#include "IGUIInOutFader.h" +#include "IGUIImage.h" +#include "IGUIListBox.h" +#include "IGUIMeshViewer.h" +#include "IGUIScrollBar.h" +#include "IGUISpinBox.h" +#include "IGUIStaticText.h" +#include "IGUITabControl.h" +#include "IGUITable.h" +#include "IGUIToolbar.h" +#include "IGUIWindow.h" +#include "IGUITreeView.h" + +namespace irr +{ +namespace gui +{ + +CDefaultGUIElementFactory::CDefaultGUIElementFactory(IGUIEnvironment* env) +: Environment(env) +{ + + #ifdef _DEBUG + setDebugName("CDefaultGUIElementFactory"); + #endif + + // don't grab the gui environment here to prevent cyclic references +} + + +//! adds an element to the env based on its type id +IGUIElement* CDefaultGUIElementFactory::addGUIElement(EGUI_ELEMENT_TYPE type, IGUIElement* parent) +{ + switch(type) + { + case EGUIET_BUTTON: + return Environment->addButton(core::rect(0,0,100,100),parent); + case EGUIET_CHECK_BOX: + return Environment->addCheckBox(false, core::rect(0,0,100,100), parent); + case EGUIET_COLOR_SELECT_DIALOG: + return Environment->addColorSelectDialog(0,true,parent); + case EGUIET_COMBO_BOX: + return Environment->addComboBox(core::rect(0,0,100,100),parent); + case EGUIET_CONTEXT_MENU: + return Environment->addContextMenu(core::rect(0,0,100,100),parent); + case EGUIET_MENU: + return Environment->addMenu(parent); + case EGUIET_EDIT_BOX: + return Environment->addEditBox(0,core::rect(0,0,100,100),true, parent); + case EGUIET_FILE_OPEN_DIALOG: + return Environment->addFileOpenDialog(0,true,parent); + case EGUIET_IMAGE: + return Environment->addImage(0,core::position2di(0,0), true, parent); + case EGUIET_IN_OUT_FADER: + return Environment->addInOutFader(0,parent); + case EGUIET_LIST_BOX: + return Environment->addListBox(core::rect(0,0,100,100),parent); + case EGUIET_MESH_VIEWER: + return Environment->addMeshViewer(core::rect(0,0,100,100),parent); + case EGUIET_MODAL_SCREEN: + return Environment->addModalScreen(parent); + case EGUIET_MESSAGE_BOX: + return Environment->addMessageBox(0,0,false,0,parent); + case EGUIET_SCROLL_BAR: + return Environment->addScrollBar(false,core::rect(0,0,100,100),parent); + case EGUIET_STATIC_TEXT: + return Environment->addStaticText(0,core::rect(0,0,100,100),false,true,parent); + case EGUIET_TAB: + return Environment->addTab(core::rect(0,0,100,100),parent); + case EGUIET_TAB_CONTROL: + return Environment->addTabControl(core::rect(0,0,100,100),parent); + case EGUIET_TABLE: + return Environment->addTable(core::rect(0,0,100,100), parent); + case EGUIET_TOOL_BAR: + return Environment->addToolBar(parent); + case EGUIET_WINDOW: + return Environment->addWindow(core::rect(0,0,100,100),false,0,parent); + case EGUIET_SPIN_BOX: + return Environment->addSpinBox(L"0.0", core::rect(0,0,100,100), true, parent); + case EGUIET_TREE_VIEW: + return Environment->addTreeView(core::rect(0,0,100,100),parent); + default: + return 0; + } +} + + +//! adds an element to the environment based on its type name +IGUIElement* CDefaultGUIElementFactory::addGUIElement(const c8* typeName, IGUIElement* parent) +{ + return addGUIElement( getTypeFromName(typeName), parent ); +} + + +//! Returns the amount of element types this factory is able to create. +s32 CDefaultGUIElementFactory::getCreatableGUIElementTypeCount() const +{ + return EGUIET_COUNT; +} + + +//! Returns the type of a createable element type. +EGUI_ELEMENT_TYPE CDefaultGUIElementFactory::getCreateableGUIElementType(s32 idx) const +{ + if (idx>=0 && idx=0 && idx=0 && typegrab(); +} + + +CDefaultSceneNodeAnimatorFactory::~CDefaultSceneNodeAnimatorFactory() +{ + if (CursorControl) + CursorControl->drop(); +} + + +//! creates a scene node animator based on its type id +ISceneNodeAnimator* CDefaultSceneNodeAnimatorFactory::createSceneNodeAnimator(ESCENE_NODE_ANIMATOR_TYPE type, ISceneNode* target) +{ + scene::ISceneNodeAnimator* anim = 0; + + switch(type) + { + case ESNAT_FLY_CIRCLE: + anim = Manager->createFlyCircleAnimator(core::vector3df(0,0,0), 10); + break; + case ESNAT_FLY_STRAIGHT: + anim = Manager->createFlyStraightAnimator(core::vector3df(0,0,0), core::vector3df(100,100,100), 10000, true ); + break; + case ESNAT_FOLLOW_SPLINE: + { + core::array points; + points.push_back(core::vector3df(0,0,0)); + points.push_back(core::vector3df(10,5,10)); + anim = Manager->createFollowSplineAnimator(0, points); + } + break; + case ESNAT_ROTATION: + anim = Manager->createRotationAnimator(core::vector3df(0.3f,0,0)); + break; + case ESNAT_TEXTURE: + { + core::array textures; + anim = Manager->createTextureAnimator(textures, 250); + } + break; + case ESNAT_DELETION: + anim = Manager->createDeleteAnimator(5000); + break; + case ESNAT_COLLISION_RESPONSE: + anim = Manager->createCollisionResponseAnimator(0, target); + break; + case ESNAT_CAMERA_FPS: + anim = new CSceneNodeAnimatorCameraFPS(CursorControl); + break; + case ESNAT_CAMERA_MAYA: + anim = new CSceneNodeAnimatorCameraMaya(CursorControl); + break; + default: + break; + } + + if (anim && target) + target->addAnimator(anim); + + return anim; +} + + +//! creates a scene node animator based on its type name +ISceneNodeAnimator* CDefaultSceneNodeAnimatorFactory::createSceneNodeAnimator(const c8* typeName, ISceneNode* target) +{ + return createSceneNodeAnimator( getTypeFromName(typeName), target ); +} + + +//! returns amount of scene node animator types this factory is able to create +u32 CDefaultSceneNodeAnimatorFactory::getCreatableSceneNodeAnimatorTypeCount() const +{ + return ESNAT_COUNT; +} + + +//! returns type of a createable scene node animator type +ESCENE_NODE_ANIMATOR_TYPE CDefaultSceneNodeAnimatorFactory::getCreateableSceneNodeAnimatorType(u32 idx) const +{ + if (idxaddCubeSceneNode(10, parent); + case ESNT_SPHERE: + return Manager->addSphereSceneNode(5, 16, parent); + case ESNT_TEXT: + return Manager->addTextSceneNode(0, L"example"); + case ESNT_WATER_SURFACE: + return Manager->addWaterSurfaceSceneNode(0, 2.0f, 300.0f, 10.0f, parent); + case ESNT_TERRAIN: + return Manager->addTerrainSceneNode("", parent, -1, + core::vector3df(0.0f,0.0f,0.0f), + core::vector3df(0.0f,0.0f,0.0f), + core::vector3df(1.0f,1.0f,1.0f), + video::SColor(255,255,255,255), + 4, ETPS_17, 0, true); + case ESNT_SKY_BOX: + return Manager->addSkyBoxSceneNode(0,0,0,0,0,0, parent); + case ESNT_SKY_DOME: + return Manager->addSkyDomeSceneNode(0, 16, 8, 0.9f, 2.0f, 1000.0f, parent); + case ESNT_SHADOW_VOLUME: + return 0; + case ESNT_OCTREE: + return Manager->addOctreeSceneNode((IMesh*)0, parent, -1, 128, true); + case ESNT_MESH: + return Manager->addMeshSceneNode(0, parent, -1, core::vector3df(), + core::vector3df(), core::vector3df(1,1,1), true); + case ESNT_LIGHT: + return Manager->addLightSceneNode(parent); + case ESNT_EMPTY: + return Manager->addEmptySceneNode(parent); + case ESNT_DUMMY_TRANSFORMATION: + return Manager->addDummyTransformationSceneNode(parent); + case ESNT_CAMERA: + return Manager->addCameraSceneNode(parent); + case ESNT_CAMERA_MAYA: + return Manager->addCameraSceneNodeMaya(parent); + case ESNT_CAMERA_FPS: + return Manager->addCameraSceneNodeFPS(parent); + case ESNT_BILLBOARD: + return Manager->addBillboardSceneNode(parent); + case ESNT_ANIMATED_MESH: + return Manager->addAnimatedMeshSceneNode(0, parent, -1, core::vector3df(), + core::vector3df(), core::vector3df(1,1,1), true); + case ESNT_PARTICLE_SYSTEM: + return Manager->addParticleSystemSceneNode(true, parent); + case ESNT_VOLUME_LIGHT: + return (ISceneNode*)Manager->addVolumeLightSceneNode(parent); + default: + break; + } + + return 0; +} + + +//! adds a scene node to the scene graph based on its type name +ISceneNode* CDefaultSceneNodeFactory::addSceneNode(const c8* typeName, ISceneNode* parent) +{ + return addSceneNode( getTypeFromName(typeName), parent ); +} + + +//! returns amount of scene node types this factory is able to create +u32 CDefaultSceneNodeFactory::getCreatableSceneNodeTypeCount() const +{ + return SupportedSceneNodeTypes.size(); +} + + +//! returns type of a createable scene node type +ESCENE_NODE_TYPE CDefaultSceneNodeFactory::getCreateableSceneNodeType(u32 idx) const +{ + if (idx SupportedSceneNodeTypes; + + ISceneManager* Manager; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.cpp new file mode 100644 index 0000000..8658105 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.cpp @@ -0,0 +1,176 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "SoftwareDriver2_compile_config.h" +#include "CDepthBuffer.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! constructor +CDepthBuffer::CDepthBuffer(const core::dimension2d& size) +: Buffer(0), Size(0,0) +{ + #ifdef _DEBUG + setDebugName("CDepthBuffer"); + #endif + + setSize(size); +} + + + +//! destructor +CDepthBuffer::~CDepthBuffer() +{ + if (Buffer) + delete [] Buffer; +} + + + +//! clears the zbuffer +void CDepthBuffer::clear() +{ + +#ifdef SOFTWARE_DRIVER_2_USE_WBUFFER + f32 zMax = 0.f; +#else + f32 zMax = 1.f; +#endif + + u32 zMaxValue; + zMaxValue = IR(zMax); + + memset32 ( Buffer, zMaxValue, TotalSize ); +} + + + +//! sets the new size of the zbuffer +void CDepthBuffer::setSize(const core::dimension2d& size) +{ + if (size == Size) + return; + + Size = size; + + if (Buffer) + delete [] Buffer; + + Pitch = size.Width * sizeof ( fp24 ); + TotalSize = Pitch * size.Height; + Buffer = new u8[TotalSize]; + clear (); +} + + + +//! returns the size of the zbuffer +const core::dimension2d& CDepthBuffer::getSize() const +{ + return Size; +} + +// ----------------------------------------------------------------- + +//! constructor +CStencilBuffer::CStencilBuffer(const core::dimension2d& size) +: Buffer(0), Size(0,0) +{ + #ifdef _DEBUG + setDebugName("CDepthBuffer"); + #endif + + setSize(size); +} + + + +//! destructor +CStencilBuffer::~CStencilBuffer() +{ + if (Buffer) + delete [] Buffer; +} + + + +//! clears the zbuffer +void CStencilBuffer::clear() +{ + memset32 ( Buffer, 0, TotalSize ); +} + + + +//! sets the new size of the zbuffer +void CStencilBuffer::setSize(const core::dimension2d& size) +{ + if (size == Size) + return; + + Size = size; + + if (Buffer) + delete [] Buffer; + + Pitch = size.Width * sizeof ( u32 ); + TotalSize = Pitch * size.Height; + Buffer = new u8[TotalSize]; + clear (); +} + + + +//! returns the size of the zbuffer +const core::dimension2d& CStencilBuffer::getSize() const +{ + return Size; +} + + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a ZBuffer +IDepthBuffer* createDepthBuffer(const core::dimension2d& size) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CDepthBuffer(size); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +//! creates a ZBuffer +IStencilBuffer* createStencilBuffer(const core::dimension2d& size) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CStencilBuffer(size); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.h new file mode 100644 index 0000000..2355e61 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDepthBuffer.h @@ -0,0 +1,94 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_Z_BUFFER_H_INCLUDED__ +#define __C_Z_BUFFER_H_INCLUDED__ + +#include "IDepthBuffer.h" + +namespace irr +{ +namespace video +{ + + class CDepthBuffer : public IDepthBuffer + { + public: + + //! constructor + CDepthBuffer(const core::dimension2d& size); + + //! destructor + virtual ~CDepthBuffer(); + + //! clears the zbuffer + virtual void clear(); + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size); + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const; + + //! locks the zbuffer + virtual void* lock() { return (void*) Buffer; } + + //! unlocks the zbuffer + virtual void unlock() {} + + //! returns pitch of depthbuffer (in bytes) + virtual u32 getPitch() const { return Pitch; } + + + private: + + u8* Buffer; + core::dimension2d Size; + u32 TotalSize; + u32 Pitch; + }; + + + class CStencilBuffer : public IStencilBuffer + { + public: + + //! constructor + CStencilBuffer(const core::dimension2d& size); + + //! destructor + virtual ~CStencilBuffer(); + + //! clears the zbuffer + virtual void clear(); + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size); + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const; + + //! locks the zbuffer + virtual void* lock() { return (void*) Buffer; } + + //! unlocks the zbuffer + virtual void unlock() {} + + //! returns pitch of depthbuffer (in bytes) + virtual u32 getPitch() const { return Pitch; } + + + private: + + u8* Buffer; + core::dimension2d Size; + u32 TotalSize; + u32 Pitch; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.cpp new file mode 100644 index 0000000..812145a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CDummyTransformationSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CDummyTransformationSceneNode::CDummyTransformationSceneNode( + ISceneNode* parent, ISceneManager* mgr, s32 id) + : IDummyTransformationSceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CDummyTransformationSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CDummyTransformationSceneNode::getBoundingBox() const +{ + return Box; +} + + +//! Returns a reference to the current relative transformation matrix. +//! This is the matrix, this scene node uses instead of scale, translation +//! and rotation. +core::matrix4& CDummyTransformationSceneNode::getRelativeTransformationMatrix() +{ + return RelativeTransformationMatrix; +} + + +//! Returns the relative transformation of the scene node. +core::matrix4 CDummyTransformationSceneNode::getRelativeTransformation() const +{ + return RelativeTransformationMatrix; +} + +//! Creates a clone of this scene node and its children. +ISceneNode* CDummyTransformationSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CDummyTransformationSceneNode* nb = new CDummyTransformationSceneNode(newParent, + newManager, ID); + + nb->cloneMembers(this, newManager); + nb->RelativeTransformationMatrix = RelativeTransformationMatrix; + nb->Box = Box; + + if ( newParent ) + nb->drop(); + return nb; +} + +const core::vector3df& CDummyTransformationSceneNode::getScale() const +{ + os::Printer::log("CDummyTransformationSceneNode::getScale() does not contain the relative transformation.", ELL_DEBUG); + return RelativeScale; +} + +void CDummyTransformationSceneNode::setScale(const core::vector3df& scale) +{ + os::Printer::log("CDummyTransformationSceneNode::setScale() does not affect the relative transformation.", ELL_DEBUG); + RelativeScale = scale; +} + +const core::vector3df& CDummyTransformationSceneNode::getRotation() const +{ + os::Printer::log("CDummyTransformationSceneNode::getRotation() does not contain the relative transformation.", ELL_DEBUG); + return RelativeRotation; +} + +void CDummyTransformationSceneNode::setRotation(const core::vector3df& rotation) +{ + os::Printer::log("CDummyTransformationSceneNode::setRotation() does not affect the relative transformation.", ELL_DEBUG); + RelativeRotation = rotation; +} + +const core::vector3df& CDummyTransformationSceneNode::getPosition() const +{ + os::Printer::log("CDummyTransformationSceneNode::getPosition() does not contain the relative transformation.", ELL_DEBUG); + return RelativeTranslation; +} + +void CDummyTransformationSceneNode::setPosition(const core::vector3df& newpos) +{ + os::Printer::log("CDummyTransformationSceneNode::setPosition() does not affect the relative transformation.", ELL_DEBUG); + RelativeTranslation = newpos; +} + +} // end namespace scene +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.h new file mode 100644 index 0000000..2ad2266 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CDummyTransformationSceneNode.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ +#define __C_DUMMY_TRANSFORMATION_SCENE_NODE_H_INCLUDED__ + +#include "IDummyTransformationSceneNode.h" + +namespace irr +{ +namespace scene +{ + + class CDummyTransformationSceneNode : public IDummyTransformationSceneNode + { + public: + + //! constructor + CDummyTransformationSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns a reference to the current relative transformation matrix. + //! This is the matrix, this scene node uses instead of scale, translation + //! and rotation. + virtual core::matrix4& getRelativeTransformationMatrix(); + + //! Returns the relative transformation of the scene node. + virtual core::matrix4 getRelativeTransformation() const; + + //! does nothing. + virtual void render() {} + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_DUMMY_TRANSFORMATION; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + + private: + + // TODO: We can add least add some warnings to find troubles faster until we have + // fixed bug id 2318691. + virtual const core::vector3df& getScale() const; + virtual void setScale(const core::vector3df& scale); + virtual const core::vector3df& getRotation() const; + virtual void setRotation(const core::vector3df& rotation); + virtual const core::vector3df& getPosition() const; + virtual void setPosition(const core::vector3df& newpos); + + core::matrix4 RelativeTransformationMatrix; + core::aabbox3d Box; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.cpp new file mode 100644 index 0000000..fc1b931 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CEmptySceneNode.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CEmptySceneNode::CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) +: ISceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CEmptySceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); +} + + +//! pre render event +void CEmptySceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! render +void CEmptySceneNode::render() +{ + // do nothing +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CEmptySceneNode::getBoundingBox() const +{ + return Box; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CEmptySceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CEmptySceneNode* nb = new CEmptySceneNode(newParent, + newManager, ID); + + nb->cloneMembers(this, newManager); + nb->Box = Box; + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.h new file mode 100644 index 0000000..cbd8971 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CEmptySceneNode.h @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_EMPTY_SCENE_NODE_H_INCLUDED__ +#define __C_EMPTY_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + + class CEmptySceneNode : public ISceneNode + { + public: + + //! constructor + CEmptySceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! This method is called just before the rendering process of the whole scene. + virtual void OnRegisterSceneNode(); + + //! does nothing. + virtual void render(); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_EMPTY; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + core::aabbox3d Box; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.cpp new file mode 100644 index 0000000..3bbf3af --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.cpp @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CFPSCounter.h" +#include "irrMath.h" + +namespace irr +{ +namespace video +{ + + +CFPSCounter::CFPSCounter() +: FPS(60), Primitive(0), StartTime(0), FramesCounted(0), + PrimitivesCounted(0), PrimitiveAverage(0), PrimitiveTotal(0) +{ + +} + + +//! returns current fps +s32 CFPSCounter::getFPS() const +{ + return FPS; +} + + +//! returns current primitive count +u32 CFPSCounter::getPrimitive() const +{ + return Primitive; +} + + +//! returns average primitive count of last period +u32 CFPSCounter::getPrimitiveAverage() const +{ + return PrimitiveAverage; +} + + +//! returns accumulated primitive count since start +u32 CFPSCounter::getPrimitiveTotal() const +{ + return PrimitiveTotal; +} + + +//! to be called every frame +void CFPSCounter::registerFrame(u32 now, u32 primitivesDrawn) +{ + ++FramesCounted; + PrimitiveTotal += primitivesDrawn; + PrimitivesCounted += primitivesDrawn; + Primitive = primitivesDrawn; + + const u32 milliseconds = now - StartTime; + + if (milliseconds >= 1500 ) + { + const f32 invMilli = core::reciprocal ( (f32) milliseconds ); + + FPS = core::ceil32 ( ( 1000 * FramesCounted ) * invMilli ); + PrimitiveAverage = core::ceil32 ( ( 1000 * PrimitivesCounted ) * invMilli ); + + FramesCounted = 0; + PrimitivesCounted = 0; + StartTime = now; + } +} + + +} // end namespace video +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.h new file mode 100644 index 0000000..ca36527 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CFPSCounter.h @@ -0,0 +1,54 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_FPSCOUNTER_H_INCLUDED__ +#define __C_FPSCOUNTER_H_INCLUDED__ + +#include "irrTypes.h" + +namespace irr +{ +namespace video +{ + + +class CFPSCounter +{ +public: + CFPSCounter(); + + //! returns current fps + s32 getFPS() const; + + //! returns primitive count + u32 getPrimitive() const; + + //! returns average primitive count of last period + u32 getPrimitiveAverage() const; + + //! returns accumulated primitive count since start + u32 getPrimitiveTotal() const; + + //! to be called every frame + void registerFrame(u32 now, u32 primitive); + +private: + + s32 FPS; + u32 Primitive; + u32 StartTime; + + u32 FramesCounted; + u32 PrimitivesCounted; + u32 PrimitiveAverage; + u32 PrimitiveTotal; +}; + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.cpp new file mode 100644 index 0000000..1b8ff4f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.cpp @@ -0,0 +1,165 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CFileList.h" +#include "IrrCompileConfig.h" +#include "irrArray.h" +#include "coreutil.h" + +#include "os.h" + +namespace irr +{ +namespace io +{ + +static const io::path emptyFileListEntry; + +CFileList::CFileList(const io::path& path, bool ignoreCase, bool ignorePaths) + : IgnorePaths(ignorePaths), IgnoreCase(ignoreCase), Path(path) +{ + #ifdef _DEBUG + setDebugName("CFileList"); + #endif + + Path.replace('\\', '/'); +} + +CFileList::~CFileList() +{ + Files.clear(); +} + +u32 CFileList::getFileCount() const +{ + return Files.size(); +} + +void CFileList::sort() +{ + Files.sort(); +} + +const io::path& CFileList::getFileName(u32 index) const +{ + if (index >= Files.size()) + return emptyFileListEntry; + + return Files[index].Name; +} + + +//! Gets the full name of a file in the list, path included, based on an index. +const io::path& CFileList::getFullFileName(u32 index) const +{ + if (index >= Files.size()) + return emptyFileListEntry; + + return Files[index].FullName; +} + +//! adds a file or folder +u32 CFileList::addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id) +{ + SFileListEntry entry; + entry.ID = id ? id : Files.size(); + entry.Offset = offset; + entry.Size = size; + entry.Name = fullPath; + entry.Name.replace('\\', '/'); + entry.IsDirectory = isDirectory; + + // remove trailing slash + if (entry.Name.lastChar() == '/') + { + entry.IsDirectory = true; + entry.Name[entry.Name.size()-1] = 0; + entry.Name.validate(); + } + + if (IgnoreCase) + entry.Name.make_lower(); + + entry.FullName = entry.Name; + + core::deletePathFromFilename(entry.Name); + + if (IgnorePaths) + entry.FullName = entry.Name; + + //os::Printer::log(Path.c_str(), entry.FullName); + + Files.push_back(entry); + + return Files.size() - 1; +} + +//! Returns the ID of a file in the file list, based on an index. +u32 CFileList::getID(u32 index) const +{ + return index < Files.size() ? Files[index].ID : 0; +} + +bool CFileList::isDirectory(u32 index) const +{ + bool ret = false; + if (index < Files.size()) + ret = Files[index].IsDirectory; + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +//! Returns the size of a file +u32 CFileList::getFileSize(u32 index) const +{ + return index < Files.size() ? Files[index].Size : 0; +} + +//! Returns the size of a file +u32 CFileList::getFileOffset(u32 index) const +{ + return index < Files.size() ? Files[index].Offset : 0; +} + + +//! Searches for a file or folder within the list, returns the index +s32 CFileList::findFile(const io::path& filename, bool isDirectory = false) const +{ + SFileListEntry entry; + // we only need FullName to be set for the search + entry.FullName = filename; + entry.IsDirectory = isDirectory; + + // exchange + entry.FullName.replace('\\', '/'); + + // remove trailing slash + if (entry.FullName.lastChar() == '/') + { + entry.IsDirectory = true; + entry.FullName[entry.FullName.size()-1] = 0; + entry.FullName.validate(); + } + + if (IgnoreCase) + entry.FullName.make_lower(); + + if (IgnorePaths) + core::deletePathFromFilename(entry.FullName); + + return Files.binary_search(entry); +} + + +//! Returns the base path of the file list +const io::path& CFileList::getPath() const +{ + return Path; +} + + +} // end namespace irr +} // end namespace io + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.h new file mode 100644 index 0000000..f1d2ae3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileList.h @@ -0,0 +1,138 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_FILE_LIST_H_INCLUDED__ +#define __C_FILE_LIST_H_INCLUDED__ + +#include "IFileList.h" +#include "irrString.h" +#include "irrArray.h" + + +namespace irr +{ +namespace io +{ + +//! An entry in a list of files, can be a folder or a file. +struct SFileListEntry +{ + //! The name of the file + /** If this is a file or folder in the virtual filesystem and the archive + was created with the ignoreCase flag then the file name will be lower case. */ + io::path Name; + + //! The name of the file including the path + /** If this is a file or folder in the virtual filesystem and the archive was + created with the ignoreDirs flag then it will be the same as Name. */ + io::path FullName; + + //! The size of the file in bytes + u32 Size; + + //! The ID of the file in an archive + /** This is used to link the FileList entry to extra info held about this + file in an archive, which can hold things like data offset and CRC. */ + u32 ID; + + //! FileOffset inside an archive + u32 Offset; + + //! True if this is a folder, false if not. + bool IsDirectory; + + //! The == operator is provided so that CFileList can slowly search the list! + bool operator ==(const struct SFileListEntry& other) const + { + if (IsDirectory != other.IsDirectory) + return false; + + return FullName.equals_ignore_case(other.FullName); + } + + //! The < operator is provided so that CFileList can sort and quickly search the list. + bool operator <(const struct SFileListEntry& other) const + { + if (IsDirectory != other.IsDirectory) + return IsDirectory; + + return FullName.lower_ignore_case(other.FullName); + } +}; + + +//! Implementation of a file list +class CFileList : public IFileList +{ +public: + + // CFileList methods + + //! Constructor + /** \param path The path of this file archive */ + CFileList(const io::path& path, bool ignoreCase, bool ignorePaths); + + //! Destructor + virtual ~CFileList(); + + //! Add as a file or folder to the list + /** \param fullPath The file name including path, up to the root of the file list. + \param isDirectory True if this is a directory rather than a file. + \param offset The offset where the file is stored in an archive + \param size The size of the file in bytes. + \param id The ID of the file in the archive which owns it */ + virtual u32 addItem(const io::path& fullPath, u32 offset, u32 size, bool isDirectory, u32 id=0); + + //! Sorts the file list. You should call this after adding any items to the file list + virtual void sort(); + + //! Returns the amount of files in the filelist. + virtual u32 getFileCount() const; + + //! Gets the name of a file in the list, based on an index. + virtual const io::path& getFileName(u32 index) const; + + //! Gets the full name of a file in the list, path included, based on an index. + virtual const io::path& getFullFileName(u32 index) const; + + //! Returns the ID of a file in the file list, based on an index. + virtual u32 getID(u32 index) const; + + //! Returns true if the file is a directory + virtual bool isDirectory(u32 index) const; + + //! Returns the size of a file + virtual u32 getFileSize(u32 index) const; + + //! Returns the offest of a file + virtual u32 getFileOffset(u32 index) const; + + //! Searches for a file or folder within the list, returns the index + virtual s32 findFile(const io::path& filename, bool isFolder) const; + + //! Returns the base path of the file list + virtual const io::path& getPath() const; + +protected: + + //! Ignore paths when adding or searching for files + bool IgnorePaths; + + //! Ignore case when adding or searching for files + bool IgnoreCase; + + //! Path to the file list + io::path Path; + + //! List of files + core::array Files; +}; + + +} // end namespace irr +} // end namespace io + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.cpp new file mode 100644 index 0000000..0358480 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.cpp @@ -0,0 +1,1078 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#include "CFileSystem.h" +#include "IReadFile.h" +#include "IWriteFile.h" +#include "CZipReader.h" +#include "CMountPointReader.h" +#include "CPakReader.h" +#include "CNPKReader.h" +#include "CTarReader.h" +#include "CWADReader.h" +#include "CFileList.h" +#include "CXMLReader.h" +#include "CXMLWriter.h" +#include "stdio.h" +#include "os.h" +#include "CAttributes.h" +#include "CMemoryFile.h" +#include "CLimitReadFile.h" +#include "irrList.h" + +#if defined (_IRR_WINDOWS_API_) + #if !defined ( _WIN32_WCE ) + #include // for _chdir + #include // for _access + #include + #endif +#else + #if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_)) + #include + #include + #include + #include + #include + #include + #include + #include + #endif +#endif + +namespace irr +{ +namespace io +{ + +//! constructor +CFileSystem::CFileSystem() +{ + #ifdef _DEBUG + setDebugName("CFileSystem"); + #endif + + setFileListSystem(FILESYSTEM_NATIVE); + //! reset current working directory + getWorkingDirectory(); + +#ifdef __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ + ArchiveLoader.push_back(new CArchiveLoaderPAK(this)); +#endif + +#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ + ArchiveLoader.push_back(new CArchiveLoaderNPK(this)); +#endif + +#ifdef __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ + ArchiveLoader.push_back(new CArchiveLoaderTAR(this)); +#endif + +#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ + ArchiveLoader.push_back(new CArchiveLoaderWAD(this)); +#endif + +#ifdef __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ + ArchiveLoader.push_back(new CArchiveLoaderMount(this)); +#endif + +#ifdef __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ + ArchiveLoader.push_back(new CArchiveLoaderZIP(this)); +#endif + +} + + +//! destructor +CFileSystem::~CFileSystem() +{ + u32 i; + + for ( i=0; i < FileArchives.size(); ++i) + { + FileArchives[i]->drop(); + } + + for ( i=0; i < ArchiveLoader.size(); ++i) + { + ArchiveLoader[i]->drop(); + } +} + + +//! opens a file for read access +IReadFile* CFileSystem::createAndOpenFile(const io::path& filename) +{ + IReadFile* file = 0; + u32 i; + + for (i=0; i< FileArchives.size(); ++i) + { + file = FileArchives[i]->createAndOpenFile(filename); + if (file) + return file; + } + + // Create the file using an absolute path so that it matches + // the scheme used by CNullDriver::getTexture(). + return createReadFile(getAbsolutePath(filename)); +} + + +//! Creates an IReadFile interface for treating memory like a file. +IReadFile* CFileSystem::createMemoryReadFile(void* memory, s32 len, + const io::path& fileName, bool deleteMemoryWhenDropped) +{ + if (!memory) + return 0; + else + return new CMemoryFile(memory, len, fileName, deleteMemoryWhenDropped); + } + + +//! Creates an IReadFile interface for reading files inside files +IReadFile* CFileSystem::createLimitReadFile(const io::path& fileName, + IReadFile* alreadyOpenedFile, long pos, long areaSize) +{ + if (!alreadyOpenedFile) + return 0; + else + return new CLimitReadFile(alreadyOpenedFile, pos, areaSize, fileName); +} + + +//! Creates an IReadFile interface for treating memory like a file. +IWriteFile* CFileSystem::createMemoryWriteFile(void* memory, s32 len, + const io::path& fileName, bool deleteMemoryWhenDropped) +{ + if (!memory) + return 0; + else + return new CMemoryFile(memory, len, fileName, deleteMemoryWhenDropped); +} + + +//! Opens a file for write access. +IWriteFile* CFileSystem::createAndWriteFile(const io::path& filename, bool append) +{ + return createWriteFile(filename, append); +} + + +//! Adds an external archive loader to the engine. +void CFileSystem::addArchiveLoader(IArchiveLoader* loader) +{ + if (!loader) + return; + + loader->grab(); + ArchiveLoader.push_back(loader); +} + +//! Returns the total number of archive loaders added. +u32 CFileSystem::getArchiveLoaderCount() const +{ + return ArchiveLoader.size(); +} + +//! Gets the archive loader by index. +IArchiveLoader* CFileSystem::getArchiveLoader(u32 index) const +{ + if (index < ArchiveLoader.size()) + return ArchiveLoader[index]; + else + return 0; +} + +//! move the hirarchy of the filesystem. moves sourceIndex relative up or down +bool CFileSystem::moveFileArchive(u32 sourceIndex, s32 relative) +{ + bool r = false; + const s32 dest = (s32) sourceIndex + relative; + const s32 dir = relative < 0 ? -1 : 1; + const s32 sourceEnd = ((s32) FileArchives.size() ) - 1; + IFileArchive *t; + + for (s32 s = (s32) sourceIndex;s != dest; s += dir) + { + if (s < 0 || s > sourceEnd || s + dir < 0 || s + dir > sourceEnd) + continue; + + t = FileArchives[s + dir]; + FileArchives[s + dir] = FileArchives[s]; + FileArchives[s] = t; + r = true; + } + return r; +} + + +//! Adds an archive to the file system. +bool CFileSystem::addFileArchive(const io::path& filename, bool ignoreCase, + bool ignorePaths, E_FILE_ARCHIVE_TYPE archiveType, + const core::stringc& password, + IFileArchive** retArchive) +{ + IFileArchive* archive = 0; + bool ret = false; + + // see if archive is already added + if (changeArchivePassword(filename, password, retArchive)) + return true; + + s32 i; + + // do we know what type it should be? + if (archiveType == EFAT_UNKNOWN || archiveType == EFAT_FOLDER) + { + // try to load archive based on file name + for (i = ArchiveLoader.size()-1; i >=0 ; --i) + { + if (ArchiveLoader[i]->isALoadableFileFormat(filename)) + { + archive = ArchiveLoader[i]->createArchive(filename, ignoreCase, ignorePaths); + if (archive) + break; + } + } + + // try to load archive based on content + if (!archive) + { + io::IReadFile* file = createAndOpenFile(filename); + if (file) + { + for (i = ArchiveLoader.size()-1; i >= 0; --i) + { + file->seek(0); + if (ArchiveLoader[i]->isALoadableFileFormat(file)) + { + file->seek(0); + archive = ArchiveLoader[i]->createArchive(file, ignoreCase, ignorePaths); + if (archive) + break; + } + } + file->drop(); + } + } + } + else + { + // try to open archive based on archive loader type + + io::IReadFile* file = 0; + + for (i = ArchiveLoader.size()-1; i >= 0; --i) + { + if (ArchiveLoader[i]->isALoadableFileFormat(archiveType)) + { + // attempt to open file + if (!file) + file = createAndOpenFile(filename); + + // is the file open? + if (file) + { + // attempt to open archive + file->seek(0); + if (ArchiveLoader[i]->isALoadableFileFormat(file)) + { + file->seek(0); + archive = ArchiveLoader[i]->createArchive(file, ignoreCase, ignorePaths); + if (archive) + break; + } + } + else + { + // couldn't open file + break; + } + } + } + + // if open, close the file + if (file) + file->drop(); + } + + if (archive) + { + FileArchives.push_back(archive); + if (password.size()) + archive->Password=password; + if (retArchive) + *retArchive = archive; + ret = true; + } + else + { + os::Printer::log("Could not create archive for", filename, ELL_ERROR); + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +// don't expose! +bool CFileSystem::changeArchivePassword(const path& filename, + const core::stringc& password, + IFileArchive** archive) +{ + for (s32 idx = 0; idx < (s32)FileArchives.size(); ++idx) + { + // TODO: This should go into a path normalization method + // We need to check for directory names with trailing slash and without + const path absPath = getAbsolutePath(filename); + const path arcPath = FileArchives[idx]->getFileList()->getPath(); + if ((absPath == arcPath) || ((absPath+_IRR_TEXT("/")) == arcPath)) + { + if (password.size()) + FileArchives[idx]->Password=password; + if (archive) + *archive = FileArchives[idx]; + return true; + } + } + + return false; +} + +bool CFileSystem::addFileArchive(IReadFile* file, bool ignoreCase, + bool ignorePaths, E_FILE_ARCHIVE_TYPE archiveType, + const core::stringc& password, IFileArchive** retArchive) +{ + if (!file || archiveType == EFAT_FOLDER) + return false; + + if (file) + { + if (changeArchivePassword(file->getFileName(), password, retArchive)) + return true; + + IFileArchive* archive = 0; + s32 i; + + if (archiveType == EFAT_UNKNOWN) + { + // try to load archive based on file name + for (i = ArchiveLoader.size()-1; i >=0 ; --i) + { + if (ArchiveLoader[i]->isALoadableFileFormat(file->getFileName())) + { + archive = ArchiveLoader[i]->createArchive(file, ignoreCase, ignorePaths); + if (archive) + break; + } + } + + // try to load archive based on content + if (!archive) + { + for (i = ArchiveLoader.size()-1; i >= 0; --i) + { + file->seek(0); + if (ArchiveLoader[i]->isALoadableFileFormat(file)) + { + file->seek(0); + archive = ArchiveLoader[i]->createArchive(file, ignoreCase, ignorePaths); + if (archive) + break; + } + } + } + } + else + { + // try to open archive based on archive loader type + for (i = ArchiveLoader.size()-1; i >= 0; --i) + { + if (ArchiveLoader[i]->isALoadableFileFormat(archiveType)) + { + // attempt to open archive + file->seek(0); + if (ArchiveLoader[i]->isALoadableFileFormat(file)) + { + file->seek(0); + archive = ArchiveLoader[i]->createArchive(file, ignoreCase, ignorePaths); + if (archive) + break; + } + } + } + } + + if (archive) + { + FileArchives.push_back(archive); + if (password.size()) + archive->Password=password; + if (retArchive) + *retArchive = archive; + return true; + } + else + { + os::Printer::log("Could not create archive for", file->getFileName(), ELL_ERROR); + } + } + + return false; +} + + +//! Adds an archive to the file system. +bool CFileSystem::addFileArchive(IFileArchive* archive) +{ + for (u32 i=0; i < FileArchives.size(); ++i) + { + if (archive == FileArchives[i]) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + } + FileArchives.push_back(archive); + return true; +} + + +//! removes an archive from the file system. +bool CFileSystem::removeFileArchive(u32 index) +{ + bool ret = false; + if (index < FileArchives.size()) + { + FileArchives[index]->drop(); + FileArchives.erase(index); + ret = true; + } + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! removes an archive from the file system. +bool CFileSystem::removeFileArchive(const io::path& filename) +{ + const path absPath = getAbsolutePath(filename); + for (u32 i=0; i < FileArchives.size(); ++i) + { + if (absPath == FileArchives[i]->getFileList()->getPath()) + return removeFileArchive(i); + } + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; +} + + +//! Removes an archive from the file system. +bool CFileSystem::removeFileArchive(const IFileArchive* archive) +{ + for (u32 i=0; i < FileArchives.size(); ++i) + { + if (archive == FileArchives[i]) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return removeFileArchive(i); + } + } + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; +} + + +//! gets an archive +u32 CFileSystem::getFileArchiveCount() const +{ + return FileArchives.size(); +} + + +IFileArchive* CFileSystem::getFileArchive(u32 index) +{ + return index < getFileArchiveCount() ? FileArchives[index] : 0; +} + + +//! Returns the string of the current working directory +const io::path& CFileSystem::getWorkingDirectory() +{ + EFileSystemType type = FileSystemType; + + if (type != FILESYSTEM_NATIVE) + { + type = FILESYSTEM_VIRTUAL; + } + else + { + #if defined(_IRR_WINDOWS_CE_PLATFORM_) + // does not need this + #elif defined(_IRR_WINDOWS_API_) + fschar_t tmp[_MAX_PATH]; + #if defined(_IRR_WCHAR_FILESYSTEM ) + _wgetcwd(tmp, _MAX_PATH); + WorkingDirectory[FILESYSTEM_NATIVE] = tmp; + WorkingDirectory[FILESYSTEM_NATIVE].replace(L'\\', L'/'); + #else + _getcwd(tmp, _MAX_PATH); + WorkingDirectory[FILESYSTEM_NATIVE] = tmp; + WorkingDirectory[FILESYSTEM_NATIVE].replace('\\', '/'); + #endif + #endif + + #if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_)) + + // getting the CWD is rather complex as we do not know the size + // so try it until the call was successful + // Note that neither the first nor the second parameter may be 0 according to POSIX + + #if defined(_IRR_WCHAR_FILESYSTEM ) + u32 pathSize=256; + wchar_t *tmpPath = new wchar_t[pathSize]; + while ((pathSize < (1<<16)) && !(wgetcwd(tmpPath,pathSize))) + { + delete [] tmpPath; + pathSize *= 2; + tmpPath = new char[pathSize]; + } + if (tmpPath) + { + WorkingDirectory[FILESYSTEM_NATIVE] = tmpPath; + delete [] tmpPath; + } + #else + u32 pathSize=256; + char *tmpPath = new char[pathSize]; + while ((pathSize < (1<<16)) && !(getcwd(tmpPath,pathSize))) + { + delete [] tmpPath; + pathSize *= 2; + tmpPath = new char[pathSize]; + } + if (tmpPath) + { + WorkingDirectory[FILESYSTEM_NATIVE] = tmpPath; + delete [] tmpPath; + } + #endif + #endif + + WorkingDirectory[type].validate(); + } + + return WorkingDirectory[type]; +} + + +//! Changes the current Working Directory to the given string. +bool CFileSystem::changeWorkingDirectoryTo(const io::path& newDirectory) +{ + bool success=false; + + if (FileSystemType != FILESYSTEM_NATIVE) + { + WorkingDirectory[FILESYSTEM_VIRTUAL] = newDirectory; + // is this empty string constant really intended? + flattenFilename(WorkingDirectory[FILESYSTEM_VIRTUAL], _IRR_TEXT("")); + success = true; + } + else + { + WorkingDirectory[FILESYSTEM_NATIVE] = newDirectory; + +#if defined(_IRR_WINDOWS_CE_PLATFORM_) + success = true; +#elif defined(_MSC_VER) + #if defined(_IRR_WCHAR_FILESYSTEM) + success = (_wchdir(newDirectory.c_str()) == 0); + #else + success = (_chdir(newDirectory.c_str()) == 0); + #endif +#else + #if defined(_IRR_WCHAR_FILESYSTEM) + success = (_wchdir(newDirectory.c_str()) == 0); + #else + success = (chdir(newDirectory.c_str()) == 0); + #endif +#endif + } + + return success; +} + + +io::path CFileSystem::getAbsolutePath(const io::path& filename) const +{ +#if defined(_IRR_WINDOWS_CE_PLATFORM_) + return filename; +#elif defined(_IRR_WINDOWS_API_) + fschar_t *p=0; + fschar_t fpath[_MAX_PATH]; + #if defined(_IRR_WCHAR_FILESYSTEM ) + p = _wfullpath(fpath, filename.c_str(), _MAX_PATH); + core::stringw tmp(p); + tmp.replace(L'\\', L'/'); + #else + p = _fullpath(fpath, filename.c_str(), _MAX_PATH); + core::stringc tmp(p); + tmp.replace('\\', '/'); + #endif + return tmp; +#elif (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_)) + c8* p=0; + c8 fpath[4096]; + fpath[0]=0; + p = realpath(filename.c_str(), fpath); + if (!p) + { + // content in fpath is unclear at this point + if (!fpath[0]) // seems like fpath wasn't altered, use our best guess + { + io::path tmp(filename); + return flattenFilename(tmp); + } + else + return io::path(fpath); + } + if (filename[filename.size()-1]=='/') + return io::path(p)+_IRR_TEXT("/"); + else + return io::path(p); +#else + return io::path(filename); +#endif +} + + +//! returns the directory part of a filename, i.e. all until the first +//! slash or backslash, excluding it. If no directory path is prefixed, a '.' +//! is returned. +io::path CFileSystem::getFileDir(const io::path& filename) const +{ + // find last forward or backslash + s32 lastSlash = filename.findLast('/'); + const s32 lastBackSlash = filename.findLast('\\'); + lastSlash = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; + + if ((u32)lastSlash < filename.size()) + return filename.subString(0, lastSlash); + else + return _IRR_TEXT("."); +} + + +//! returns the base part of a filename, i.e. all except for the directory +//! part. If no directory path is prefixed, the full name is returned. +io::path CFileSystem::getFileBasename(const io::path& filename, bool keepExtension) const +{ + // find last forward or backslash + s32 lastSlash = filename.findLast('/'); + const s32 lastBackSlash = filename.findLast('\\'); + lastSlash = core::max_(lastSlash, lastBackSlash); + + // get number of chars after last dot + s32 end = 0; + if (!keepExtension) + { + // take care to search only after last slash to check only for + // dots in the filename + end = filename.findLast('.'); + if (end == -1 || end < lastSlash) + end=0; + else + end = filename.size()-end; + } + + if ((u32)lastSlash < filename.size()) + return filename.subString(lastSlash+1, filename.size()-lastSlash-1-end); + else if (end != 0) + return filename.subString(0, filename.size()-end); + else + return filename; +} + + +//! flatten a path and file name for example: "/you/me/../." becomes "/you" +io::path& CFileSystem::flattenFilename(io::path& directory, const io::path& root) const +{ + directory.replace('\\', '/'); + if (directory.lastChar() != '/') + directory.append('/'); + + io::path dir; + io::path subdir; + + s32 lastpos = 0; + s32 pos = 0; + bool lastWasRealDir=false; + + while ((pos = directory.findNext('/', lastpos)) >= 0) + { + subdir = directory.subString(lastpos, pos - lastpos + 1); + + if (subdir == _IRR_TEXT("../")) + { + if (lastWasRealDir) + { + deletePathFromPath(dir, 2); + lastWasRealDir=(dir.size()!=0); + } + else + { + dir.append(subdir); + lastWasRealDir=false; + } + } + else if (subdir == _IRR_TEXT("/")) + { + dir = root; + } + else if (subdir != _IRR_TEXT("./")) + { + dir.append(subdir); + lastWasRealDir=true; + } + + lastpos = pos + 1; + } + directory = dir; + return directory; +} + + +//! Get the relative filename, relative to the given directory +path CFileSystem::getRelativeFilename(const path& filename, const path& directory) const +{ + if ( filename.empty() || directory.empty() ) + return filename; + + io::path path1, file, ext; + core::splitFilename(getAbsolutePath(filename), &path1, &file, &ext); + io::path path2(getAbsolutePath(directory)); + core::list list1, list2; + path1.split(list1, _IRR_TEXT("/\\"), 2); + path2.split(list2, _IRR_TEXT("/\\"), 2); + u32 i=0; + core::list::ConstIterator it1,it2; + it1=list1.begin(); + it2=list2.begin(); + + #if defined (_IRR_WINDOWS_API_) + fschar_t partition1 = 0, partition2 = 0; + io::path prefix1, prefix2; + if ( it1 != list1.end() ) + prefix1 = *it1; + if ( it2 != list2.end() ) + prefix2 = *it2; + if ( prefix1.size() > 1 && prefix1[1] == _IRR_TEXT(':') ) + partition1 = core::locale_lower(prefix1[0]); + if ( prefix2.size() > 1 && prefix2[1] == _IRR_TEXT(':') ) + partition2 = core::locale_lower(prefix2[0]); + + // must have the same prefix or we can't resolve it to a relative filename + if ( partition1 != partition2 ) + { + return filename; + } + #endif + + + for (; iaddItem(Path + c_file.name, 0, c_file.size, (_A_SUBDIR & c_file.attrib) != 0, 0); + } + while( _tfindnext( hFile, &c_file ) == 0 ); + + _findclose( hFile ); + } + #endif + + //TODO add drives + //entry.Name = "E:\\"; + //entry.isDirectory = true; + //Files.push_back(entry); + #endif + + // -------------------------------------------- + //! Linux version + #if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_)) + + + r = new CFileList(Path, false, false); + + r->addItem(Path + _IRR_TEXT(".."), 0, 0, true, 0); + + //! We use the POSIX compliant methods instead of scandir + DIR* dirHandle=opendir(Path.c_str()); + if (dirHandle) + { + struct dirent *dirEntry; + while ((dirEntry=readdir(dirHandle))) + { + u32 size = 0; + bool isDirectory = false; + + if((strcmp(dirEntry->d_name, ".")==0) || + (strcmp(dirEntry->d_name, "..")==0)) + { + continue; + } + struct stat buf; + if (stat(dirEntry->d_name, &buf)==0) + { + size = buf.st_size; + isDirectory = S_ISDIR(buf.st_mode); + } + #if !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__CYGWIN__) + // only available on some systems + else + { + isDirectory = dirEntry->d_type == DT_DIR; + } + #endif + + r->addItem(Path + dirEntry->d_name, 0, size, isDirectory, 0); + } + closedir(dirHandle); + } + #endif + } + else + { + //! create file list for the virtual filesystem + r = new CFileList(Path, false, false); + + //! add relative navigation + SFileListEntry e2; + SFileListEntry e3; + + //! PWD + r->addItem(Path + _IRR_TEXT("."), 0, 0, true, 0); + + //! parent + r->addItem(Path + _IRR_TEXT(".."), 0, 0, true, 0); + + //! merge archives + for (u32 i=0; i < FileArchives.size(); ++i) + { + const IFileList *merge = FileArchives[i]->getFileList(); + + for (u32 j=0; j < merge->getFileCount(); ++j) + { + if (core::isInSameDirectory(Path, merge->getFullFileName(j)) == 0) + { + r->addItem(merge->getFullFileName(j), merge->getFileOffset(j), merge->getFileSize(j), merge->isDirectory(j), 0); + } + } + } + } + + if (r) + r->sort(); + return r; +} + +//! Creates an empty filelist +IFileList* CFileSystem::createEmptyFileList(const io::path& path, bool ignoreCase, bool ignorePaths) +{ + return new CFileList(path, ignoreCase, ignorePaths); +} + + +//! determines if a file exists and would be able to be opened. +bool CFileSystem::existFile(const io::path& filename) const +{ + for (u32 i=0; i < FileArchives.size(); ++i) + if (FileArchives[i]->getFileList()->findFile(filename)!=-1) + return true; + +#if defined(_IRR_WINDOWS_CE_PLATFORM_) +#if defined(_IRR_WCHAR_FILESYSTEM) + HANDLE hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); +#else + HANDLE hFile = CreateFileW(core::stringw(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); +#endif + if (hFile == INVALID_HANDLE_VALUE) + return false; + else + { + CloseHandle(hFile); + return true; + } +#else + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; +#if defined(_MSC_VER) + #if defined(_IRR_WCHAR_FILESYSTEM) + return (_waccess(filename.c_str(), 0) != -1); + #else + return (_access(filename.c_str(), 0) != -1); + #endif +#elif defined(F_OK) + #if defined(_IRR_WCHAR_FILESYSTEM) + return (_waccess(filename.c_str(), F_OK) != -1); + #else + return (access(filename.c_str(), F_OK) != -1); + #endif +#else + return (access(filename.c_str(), 0) != -1); +#endif +#endif +} + + +//! Creates a XML Reader from a file. +IXMLReader* CFileSystem::createXMLReader(const io::path& filename) +{ + IReadFile* file = createAndOpenFile(filename); + if (!file) + return 0; + + IXMLReader* reader = createXMLReader(file); + file->drop(); + return reader; +} + + +//! Creates a XML Reader from a file. +IXMLReader* CFileSystem::createXMLReader(IReadFile* file) +{ + if (!file) + return 0; + + return createIXMLReader(file); +} + + +//! Creates a XML Reader from a file. +IXMLReaderUTF8* CFileSystem::createXMLReaderUTF8(const io::path& filename) +{ + IReadFile* file = createAndOpenFile(filename); + if (!file) + return 0; + + IXMLReaderUTF8* reader = createIXMLReaderUTF8(file); + file->drop(); + return reader; +} + + +//! Creates a XML Reader from a file. +IXMLReaderUTF8* CFileSystem::createXMLReaderUTF8(IReadFile* file) +{ + if (!file) + return 0; + + return createIXMLReaderUTF8(file); +} + + +//! Creates a XML Writer from a file. +IXMLWriter* CFileSystem::createXMLWriter(const io::path& filename) +{ + IWriteFile* file = createAndWriteFile(filename); + IXMLWriter* writer = 0; + if (file) + { + writer = createXMLWriter(file); + file->drop(); + } + return writer; +} + + +//! Creates a XML Writer from a file. +IXMLWriter* CFileSystem::createXMLWriter(IWriteFile* file) +{ + return new CXMLWriter(file); +} + + +//! creates a filesystem which is able to open files from the ordinary file system, +//! and out of zipfiles, which are able to be added to the filesystem. +IFileSystem* createFileSystem() +{ + return new CFileSystem(); +} + + +//! Creates a new empty collection of attributes, usable for serialization and more. +IAttributes* CFileSystem::createEmptyAttributes(video::IVideoDriver* driver) +{ + return new CAttributes(driver); +} + + +} // end namespace irr +} // end namespace io + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.h new file mode 100644 index 0000000..0af5356 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CFileSystem.h @@ -0,0 +1,173 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_FILE_SYSTEM_H_INCLUDED__ +#define __C_FILE_SYSTEM_H_INCLUDED__ + +#include "IFileSystem.h" +#include "irrArray.h" + +namespace irr +{ +namespace io +{ + + class CZipReader; + class CPakReader; + class CMountPointReader; + +/*! + FileSystem which uses normal files and one zipfile +*/ +class CFileSystem : public IFileSystem +{ +public: + + //! constructor + CFileSystem(); + + //! destructor + virtual ~CFileSystem(); + + //! opens a file for read access + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! Creates an IReadFile interface for accessing memory like a file. + virtual IReadFile* createMemoryReadFile(void* memory, s32 len, const io::path& fileName, bool deleteMemoryWhenDropped = false); + + //! Creates an IReadFile interface for accessing files inside files + virtual IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize); + + //! Creates an IWriteFile interface for accessing memory like a file. + virtual IWriteFile* createMemoryWriteFile(void* memory, s32 len, const io::path& fileName, bool deleteMemoryWhenDropped=false); + + //! Opens a file for write access. + virtual IWriteFile* createAndWriteFile(const io::path& filename, bool append=false); + + //! Adds an archive to the file system. + virtual bool addFileArchive(const io::path& filename, + bool ignoreCase = true, bool ignorePaths = true, + E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN, + const core::stringc& password="", + IFileArchive** retArchive = 0); + + //! Adds an archive to the file system. + virtual bool addFileArchive(IReadFile* file, bool ignoreCase=true, + bool ignorePaths=true, + E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN, + const core::stringc& password="", + IFileArchive** retArchive = 0); + + //! Adds an archive to the file system. + virtual bool addFileArchive(IFileArchive* archive); + + //! move the hirarchy of the filesystem. moves sourceIndex relative up or down + virtual bool moveFileArchive(u32 sourceIndex, s32 relative); + + //! Adds an external archive loader to the engine. + virtual void addArchiveLoader(IArchiveLoader* loader); + + //! Returns the total number of archive loaders added. + virtual u32 getArchiveLoaderCount() const; + + //! Gets the archive loader by index. + virtual IArchiveLoader* getArchiveLoader(u32 index) const; + + //! gets the file archive count + virtual u32 getFileArchiveCount() const; + + //! gets an archive + virtual IFileArchive* getFileArchive(u32 index); + + //! removes an archive from the file system. + virtual bool removeFileArchive(u32 index); + + //! removes an archive from the file system. + virtual bool removeFileArchive(const io::path& filename); + + //! Removes an archive from the file system. + virtual bool removeFileArchive(const IFileArchive* archive); + + //! Returns the string of the current working directory + virtual const io::path& getWorkingDirectory(); + + //! Changes the current Working Directory to the string given. + //! The string is operating system dependent. Under Windows it will look + //! like this: "drive:\directory\sudirectory\" + virtual bool changeWorkingDirectoryTo(const io::path& newDirectory); + + //! Converts a relative path to an absolute (unique) path, resolving symbolic links + virtual io::path getAbsolutePath(const io::path& filename) const; + + //! Returns the directory a file is located in. + /** \param filename: The file to get the directory from */ + virtual io::path getFileDir(const io::path& filename) const; + + //! Returns the base part of a filename, i.e. the name without the directory + //! part. If no directory is prefixed, the full name is returned. + /** \param filename: The file to get the basename from */ + virtual io::path getFileBasename(const io::path& filename, bool keepExtension=true) const; + + //! flatten a path and file name for example: "/you/me/../." becomes "/you" + virtual io::path& flattenFilename( io::path& directory, const io::path& root = "/" ) const; + + //! Get the relative filename, relative to the given directory + virtual path getRelativeFilename(const path& filename, const path& directory) const; + + virtual EFileSystemType setFileListSystem(EFileSystemType listType); + + //! Creates a list of files and directories in the current working directory + //! and returns it. + virtual IFileList* createFileList(); + + //! Creates an empty filelist + virtual IFileList* createEmptyFileList(const io::path& path, bool ignoreCase, bool ignorePaths); + + //! determines if a file exists and would be able to be opened. + virtual bool existFile(const io::path& filename) const; + + //! Creates a XML Reader from a file. + virtual IXMLReader* createXMLReader(const io::path& filename); + + //! Creates a XML Reader from a file. + virtual IXMLReader* createXMLReader(IReadFile* file); + + //! Creates a XML Reader from a file. + virtual IXMLReaderUTF8* createXMLReaderUTF8(const io::path& filename); + + //! Creates a XML Reader from a file. + virtual IXMLReaderUTF8* createXMLReaderUTF8(IReadFile* file); + + //! Creates a XML Writer from a file. + virtual IXMLWriter* createXMLWriter(const io::path& filename); + + //! Creates a XML Writer from a file. + virtual IXMLWriter* createXMLWriter(IWriteFile* file); + + //! Creates a new empty collection of attributes, usable for serialization and more. + virtual IAttributes* createEmptyAttributes(video::IVideoDriver* driver); + +private: + + // don't expose, needs refactoring + bool changeArchivePassword(const path& filename, + const core::stringc& password, + IFileArchive** archive = 0); + + //! Currently used FileSystemType + EFileSystemType FileSystemType; + //! WorkingDirectory for Native and Virtual filesystems + io::path WorkingDirectory [2]; + //! currently attached ArchiveLoaders + core::array ArchiveLoader; + //! currently attached Archives + core::array FileArchives; +}; + + +} // end namespace irr +} // end namespace io + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.cpp new file mode 100644 index 0000000..5a451cd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.cpp @@ -0,0 +1,531 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIButton.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIButton::CGUIButton(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool noclip) +: IGUIButton(environment, parent, id, rectangle), + SpriteBank(0), OverrideFont(0), Image(0), PressedImage(0), + ClickTime(0), HoverTime(0), FocusTime(0), + IsPushButton(false), Pressed(false), + UseAlphaChannel(false), DrawBorder(true), ScaleImage(false) +{ + #ifdef _DEBUG + setDebugName("CGUIButton"); + #endif + setNotClipped(noclip); + + // Initialize the sprites. + for (u32 i=0; idrop(); + + if (Image) + Image->drop(); + + if (PressedImage) + PressedImage->drop(); + + if (SpriteBank) + SpriteBank->drop(); +} + + +//! Sets if the images should be scaled to fit the button +void CGUIButton::setScaleImage(bool scaleImage) +{ + ScaleImage = scaleImage; +} + + +//! Returns whether the button scale the used images +bool CGUIButton::isScalingImage() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ScaleImage; +} + + +//! Sets if the button should use the skin to draw its border +void CGUIButton::setDrawBorder(bool border) +{ + DrawBorder = border; +} + + +void CGUIButton::setSpriteBank(IGUISpriteBank* sprites) +{ + if (sprites) + sprites->grab(); + + if (SpriteBank) + SpriteBank->drop(); + + SpriteBank = sprites; +} + + +void CGUIButton::setSprite(EGUI_BUTTON_STATE state, s32 index, video::SColor color, bool loop) +{ + if (SpriteBank) + { + ButtonSprites[(u32)state].Index = index; + ButtonSprites[(u32)state].Color = color; + ButtonSprites[(u32)state].Loop = loop; + } + else + { + ButtonSprites[(u32)state].Index = -1; + } +} + + +//! called if an event happened. +bool CGUIButton::OnEvent(const SEvent& event) +{ + if (!isEnabled()) + return IGUIElement::OnEvent(event); + + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) + { + if (!IsPushButton) + setPressed(true); + else + setPressed(!Pressed); + + return true; + } + if (Pressed && !IsPushButton && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + setPressed(false); + return true; + } + else + if (!event.KeyInput.PressedDown && Pressed && + (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) + { + + if (!IsPushButton) + setPressed(false); + + if (Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.Caller == this) + { + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (!IsPushButton) + setPressed(false); + FocusTime = os::Timer::getTime(); + } + else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED) + { + FocusTime = os::Timer::getTime(); + } + else if (event.GUIEvent.EventType == EGET_ELEMENT_HOVERED || event.GUIEvent.EventType == EGET_ELEMENT_LEFT) + { + HoverTime = os::Timer::getTime(); + } + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + if (Environment->hasFocus(this) && + !AbsoluteClippingRect.isPointInside(core::position2d(event.MouseInput.X, event.MouseInput.Y))) + { + Environment->removeFocus(this); + return false; + } + + if (!IsPushButton) + setPressed(true); + + Environment->setFocus(this); + return true; + } + else + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + { + bool wasPressed = Pressed; + + if ( !AbsoluteClippingRect.isPointInside( core::position2d(event.MouseInput.X, event.MouseInput.Y ) ) ) + { + if (!IsPushButton) + setPressed(false); + return true; + } + + if (!IsPushButton) + setPressed(false); + else + { + setPressed(!Pressed); + } + + if ((!IsPushButton && wasPressed && Parent) || + (IsPushButton && wasPressed != Pressed)) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_BUTTON_CLICKED; + Parent->OnEvent(newEvent); + } + + return true; + } + break; + default: + break; + } + + return Parent ? Parent->OnEvent(event) : false; +} + + +//! draws the element and its children +void CGUIButton::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + + // todo: move sprite up and text down if the pressed state has a sprite + const core::position2di spritePos = AbsoluteRect.getCenter(); + + if (!Pressed) + { + if (DrawBorder) + skin->draw3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect); + + if (Image) + { + core::position2d pos = spritePos; + pos.X -= ImageRect.getWidth() / 2; + pos.Y -= ImageRect.getHeight() / 2; + + driver->draw2DImage(Image, + ScaleImage? AbsoluteRect : + core::recti(pos, ImageRect.getSize()), + ImageRect, &AbsoluteClippingRect, + 0, UseAlphaChannel); + } + } + else + { + if (DrawBorder) + skin->draw3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect); + + if (PressedImage) + { + core::position2d pos = spritePos; + pos.X -= PressedImageRect.getWidth() / 2; + pos.Y -= PressedImageRect.getHeight() / 2; + + if (Image == PressedImage && PressedImageRect == ImageRect) + { + pos.X += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X); + pos.Y += skin->getSize(EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y); + } + driver->draw2DImage(PressedImage, + ScaleImage? AbsoluteRect : + core::recti(pos, PressedImageRect.getSize()), + PressedImageRect, &AbsoluteClippingRect, + 0, UseAlphaChannel); + } + } + + if (SpriteBank) + { + // pressed / unpressed animation + u32 state = Pressed ? (u32)EGBS_BUTTON_DOWN : (u32)EGBS_BUTTON_UP; + if (ButtonSprites[state].Index != -1) + { + SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos, + &AbsoluteClippingRect, ButtonSprites[state].Color, ClickTime, os::Timer::getTime(), + ButtonSprites[state].Loop, true); + } + + // focused / unfocused animation + state = Environment->hasFocus(this) ? (u32)EGBS_BUTTON_FOCUSED : (u32)EGBS_BUTTON_NOT_FOCUSED; + if (ButtonSprites[state].Index != -1) + { + SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos, + &AbsoluteClippingRect, ButtonSprites[state].Color, FocusTime, os::Timer::getTime(), + ButtonSprites[state].Loop, true); + } + + // mouse over / off animation + if (isEnabled()) + { + state = Environment->getHovered() == this ? (u32)EGBS_BUTTON_MOUSE_OVER : (u32)EGBS_BUTTON_MOUSE_OFF; + if (ButtonSprites[state].Index != -1) + { + SpriteBank->draw2DSprite(ButtonSprites[state].Index, spritePos, + &AbsoluteClippingRect, ButtonSprites[state].Color, HoverTime, os::Timer::getTime(), + ButtonSprites[state].Loop, true); + } + } + } + + if (Text.size()) + { + IGUIFont* font = getActiveFont(); + + core::rect rect = AbsoluteRect; + if (Pressed) + { + rect.UpperLeftCorner.X += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_X); + rect.UpperLeftCorner.Y += skin->getSize(EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y); + } + + if (font) + font->draw(Text.c_str(), rect, + skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), + true, true, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! sets another skin independent font. if this is set to zero, the button uses the font of the skin. +void CGUIButton::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont == font) + return; + + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); +} + +//! Gets the override font (if any) +IGUIFont * CGUIButton::getOverrideFont() const +{ + return OverrideFont; +} + +//! Get the font which is used right now for drawing +IGUIFont* CGUIButton::getActiveFont() const +{ + if ( OverrideFont ) + return OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (skin) + return skin->getFont(EGDF_BUTTON); + return 0; +} + +//! Sets an image which should be displayed on the button when it is in normal state. +void CGUIButton::setImage(video::ITexture* image) +{ + if (image) + image->grab(); + if (Image) + Image->drop(); + + Image = image; + if (image) + ImageRect = core::rect(core::position2d(0,0), image->getOriginalSize()); + + if (!PressedImage) + setPressedImage(Image); +} + + +//! Sets the image which should be displayed on the button when it is in its normal state. +void CGUIButton::setImage(video::ITexture* image, const core::rect& pos) +{ + setImage(image); + ImageRect = pos; +} + + +//! Sets an image which should be displayed on the button when it is in pressed state. +void CGUIButton::setPressedImage(video::ITexture* image) +{ + if (image) + image->grab(); + + if (PressedImage) + PressedImage->drop(); + + PressedImage = image; + if (image) + PressedImageRect = core::rect(core::position2d(0,0), image->getOriginalSize()); +} + + +//! Sets the image which should be displayed on the button when it is in its pressed state. +void CGUIButton::setPressedImage(video::ITexture* image, const core::rect& pos) +{ + setPressedImage(image); + PressedImageRect = pos; +} + + +//! Sets if the button should behave like a push button. Which means it +//! can be in two states: Normal or Pressed. With a click on the button, +//! the user can change the state of the button. +void CGUIButton::setIsPushButton(bool isPushButton) +{ + IsPushButton = isPushButton; +} + + +//! Returns if the button is currently pressed +bool CGUIButton::isPressed() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Pressed; +} + + +//! Sets the pressed state of the button if this is a pushbutton +void CGUIButton::setPressed(bool pressed) +{ + if (Pressed != pressed) + { + ClickTime = os::Timer::getTime(); + Pressed = pressed; + } +} + + +//! Returns whether the button is a push button +bool CGUIButton::isPushButton() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsPushButton; +} + + +//! Sets if the alpha channel should be used for drawing images on the button (default is false) +void CGUIButton::setUseAlphaChannel(bool useAlphaChannel) +{ + UseAlphaChannel = useAlphaChannel; +} + + +//! Returns if the alpha channel should be used for drawing images on the button +bool CGUIButton::isAlphaChannelUsed() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return UseAlphaChannel; +} + + +bool CGUIButton::isDrawingBorder() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return DrawBorder; +} + + +//! Writes attributes of the element. +void CGUIButton::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIButton::serializeAttributes(out,options); + + out->addBool ("PushButton", IsPushButton ); + if (IsPushButton) + out->addBool("Pressed", Pressed); + + out->addTexture ("Image", Image); + out->addRect ("ImageRect", ImageRect); + out->addTexture ("PressedImage", PressedImage); + out->addRect ("PressedImageRect", PressedImageRect); + + out->addBool ("UseAlphaChannel", isAlphaChannelUsed()); + out->addBool ("Border", isDrawingBorder()); + out->addBool ("ScaleImage", isScalingImage()); + + // out->addString ("OverrideFont", OverrideFont); +} + + +//! Reads attributes of the element +void CGUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIButton::deserializeAttributes(in,options); + + IsPushButton = in->getAttributeAsBool("PushButton"); + Pressed = IsPushButton ? in->getAttributeAsBool("Pressed") : false; + + core::rect rec = in->getAttributeAsRect("ImageRect"); + if (rec.isValid()) + setImage( in->getAttributeAsTexture("Image"), rec); + else + setImage( in->getAttributeAsTexture("Image") ); + + rec = in->getAttributeAsRect("PressedImageRect"); + if (rec.isValid()) + setPressedImage( in->getAttributeAsTexture("PressedImage"), rec); + else + setPressedImage( in->getAttributeAsTexture("PressedImage") ); + + setDrawBorder(in->getAttributeAsBool("Border")); + setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel")); + setScaleImage(in->getAttributeAsBool("ScaleImage")); + + // setOverrideFont(in->getAttributeAsString("OverrideFont")); + + updateAbsolutePosition(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.d new file mode 100644 index 0000000..357d4fb --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.d @@ -0,0 +1,2 @@ +CGUIButton.o: CGUIButton.cpp CGUIButton.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.h new file mode 100644 index 0000000..86e6954 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIButton.h @@ -0,0 +1,143 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_BUTTON_H_INCLUDED__ +#define __C_GUI_BUTTON_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIButton.h" +#include "IGUISpriteBank.h" +#include "SColor.h" + +namespace irr +{ +namespace gui +{ + + class CGUIButton : public IGUIButton + { + public: + + //! constructor + CGUIButton(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool noclip=false); + + //! destructor + virtual ~CGUIButton(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! sets another skin independent font. if this is set to zero, the button uses the font of the skin. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Gets the override font (if any) + virtual IGUIFont* getOverrideFont() const; + + //! Get the font which is used right now for drawing + virtual IGUIFont* getActiveFont() const; + + //! Sets an image which should be displayed on the button when it is in normal state. + virtual void setImage(video::ITexture* image=0); + + //! Sets an image which should be displayed on the button when it is in normal state. + virtual void setImage(video::ITexture* image, const core::rect& pos); + + //! Sets an image which should be displayed on the button when it is in pressed state. + virtual void setPressedImage(video::ITexture* image=0); + + //! Sets an image which should be displayed on the button when it is in pressed state. + virtual void setPressedImage(video::ITexture* image, const core::rect& pos); + + //! Sets the sprite bank used by the button + virtual void setSpriteBank(IGUISpriteBank* bank=0); + + //! Sets the animated sprite for a specific button state + /** \param index: Number of the sprite within the sprite bank, use -1 for no sprite + \param state: State of the button to set the sprite for + \param index: The sprite number from the current sprite bank + \param color: The color of the sprite + */ + virtual void setSprite(EGUI_BUTTON_STATE state, s32 index, + video::SColor color=video::SColor(255,255,255,255), bool loop=false); + + //! Sets if the button should behave like a push button. Which means it + //! can be in two states: Normal or Pressed. With a click on the button, + //! the user can change the state of the button. + virtual void setIsPushButton(bool isPushButton=true); + + //! Checks whether the button is a push button + virtual bool isPushButton() const; + + //! Sets the pressed state of the button if this is a pushbutton + virtual void setPressed(bool pressed=true); + + //! Returns if the button is currently pressed + virtual bool isPressed() const; + + //! Sets if the button should use the skin to draw its border + virtual void setDrawBorder(bool border=true); + + //! Checks if the button face and border are being drawn + virtual bool isDrawingBorder() const; + + //! Sets if the alpha channel should be used for drawing images on the button (default is false) + virtual void setUseAlphaChannel(bool useAlphaChannel=true); + + //! Checks if the alpha channel should be used for drawing images on the button + virtual bool isAlphaChannelUsed() const; + + //! Sets if the button should scale the button images to fit + virtual void setScaleImage(bool scaleImage=true); + + //! Checks whether the button scales the used images + virtual bool isScalingImage() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + struct ButtonSprite + { + s32 Index; + video::SColor Color; + bool Loop; + }; + + ButtonSprite ButtonSprites[EGBS_COUNT]; + + IGUISpriteBank* SpriteBank; + IGUIFont* OverrideFont; + + video::ITexture* Image; + video::ITexture* PressedImage; + + core::rect ImageRect; + core::rect PressedImageRect; + + u32 ClickTime, HoverTime, FocusTime; + + bool IsPushButton; + bool Pressed; + bool UseAlphaChannel; + bool DrawBorder; + bool ScaleImage; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_BUTTON_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.cpp new file mode 100644 index 0000000..6a38a28 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.cpp @@ -0,0 +1,205 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUICheckBox.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUICheckBox::CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUICheckBox(environment, parent, id, rectangle), checkTime(0), Pressed(false), Checked(checked) +{ + #ifdef _DEBUG + setDebugName("CGUICheckBox"); + #endif + + // this element can be tabbed into + setTabStop(true); + setTabOrder(-1); +} + + +//! called if an event happened. +bool CGUICheckBox::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) + { + Pressed = true; + return true; + } + else + if (Pressed && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + Pressed = false; + return true; + } + else + if (!event.KeyInput.PressedDown && Pressed && + (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE)) + { + Pressed = false; + if (Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + Checked = !Checked; + newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED; + Parent->OnEvent(newEvent); + } + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this) + Pressed = false; + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + Pressed = true; + checkTime = os::Timer::getTime(); + Environment->setFocus(this); + return true; + } + else + if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) + { + bool wasPressed = Pressed; + Environment->removeFocus(this); + Pressed = false; + + if (wasPressed && Parent) + { + if ( !AbsoluteClippingRect.isPointInside( core::position2d(event.MouseInput.X, event.MouseInput.Y) ) ) + { + Pressed = false; + return true; + } + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + Checked = !Checked; + newEvent.GUIEvent.EventType = EGET_CHECKBOX_CHANGED; + Parent->OnEvent(newEvent); + } + + return true; + } + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +//! draws the element and its children +void CGUICheckBox::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (skin) + { + const s32 height = skin->getSize(EGDS_CHECK_BOX_WIDTH); + + core::rect checkRect(AbsoluteRect.UpperLeftCorner.X, + ((AbsoluteRect.getHeight() - height) / 2) + AbsoluteRect.UpperLeftCorner.Y, + 0, 0); + + checkRect.LowerRightCorner.X = checkRect.UpperLeftCorner.X + height; + checkRect.LowerRightCorner.Y = checkRect.UpperLeftCorner.Y + height; + + EGUI_DEFAULT_COLOR col = EGDC_GRAY_EDITABLE; + if ( isEnabled() ) + col = Pressed ? EGDC_FOCUSED_EDITABLE : EGDC_EDITABLE; + skin->draw3DSunkenPane(this, skin->getColor(col), + false, true, checkRect, &AbsoluteClippingRect); + + if (Checked) + { + skin->drawIcon(this, EGDI_CHECK_BOX_CHECKED, checkRect.getCenter(), + checkTime, os::Timer::getTime(), false, &AbsoluteClippingRect); + } + if (Text.size()) + { + checkRect = AbsoluteRect; + checkRect.UpperLeftCorner.X += height + 5; + + IGUIFont* font = skin->getFont(); + if (font) + { + font->draw(Text.c_str(), checkRect, + skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), false, true, &AbsoluteClippingRect); + } + } + } + IGUIElement::draw(); +} + + +//! set if box is checked +void CGUICheckBox::setChecked(bool checked) +{ + Checked = checked; +} + + +//! returns if box is checked +bool CGUICheckBox::isChecked() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Checked; +} + + +//! Writes attributes of the element. +void CGUICheckBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUICheckBox::serializeAttributes(out,options); + out->addBool("Checked", Checked); +} + + +//! Reads attributes of the element +void CGUICheckBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Checked = in->getAttributeAsBool ("Checked"); + + IGUICheckBox::deserializeAttributes(in,options); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.d new file mode 100644 index 0000000..10b995d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.d @@ -0,0 +1,2 @@ +CGUICheckBox.o: CGUICheckBox.cpp CGUICheckBox.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.h new file mode 100644 index 0000000..09ed36b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUICheckBox.h @@ -0,0 +1,55 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_CHECKBOX_H_INCLUDED__ +#define __C_GUI_CHECKBOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUICheckBox.h" + +namespace irr +{ +namespace gui +{ + + class CGUICheckBox : public IGUICheckBox + { + public: + + //! constructor + CGUICheckBox(bool checked, IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! set if box is checked + virtual void setChecked(bool checked); + + //! returns if box is checked + virtual bool isChecked() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + u32 checkTime; + bool Pressed; + bool Checked; + }; + +} // end namespace gui +} // end namespace irr + +#endif // __C_GUI_CHECKBOX_H_INCLUDED__ + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.cpp new file mode 100644 index 0000000..0744ce9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.cpp @@ -0,0 +1,483 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIColorSelectDialog.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIStaticText.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "IFileList.h" +#include "os.h" +#include "fast_atof.h" + +namespace irr +{ +namespace gui +{ + +const s32 CSD_WIDTH = 350; +const s32 CSD_HEIGHT = 300; + +namespace +{ + +struct subElementPredefines +{ + const wchar_t *pre; + const wchar_t *init; + const wchar_t *post; + int x, y; + int range_down ,range_up; +}; + +static const subElementPredefines Template [] = +{ + { L"A:", L"0", 0,50,165, 0, 255 }, + { L"R:", L"0", 0,20,205, 0, 255 }, + { L"G:", L"0", 0,20,230, 0, 255 }, + { L"B:", L"0", 0,20,255, 0, 255 }, + { L"H:", L"0", L"°",80,205, 0, 360 }, + { L"S:", L"0", L"%",80,230, 0, 100 }, + { L"L:", L"0", L"%",80,255, 0, 100 }, +}; + +} + +//! constructor +CGUIColorSelectDialog::CGUIColorSelectDialog(const wchar_t* title, IGUIEnvironment* environment, IGUIElement* parent, s32 id) + : IGUIColorSelectDialog(environment, parent, id, + core::rect((parent->getAbsolutePosition().getWidth()-CSD_WIDTH)/2, + (parent->getAbsolutePosition().getHeight()-CSD_HEIGHT)/2, + (parent->getAbsolutePosition().getWidth()-CSD_WIDTH)/2+CSD_WIDTH, + (parent->getAbsolutePosition().getHeight()-CSD_HEIGHT)/2+CSD_HEIGHT)), + Dragging(false) +{ + #ifdef _DEBUG + IGUIElement::setDebugName("CGUIColorSelectDialog"); + #endif + + Text = title; + + IGUISkin* skin = Environment->getSkin(); + + const s32 buttonw = environment->getSkin()->getSize(EGDS_WINDOW_BUTTON_WIDTH); + const s32 posx = RelativeRect.getWidth() - buttonw - 4; + + CloseButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), + this, -1, L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close"); + if (skin && skin->getSpriteBank()) + { + CloseButton->setSpriteBank(skin->getSpriteBank()); + CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), skin->getColor(EGDC_WINDOW_SYMBOL)); + CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), skin->getColor(EGDC_WINDOW_SYMBOL)); + } + CloseButton->setSubElement(true); + CloseButton->setTabStop(false); + CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CloseButton->grab(); + + OKButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK"); + OKButton->setSubElement(true); + OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + OKButton->grab(); + + CancelButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel"); + CancelButton->setSubElement(true); + CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CancelButton->grab(); + + video::IVideoDriver* driver = Environment->getVideoDriver(); + ColorRing.Texture = driver->getTexture ( "#colorring" ); + if ( 0 == ColorRing.Texture ) + { + buildColorRing(core::dimension2d(128, 128), 1, + Environment->getSkin()->getColor(EGDC_3D_SHADOW)); + } + + core::rect r(20,20, 0,0); + + ColorRing.Control = Environment->addImage(ColorRing.Texture, r.UpperLeftCorner, true, this); + ColorRing.Control->setSubElement(true); + ColorRing.Control->grab(); + + for ( u32 i = 0; i != sizeof (Template) / sizeof ( subElementPredefines ); ++i ) + { + if ( Template[i].pre ) + { + r.UpperLeftCorner.X = Template[i].x; + r.UpperLeftCorner.Y = Template[i].y; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 15; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 20; + IGUIElement *t = Environment->addStaticText(Template[i].pre, r, false, false, this); + t->setSubElement(true); + } + + if ( Template[i].post ) + { + r.UpperLeftCorner.X = Template[i].x + 56; + r.UpperLeftCorner.Y = Template[i].y; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 15; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 20; + IGUIElement *t = Environment->addStaticText( Template[i].post, r, false, false, this); + t->setSubElement(true); + } + + r.UpperLeftCorner.X = Template[i].x + 15; + r.UpperLeftCorner.Y = Template[i].y-2; + r.LowerRightCorner.X = r.UpperLeftCorner.X + 40; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + 20; + + gui::IGUISpinBox* spin = Environment->addSpinBox( Template[i].init, r, true, this); + spin->setSubElement(true); + spin->setDecimalPlaces(0); + spin->setRange((f32)Template[i].range_down, (f32)Template[i].range_up); + spin->grab(); + + Battery.push_back(spin); + } + + bringToFront(CancelButton); + bringToFront(OKButton); +} + + +//! destructor +CGUIColorSelectDialog::~CGUIColorSelectDialog() +{ + if (CloseButton) + CloseButton->drop(); + + if (OKButton) + OKButton->drop(); + + if (CancelButton) + CancelButton->drop(); + + for (u32 i = 0; i != Battery.size(); ++i) + Battery[i]->drop(); + + if (ColorRing.Control) + ColorRing.Control->drop(); +} + + +//! renders a antialiased, colored ring +void CGUIColorSelectDialog::buildColorRing( const core::dimension2d & dim, s32 supersample, const video::SColor& borderColor ) +{ + const core::dimension2d d(dim.Width * supersample, dim.Height * supersample); + video::IVideoDriver* driver = Environment->getVideoDriver(); + + video::IImage *RawTexture = driver->createImage(video::ECF_A8R8G8B8, d); + + RawTexture->fill ( 0x00808080 ); + + const s32 radiusOut = ( d.Width / 2 ) - 4; + const s32 fullR2 = radiusOut * radiusOut; + + video::SColorf rgb(0,0,0); + video::SColorHSL hsl; + hsl.Luminance = 50; + hsl.Saturation = 100; + + core::position2d p; + for ( p.Y = -radiusOut; p.Y <= radiusOut; p.Y += 1 ) + { + s32 y2 = p.Y * p.Y; + + for (p.X = -radiusOut; p.X <= radiusOut; p.X += 1) + { + s32 r2 = y2 + ( p.X * p.X ); + + // test point in circle + s32 testa = r2 - fullR2; + + if ( testa < 0 ) + { + // dotproduct u ( x,y ) * v ( 1, 0 ) = cosinus(a) + + const f32 r = sqrtf((f32) r2); + + // normalize, dotproduct = xnorm + const f32 xn = r == 0.f ? 0.f : -p.X * core::reciprocal(r); + + hsl.Hue = acosf(xn)*core::RADTODEG; + if ( p.Y > 0 ) + hsl.Hue = 360 - hsl.Hue; + hsl.Hue -= 90; + + const f32 rTest = r / radiusOut; +#if 0 + if (rTest < 0.33f) + { + // luminance from 0 to 50 + hsl.Luminance = 50*(rTest/0.33); + hsl.Saturation = 0.f; + hsl.toRGB(rgb); + } + else + if ( rTest < 0.66f ) + { + // saturation from 0 to 100 + hsl.Saturation = 100*(( rTest - 0.33f ) / 0.33f); + hsl.Luminance = 50; + hsl.toRGB(rgb); + } + else + { + // luminance from 50 to 100 + hsl.Luminance = 100*(0.5f + ( ( rTest - 0.66f ) / .66f )); + hsl.Saturation = 100; + hsl.toRGB(rgb); + } + // borders should be slightly transparent + if ( rTest >= 0.95f ) + rgb.a = (1.f-rTest)*20; + else + rgb.a=1.f; +#else + if ( rTest > 0.5f ) + { + hsl.Saturation = 100; + hsl.Luminance = 50; + hsl.toRGB(rgb); + } + // borders should be slightly transparent + if ( rTest < 0.5f ) + rgb.a = 0; + else if ( rTest >= 0.95f ) + rgb.a = (1.f-rTest)*20; + else if ( rTest <= 0.55f ) + rgb.a = (rTest-0.5f)*20; + else + rgb.a=1.f; +#endif + RawTexture->setPixel(4+p.X+radiusOut, 4+p.Y+radiusOut, rgb.toSColor()); + } + } + } + + RawTexture->unlock (); + + if ( supersample > 1 ) + { + video::IImage * filter = driver->createImage(video::ECF_A8R8G8B8, dim ); + RawTexture->copyToScalingBoxFilter(filter); + RawTexture->drop(); + RawTexture = filter; + } + + bool generateMipLevels = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + driver->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, false); + + ColorRing.Texture = driver->addTexture ( "#colorring", RawTexture); + RawTexture->drop(); + + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, generateMipLevels); +} + + +//! called if an event happened. +bool CGUIColorSelectDialog::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_SPINBOX_CHANGED: + { + for ( u32 i = 0; i!= Battery.size (); ++i ) + { + if ( event.GUIEvent.Caller == Battery[i] ) + { + if (i<4) + { + video::SColor rgb((u32)Battery[0]->getValue(), (u32)Battery[1]->getValue(), + (u32)Battery[2]->getValue(), (u32)Battery[3]->getValue()); + video::SColorHSL hsl; + video::SColorf rgb2(rgb); + hsl.fromRGB(rgb2); + Battery[4]->setValue(hsl.Hue); + Battery[5]->setValue(hsl.Saturation); + Battery[6]->setValue(hsl.Luminance); + } + else + { + video::SColorHSL hsl(Battery[4]->getValue(), Battery[5]->getValue(), + Battery[6]->getValue()); + video::SColorf rgb2; + hsl.toRGB(rgb2); + video::SColor rgb = rgb2.toSColor(); + Battery[1]->setValue((f32)rgb.getRed()); + Battery[2]->setValue((f32)rgb.getGreen()); + Battery[3]->setValue((f32)rgb.getBlue()); + } + } + } + return true; + } + + case EGET_ELEMENT_FOCUS_LOST: + Dragging = false; + break; + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == CloseButton || + event.GUIEvent.Caller == CancelButton) + { + sendCancelEvent(); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == OKButton) + { + sendSelectedEvent(); + remove(); + return true; + } + break; + + case EGET_LISTBOX_CHANGED: + case EGET_LISTBOX_SELECTED_AGAIN: + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + Dragging = true; + Environment->setFocus(this); + return true; + case EMIE_LMOUSE_LEFT_UP: + Dragging = false; + Environment->removeFocus(this); + return true; + case EMIE_MOUSE_MOVED: + if (Dragging) + { + // gui window should not be dragged outside its parent + if (Parent) + if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || + event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || + event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || + event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1) + + return true; + + move(core::position2d(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + return true; + } + default: + break; + } + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +//! draws the element and its children +void CGUIColorSelectDialog::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + core::rect rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER), + AbsoluteRect, &AbsoluteClippingRect); + + if (Text.size()) + { + rect.UpperLeftCorner.X += 2; + rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; + + IGUIFont* font = skin->getFont(EGDF_WINDOW); + if (font) + font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, + &AbsoluteClippingRect); + } + + IGUIElement::draw(); + + // draw color selector after the window elements + core::vector2di pos(ColorRing.Control->getAbsolutePosition().UpperLeftCorner); + pos.X += ColorRing.Texture->getOriginalSize().Width/2; + pos.Y += ColorRing.Texture->getOriginalSize().Height/2; +#if 0 + const f32 h = Battery[4]->getValue(); + const f32 s = Battery[5]->getValue(); + const f32 l = Battery[6]->getValue(); + const f32 factor = 58.f*(((s==0)&&(l<50))?(l*0.33f/50):( + (s<100)?((.33f+(s*0.33f/100))):((0.66f+(l-50)*0.33f/50)))); + +#else + const f32 factor = 44; +#endif + pos.X += core::round32(sinf(Battery[4]->getValue()*core::DEGTORAD)*factor); + pos.Y -= core::round32(cosf(Battery[4]->getValue()*core::DEGTORAD)*factor); + Environment->getVideoDriver()->draw2DPolygon(pos, 4, 0xffffffff, 4); +} + + +video::SColor CGUIColorSelectDialog::getColor() +{ + return video::SColor((u32)Battery[0]->getValue(), (u32)Battery[1]->getValue(), + (u32)Battery[2]->getValue(), (u32)Battery[3]->getValue()); +} + +video::SColorHSL CGUIColorSelectDialog::getColorHSL() +{ + return video::SColorHSL(Battery[4]->getValue(), Battery[5]->getValue(), + Battery[6]->getValue()); +} + +//! sends the event that the file has been selected. +void CGUIColorSelectDialog::sendSelectedEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_SELECTED; + Parent->OnEvent(event); +} + + +//! sends the event that the file choose process has been canceld +void CGUIColorSelectDialog::sendCancelEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED; + Parent->OnEvent(event); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.d new file mode 100644 index 0000000..f4fe651 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.d @@ -0,0 +1,2 @@ +CGUIColorSelectDialog.o: CGUIColorSelectDialog.cpp \ + CGUIColorSelectDialog.h ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.h new file mode 100644 index 0000000..7f5cada --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIColorSelectDialog.h @@ -0,0 +1,74 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ +#define __C_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIColorSelectDialog.h" +#include "IGUIButton.h" +#include "IGUISpinBox.h" +#include "IGUIImage.h" +#include "irrArray.h" + + +namespace irr +{ +namespace gui +{ + + class CGUIColorSelectDialog : public IGUIColorSelectDialog + { + public: + + //! constructor + CGUIColorSelectDialog(const wchar_t* title, IGUIEnvironment* environment, IGUIElement* parent, s32 id); + + //! destructor + virtual ~CGUIColorSelectDialog(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + virtual video::SColor getColor(); + virtual video::SColorHSL getColorHSL(); + + private: + + //! sends the event that the file has been selected. + void sendSelectedEvent(); + + //! sends the event that the file choose process has been canceld + void sendCancelEvent(); + + core::position2d DragStart; + bool Dragging; + IGUIButton* CloseButton; + IGUIButton* OKButton; + IGUIButton* CancelButton; + + core::array Battery; + + struct SColorCircle + { + IGUIImage * Control; + video::ITexture * Texture; + }; + SColorCircle ColorRing; + + void buildColorRing( const core::dimension2d & dim, s32 supersample, const video::SColor& borderColor ); + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_COLOR_SELECT_DIALOG_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.cpp new file mode 100644 index 0000000..44d92e4 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.cpp @@ -0,0 +1,523 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIComboBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IGUIButton.h" +#include "CGUIListBox.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle) + : IGUIComboBox(environment, parent, id, rectangle), + ListButton(0), SelectedText(0), ListBox(0), LastFocus(0), + Selected(-1), HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER), MaxSelectionRows(5), HasFocus(false) +{ + #ifdef _DEBUG + setDebugName("CGUIComboBox"); + #endif + + IGUISkin* skin = Environment->getSkin(); + + s32 width = 15; + if (skin) + width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + + core::rect r; + r.UpperLeftCorner.X = rectangle.getWidth() - width - 2; + r.LowerRightCorner.X = rectangle.getWidth() - 2; + + r.UpperLeftCorner.Y = 2; + r.LowerRightCorner.Y = rectangle.getHeight() - 2; + + ListButton = Environment->addButton(r, this, -1, L""); + if (skin && skin->getSpriteBank()) + { + ListButton->setSpriteBank(skin->getSpriteBank()); + ListButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); + ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL)); + } + ListButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + ListButton->setSubElement(true); + ListButton->setTabStop(false); + + r.UpperLeftCorner.X = 2; + r.UpperLeftCorner.Y = 2; + r.LowerRightCorner.X = RelativeRect.getWidth() - (ListButton->getAbsolutePosition().getWidth() + 2); + r.LowerRightCorner.Y = RelativeRect.getHeight() - 2; + + SelectedText = Environment->addStaticText(L"", r, false, false, this, -1, false); + SelectedText->setSubElement(true); + SelectedText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + SelectedText->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_CENTER); + if (skin) + SelectedText->setOverrideColor(skin->getColor(EGDC_BUTTON_TEXT)); + SelectedText->enableOverrideColor(true); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); +} + + +void CGUIComboBox::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + HAlign = horizontal; + VAlign = vertical; + SelectedText->setTextAlignment(horizontal, vertical); +} + + +//! Set the maximal number of rows for the selection listbox +void CGUIComboBox::setMaxSelectionRows(u32 max) +{ + MaxSelectionRows = max; + + // force recalculation of open listbox + if (ListBox) + { + openCloseMenu(); + openCloseMenu(); + } +} + +//! Get the maximimal number of rows for the selection listbox +u32 CGUIComboBox::getMaxSelectionRows() const +{ + return MaxSelectionRows; +} + + +//! Returns amount of items in box +u32 CGUIComboBox::getItemCount() const +{ + return Items.size(); +} + + +//! returns string of an item. the idx may be a value from 0 to itemCount-1 +const wchar_t* CGUIComboBox::getItem(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].Name.c_str(); +} + +//! returns string of an item. the idx may be a value from 0 to itemCount-1 +u32 CGUIComboBox::getItemData(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].Data; +} + +//! Returns index based on item data +s32 CGUIComboBox::getIndexForItemData(u32 data ) const +{ + for ( u32 i = 0; i < Items.size (); ++i ) + { + if ( Items[i].Data == data ) + return i; + } + return -1; +} + + +//! Removes an item from the combo box. +void CGUIComboBox::removeItem(u32 idx) +{ + if (idx >= Items.size()) + return; + + if (Selected == (s32)idx) + setSelected(-1); + + Items.erase(idx); +} + + +//! Returns caption of this element. +const wchar_t* CGUIComboBox::getText() const +{ + return getItem(Selected); +} + + +//! adds an item and returns the index of it +u32 CGUIComboBox::addItem(const wchar_t* text, u32 data) +{ + Items.push_back( SComboData ( text, data ) ); + + if (Selected == -1) + setSelected(0); + + return Items.size() - 1; +} + + +//! deletes all items in the combo box +void CGUIComboBox::clear() +{ + Items.clear(); + setSelected(-1); +} + + +//! returns id of selected item. returns -1 if no item is selected. +s32 CGUIComboBox::getSelected() const +{ + return Selected; +} + + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUIComboBox::setSelected(s32 idx) +{ + if (idx < -1 || idx >= (s32)Items.size()) + return; + + Selected = idx; + if (Selected == -1) + SelectedText->setText(L""); + else + SelectedText->setText(Items[Selected].Name.c_str()); +} + + +//! called if an event happened. +bool CGUIComboBox::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + switch(event.EventType) + { + + case EET_KEY_INPUT_EVENT: + if (ListBox && event.KeyInput.PressedDown && event.KeyInput.Key == KEY_ESCAPE) + { + // hide list box + openCloseMenu(); + return true; + } + else + if (event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE) + { + if (!event.KeyInput.PressedDown) + { + openCloseMenu(); + } + + ListButton->setPressed(ListBox == 0); + + return true; + } + else + if (event.KeyInput.PressedDown) + { + s32 oldSelected = Selected; + bool absorb = true; + switch (event.KeyInput.Key) + { + case KEY_DOWN: + setSelected(Selected+1); + break; + case KEY_UP: + setSelected(Selected-1); + break; + case KEY_HOME: + case KEY_PRIOR: + setSelected(0); + break; + case KEY_END: + case KEY_NEXT: + setSelected((s32)Items.size()-1); + break; + default: + absorb = false; + } + + if (Selected <0) + setSelected(0); + + if (Selected >= (s32)Items.size()) + setSelected((s32)Items.size() -1); + + if (Selected != oldSelected) + { + sendSelectionChangedEvent(); + return true; + } + + if (absorb) + return true; + } + break; + + case EET_GUI_EVENT: + + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUS_LOST: + if (ListBox && + (Environment->hasFocus(ListBox) || ListBox->isMyChild(event.GUIEvent.Caller) ) && + event.GUIEvent.Element != this && + !isMyChild(event.GUIEvent.Element) && + !ListBox->isMyChild(event.GUIEvent.Element)) + { + openCloseMenu(); + } + break; + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == ListButton) + { + openCloseMenu(); + return true; + } + break; + case EGET_LISTBOX_SELECTED_AGAIN: + case EGET_LISTBOX_CHANGED: + if (event.GUIEvent.Caller == ListBox) + { + setSelected(ListBox->getSelected()); + if (Selected <0 || Selected >= (s32)Items.size()) + setSelected(-1); + openCloseMenu(); + + sendSelectionChangedEvent(); + } + return true; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + // send to list box + if (ListBox && ListBox->isPointInside(p) && ListBox->OnEvent(event)) + return true; + + return true; + } + case EMIE_LMOUSE_LEFT_UP: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + // send to list box + if (!(ListBox && + ListBox->getAbsolutePosition().isPointInside(p) && + ListBox->OnEvent(event))) + { + openCloseMenu(); + } + return true; + } + case EMIE_MOUSE_WHEEL: + { + s32 oldSelected = Selected; + setSelected( Selected + ((event.MouseInput.Wheel < 0) ? 1 : -1)); + + if (Selected <0) + setSelected(0); + + if (Selected >= (s32)Items.size()) + setSelected((s32)Items.size() -1); + + if (Selected != oldSelected) + { + sendSelectionChangedEvent(); + return true; + } + } + default: + break; + } + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +void CGUIComboBox::sendSelectionChangedEvent() +{ + if (Parent) + { + SEvent event; + + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_COMBO_BOX_CHANGED; + Parent->OnEvent(event); + } +} + + +//! draws the element and its children +void CGUIComboBox::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + IGUIElement *currentFocus = Environment->getFocus(); + if (currentFocus != LastFocus) + { + HasFocus = currentFocus == this || isMyChild(currentFocus); + LastFocus = currentFocus; + } + + // set colors each time as skin-colors can be changed + SelectedText->setBackgroundColor(skin->getColor(EGDC_HIGH_LIGHT)); + if(isEnabled()) + { + SelectedText->setDrawBackground(HasFocus); + SelectedText->setOverrideColor(skin->getColor(HasFocus ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT)); + } + else + { + SelectedText->setDrawBackground(false); + SelectedText->setOverrideColor(skin->getColor(EGDC_GRAY_TEXT)); + } + ListButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL)); + ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL)); + + + core::rect frameRect(AbsoluteRect); + + // draw the border + + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), + true, true, frameRect, &AbsoluteClippingRect); + + // draw children + IGUIElement::draw(); +} + + +void CGUIComboBox::openCloseMenu() +{ + if (ListBox) + { + // close list box + Environment->setFocus(this); + ListBox->remove(); + ListBox = 0; + } + else + { + if (Parent) + Parent->bringToFront(this); + + IGUISkin* skin = Environment->getSkin(); + u32 h = Items.size(); + + if (h > getMaxSelectionRows()) + h = getMaxSelectionRows(); + if (h == 0) + h = 1; + + IGUIFont* font = skin->getFont(); + if (font) + h *= (font->getDimension(L"A").Height + 4); + + // open list box + core::rect r(0, AbsoluteRect.getHeight(), + AbsoluteRect.getWidth(), AbsoluteRect.getHeight() + h); + + ListBox = new CGUIListBox(Environment, this, -1, r, false, true, true); + ListBox->setSubElement(true); + ListBox->setNotClipped(true); + ListBox->drop(); + + // ensure that list box is always completely visible + if (ListBox->getAbsolutePosition().LowerRightCorner.Y > Environment->getRootGUIElement()->getAbsolutePosition().getHeight()) + ListBox->setRelativePosition( core::rect(0, -ListBox->getAbsolutePosition().getHeight(), AbsoluteRect.getWidth(), 0) ); + + for (s32 i=0; i<(s32)Items.size(); ++i) + ListBox->addItem(Items[i].Name.c_str()); + + ListBox->setSelected(Selected); + + // set focus + Environment->setFocus(ListBox); + } +} + + +//! Writes attributes of the element. +void CGUIComboBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIComboBox::serializeAttributes(out,options); + + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + out->addInt("MaxSelectionRows", (s32)MaxSelectionRows ); + + out->addInt ("Selected", Selected ); + out->addInt ("ItemCount", Items.size()); + for (u32 i=0; i < Items.size(); ++i) + { + core::stringc s = "Item"; + s += i; + s += "Text"; + out->addString(s.c_str(), Items[i].Name.c_str()); + } +} + + +//! Reads attributes of the element +void CGUIComboBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIComboBox::deserializeAttributes(in,options); + + setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames)); + setMaxSelectionRows( (u32)(in->getAttributeAsInt("MaxSelectionRows")) ); + + // clear the list + clear(); + // get item count + u32 c = in->getAttributeAsInt("ItemCount"); + // add items + for (u32 i=0; i < c; ++i) + { + core::stringc s = "Item"; + s += i; + s += "Text"; + addItem(in->getAttributeAsStringW(s.c_str()).c_str(), 0); + } + + setSelected(in->getAttributeAsInt("Selected")); +} + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.d new file mode 100644 index 0000000..28c1475 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.d @@ -0,0 +1,2 @@ +CGUIComboBox.o: CGUIComboBox.cpp CGUIComboBox.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.h new file mode 100644 index 0000000..3d020ac --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIComboBox.h @@ -0,0 +1,117 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_COMBO_BOX_H_INCLUDED__ +#define __C_GUI_COMBO_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIComboBox.h" +#include "IGUIStaticText.h" +#include "irrString.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class IGUIButton; + class IGUIListBox; + + //! Single line edit box for editing simple text. + class CGUIComboBox : public IGUIComboBox + { + public: + + //! constructor + CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle); + + //! Returns amount of items in box + virtual u32 getItemCount() const; + + //! returns string of an item. the idx may be a value from 0 to itemCount-1 + virtual const wchar_t* getItem(u32 idx) const; + + //! Returns item data of an item. the idx may be a value from 0 to itemCount-1 + virtual u32 getItemData(u32 idx) const; + + //! Returns index based on item data + virtual s32 getIndexForItemData( u32 data ) const; + + //! adds an item and returns the index of it + virtual u32 addItem(const wchar_t* text, u32 data); + + //! Removes an item from the combo box. + virtual void removeItem(u32 id); + + //! deletes all items in the combo box + virtual void clear(); + + //! returns the text of the currently selected item + virtual const wchar_t* getText() const; + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 idx); + + //! sets the text alignment of the text part + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! Set the maximal number of rows for the selection listbox + virtual void setMaxSelectionRows(u32 max); + + //! Get the maximimal number of rows for the selection listbox + virtual u32 getMaxSelectionRows() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void openCloseMenu(); + void sendSelectionChangedEvent(); + + IGUIButton* ListButton; + IGUIStaticText* SelectedText; + IGUIListBox* ListBox; + IGUIElement *LastFocus; + + + struct SComboData + { + SComboData ( const wchar_t * text, u32 data ) + : Name (text), Data ( data ) {} + + core::stringw Name; + u32 Data; + }; + core::array< SComboData > Items; + + s32 Selected; + EGUI_ALIGNMENT HAlign, VAlign; + u32 MaxSelectionRows; + bool HasFocus; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_COMBO_BOX_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp new file mode 100644 index 0000000..67631e7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.cpp @@ -0,0 +1,869 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIContextMenu.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIContextMenu::CGUIContextMenu(IGUIEnvironment* environment, + IGUIElement* parent, s32 id, + core::rect rectangle, bool getFocus, bool allowFocus) + : IGUIContextMenu(environment, parent, id, rectangle), EventParent(0), LastFont(0), + CloseHandling(ECMC_REMOVE), HighLighted(-1), ChangeTime(0), AllowFocus(allowFocus) +{ + #ifdef _DEBUG + setDebugName("CGUIContextMenu"); + #endif + + Pos = rectangle.UpperLeftCorner; + recalculateSize(); + + if (getFocus) + Environment->setFocus(this); + + setNotClipped(true); +} + + +//! destructor +CGUIContextMenu::~CGUIContextMenu() +{ + for (u32 i=0; idrop(); + + if (LastFont) + LastFont->drop(); +} + +//! set behavior when menus are closed +void CGUIContextMenu::setCloseHandling(ECONTEXT_MENU_CLOSE onClose) +{ + CloseHandling = onClose; +} + +//! get current behavior when the menue will be closed +ECONTEXT_MENU_CLOSE CGUIContextMenu::getCloseHandling() const +{ + return CloseHandling; +} + +//! Returns amount of menu items +u32 CGUIContextMenu::getItemCount() const +{ + return Items.size(); +} + + +//! Adds a menu item. +u32 CGUIContextMenu::addItem(const wchar_t* text, s32 commandId, bool enabled, bool hasSubMenu, bool checked, bool autoChecking) +{ + return insertItem(Items.size(), text, commandId, enabled, hasSubMenu, checked, autoChecking); +} + +//! Insert a menu item at specified position. +u32 CGUIContextMenu::insertItem(u32 idx, const wchar_t* text, s32 commandId, bool enabled, + bool hasSubMenu, bool checked, bool autoChecking) +{ + SItem s; + s.Enabled = enabled; + s.Checked = checked; + s.AutoChecking = autoChecking; + s.Text = text; + s.IsSeparator = (text == 0); + s.SubMenu = 0; + s.CommandId = commandId; + + if (hasSubMenu) + { + s.SubMenu = new CGUIContextMenu(Environment, this, commandId, + core::rect(0,0,100,100), false, false); + s.SubMenu->setVisible(false); + } + + u32 result = idx; + if ( idx < Items.size() ) + { + Items.insert(s, idx); + } + else + { + Items.push_back(s); + result = Items.size() - 1; + } + + recalculateSize(); + return result; +} + +s32 CGUIContextMenu::findItemWithCommandId(s32 commandId, u32 idxStartSearch) const +{ + for ( u32 i=idxStartSearch; i= Items.size()) + return; + + if (menu) + menu->grab(); + if (Items[index].SubMenu) + Items[index].SubMenu->drop(); + + Items[index].SubMenu = menu; + menu->setVisible(false); + + if (Items[index].SubMenu) + { + menu->AllowFocus = false; + if ( Environment->getFocus() == menu ) + { + Environment->setFocus( this ); + } + } + + recalculateSize(); +} + + +//! Adds a separator item to the menu +void CGUIContextMenu::addSeparator() +{ + addItem(0, -1, true, false, false, false); +} + + +//! Returns text of the menu item. +const wchar_t* CGUIContextMenu::getItemText(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].Text.c_str(); +} + + +//! Sets text of the menu item. +void CGUIContextMenu::setItemText(u32 idx, const wchar_t* text) +{ + if (idx >= Items.size()) + return; + + Items[idx].Text = text; + recalculateSize(); +} + +//! should the element change the checked status on clicking +void CGUIContextMenu::setItemAutoChecking(u32 idx, bool autoChecking) +{ + if ( idx >= Items.size()) + return; + + Items[idx].AutoChecking = autoChecking; +} + +//! does the element change the checked status on clicking +bool CGUIContextMenu::getItemAutoChecking(u32 idx) const +{ + if (idx >= Items.size()) + return false; + + return Items[idx].AutoChecking; +} + + +//! Returns if a menu item is enabled +bool CGUIContextMenu::isItemEnabled(u32 idx) const +{ + if (idx >= Items.size()) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Items[idx].Enabled; +} + + +//! Returns if a menu item is checked +bool CGUIContextMenu::isItemChecked(u32 idx) const +{ + if (idx >= Items.size()) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Items[idx].Checked; +} + + +//! Sets if the menu item should be enabled. +void CGUIContextMenu::setItemEnabled(u32 idx, bool enabled) +{ + if (idx >= Items.size()) + return; + + Items[idx].Enabled = enabled; +} + + +//! Sets if the menu item should be checked. +void CGUIContextMenu::setItemChecked(u32 idx, bool checked ) +{ + if (idx >= Items.size()) + return; + + Items[idx].Checked = checked; +} + + +//! Removes a menu item +void CGUIContextMenu::removeItem(u32 idx) +{ + if (idx >= Items.size()) + return; + + if (Items[idx].SubMenu) + { + Items[idx].SubMenu->drop(); + Items[idx].SubMenu = 0; + } + + Items.erase(idx); + recalculateSize(); +} + + +//! Removes all menu items +void CGUIContextMenu::removeAllItems() +{ + for (u32 i=0; idrop(); + + Items.clear(); + recalculateSize(); +} + + +//! called if an event happened. +bool CGUIContextMenu::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUS_LOST: + if (event.GUIEvent.Caller == this && !isMyChild(event.GUIEvent.Element) && AllowFocus) + { + // set event parent of submenus + IGUIElement * p = EventParent ? EventParent : Parent; + setEventParent(p); + + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_ELEMENT_CLOSED; + if ( !p->OnEvent(event) ) + { + if ( CloseHandling & ECMC_HIDE ) + { + setVisible(false); + } + if ( CloseHandling & ECMC_REMOVE ) + { + remove(); + } + } + + return false; + } + break; + case EGET_ELEMENT_FOCUSED: + if (event.GUIEvent.Caller == this && !AllowFocus) + { + return true; + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_LEFT_UP: + { + // menu might be removed if it loses focus in sendClick, so grab a reference + grab(); + const u32 t = sendClick(core::position2d(event.MouseInput.X, event.MouseInput.Y)); + if ((t==0 || t==1) && Environment->hasFocus(this)) + Environment->removeFocus(this); + drop(); + } + return true; + case EMIE_LMOUSE_PRESSED_DOWN: + return true; + case EMIE_MOUSE_MOVED: + if (Environment->hasFocus(this)) + highlight(core::position2d(event.MouseInput.X, event.MouseInput.Y), true); + return true; + default: + break; + } + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +//! Sets the visible state of this element. +void CGUIContextMenu::setVisible(bool visible) +{ + HighLighted = -1; + ChangeTime = os::Timer::getTime(); + for (u32 j=0; jsetVisible(false); + + IGUIElement::setVisible(visible); +} + + +//! sends a click Returns: +//! 0 if click went outside of the element, +//! 1 if a valid button was clicked, +//! 2 if a nonclickable element was clicked +u32 CGUIContextMenu::sendClick(const core::position2d& p) +{ + u32 t = 0; + + // get number of open submenu + s32 openmenu = -1; + s32 j; + for (j=0; j<(s32)Items.size(); ++j) + if (Items[j].SubMenu && Items[j].SubMenu->isVisible()) + { + openmenu = j; + break; + } + + // delegate click operation to submenu + if (openmenu != -1) + { + t = Items[j].SubMenu->sendClick(p); + if (t != 0) + return t; // clicked something + } + + // check click on myself + if (isPointInside(p) && + (u32)HighLighted < Items.size()) + { + if (!Items[HighLighted].Enabled || + Items[HighLighted].IsSeparator || + Items[HighLighted].SubMenu) + return 2; + + if ( Items[HighLighted].AutoChecking ) + { + Items[HighLighted].Checked = Items[HighLighted].Checked ? false : true; + } + + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_MENU_ITEM_SELECTED; + if (EventParent) + EventParent->OnEvent(event); + else if (Parent) + Parent->OnEvent(event); + + return 1; + } + + return 0; +} + + +//! returns true, if an element was highligted +bool CGUIContextMenu::highlight(const core::position2d& p, bool canOpenSubMenu) +{ + if (!isEnabled()) + { + return false; + } + + // get number of open submenu + s32 openmenu = -1; + s32 i; + for (i=0; i<(s32)Items.size(); ++i) + if (Items[i].Enabled && Items[i].SubMenu && Items[i].SubMenu->isVisible()) + { + openmenu = i; + break; + } + + // delegate highlight operation to submenu + if (openmenu != -1) + { + if (Items[openmenu].Enabled && Items[openmenu].SubMenu->highlight(p, canOpenSubMenu)) + { + HighLighted = openmenu; + ChangeTime = os::Timer::getTime(); + return true; + } + } + + // highlight myself + for (i=0; i<(s32)Items.size(); ++i) + { + if (Items[i].Enabled && getHRect(Items[i], AbsoluteRect).isPointInside(p)) + { + HighLighted = i; + ChangeTime = os::Timer::getTime(); + + // make submenus visible/invisible + for (s32 j=0; j<(s32)Items.size(); ++j) + if (Items[j].SubMenu) + { + if ( j == i && canOpenSubMenu && Items[j].Enabled ) + Items[j].SubMenu->setVisible(true); + else if ( j != i ) + Items[j].SubMenu->setVisible(false); + } + return true; + } + } + + HighLighted = openmenu; + return false; +} + + +//! returns the item highlight-area +core::rect CGUIContextMenu::getHRect(const SItem& i, const core::rect& absolute) const +{ + core::rect r = absolute; + r.UpperLeftCorner.Y += i.PosY; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + i.Dim.Height; + return r; +} + + +//! Gets drawing rect of Item +core::rect CGUIContextMenu::getRect(const SItem& i, const core::rect& absolute) const +{ + core::rect r = absolute; + r.UpperLeftCorner.Y += i.PosY; + r.LowerRightCorner.Y = r.UpperLeftCorner.Y + i.Dim.Height; + r.UpperLeftCorner.X += 20; + return r; +} + + +//! draws the element and its children +void CGUIContextMenu::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + if (!skin) + return; + + IGUIFont* font = skin->getFont(EGDF_MENU); + if (font != LastFont) + { + if (LastFont) + LastFont->drop(); + LastFont = font; + if (LastFont) + LastFont->grab(); + + recalculateSize(); + } + + IGUISpriteBank* sprites = skin->getSpriteBank(); + + core::rect rect = AbsoluteRect; + core::rect* clip = 0; + + // draw frame + skin->draw3DMenuPane(this, AbsoluteRect, clip); + + // loop through all menu items + + rect = AbsoluteRect; + s32 y = AbsoluteRect.UpperLeftCorner.Y; + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (Items[i].IsSeparator) + { + // draw separator + rect = AbsoluteRect; + rect.UpperLeftCorner.Y += Items[i].PosY + 3; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + rect.UpperLeftCorner.X += 5; + rect.LowerRightCorner.X -= 5; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), rect, clip); + + rect.LowerRightCorner.Y += 1; + rect.UpperLeftCorner.Y += 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + y += 10; + } + else + { + rect = getRect(Items[i], AbsoluteRect); + + // draw highlighted + + if (i == HighLighted && Items[i].Enabled) + { + core::rect r = AbsoluteRect; + r.LowerRightCorner.Y = rect.LowerRightCorner.Y; + r.UpperLeftCorner.Y = rect.UpperLeftCorner.Y; + r.LowerRightCorner.X -= 5; + r.UpperLeftCorner.X += 5; + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), r, clip); + } + + // draw text + + EGUI_DEFAULT_COLOR c = EGDC_BUTTON_TEXT; + + if (i == HighLighted) + c = EGDC_HIGH_LIGHT_TEXT; + + if (!Items[i].Enabled) + c = EGDC_GRAY_TEXT; + + if (font) + font->draw(Items[i].Text.c_str(), rect, + skin->getColor(c), false, true, clip); + + // draw submenu symbol + if (Items[i].SubMenu && sprites) + { + core::rect r = rect; + r.UpperLeftCorner.X = r.LowerRightCorner.X - 15; + + sprites->draw2DSprite(skin->getIcon(EGDI_CURSOR_RIGHT), + r.getCenter(), clip, skin->getColor(c), + (i == HighLighted) ? ChangeTime : 0, + (i == HighLighted) ? os::Timer::getTime() : 0, + (i == HighLighted), true); + } + + // draw checked symbol + if (Items[i].Checked && sprites) + { + core::rect r = rect; + r.LowerRightCorner.X = r.UpperLeftCorner.X - 15; + r.UpperLeftCorner.X = r.LowerRightCorner.X + 15; + sprites->draw2DSprite(skin->getIcon(EGDI_CHECK_BOX_CHECKED), + r.getCenter(), clip, skin->getColor(c), + (i == HighLighted) ? ChangeTime : 0, + (i == HighLighted) ? os::Timer::getTime() : 0, + (i == HighLighted), true); + } + } + } + + IGUIElement::draw(); +} + + +void CGUIContextMenu::recalculateSize() +{ + IGUIFont* font = Environment->getSkin()->getFont(EGDF_MENU); + + if (!font) + return; + + core::rect rect; + rect.UpperLeftCorner = RelativeRect.UpperLeftCorner; + u32 width = 100; + u32 height = 3; + + u32 i; + for (i=0; igetDimension(Items[i].Text.c_str()); + Items[i].Dim.Width += 40; + + if (Items[i].Dim.Width > width) + width = Items[i].Dim.Width; + } + + Items[i].PosY = height; + height += Items[i].Dim.Height; + } + + height += 5; + + if (height < 10) + height = 10; + + rect.LowerRightCorner.X = RelativeRect.UpperLeftCorner.X + width; + rect.LowerRightCorner.Y = RelativeRect.UpperLeftCorner.Y + height; + + setRelativePosition(rect); + + // recalculate submenus + for (i=0; igetAbsolutePosition().getWidth(); + const s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); + + core::rect subRect(width-5, Items[i].PosY, width+w-5, Items[i].PosY+h); + + // if it would be drawn beyond the right border, then add it to the left side + gui::IGUIElement * root = Environment->getRootGUIElement(); + if ( root ) + { + core::rect rectRoot( root->getAbsolutePosition() ); + if ( getAbsolutePosition().UpperLeftCorner.X+subRect.LowerRightCorner.X > rectRoot.LowerRightCorner.X ) + { + subRect.UpperLeftCorner.X = -w; + subRect.LowerRightCorner.X = 0; + } + } + + Items[i].SubMenu->setRelativePosition(subRect); + } + } +} + + +//! Returns the selected item in the menu +s32 CGUIContextMenu::getSelectedItem() const +{ + return HighLighted; +} + + +//! \return Returns a pointer to the submenu of an item. +IGUIContextMenu* CGUIContextMenu::getSubMenu(u32 idx) const +{ + if (idx >= Items.size()) + return 0; + + return Items[idx].SubMenu; +} + + +//! Returns command id of a menu item +s32 CGUIContextMenu::getItemCommandId(u32 idx) const +{ + if (idx >= Items.size()) + return -1; + + return Items[idx].CommandId; +} + + +//! Sets the command id of a menu item +void CGUIContextMenu::setItemCommandId(u32 idx, s32 id) +{ + if (idx >= Items.size()) + return; + + Items[idx].CommandId = id; +} + + +//! Writes attributes of the element. +void CGUIContextMenu::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIElement::serializeAttributes(out,options); + out->addPosition2d("Position", Pos); + + if (Parent->getType() == EGUIET_CONTEXT_MENU || Parent->getType() == EGUIET_MENU ) + { + const IGUIContextMenu* const ptr = (const IGUIContextMenu*)Parent; + // find the position of this item in its parent's list + u32 i; + // VC6 needs the cast for this + for (i=0; (igetItemCount()) && (ptr->getSubMenu(i) != (const IGUIContextMenu*)this); ++i) + ; // do nothing + + out->addInt("ParentItem", i); + } + + out->addInt("CloseHandling", (s32)CloseHandling); + + // write out the item list + out->addInt("ItemCount", Items.size()); + + core::stringc tmp; + + for (u32 i=0; i < Items.size(); ++i) + { + tmp = "IsSeparator"; tmp += i; + out->addBool(tmp.c_str(), Items[i].IsSeparator); + + if (!Items[i].IsSeparator) + { + tmp = "Text"; tmp += i; + out->addString(tmp.c_str(), Items[i].Text.c_str()); + tmp = "CommandID"; tmp += i; + out->addInt(tmp.c_str(), Items[i].CommandId); + tmp = "Enabled"; tmp += i; + out->addBool(tmp.c_str(), Items[i].Enabled); + tmp = "Checked"; tmp += i; + out->addBool(tmp.c_str(), Items[i].Checked); + tmp = "AutoChecking"; tmp += i; + out->addBool(tmp.c_str(), Items[i].AutoChecking); + } + } +} + + +//! Reads attributes of the element +void CGUIContextMenu::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIElement::deserializeAttributes(in,options); + + Pos = in->getAttributeAsPosition2d("Position"); + + // link to this item's parent + if (Parent && ( Parent->getType() == EGUIET_CONTEXT_MENU || Parent->getType() == EGUIET_MENU ) ) + ((CGUIContextMenu*)Parent)->setSubMenu(in->getAttributeAsInt("ParentItem"),this); + + CloseHandling = (ECONTEXT_MENU_CLOSE)in->getAttributeAsInt("CloseHandling"); + + removeAllItems(); + + // read the item list + const s32 count = in->getAttributeAsInt("ItemCount"); + + for (s32 i=0; iexistsAttribute(tmp.c_str()) && in->getAttributeAsBool(tmp.c_str()) ) + addSeparator(); + else + { + tmp = "Text"; tmp += i; + if ( in->existsAttribute(tmp.c_str()) ) + txt = in->getAttributeAsStringW(tmp.c_str()); + + tmp = "CommandID"; tmp += i; + if ( in->existsAttribute(tmp.c_str()) ) + commandid = in->getAttributeAsInt(tmp.c_str()); + + tmp = "Enabled"; tmp += i; + if ( in->existsAttribute(tmp.c_str()) ) + enabled = in->getAttributeAsBool(tmp.c_str()); + + tmp = "Checked"; tmp += i; + if ( in->existsAttribute(tmp.c_str()) ) + checked = in->getAttributeAsBool(tmp.c_str()); + + tmp = "AutoChecking"; tmp += i; + if ( in->existsAttribute(tmp.c_str()) ) + autochecking = in->getAttributeAsBool(tmp.c_str()); + + addItem(core::stringw(txt.c_str()).c_str(), commandid, enabled, false, checked, autochecking); + } + } + + recalculateSize(); +} + + +// because sometimes the element has no parent at click time +void CGUIContextMenu::setEventParent(IGUIElement *parent) +{ + EventParent = parent; + + for (u32 i=0; isetEventParent(parent); +} + + +bool CGUIContextMenu::hasOpenSubMenu() const +{ + for (u32 i=0; iisVisible()) + return true; + + return false; +} + + +void CGUIContextMenu::closeAllSubMenus() +{ + for (u32 i=0; isetVisible(false); + + //HighLighted = -1; +} + + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.d new file mode 100644 index 0000000..4cf8e6a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.d @@ -0,0 +1,2 @@ +CGUIContextMenu.o: CGUIContextMenu.cpp CGUIContextMenu.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.h new file mode 100644 index 0000000..843b2b7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIContextMenu.h @@ -0,0 +1,174 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_CONTEXT_MENU_H_INCLUDED__ +#define __C_GUI_CONTEXT_MENU_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIContextMenu.h" +#include "irrString.h" +#include "irrArray.h" +#include "IGUIFont.h" + +namespace irr +{ +namespace gui +{ + + //! GUI Context menu interface. + class CGUIContextMenu : public IGUIContextMenu + { + public: + + //! constructor + CGUIContextMenu(IGUIEnvironment* environment, + IGUIElement* parent, s32 id, core::rect rectangle, + bool getFocus = true, bool allowFocus = true); + + //! destructor + virtual ~CGUIContextMenu(); + + //! set behavior when menus are closed + virtual void setCloseHandling(ECONTEXT_MENU_CLOSE onClose); + + //! get current behavior when the menue will be closed + virtual ECONTEXT_MENU_CLOSE getCloseHandling() const; + + //! Returns amount of menu items + virtual u32 getItemCount() const; + + //! Adds a menu item. + virtual u32 addItem(const wchar_t* text, s32 commandid, + bool enabled, bool hasSubMenu, bool checked, bool autoChecking); + + //! Insert a menu item at specified position. + virtual u32 insertItem(u32 idx, const wchar_t* text, s32 commandId, bool enabled, + bool hasSubMenu, bool checked, bool autoChecking); + + //! Find a item which has the given CommandId starting from given index + virtual s32 findItemWithCommandId(s32 commandId, u32 idxStartSearch) const; + + //! Adds a separator item to the menu + virtual void addSeparator(); + + //! Returns text of the menu item. + virtual const wchar_t* getItemText(u32 idx) const; + + //! Sets text of the menu item. + virtual void setItemText(u32 idx, const wchar_t* text); + + //! Returns if a menu item is enabled + virtual bool isItemEnabled(u32 idx) const; + + //! Sets if the menu item should be enabled. + virtual void setItemEnabled(u32 idx, bool enabled); + + //! Returns if a menu item is checked + virtual bool isItemChecked(u32 idx) const; + + //! Sets if the menu item should be checked. + virtual void setItemChecked(u32 idx, bool enabled); + + //! Removes a menu item + virtual void removeItem(u32 idx); + + //! Removes all menu items + virtual void removeAllItems(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Returns the selected item in the menu + virtual s32 getSelectedItem() const; + + //! Returns a pointer to the submenu of an item. + //! \return Pointer to the submenu of an item. + virtual IGUIContextMenu* getSubMenu(u32 idx) const; + + //! Sets the visible state of this element. + virtual void setVisible(bool visible); + + //! should the element change the checked status on clicking + virtual void setItemAutoChecking(u32 idx, bool autoChecking); + + //! does the element change the checked status on clicking + virtual bool getItemAutoChecking(u32 idx) const; + + //! Returns command id of a menu item + virtual s32 getItemCommandId(u32 idx) const; + + //! Sets the command id of a menu item + virtual void setItemCommandId(u32 idx, s32 id); + + //! Adds a sub menu from an element that already exists. + virtual void setSubMenu(u32 index, CGUIContextMenu* menu); + + //! When an eventparent is set it receives events instead of the usual parent element + virtual void setEventParent(IGUIElement *parent); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + + void closeAllSubMenus(); + bool hasOpenSubMenu() const; + + struct SItem + { + core::stringw Text; + bool IsSeparator; + bool Enabled; + bool Checked; + bool AutoChecking; + core::dimension2d Dim; + s32 PosY; + CGUIContextMenu* SubMenu; + s32 CommandId; + }; + + virtual void recalculateSize(); + + //! returns true, if an element was highlighted + virtual bool highlight(const core::position2d& p, bool canOpenSubMenu); + + //! sends a click Returns: + //! 0 if click went outside of the element, + //! 1 if a valid button was clicked, + //! 2 if a nonclickable element was clicked + virtual u32 sendClick(const core::position2d& p); + + //! returns the item highlight-area + virtual core::rect getHRect(const SItem& i, const core::rect& absolute) const; + + //! Gets drawing rect of Item + virtual core::rect getRect(const SItem& i, const core::rect& absolute) const; + + + core::array Items; + core::position2d Pos; + IGUIElement* EventParent; + IGUIFont *LastFont; + ECONTEXT_MENU_CLOSE CloseHandling; + s32 HighLighted; + u32 ChangeTime; + bool AllowFocus; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_CONTEXT_MENU_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.cpp new file mode 100644 index 0000000..a937cc2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.cpp @@ -0,0 +1,1555 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIEditBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" +#include "os.h" +#include "Keycodes.h" + +/* + todo: + optional scrollbars + ctrl+left/right to select word + double click/ctrl click: word select + drag to select whole words, triple click to select line + optional? dragging selected text + numerical +*/ + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border, + IGUIEnvironment* environment, IGUIElement* parent, s32 id, + const core::rect& rectangle) + : IGUIEditBox(environment, parent, id, rectangle), MouseMarking(false), + Border(border), Background(true), OverrideColorEnabled(false), MarkBegin(0), MarkEnd(0), + OverrideColor(video::SColor(101,255,255,255)), OverrideFont(0), LastBreakFont(0), + Operator(0), BlinkStartTime(0), CursorPos(0), HScrollPos(0), VScrollPos(0), Max(0), + WordWrap(false), MultiLine(false), AutoScroll(true), PasswordBox(false), + PasswordChar(L'*'), HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_CENTER), + CurrentTextRect(0,0,1,1), FrameRect(rectangle) +{ + #ifdef _DEBUG + setDebugName("CGUIEditBox"); + #endif + + Text = text; + + if (Environment) + Operator = Environment->getOSOperator(); + + if (Operator) + Operator->grab(); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + calculateFrameRect(); + breakText(); + + calculateScrollPos(); +} + + +//! destructor +CGUIEditBox::~CGUIEditBox() +{ + if (OverrideFont) + OverrideFont->drop(); + + if (Operator) + Operator->drop(); +} + + +//! Sets another skin independent font. +void CGUIEditBox::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont == font) + return; + + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); + + breakText(); +} + +//! Gets the override font (if any) +IGUIFont * CGUIEditBox::getOverrideFont() const +{ + return OverrideFont; +} + +//! Get the font which is used right now for drawing +IGUIFont* CGUIEditBox::getActiveFont() const +{ + if ( OverrideFont ) + return OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (skin) + return skin->getFont(); + return 0; +} + +//! Sets another color for the text. +void CGUIEditBox::setOverrideColor(video::SColor color) +{ + OverrideColor = color; + OverrideColorEnabled = true; +} + + +video::SColor CGUIEditBox::getOverrideColor() const +{ + return OverrideColor; +} + + +//! Turns the border on or off +void CGUIEditBox::setDrawBorder(bool border) +{ + Border = border; +} + +//! Sets whether to draw the background +void CGUIEditBox::setDrawBackground(bool draw) +{ + Background = draw; +} + +//! Sets if the text should use the overide color or the color in the gui skin. +void CGUIEditBox::enableOverrideColor(bool enable) +{ + OverrideColorEnabled = enable; +} + +bool CGUIEditBox::isOverrideColorEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return OverrideColorEnabled; +} + +//! Enables or disables word wrap +void CGUIEditBox::setWordWrap(bool enable) +{ + WordWrap = enable; + breakText(); +} + + +void CGUIEditBox::updateAbsolutePosition() +{ + core::rect oldAbsoluteRect(AbsoluteRect); + IGUIElement::updateAbsolutePosition(); + if ( oldAbsoluteRect != AbsoluteRect ) + { + calculateFrameRect(); + breakText(); + calculateScrollPos(); + } +} + + +//! Checks if word wrap is enabled +bool CGUIEditBox::isWordWrapEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return WordWrap; +} + + +//! Enables or disables newlines. +void CGUIEditBox::setMultiLine(bool enable) +{ + MultiLine = enable; +} + + +//! Checks if multi line editing is enabled +bool CGUIEditBox::isMultiLineEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return MultiLine; +} + + +void CGUIEditBox::setPasswordBox(bool passwordBox, wchar_t passwordChar) +{ + PasswordBox = passwordBox; + if (PasswordBox) + { + PasswordChar = passwordChar; + setMultiLine(false); + setWordWrap(false); + BrokenText.clear(); + } +} + + +bool CGUIEditBox::isPasswordBox() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return PasswordBox; +} + + +//! Sets text justification +void CGUIEditBox::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + HAlign = horizontal; + VAlign = vertical; +} + + +//! called if an event happened. +bool CGUIEditBox::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this) + { + MouseMarking = false; + setTextMarkers(0,0); + } + } + break; + case EET_KEY_INPUT_EVENT: + if (processKey(event)) + return true; + break; + case EET_MOUSE_INPUT_EVENT: + if (processMouse(event)) + return true; + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +bool CGUIEditBox::processKey(const SEvent& event) +{ + if (!event.KeyInput.PressedDown) + return false; + + bool textChanged = false; + s32 newMarkBegin = MarkBegin; + s32 newMarkEnd = MarkEnd; + + // control shortcut handling + + if (event.KeyInput.Control) + { + // german backlash '\' entered with control + '?' + if ( event.KeyInput.Char == '\\' ) + { + inputChar(event.KeyInput.Char); + return true; + } + + switch(event.KeyInput.Key) + { + case KEY_KEY_A: + // select all + newMarkBegin = 0; + newMarkEnd = Text.size(); + break; + case KEY_KEY_C: + // copy to clipboard + if (!PasswordBox && Operator && MarkBegin != MarkEnd) + { + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + core::stringc s; + s = Text.subString(realmbgn, realmend - realmbgn).c_str(); + Operator->copyToClipboard(s.c_str()); + } + break; + case KEY_KEY_X: + // cut to the clipboard + if (!PasswordBox && Operator && MarkBegin != MarkEnd) + { + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + // copy + core::stringc sc; + sc = Text.subString(realmbgn, realmend - realmbgn).c_str(); + Operator->copyToClipboard(sc.c_str()); + + if (isEnabled()) + { + // delete + core::stringw s; + s = Text.subString(0, realmbgn); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + + CursorPos = realmbgn; + newMarkBegin = 0; + newMarkEnd = 0; + textChanged = true; + } + } + break; + case KEY_KEY_V: + if ( !isEnabled() ) + break; + + // paste from the clipboard + if (Operator) + { + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + // add new character + const c8* p = Operator->getTextFromClipboard(); + if (p) + { + if (MarkBegin == MarkEnd) + { + // insert text + core::stringw s = Text.subString(0, CursorPos); + s.append(p); + s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); + + if (!Max || s.size()<=Max) // thx to Fish FH for fix + { + Text = s; + s = p; + CursorPos += s.size(); + } + } + else + { + // replace text + + core::stringw s = Text.subString(0, realmbgn); + s.append(p); + s.append( Text.subString(realmend, Text.size()-realmend) ); + + if (!Max || s.size()<=Max) // thx to Fish FH for fix + { + Text = s; + s = p; + CursorPos = realmbgn + s.size(); + } + } + } + + newMarkBegin = 0; + newMarkEnd = 0; + textChanged = true; + } + break; + case KEY_HOME: + // move/highlight to start of text + if (event.KeyInput.Shift) + { + newMarkEnd = CursorPos; + newMarkBegin = 0; + CursorPos = 0; + } + else + { + CursorPos = 0; + newMarkBegin = 0; + newMarkEnd = 0; + } + break; + case KEY_END: + // move/highlight to end of text + if (event.KeyInput.Shift) + { + newMarkBegin = CursorPos; + newMarkEnd = Text.size(); + CursorPos = 0; + } + else + { + CursorPos = Text.size(); + newMarkBegin = 0; + newMarkEnd = 0; + } + break; + default: + return false; + } + } + // default keyboard handling + else + switch(event.KeyInput.Key) + { + case KEY_END: + { + s32 p = Text.size(); + if (WordWrap || MultiLine) + { + p = getLineFromPos(CursorPos); + p = BrokenTextPositions[p] + (s32)BrokenText[p].size(); + if (p > 0 && (Text[p-1] == L'\r' || Text[p-1] == L'\n' )) + p-=1; + } + + if (event.KeyInput.Shift) + { + if (MarkBegin == MarkEnd) + newMarkBegin = CursorPos; + + newMarkEnd = p; + } + else + { + newMarkBegin = 0; + newMarkEnd = 0; + } + CursorPos = p; + BlinkStartTime = os::Timer::getTime(); + } + break; + case KEY_HOME: + { + + s32 p = 0; + if (WordWrap || MultiLine) + { + p = getLineFromPos(CursorPos); + p = BrokenTextPositions[p]; + } + + if (event.KeyInput.Shift) + { + if (MarkBegin == MarkEnd) + newMarkBegin = CursorPos; + newMarkEnd = p; + } + else + { + newMarkBegin = 0; + newMarkEnd = 0; + } + CursorPos = p; + BlinkStartTime = os::Timer::getTime(); + } + break; + case KEY_RETURN: + if (MultiLine) + { + inputChar(L'\n'); + } + else + { + calculateScrollPos(); + sendGuiEvent( EGET_EDITBOX_ENTER ); + } + return true; + case KEY_LEFT: + + if (event.KeyInput.Shift) + { + if (CursorPos > 0) + { + if (MarkBegin == MarkEnd) + newMarkBegin = CursorPos; + + newMarkEnd = CursorPos-1; + } + } + else + { + newMarkBegin = 0; + newMarkEnd = 0; + } + + if (CursorPos > 0) CursorPos--; + BlinkStartTime = os::Timer::getTime(); + break; + + case KEY_RIGHT: + if (event.KeyInput.Shift) + { + if (Text.size() > (u32)CursorPos) + { + if (MarkBegin == MarkEnd) + newMarkBegin = CursorPos; + + newMarkEnd = CursorPos+1; + } + } + else + { + newMarkBegin = 0; + newMarkEnd = 0; + } + + if (Text.size() > (u32)CursorPos) CursorPos++; + BlinkStartTime = os::Timer::getTime(); + break; + case KEY_UP: + if (MultiLine || (WordWrap && BrokenText.size() > 1) ) + { + s32 lineNo = getLineFromPos(CursorPos); + s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd); + if (lineNo > 0) + { + s32 cp = CursorPos - BrokenTextPositions[lineNo]; + if ((s32)BrokenText[lineNo-1].size() < cp) + CursorPos = BrokenTextPositions[lineNo-1] + core::max_((u32)1, BrokenText[lineNo-1].size())-1; + else + CursorPos = BrokenTextPositions[lineNo-1] + cp; + } + + if (event.KeyInput.Shift) + { + newMarkBegin = mb; + newMarkEnd = CursorPos; + } + else + { + newMarkBegin = 0; + newMarkEnd = 0; + } + + } + else + { + return false; + } + break; + case KEY_DOWN: + if (MultiLine || (WordWrap && BrokenText.size() > 1) ) + { + s32 lineNo = getLineFromPos(CursorPos); + s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd); + if (lineNo < (s32)BrokenText.size()-1) + { + s32 cp = CursorPos - BrokenTextPositions[lineNo]; + if ((s32)BrokenText[lineNo+1].size() < cp) + CursorPos = BrokenTextPositions[lineNo+1] + core::max_((u32)1, BrokenText[lineNo+1].size())-1; + else + CursorPos = BrokenTextPositions[lineNo+1] + cp; + } + + if (event.KeyInput.Shift) + { + newMarkBegin = mb; + newMarkEnd = CursorPos; + } + else + { + newMarkBegin = 0; + newMarkEnd = 0; + } + + } + else + { + return false; + } + break; + + case KEY_BACK: + if ( !isEnabled() ) + break; + + if (Text.size()) + { + core::stringw s; + + if (MarkBegin != MarkEnd) + { + // delete marked text + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + s = Text.subString(0, realmbgn); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + + CursorPos = realmbgn; + } + else + { + // delete text behind cursor + if (CursorPos>0) + s = Text.subString(0, CursorPos-1); + else + s = L""; + s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); + Text = s; + --CursorPos; + } + + if (CursorPos < 0) + CursorPos = 0; + BlinkStartTime = os::Timer::getTime(); + newMarkBegin = 0; + newMarkEnd = 0; + textChanged = true; + } + break; + case KEY_DELETE: + if ( !isEnabled() ) + break; + + if (Text.size() != 0) + { + core::stringw s; + + if (MarkBegin != MarkEnd) + { + // delete marked text + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + s = Text.subString(0, realmbgn); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + + CursorPos = realmbgn; + } + else + { + // delete text before cursor + s = Text.subString(0, CursorPos); + s.append( Text.subString(CursorPos+1, Text.size()-CursorPos-1) ); + Text = s; + } + + if (CursorPos > (s32)Text.size()) + CursorPos = (s32)Text.size(); + + BlinkStartTime = os::Timer::getTime(); + newMarkBegin = 0; + newMarkEnd = 0; + textChanged = true; + } + break; + + case KEY_ESCAPE: + case KEY_TAB: + case KEY_SHIFT: + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + case KEY_F11: + case KEY_F12: + case KEY_F13: + case KEY_F14: + case KEY_F15: + case KEY_F16: + case KEY_F17: + case KEY_F18: + case KEY_F19: + case KEY_F20: + case KEY_F21: + case KEY_F22: + case KEY_F23: + case KEY_F24: + // ignore these keys + return false; + + default: + inputChar(event.KeyInput.Char); + return true; + } + + // Set new text markers + setTextMarkers( newMarkBegin, newMarkEnd ); + + // break the text if it has changed + if (textChanged) + { + breakText(); + calculateScrollPos(); + sendGuiEvent(EGET_EDITBOX_CHANGED); + } + else + { + calculateScrollPos(); + } + + return true; +} + + +//! draws the element and its children +void CGUIEditBox::draw() +{ + if (!IsVisible) + return; + + const bool focus = Environment->hasFocus(this); + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + EGUI_DEFAULT_COLOR bgCol = EGDC_GRAY_EDITABLE; + if ( isEnabled() ) + bgCol = focus ? EGDC_FOCUSED_EDITABLE : EGDC_EDITABLE; + + if (!Border && Background) + { + skin->draw2DRectangle(this, skin->getColor(bgCol), AbsoluteRect, &AbsoluteClippingRect); + } + + if (Border) + { + // draw the border + skin->draw3DSunkenPane(this, skin->getColor(bgCol), false, Background, AbsoluteRect, &AbsoluteClippingRect); + + calculateFrameRect(); + } + + core::rect localClipRect = FrameRect; + localClipRect.clipAgainst(AbsoluteClippingRect); + + // draw the text + + IGUIFont* font = getActiveFont(); + + s32 cursorLine = 0; + s32 charcursorpos = 0; + + if (font) + { + if (LastBreakFont != font) + { + breakText(); + } + + // calculate cursor pos + + core::stringw *txtLine = &Text; + s32 startPos = 0; + + core::stringw s, s2; + + // get mark position + const bool ml = (!PasswordBox && (WordWrap || MultiLine)); + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + const s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0; + const s32 hlineCount = ml ? getLineFromPos(realmend) - hlineStart + 1 : 1; + const s32 lineCount = ml ? BrokenText.size() : 1; + + // Save the override color information. + // Then, alter it if the edit box is disabled. + const bool prevOver = OverrideColorEnabled; + const video::SColor prevColor = OverrideColor; + + if (Text.size()) + { + if (!isEnabled() && !OverrideColorEnabled) + { + OverrideColorEnabled = true; + OverrideColor = skin->getColor(EGDC_GRAY_TEXT); + } + + for (s32 i=0; i < lineCount; ++i) + { + setTextRect(i); + + // clipping test - don't draw anything outside the visible area + core::rect c = localClipRect; + c.clipAgainst(CurrentTextRect); + if (!c.isValid()) + continue; + + // get current line + if (PasswordBox) + { + if (BrokenText.size() != 1) + { + BrokenText.clear(); + BrokenText.push_back(core::stringw()); + } + if (BrokenText[0].size() != Text.size()) + { + BrokenText[0] = Text; + for (u32 q = 0; q < Text.size(); ++q) + { + BrokenText[0] [q] = PasswordChar; + } + } + txtLine = &BrokenText[0]; + startPos = 0; + } + else + { + txtLine = ml ? &BrokenText[i] : &Text; + startPos = ml ? BrokenTextPositions[i] : 0; + } + + + // draw normal text + font->draw(txtLine->c_str(), CurrentTextRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), + false, true, &localClipRect); + + // draw mark and marked text + if (focus && MarkBegin != MarkEnd && i >= hlineStart && i < hlineStart + hlineCount) + { + + s32 mbegin = 0, mend = 0; + s32 lineStartPos = 0, lineEndPos = txtLine->size(); + + if (i == hlineStart) + { + // highlight start is on this line + s = txtLine->subString(0, realmbgn - startPos); + mbegin = font->getDimension(s.c_str()).Width; + + // deal with kerning + mbegin += font->getKerningWidth( + &((*txtLine)[realmbgn - startPos]), + realmbgn - startPos > 0 ? &((*txtLine)[realmbgn - startPos - 1]) : 0); + + lineStartPos = realmbgn - startPos; + } + if (i == hlineStart + hlineCount - 1) + { + // highlight end is on this line + s2 = txtLine->subString(0, realmend - startPos); + mend = font->getDimension(s2.c_str()).Width; + lineEndPos = (s32)s2.size(); + } + else + mend = font->getDimension(txtLine->c_str()).Width; + + CurrentTextRect.UpperLeftCorner.X += mbegin; + CurrentTextRect.LowerRightCorner.X = CurrentTextRect.UpperLeftCorner.X + mend - mbegin; + + // draw mark + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), CurrentTextRect, &localClipRect); + + // draw marked text + s = txtLine->subString(lineStartPos, lineEndPos - lineStartPos); + + if (s.size()) + font->draw(s.c_str(), CurrentTextRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_HIGH_LIGHT_TEXT), + false, true, &localClipRect); + + } + } + + // Return the override color information to its previous settings. + OverrideColorEnabled = prevOver; + OverrideColor = prevColor; + } + + // draw cursor + if ( IsEnabled ) + { + if (WordWrap || MultiLine) + { + cursorLine = getLineFromPos(CursorPos); + txtLine = &BrokenText[cursorLine]; + startPos = BrokenTextPositions[cursorLine]; + } + s = txtLine->subString(0,CursorPos-startPos); + charcursorpos = font->getDimension(s.c_str()).Width + + font->getKerningWidth(L"_", CursorPos-startPos > 0 ? &((*txtLine)[CursorPos-startPos-1]) : 0); + + if (focus && (os::Timer::getTime() - BlinkStartTime) % 700 < 350) + { + setTextRect(cursorLine); + CurrentTextRect.UpperLeftCorner.X += charcursorpos; + + font->draw(L"_", CurrentTextRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), + false, true, &localClipRect); + } + } + } + + // draw children + IGUIElement::draw(); +} + + +//! Sets the new caption of this element. +void CGUIEditBox::setText(const wchar_t* text) +{ + Text = text; + if (u32(CursorPos) > Text.size()) + CursorPos = Text.size(); + HScrollPos = 0; + breakText(); +} + + +//! Enables or disables automatic scrolling with cursor position +//! \param enable: If set to true, the text will move around with the cursor position +void CGUIEditBox::setAutoScroll(bool enable) +{ + AutoScroll = enable; +} + + +//! Checks to see if automatic scrolling is enabled +//! \return true if automatic scrolling is enabled, false if not +bool CGUIEditBox::isAutoScrollEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return AutoScroll; +} + + +//! Gets the area of the text in the edit box +//! \return Returns the size in pixels of the text +core::dimension2du CGUIEditBox::getTextDimension() +{ + core::rect ret; + + setTextRect(0); + ret = CurrentTextRect; + + for (u32 i=1; i < BrokenText.size(); ++i) + { + setTextRect(i); + ret.addInternalPoint(CurrentTextRect.UpperLeftCorner); + ret.addInternalPoint(CurrentTextRect.LowerRightCorner); + } + + return core::dimension2du(ret.getSize()); +} + + +//! Sets the maximum amount of characters which may be entered in the box. +//! \param max: Maximum amount of characters. If 0, the character amount is +//! infinity. +void CGUIEditBox::setMax(u32 max) +{ + Max = max; + + if (Text.size() > Max && Max != 0) + Text = Text.subString(0, Max); +} + + +//! Returns maximum amount of characters, previously set by setMax(); +u32 CGUIEditBox::getMax() const +{ + return Max; +} + + +bool CGUIEditBox::processMouse(const SEvent& event) +{ + switch(event.MouseInput.Event) + { + case irr::EMIE_LMOUSE_LEFT_UP: + if (Environment->hasFocus(this)) + { + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + if (MouseMarking) + { + setTextMarkers( MarkBegin, CursorPos ); + } + MouseMarking = false; + calculateScrollPos(); + return true; + } + break; + case irr::EMIE_MOUSE_MOVED: + { + if (MouseMarking) + { + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + setTextMarkers( MarkBegin, CursorPos ); + calculateScrollPos(); + return true; + } + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: + if (!Environment->hasFocus(this)) + { + BlinkStartTime = os::Timer::getTime(); + MouseMarking = true; + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + setTextMarkers(CursorPos, CursorPos ); + calculateScrollPos(); + return true; + } + else + { + if (!AbsoluteClippingRect.isPointInside( + core::position2d(event.MouseInput.X, event.MouseInput.Y))) + { + return false; + } + else + { + // move cursor + CursorPos = getCursorPos(event.MouseInput.X, event.MouseInput.Y); + + s32 newMarkBegin = MarkBegin; + if (!MouseMarking) + newMarkBegin = CursorPos; + + MouseMarking = true; + setTextMarkers( newMarkBegin, CursorPos); + calculateScrollPos(); + return true; + } + } + default: + break; + } + + return false; +} + + +s32 CGUIEditBox::getCursorPos(s32 x, s32 y) +{ + IGUIFont* font = getActiveFont(); + + const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1; + + core::stringw *txtLine=0; + s32 startPos=0; + x+=3; + + for (u32 i=0; i < lineCount; ++i) + { + setTextRect(i); + if (i == 0 && y < CurrentTextRect.UpperLeftCorner.Y) + y = CurrentTextRect.UpperLeftCorner.Y; + if (i == lineCount - 1 && y > CurrentTextRect.LowerRightCorner.Y ) + y = CurrentTextRect.LowerRightCorner.Y; + + // is it inside this region? + if (y >= CurrentTextRect.UpperLeftCorner.Y && y <= CurrentTextRect.LowerRightCorner.Y) + { + // we've found the clicked line + txtLine = (WordWrap || MultiLine) ? &BrokenText[i] : &Text; + startPos = (WordWrap || MultiLine) ? BrokenTextPositions[i] : 0; + break; + } + } + + if (x < CurrentTextRect.UpperLeftCorner.X) + x = CurrentTextRect.UpperLeftCorner.X; + + if ( !txtLine ) + return 0; + + s32 idx = font->getCharacterFromPos(txtLine->c_str(), x - CurrentTextRect.UpperLeftCorner.X); + + // click was on or left of the line + if (idx != -1) + return idx + startPos; + + // click was off the right edge of the line, go to end. + return txtLine->size() + startPos; +} + + +//! Breaks the single text line. +void CGUIEditBox::breakText() +{ + if ((!WordWrap && !MultiLine)) + return; + + BrokenText.clear(); // need to reallocate :/ + BrokenTextPositions.set_used(0); + + IGUIFont* font = getActiveFont(); + if (!font) + return; + + LastBreakFont = font; + + core::stringw line; + core::stringw word; + core::stringw whitespace; + s32 lastLineStart = 0; + s32 size = Text.size(); + s32 length = 0; + s32 elWidth = RelativeRect.getWidth() - 6; + wchar_t c; + + for (s32 i=0; i i ) + --CursorPos; + } + } + else if (c == L'\n') // Unix breaks + { + lineBreak = true; + c = 0; + } + + // don't break if we're not a multi-line edit box + if (!MultiLine) + lineBreak = false; + + if (c == L' ' || c == 0 || i == (size-1)) + { + // here comes the next whitespace, look if + // we can break the last word to the next line + // We also break whitespace, otherwise cursor would vanish beside the right border. + s32 whitelgth = font->getDimension(whitespace.c_str()).Width; + s32 worldlgth = font->getDimension(word.c_str()).Width; + + if (WordWrap && length + worldlgth + whitelgth > elWidth && line.size() > 0) + { + // break to next line + length = worldlgth; + BrokenText.push_back(line); + BrokenTextPositions.push_back(lastLineStart); + lastLineStart = i - (s32)word.size(); + line = word; + } + else + { + // add word to line + line += whitespace; + line += word; + length += whitelgth + worldlgth; + } + + word = L""; + whitespace = L""; + + + if ( c ) + whitespace += c; + + // compute line break + if (lineBreak) + { + line += whitespace; + line += word; + BrokenText.push_back(line); + BrokenTextPositions.push_back(lastLineStart); + lastLineStart = i+1; + line = L""; + word = L""; + whitespace = L""; + length = 0; + } + } + else + { + // yippee this is a word.. + word += c; + } + } + + line += whitespace; + line += word; + BrokenText.push_back(line); + BrokenTextPositions.push_back(lastLineStart); +} + +// TODO: that function does interpret VAlign according to line-index (indexed line is placed on top-center-bottom) +// but HAlign according to line-width (pixels) and not by row. +// Intuitively I suppose HAlign handling is better as VScrollPos should handle the line-scrolling. +// But please no one change this without also rewriting (and this time fucking testing!!!) autoscrolling (I noticed this when fixing the old autoscrolling). +void CGUIEditBox::setTextRect(s32 line) +{ + if ( line < 0 ) + return; + + IGUIFont* font = getActiveFont(); + if (!font) + return; + + core::dimension2du d; + + // get text dimension + const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1; + if (WordWrap || MultiLine) + { + d = font->getDimension(BrokenText[line].c_str()); + } + else + { + d = font->getDimension(Text.c_str()); + d.Height = AbsoluteRect.getHeight(); + } + d.Height += font->getKerningHeight(); + + // justification + switch (HAlign) + { + case EGUIA_CENTER: + // align to h centre + CurrentTextRect.UpperLeftCorner.X = (FrameRect.getWidth()/2) - (d.Width/2); + CurrentTextRect.LowerRightCorner.X = (FrameRect.getWidth()/2) + (d.Width/2); + break; + case EGUIA_LOWERRIGHT: + // align to right edge + CurrentTextRect.UpperLeftCorner.X = FrameRect.getWidth() - d.Width; + CurrentTextRect.LowerRightCorner.X = FrameRect.getWidth(); + break; + default: + // align to left edge + CurrentTextRect.UpperLeftCorner.X = 0; + CurrentTextRect.LowerRightCorner.X = d.Width; + + } + + switch (VAlign) + { + case EGUIA_CENTER: + // align to v centre + CurrentTextRect.UpperLeftCorner.Y = + (FrameRect.getHeight()/2) - (lineCount*d.Height)/2 + d.Height*line; + break; + case EGUIA_LOWERRIGHT: + // align to bottom edge + CurrentTextRect.UpperLeftCorner.Y = + FrameRect.getHeight() - lineCount*d.Height + d.Height*line; + break; + default: + // align to top edge + CurrentTextRect.UpperLeftCorner.Y = d.Height*line; + break; + } + + CurrentTextRect.UpperLeftCorner.X -= HScrollPos; + CurrentTextRect.LowerRightCorner.X -= HScrollPos; + CurrentTextRect.UpperLeftCorner.Y -= VScrollPos; + CurrentTextRect.LowerRightCorner.Y = CurrentTextRect.UpperLeftCorner.Y + d.Height; + + CurrentTextRect += FrameRect.UpperLeftCorner; + +} + + +s32 CGUIEditBox::getLineFromPos(s32 pos) +{ + if (!WordWrap && !MultiLine) + return 0; + + s32 i=0; + while (i < (s32)BrokenTextPositions.size()) + { + if (BrokenTextPositions[i] > pos) + return i-1; + ++i; + } + return (s32)BrokenTextPositions.size() - 1; +} + + +void CGUIEditBox::inputChar(wchar_t c) +{ + if (!isEnabled()) + return; + + if (c != 0) + { + if (Text.size() < Max || Max == 0) + { + core::stringw s; + + if (MarkBegin != MarkEnd) + { + // replace marked text + const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; + const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; + + s = Text.subString(0, realmbgn); + s.append(c); + s.append( Text.subString(realmend, Text.size()-realmend) ); + Text = s; + CursorPos = realmbgn+1; + } + else + { + // add new character + s = Text.subString(0, CursorPos); + s.append(c); + s.append( Text.subString(CursorPos, Text.size()-CursorPos) ); + Text = s; + ++CursorPos; + } + + BlinkStartTime = os::Timer::getTime(); + setTextMarkers(0, 0); + } + } + breakText(); + calculateScrollPos(); + sendGuiEvent(EGET_EDITBOX_CHANGED); +} + +// calculate autoscroll +void CGUIEditBox::calculateScrollPos() +{ + if (!AutoScroll) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont(); + if (!font) + return; + + s32 cursLine = getLineFromPos(CursorPos); + if ( cursLine < 0 ) + return; + setTextRect(cursLine); + const bool hasBrokenText = MultiLine || WordWrap; + + // Check horizonal scrolling + // NOTE: Calculations different to vertical scrolling because setTextRect interprets VAlign relative to line but HAlign not relative to row + { + // get cursor position + IGUIFont* font = getActiveFont(); + if (!font) + return; + + // get cursor area + irr::u32 cursorWidth = font->getDimension(L"_").Width; + core::stringw *txtLine = hasBrokenText ? &BrokenText[cursLine] : &Text; + s32 cPos = hasBrokenText ? CursorPos - BrokenTextPositions[cursLine] : CursorPos; // column + s32 cStart = font->getDimension(txtLine->subString(0, cPos).c_str()).Width; // pixels from text-start + s32 cEnd = cStart + cursorWidth; + s32 txtWidth = font->getDimension(txtLine->c_str()).Width; + + if ( txtWidth < FrameRect.getWidth() ) + { + // TODO: Needs a clean left and right gap removal depending on HAlign, similar to vertical scrolling tests for top/bottom. + // This check just fixes the case where it was most noticable (text smaller than clipping area). + + HScrollPos = 0; + setTextRect(cursLine); + } + + if ( CurrentTextRect.UpperLeftCorner.X+cStart < FrameRect.UpperLeftCorner.X ) + { + // cursor to the left of the clipping area + HScrollPos -= FrameRect.UpperLeftCorner.X-(CurrentTextRect.UpperLeftCorner.X+cStart); + setTextRect(cursLine); + + // TODO: should show more characters to the left when we're scrolling left + // and the cursor reaches the border. + } + else if ( CurrentTextRect.UpperLeftCorner.X+cEnd > FrameRect.LowerRightCorner.X) + { + // cursor to the right of the clipping area + HScrollPos += (CurrentTextRect.UpperLeftCorner.X+cEnd)-FrameRect.LowerRightCorner.X; + setTextRect(cursLine); + } + } + + // calculate vertical scrolling + if (hasBrokenText) + { + irr::u32 lineHeight = font->getDimension(L"A").Height + font->getKerningHeight(); + // only up to 1 line fits? + if ( lineHeight >= (irr::u32)FrameRect.getHeight() ) + { + VScrollPos = 0; + setTextRect(cursLine); + s32 unscrolledPos = CurrentTextRect.UpperLeftCorner.Y; + s32 pivot = FrameRect.UpperLeftCorner.Y; + switch (VAlign) + { + case EGUIA_CENTER: + pivot += FrameRect.getHeight()/2; + unscrolledPos += lineHeight/2; + break; + case EGUIA_LOWERRIGHT: + pivot += FrameRect.getHeight(); + unscrolledPos += lineHeight; + break; + default: + break; + } + VScrollPos = unscrolledPos-pivot; + setTextRect(cursLine); + } + else + { + // First 2 checks are necessary when people delete lines + setTextRect(0); + if ( CurrentTextRect.UpperLeftCorner.Y > FrameRect.UpperLeftCorner.Y && VAlign != EGUIA_LOWERRIGHT) + { + // first line is leaving a gap on top + VScrollPos = 0; + } + else if (VAlign != EGUIA_UPPERLEFT) + { + u32 lastLine = BrokenTextPositions.empty() ? 0 : BrokenTextPositions.size()-1; + setTextRect(lastLine); + if ( CurrentTextRect.LowerRightCorner.Y < FrameRect.LowerRightCorner.Y) + { + // last line is leaving a gap on bottom + VScrollPos -= FrameRect.LowerRightCorner.Y-CurrentTextRect.LowerRightCorner.Y; + } + } + + setTextRect(cursLine); + if ( CurrentTextRect.UpperLeftCorner.Y < FrameRect.UpperLeftCorner.Y ) + { + // text above valid area + VScrollPos -= FrameRect.UpperLeftCorner.Y-CurrentTextRect.UpperLeftCorner.Y; + setTextRect(cursLine); + } + else if ( CurrentTextRect.LowerRightCorner.Y > FrameRect.LowerRightCorner.Y) + { + // text below valid area + VScrollPos += CurrentTextRect.LowerRightCorner.Y-FrameRect.LowerRightCorner.Y; + setTextRect(cursLine); + } + } + } +} + +void CGUIEditBox::calculateFrameRect() +{ + FrameRect = AbsoluteRect; + IGUISkin *skin = 0; + if (Environment) + skin = Environment->getSkin(); + if (Border && skin) + { + FrameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X)+1; + FrameRect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; + FrameRect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X)+1; + FrameRect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y)+1; + } +} + +//! set text markers +void CGUIEditBox::setTextMarkers(s32 begin, s32 end) +{ + if ( begin != MarkBegin || end != MarkEnd ) + { + MarkBegin = begin; + MarkEnd = end; + sendGuiEvent(EGET_EDITBOX_MARKING_CHANGED); + } +} + +//! send some gui event to parent +void CGUIEditBox::sendGuiEvent(EGUI_EVENT_TYPE type) +{ + if ( Parent ) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = type; + + Parent->OnEvent(e); + } +} + +//! Writes attributes of the element. +void CGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + // IGUIEditBox::serializeAttributes(out,options); + + out->addBool ("Border", Border); + out->addBool ("Background", Background); + out->addBool ("OverrideColorEnabled", OverrideColorEnabled ); + out->addColor ("OverrideColor", OverrideColor); + // out->addFont("OverrideFont", OverrideFont); + out->addInt ("MaxChars", Max); + out->addBool ("WordWrap", WordWrap); + out->addBool ("MultiLine", MultiLine); + out->addBool ("AutoScroll", AutoScroll); + out->addBool ("PasswordBox", PasswordBox); + core::stringw ch = L" "; + ch[0] = PasswordChar; + out->addString("PasswordChar", ch.c_str()); + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + + IGUIEditBox::serializeAttributes(out,options); +} + + +//! Reads attributes of the element +void CGUIEditBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIEditBox::deserializeAttributes(in,options); + + setDrawBorder( in->getAttributeAsBool("Border") ); + setDrawBackground( in->getAttributeAsBool("Background") ); + setOverrideColor(in->getAttributeAsColor("OverrideColor")); + enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled")); + setMax(in->getAttributeAsInt("MaxChars")); + setWordWrap(in->getAttributeAsBool("WordWrap")); + setMultiLine(in->getAttributeAsBool("MultiLine")); + setAutoScroll(in->getAttributeAsBool("AutoScroll")); + core::stringw ch = in->getAttributeAsStringW("PasswordChar"); + + if (!ch.size()) + setPasswordBox(in->getAttributeAsBool("PasswordBox")); + else + setPasswordBox(in->getAttributeAsBool("PasswordBox"), ch[0]); + + setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames)); + + // setOverrideFont(in->getAttributeAsFont("OverrideFont")); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.d new file mode 100644 index 0000000..eb977af --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.d @@ -0,0 +1,2 @@ +CGUIEditBox.o: CGUIEditBox.cpp CGUIEditBox.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.h new file mode 100644 index 0000000..b80aa0f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEditBox.h @@ -0,0 +1,182 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_EDIT_BOX_H_INCLUDED__ +#define __C_GUI_EDIT_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEditBox.h" +#include "irrArray.h" +#include "IOSOperator.h" + +namespace irr +{ +namespace gui +{ + class CGUIEditBox : public IGUIEditBox + { + public: + + //! constructor + CGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle); + + //! destructor + virtual ~CGUIEditBox(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Gets the override font (if any) + /** \return The override font (may be 0) */ + virtual IGUIFont* getOverrideFont() const; + + //! Get the font which is used right now for drawing + /** Currently this is the override font when one is set and the + font of the active skin otherwise */ + virtual IGUIFont* getActiveFont() const; + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Gets the override color + virtual video::SColor getOverrideColor() const; + + //! Sets if the text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Checks if an override color is enabled + /** \return true if the override color is enabled, false otherwise */ + virtual bool isOverrideColorEnabled(void) const; + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + //! Turns the border on or off + virtual void setDrawBorder(bool border); + + //! Enables or disables word wrap for using the edit box as multiline text editor. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + //! \return true if word wrap is enabled, false otherwise + virtual bool isWordWrapEnabled() const; + + //! Enables or disables newlines. + /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, + instead a newline character will be inserted. */ + virtual void setMultiLine(bool enable); + + //! Checks if multi line editing is enabled + //! \return true if mult-line is enabled, false otherwise + virtual bool isMultiLineEnabled() const; + + //! Enables or disables automatic scrolling with cursor position + //! \param enable: If set to true, the text will move around with the cursor position + virtual void setAutoScroll(bool enable); + + //! Checks to see if automatic scrolling is enabled + //! \return true if automatic scrolling is enabled, false if not + virtual bool isAutoScrollEnabled() const; + + //! Gets the size area of the text in the edit box + //! \return Returns the size in pixels of the text + virtual core::dimension2du getTextDimension(); + + //! Sets text justification + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text); + + //! Sets the maximum amount of characters which may be entered in the box. + //! \param max: Maximum amount of characters. If 0, the character amount is + //! infinity. + virtual void setMax(u32 max); + + //! Returns maximum amount of characters, previously set by setMax(); + virtual u32 getMax() const; + + //! Sets whether the edit box is a password box. Setting this to true will + /** disable MultiLine, WordWrap and the ability to copy with ctrl+c or ctrl+x + \param passwordBox: true to enable password, false to disable + \param passwordChar: the character that is displayed instead of letters */ + virtual void setPasswordBox(bool passwordBox, wchar_t passwordChar = L'*'); + + //! Returns true if the edit box is currently a password box. + virtual bool isPasswordBox() const; + + //! Updates the absolute position, splits text if required + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + //! Breaks the single text line. + void breakText(); + //! sets the area of the given line + void setTextRect(s32 line); + //! returns the line number that the cursor is on + s32 getLineFromPos(s32 pos); + //! adds a letter to the edit box + void inputChar(wchar_t c); + //! calculates the current scroll position + void calculateScrollPos(); + //! calculated the FrameRect + void calculateFrameRect(); + //! send some gui event to parent + void sendGuiEvent(EGUI_EVENT_TYPE type); + //! set text markers + void setTextMarkers(s32 begin, s32 end); + + bool processKey(const SEvent& event); + bool processMouse(const SEvent& event); + s32 getCursorPos(s32 x, s32 y); + + bool MouseMarking; + bool Border; + bool Background; + bool OverrideColorEnabled; + s32 MarkBegin; + s32 MarkEnd; + + video::SColor OverrideColor; + gui::IGUIFont *OverrideFont, *LastBreakFont; + IOSOperator* Operator; + + u32 BlinkStartTime; + s32 CursorPos; + s32 HScrollPos, VScrollPos; // scroll position in characters + u32 Max; + + bool WordWrap, MultiLine, AutoScroll, PasswordBox; + wchar_t PasswordChar; + EGUI_ALIGNMENT HAlign, VAlign; + + core::array< core::stringw > BrokenText; + core::array< s32 > BrokenTextPositions; + + core::rect CurrentTextRect, FrameRect; // temporary values + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ +#endif // __C_GUI_EDIT_BOX_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.cpp new file mode 100644 index 0000000..bf3fa86 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.cpp @@ -0,0 +1,1658 @@ + +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIEnvironment.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IVideoDriver.h" + +#include "CGUISkin.h" +#include "CGUIButton.h" +#include "CGUIWindow.h" +#include "CGUIScrollBar.h" +#include "CGUIFont.h" +#include "CGUISpriteBank.h" +#include "CGUIImage.h" +#include "CGUIMeshViewer.h" +#include "CGUICheckBox.h" +#include "CGUIListBox.h" +#include "CGUITreeView.h" +#include "CGUIImageList.h" +#include "CGUIFileOpenDialog.h" +#include "CGUIColorSelectDialog.h" +#include "CGUIStaticText.h" +#include "CGUIEditBox.h" +#include "CGUISpinBox.h" +#include "CGUIInOutFader.h" +#include "CGUIMessageBox.h" +#include "CGUIModalScreen.h" +#include "CGUITabControl.h" +#include "CGUIContextMenu.h" +#include "CGUIComboBox.h" +#include "CGUIMenu.h" +#include "CGUIToolBar.h" +#include "CGUITable.h" + +#include "CDefaultGUIElementFactory.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" + +#include "BuiltInFont.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +const wchar_t* IRR_XML_FORMAT_GUI_ENV = L"irr_gui"; +const wchar_t* IRR_XML_FORMAT_GUI_ELEMENT = L"element"; +const wchar_t* IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE = L"type"; + +const io::path CGUIEnvironment::DefaultFontName = "#DefaultFont"; + +//! constructor +CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op) +: IGUIElement(EGUIET_ROOT, 0, 0, 0, core::rect(core::position2d(0,0), driver ? core::dimension2d(driver->getScreenSize()) : core::dimension2d(0,0))), + Driver(driver), Hovered(0), HoveredNoSubelement(0), Focus(0), LastHoveredMousePos(0,0), CurrentSkin(0), + FileSystem(fs), UserReceiver(0), Operator(op) +{ + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); + + if (Operator) + Operator->grab(); + + #ifdef _DEBUG + IGUIEnvironment::setDebugName("CGUIEnvironment"); + #endif + + // gui factory + IGUIElementFactory* factory = new CDefaultGUIElementFactory(this); + registerGUIElementFactory(factory); + factory->drop(); + + loadBuiltInFont(); + + IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC ); + setSkin(skin); + skin->drop(); + + //set tooltip default + ToolTip.LastTime = 0; + ToolTip.EnterTime = 0; + ToolTip.LaunchTime = 1000; + ToolTip.RelaunchTime = 500; + ToolTip.Element = 0; + + // environment is root tab group + Environment = this; + setTabGroup(true); +} + + +//! destructor +CGUIEnvironment::~CGUIEnvironment() +{ + if ( HoveredNoSubelement && HoveredNoSubelement != this ) + { + HoveredNoSubelement->drop(); + HoveredNoSubelement = 0; + } + + if (Hovered && Hovered != this) + { + Hovered->drop(); + Hovered = 0; + } + + if (Focus) + { + Focus->drop(); + Focus = 0; + } + + if (ToolTip.Element) + { + ToolTip.Element->drop(); + ToolTip.Element = 0; + } + + // drop skin + if (CurrentSkin) + { + CurrentSkin->drop(); + CurrentSkin = 0; + } + + u32 i; + + // delete all sprite banks + for (i=0; idrop(); + + // delete all fonts + for (i=0; idrop(); + + // remove all factories + for (i=0; idrop(); + + if (Operator) + { + Operator->drop(); + Operator = 0; + } + + if (FileSystem) + { + FileSystem->drop(); + FileSystem = 0; + } + + if (Driver) + { + Driver->drop(); + Driver = 0; + } +} + + +void CGUIEnvironment::loadBuiltInFont() +{ + io::IReadFile* file = io::createMemoryReadFile(BuiltInFontData, BuiltInFontDataSize, DefaultFontName, false); + + CGUIFont* font = new CGUIFont(this, DefaultFontName ); + if (!font->load(file)) + { + os::Printer::log("Error: Could not load built-in Font. Did you compile without the BMP loader?", ELL_ERROR); + font->drop(); + file->drop(); + return; + } + + SFont f; + f.NamedPath.setPath(DefaultFontName); + f.Font = font; + Fonts.push_back(f); + + file->drop(); +} + + +//! draws all gui elements +void CGUIEnvironment::drawAll() +{ + if (Driver) + { + core::dimension2d dim(Driver->getScreenSize()); + if (AbsoluteRect.LowerRightCorner.X != dim.Width || + AbsoluteRect.LowerRightCorner.Y != dim.Height) + { + // resize gui environment + DesiredRect.LowerRightCorner = dim; + AbsoluteClippingRect = DesiredRect; + AbsoluteRect = DesiredRect; + updateAbsolutePosition(); + } + } + + // make sure tooltip is always on top + if (ToolTip.Element) + bringToFront(ToolTip.Element); + + draw(); + OnPostRender ( os::Timer::getTime () ); +} + + +//! sets the focus to an element +bool CGUIEnvironment::setFocus(IGUIElement* element) +{ + if (Focus == element) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // GUI Environment should not get the focus + if (element == this) + element = 0; + + // stop element from being deleted + if (element) + element->grab(); + + // focus may change or be removed in this call + IGUIElement *currentFocus = 0; + if (Focus) + { + currentFocus = Focus; + currentFocus->grab(); + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = Focus; + e.GUIEvent.Element = element; + e.GUIEvent.EventType = EGET_ELEMENT_FOCUS_LOST; + if (Focus->OnEvent(e)) + { + if (element) + element->drop(); + currentFocus->drop(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + currentFocus->drop(); + currentFocus = 0; + } + + if (element) + { + currentFocus = Focus; + if (currentFocus) + currentFocus->grab(); + + // send focused event + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = element; + e.GUIEvent.Element = Focus; + e.GUIEvent.EventType = EGET_ELEMENT_FOCUSED; + if (element->OnEvent(e)) + { + if (element) + element->drop(); + if (currentFocus) + currentFocus->drop(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + } + + if (currentFocus) + currentFocus->drop(); + + if (Focus) + Focus->drop(); + + // element is the new focus so it doesn't have to be dropped + Focus = element; + + return true; +} + + +//! returns the element with the focus +IGUIElement* CGUIEnvironment::getFocus() const +{ + return Focus; +} + +//! returns the element last known to be under the mouse cursor +IGUIElement* CGUIEnvironment::getHovered() const +{ + return Hovered; +} + + +//! removes the focus from an element +bool CGUIEnvironment::removeFocus(IGUIElement* element) +{ + if (Focus && Focus==element) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = Focus; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_ELEMENT_FOCUS_LOST; + if (Focus->OnEvent(e)) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + } + if (Focus) + { + Focus->drop(); + Focus = 0; + } + + return true; +} + + +//! Returns if the element has focus +bool CGUIEnvironment::hasFocus(IGUIElement* element) const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (element == Focus); +} + + +//! returns the current video driver +video::IVideoDriver* CGUIEnvironment::getVideoDriver() const +{ + return Driver; +} + + +//! returns the current file system +io::IFileSystem* CGUIEnvironment::getFileSystem() const +{ + return FileSystem; +} + + +//! returns a pointer to the OS operator +IOSOperator* CGUIEnvironment::getOSOperator() const +{ + return Operator; +} + + +//! clear all GUI elements +void CGUIEnvironment::clear() +{ + // Remove the focus + if (Focus) + { + Focus->drop(); + Focus = 0; + } + + if (Hovered && Hovered != this) + { + Hovered->drop(); + Hovered = 0; + } + if ( HoveredNoSubelement && HoveredNoSubelement != this) + { + HoveredNoSubelement->drop(); + HoveredNoSubelement = 0; + } + + // get the root's children in case the root changes in future + const core::list& children = getRootGUIElement()->getChildren(); + + while (!children.empty()) + (*children.getLast())->remove(); +} + + +//! called by ui if an event happened. +bool CGUIEnvironment::OnEvent(const SEvent& event) +{ + bool ret = false; + if (UserReceiver + && (event.EventType != EET_MOUSE_INPUT_EVENT) + && (event.EventType != EET_KEY_INPUT_EVENT) + && (event.EventType != EET_GUI_EVENT || event.GUIEvent.Caller != this)) + { + ret = UserReceiver->OnEvent(event); + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + +// +void CGUIEnvironment::OnPostRender( u32 time ) +{ + // launch tooltip + if ( ToolTip.Element == 0 && + HoveredNoSubelement && HoveredNoSubelement != this && + (time - ToolTip.EnterTime >= ToolTip.LaunchTime + || (time - ToolTip.LastTime >= ToolTip.RelaunchTime && time - ToolTip.LastTime < ToolTip.LaunchTime)) && + HoveredNoSubelement->getToolTipText().size() && + getSkin() && + getSkin()->getFont(EGDF_TOOLTIP) + ) + { + core::rect pos; + + pos.UpperLeftCorner = LastHoveredMousePos; + core::dimension2du dim = getSkin()->getFont(EGDF_TOOLTIP)->getDimension(HoveredNoSubelement->getToolTipText().c_str()); + dim.Width += getSkin()->getSize(EGDS_TEXT_DISTANCE_X)*2; + dim.Height += getSkin()->getSize(EGDS_TEXT_DISTANCE_Y)*2; + + pos.UpperLeftCorner.Y -= dim.Height+1; + pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + dim.Height-1; + pos.LowerRightCorner.X = pos.UpperLeftCorner.X + dim.Width; + + pos.constrainTo(getAbsolutePosition()); + + ToolTip.Element = addStaticText(HoveredNoSubelement->getToolTipText().c_str(), pos, true, true, this, -1, true); + ToolTip.Element->setOverrideColor(getSkin()->getColor(EGDC_TOOLTIP)); + ToolTip.Element->setBackgroundColor(getSkin()->getColor(EGDC_TOOLTIP_BACKGROUND)); + ToolTip.Element->setOverrideFont(getSkin()->getFont(EGDF_TOOLTIP)); + ToolTip.Element->setSubElement(true); + ToolTip.Element->grab(); + + s32 textHeight = ToolTip.Element->getTextHeight(); + pos = ToolTip.Element->getRelativePosition(); + pos.LowerRightCorner.Y = pos.UpperLeftCorner.Y + textHeight; + ToolTip.Element->setRelativePosition(pos); + } + + if (ToolTip.Element && ToolTip.Element->isVisible() ) // (isVisible() check only because we might use visibility for ToolTip one day) + { + ToolTip.LastTime = time; + + // got invisible or removed in the meantime? + if ( !HoveredNoSubelement || + !HoveredNoSubelement->isVisible() || + !HoveredNoSubelement->getParent() + ) // got invisible or removed in the meantime? + { + ToolTip.Element->remove(); + ToolTip.Element->drop(); + ToolTip.Element = 0; + } + } + + IGUIElement::OnPostRender ( time ); +} + + +// +void CGUIEnvironment::updateHoveredElement(core::position2d mousePos) +{ + IGUIElement* lastHovered = Hovered; + IGUIElement* lastHoveredNoSubelement = HoveredNoSubelement; + LastHoveredMousePos = mousePos; + + Hovered = getElementFromPoint(mousePos); + + if ( ToolTip.Element && Hovered == ToolTip.Element ) + { + // When the mouse is over the ToolTip we remove that so it will be re-created at a new position. + // Note that ToolTip.EnterTime does not get changed here, so it will be re-created at once. + ToolTip.Element->remove(); + ToolTip.Element->drop(); + ToolTip.Element = 0; + + // Get the real Hovered + Hovered = getElementFromPoint(mousePos); + } + + // for tooltips we want the element itself and not some of it's subelements + HoveredNoSubelement = Hovered; + while ( HoveredNoSubelement && HoveredNoSubelement->isSubElement() ) + { + HoveredNoSubelement = HoveredNoSubelement->getParent(); + } + + if (Hovered && Hovered != this) + Hovered->grab(); + if ( HoveredNoSubelement && HoveredNoSubelement != this) + HoveredNoSubelement->grab(); + + if (Hovered != lastHovered) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + + if (lastHovered) + { + event.GUIEvent.Caller = lastHovered; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_ELEMENT_LEFT; + lastHovered->OnEvent(event); + } + + if ( Hovered ) + { + event.GUIEvent.Caller = Hovered; + event.GUIEvent.Element = Hovered; + event.GUIEvent.EventType = EGET_ELEMENT_HOVERED; + Hovered->OnEvent(event); + } + } + + if ( lastHoveredNoSubelement != HoveredNoSubelement ) + { + if (ToolTip.Element) + { + ToolTip.Element->remove(); + ToolTip.Element->drop(); + ToolTip.Element = 0; + } + + if ( HoveredNoSubelement ) + { + u32 now = os::Timer::getTime(); + ToolTip.EnterTime = now; + } + } + + if (lastHovered && lastHovered != this) + lastHovered->drop(); + if (lastHoveredNoSubelement && lastHoveredNoSubelement != this) + lastHoveredNoSubelement->drop(); +} + + +//! This sets a new event receiver for gui events. Usually you do not have to +//! use this method, it is used by the internal engine. +void CGUIEnvironment::setUserEventReceiver(IEventReceiver* evr) +{ + UserReceiver = evr; +} + + +//! posts an input event to the environment +bool CGUIEnvironment::postEventFromUser(const SEvent& event) +{ + switch(event.EventType) + { + case EET_GUI_EVENT: + // hey, why is the user sending gui events..? + break; + case EET_MOUSE_INPUT_EVENT: + + updateHoveredElement(core::position2d(event.MouseInput.X, event.MouseInput.Y)); + + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + if ( (Hovered && Hovered != Focus) || !Focus ) + { + setFocus(Hovered); + } + + // sending input to focus + if (Focus && Focus->OnEvent(event)) + return true; + + // focus could have died in last call + if (!Focus && Hovered) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Hovered->OnEvent(event); + } + + break; + case EET_KEY_INPUT_EVENT: + { + if (Focus && Focus->OnEvent(event)) + return true; + + // For keys we handle the event before changing focus to give elements the chance for catching the TAB + // Send focus changing event + if (event.EventType == EET_KEY_INPUT_EVENT && + event.KeyInput.PressedDown && + event.KeyInput.Key == KEY_TAB) + { + IGUIElement *next = getNextElement(event.KeyInput.Shift, event.KeyInput.Control); + if (next && next != Focus) + { + if (setFocus(next)) + return true; + } + } + + } + break; + default: + break; + } // end switch + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; +} + + +//! returns the current gui skin +IGUISkin* CGUIEnvironment::getSkin() const +{ + return CurrentSkin; +} + + +//! Sets a new GUI Skin +void CGUIEnvironment::setSkin(IGUISkin* skin) +{ + if (CurrentSkin==skin) + return; + + if (CurrentSkin) + CurrentSkin->drop(); + + CurrentSkin = skin; + + if (CurrentSkin) + CurrentSkin->grab(); +} + + +//! Creates a new GUI Skin based on a template. +/** \return Returns a pointer to the created skin. +If you no longer need the skin, you should call IGUISkin::drop(). +See IReferenceCounted::drop() for more information. */ +IGUISkin* CGUIEnvironment::createSkin(EGUI_SKIN_TYPE type) +{ + IGUISkin* skin = new CGUISkin(type, Driver); + + IGUIFont* builtinfont = getBuiltInFont(); + IGUIFontBitmap* bitfont = 0; + if (builtinfont && builtinfont->getType() == EGFT_BITMAP) + bitfont = (IGUIFontBitmap*)builtinfont; + + IGUISpriteBank* bank = 0; + skin->setFont(builtinfont); + + if (bitfont) + bank = bitfont->getSpriteBank(); + + skin->setSpriteBank(bank); + + return skin; +} + + +//! Returns the default element factory which can create all built in elements +IGUIElementFactory* CGUIEnvironment::getDefaultGUIElementFactory() const +{ + return getGUIElementFactory(0); +} + + +//! Adds an element factory to the gui environment. +/** Use this to extend the gui environment with new element types which it should be +able to create automaticly, for example when loading data from xml files. */ +void CGUIEnvironment::registerGUIElementFactory(IGUIElementFactory* factoryToAdd) +{ + if (factoryToAdd) + { + factoryToAdd->grab(); + GUIElementFactoryList.push_back(factoryToAdd); + } +} + + +//! Returns amount of registered scene node factories. +u32 CGUIEnvironment::getRegisteredGUIElementFactoryCount() const +{ + return GUIElementFactoryList.size(); +} + + +//! Returns a scene node factory by index +IGUIElementFactory* CGUIEnvironment::getGUIElementFactory(u32 index) const +{ + if (index < GUIElementFactoryList.size()) + return GUIElementFactoryList[index]; + else + return 0; +} + + +//! adds a GUI Element using its name +IGUIElement* CGUIEnvironment::addGUIElement(const c8* elementName, IGUIElement* parent) +{ + IGUIElement* node=0; + + if (!parent) + parent = this; + + for (s32 i=GUIElementFactoryList.size()-1; i>=0 && !node; --i) + node = GUIElementFactoryList[i]->addGUIElement(elementName, parent); + + + return node; +} + + +//! Saves the current gui into a file. +//! \param filename: Name of the file . +bool CGUIEnvironment::saveGUI(const io::path& filename, IGUIElement* start) +{ + io::IWriteFile* file = FileSystem->createAndWriteFile(filename); + if (!file) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + bool ret = saveGUI(file, start); + file->drop(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! Saves the current gui into a file. +bool CGUIEnvironment::saveGUI(io::IWriteFile* file, IGUIElement* start) +{ + if (!file) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + io::IXMLWriter* writer = FileSystem->createXMLWriter(file); + if (!writer) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + writer->writeXMLHeader(); + writeGUIElement(writer, start ? start : this); + writer->drop(); + + return true; +} + + +//! Loads the gui. Note that the current gui is not cleared before. +//! \param filename: Name of the file. +bool CGUIEnvironment::loadGUI(const io::path& filename, IGUIElement* parent) +{ + io::IReadFile* read = FileSystem->createAndOpenFile(filename); + if (!read) + { + os::Printer::log("Unable to open gui file", filename, ELL_ERROR); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + bool ret = loadGUI(read, parent); + read->drop(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! Loads the gui. Note that the current gui is not cleared before. +bool CGUIEnvironment::loadGUI(io::IReadFile* file, IGUIElement* parent) +{ + if (!file) + { + os::Printer::log("Unable to open GUI file", ELL_ERROR); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + { + os::Printer::log("GUI is not a valid XML file", file->getFileName(), ELL_ERROR); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + // read file + while(reader->read()) + { + readGUIElement(reader, parent); + } + + // finish up + + reader->drop(); + return true; +} + + +//! reads an element +void CGUIEnvironment::readGUIElement(io::IXMLReader* reader, IGUIElement* node) +{ + if (!reader) + return; + + io::EXML_NODE nodeType = reader->getNodeType(); + + if (nodeType == io::EXN_NONE || nodeType == io::EXN_UNKNOWN || nodeType == io::EXN_ELEMENT_END) + return; + + IGUIElement* deferedNode = 0; + if (!wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + // GuiEnvironment always must be this as it would serialize into a wrong element otherwise. + // So we use the given node next time + if ( node && node != this ) + deferedNode = node; + node = this; // root + } + else if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName())) + { + // find node type and create it + const core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE); + + node = addGUIElement(attrName.c_str(), node); + + if (!node) + os::Printer::log("Could not create GUI element of unknown type", attrName.c_str()); + } + + // read attributes + + while(reader->read()) + { + bool endreached = false; + + switch (reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || + !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + endreached = true; + } + break; + case io::EXN_ELEMENT: + if (!wcscmp(L"attributes", reader->getNodeName())) + { + // read attributes + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + attr->read(reader, true); + + if (node) + node->deserializeAttributes(attr); + + attr->drop(); + } + else + if (!wcscmp(IRR_XML_FORMAT_GUI_ELEMENT, reader->getNodeName()) || + !wcscmp(IRR_XML_FORMAT_GUI_ENV, reader->getNodeName())) + { + if ( deferedNode ) + readGUIElement(reader, deferedNode); + else + readGUIElement(reader, node); + } + else + { + os::Printer::log("Found unknown element in irrlicht GUI file", + core::stringc(reader->getNodeName()).c_str()); + } + + break; + default: + break; + } + + if (endreached) + break; + } +} + + +//! writes an element +void CGUIEnvironment::writeGUIElement(io::IXMLWriter* writer, IGUIElement* node) +{ + if (!writer || !node ) + return; + + const wchar_t* name = 0; + + // write properties + + io::IAttributes* attr = FileSystem->createEmptyAttributes(); + node->serializeAttributes(attr); + + // all gui elements must have at least one attribute + // if they have nothing then we ignore them. + if (attr->getAttributeCount() != 0) + { + if (node == this) + { + name = IRR_XML_FORMAT_GUI_ENV; + writer->writeElement(name, false); + } + else + { + name = IRR_XML_FORMAT_GUI_ELEMENT; + writer->writeElement(name, false, IRR_XML_FORMAT_GUI_ELEMENT_ATTR_TYPE, + core::stringw(node->getTypeName()).c_str()); + } + + writer->writeLineBreak(); + writer->writeLineBreak(); + + attr->write(writer); + writer->writeLineBreak(); + } + + // write children + + core::list::ConstIterator it = node->getChildren().begin(); + for (; it != node->getChildren().end(); ++it) + { + if (!(*it)->isSubElement()) + writeGUIElement(writer, (*it)); + } + + // write closing brace if required + if (attr->getAttributeCount() != 0) + { + writer->writeClosingTag(name); + writer->writeLineBreak(); + writer->writeLineBreak(); + } + + attr->drop(); +} + + +//! Writes attributes of the environment +void CGUIEnvironment::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IGUISkin* skin = getSkin(); + + if (skin) + { + out->addEnum("Skin", getSkin()->getType(), GUISkinTypeNames); + skin->serializeAttributes(out, options); + } +} + + +//! Reads attributes of the environment +void CGUIEnvironment::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + if (in->existsAttribute("Skin")) + { + IGUISkin *skin = getSkin(); + + EGUI_SKIN_TYPE t = (EGUI_SKIN_TYPE) in->getAttributeAsEnumeration("Skin",GUISkinTypeNames); + if ( !skin || t != skin->getType()) + { + skin = createSkin(t); + setSkin(skin); + skin->drop(); + } + + skin = getSkin(); + + if (skin) + { + skin->deserializeAttributes(in, options); + } + + } + + RelativeRect = AbsoluteRect = + core::rect(core::position2d(0,0), + Driver ? core::dimension2di(Driver->getScreenSize()) : core::dimension2d(0,0)); +} + + +//! adds a button. The returned pointer must not be dropped. +IGUIButton* CGUIEnvironment::addButton(const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text, const wchar_t *tooltiptext) +{ + IGUIButton* button = new CGUIButton(this, parent ? parent : this, id, rectangle); + if (text) + button->setText(text); + + if ( tooltiptext ) + button->setToolTipText ( tooltiptext ); + + button->drop(); + return button; +} + + +//! adds a window. The returned pointer must not be dropped. +IGUIWindow* CGUIEnvironment::addWindow(const core::rect& rectangle, bool modal, + const wchar_t* text, IGUIElement* parent, s32 id) +{ + parent = parent ? parent : this; + + IGUIWindow* win = new CGUIWindow(this, parent, id, rectangle); + if (text) + win->setText(text); + win->drop(); + + if (modal) + { + // Careful, don't just set the modal as parent above. That will mess up the focus (and is hard to change because we have to be very + // careful not to get virtual function call, like OnEvent, in the window. + CGUIModalScreen * modalScreen = new CGUIModalScreen(this, parent, -1); + modalScreen->drop(); + modalScreen->addChild(win); + } + + return win; +} + + +//! adds a modal screen. The returned pointer must not be dropped. +IGUIElement* CGUIEnvironment::addModalScreen(IGUIElement* parent) +{ + parent = parent ? parent : this; + + IGUIElement *win = new CGUIModalScreen(this, parent, -1); + win->drop(); + + return win; +} + + +//! Adds a message box. +IGUIWindow* CGUIEnvironment::addMessageBox(const wchar_t* caption, const wchar_t* text, + bool modal, s32 flag, IGUIElement* parent, s32 id, video::ITexture* image) +{ + if (!CurrentSkin) + return 0; + + parent = parent ? parent : this; + + core::rect rect; + core::dimension2d screenDim, msgBoxDim; + + screenDim.Width = parent->getAbsolutePosition().getWidth(); + screenDim.Height = parent->getAbsolutePosition().getHeight(); + msgBoxDim.Width = 2; + msgBoxDim.Height = 2; + + rect.UpperLeftCorner.X = (screenDim.Width - msgBoxDim.Width) / 2; + rect.UpperLeftCorner.Y = (screenDim.Height - msgBoxDim.Height) / 2; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + msgBoxDim.Width; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + msgBoxDim.Height; + + IGUIWindow* win = new CGUIMessageBox(this, caption, text, flag, + parent, id, rect, image); + win->drop(); + + if (modal) + { + // Careful, don't just set the modal as parent above. That will mess up the focus (and is hard to change because we have to be very + // careful not to get virtual function call, like OnEvent, in the CGUIMessageBox. + CGUIModalScreen * modalScreen = new CGUIModalScreen(this, parent, -1); + modalScreen->drop(); + modalScreen->addChild( win ); + } + + + return win; +} + + +//! adds a scrollbar. The returned pointer must not be dropped. +IGUIScrollBar* CGUIEnvironment::addScrollBar(bool horizontal, const core::rect& rectangle, IGUIElement* parent, s32 id) +{ + IGUIScrollBar* bar = new CGUIScrollBar(horizontal, this, parent ? parent : this, id, rectangle); + bar->drop(); + return bar; +} + +//! Adds a table to the environment +IGUITable* CGUIEnvironment::addTable(const core::rect& rectangle, IGUIElement* parent, s32 id, bool drawBackground) +{ + CGUITable* b = new CGUITable(this, parent ? parent : this, id, rectangle, true, drawBackground, false); + b->drop(); + return b; +} + + +//! Adds an image element. +IGUIImage* CGUIEnvironment::addImage(video::ITexture* image, core::position2d pos, + bool useAlphaChannel, IGUIElement* parent, s32 id, const wchar_t* text) +{ + core::dimension2d sz(0,0); + if (image) + sz = core::dimension2d(image->getOriginalSize()); + + IGUIImage* img = new CGUIImage(this, parent ? parent : this, + id, core::rect(pos, sz)); + + if (text) + img->setText(text); + + if (useAlphaChannel) + img->setUseAlphaChannel(true); + + if (image) + img->setImage(image); + + img->drop(); + return img; +} + + +//! adds an image. The returned pointer must not be dropped. +IGUIImage* CGUIEnvironment::addImage(const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text, bool useAlphaChannel) +{ + IGUIImage* img = new CGUIImage(this, parent ? parent : this, + id, rectangle); + + if (text) + img->setText(text); + + if ( useAlphaChannel ) + img->setUseAlphaChannel(true); + + img->drop(); + return img; +} + + +//! adds an mesh viewer. The returned pointer must not be dropped. +IGUIMeshViewer* CGUIEnvironment::addMeshViewer(const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text) +{ + IGUIMeshViewer* v = new CGUIMeshViewer(this, parent ? parent : this, + id, rectangle); + + if (text) + v->setText(text); + + v->drop(); + return v; +} + + +//! adds a checkbox +IGUICheckBox* CGUIEnvironment::addCheckBox(bool checked, const core::rect& rectangle, IGUIElement* parent, s32 id, const wchar_t* text) +{ + IGUICheckBox* b = new CGUICheckBox(checked, this, + parent ? parent : this , id , rectangle); + + if (text) + b->setText(text); + + b->drop(); + return b; +} + + +//! adds a list box +IGUIListBox* CGUIEnvironment::addListBox(const core::rect& rectangle, + IGUIElement* parent, s32 id, bool drawBackground) +{ + IGUIListBox* b = new CGUIListBox(this, parent ? parent : this, id, rectangle, + true, drawBackground, false); + + if (CurrentSkin && CurrentSkin->getSpriteBank()) + { + b->setSpriteBank(CurrentSkin->getSpriteBank()); + } + else if (getBuiltInFont() && getBuiltInFont()->getType() == EGFT_BITMAP) + { + b->setSpriteBank( ((IGUIFontBitmap*)getBuiltInFont())->getSpriteBank()); + } + + b->drop(); + return b; +} + +//! adds a tree view +IGUITreeView* CGUIEnvironment::addTreeView(const core::rect& rectangle, + IGUIElement* parent, s32 id, + bool drawBackground, + bool scrollBarVertical, bool scrollBarHorizontal) +{ + IGUITreeView* b = new CGUITreeView(this, parent ? parent : this, id, rectangle, + true, drawBackground, scrollBarVertical, scrollBarHorizontal); + + b->setIconFont ( getBuiltInFont () ); + b->drop(); + return b; +} + +//! adds a file open dialog. The returned pointer must not be dropped. +IGUIFileOpenDialog* CGUIEnvironment::addFileOpenDialog(const wchar_t* title, + bool modal, IGUIElement* parent, s32 id, + bool restoreCWD, io::path::char_type* startDir) +{ + parent = parent ? parent : this; + + IGUIFileOpenDialog* d = new CGUIFileOpenDialog(title, this, parent, id, + restoreCWD, startDir); + d->drop(); + + if (modal) + { + // Careful, don't just set the modal as parent above. That will mess up the focus (and is hard to change because we have to be very + // careful not to get virtual function call, like OnEvent, in the window. + CGUIModalScreen * modalScreen = new CGUIModalScreen(this, parent, -1); + modalScreen->drop(); + modalScreen->addChild(d); + } + + return d; +} + + +//! adds a color select dialog. The returned pointer must not be dropped. +IGUIColorSelectDialog* CGUIEnvironment::addColorSelectDialog(const wchar_t* title, + bool modal, IGUIElement* parent, s32 id) +{ + parent = parent ? parent : this; + + IGUIColorSelectDialog* d = new CGUIColorSelectDialog( title, + this, parent, id); + d->drop(); + + if (modal) + { + // Careful, don't just set the modal as parent above. That will mess up the focus (and is hard to change because we have to be very + // careful not to get virtual function call, like OnEvent, in the window. + CGUIModalScreen * modalScreen = new CGUIModalScreen(this, parent, -1); + modalScreen->drop(); + modalScreen->addChild(d); + } + + return d; +} + + +//! adds a static text. The returned pointer must not be dropped. +IGUIStaticText* CGUIEnvironment::addStaticText(const wchar_t* text, + const core::rect& rectangle, + bool border, bool wordWrap, + IGUIElement* parent, s32 id, bool background) +{ + IGUIStaticText* d = new CGUIStaticText(text, border, this, + parent ? parent : this, id, rectangle, background); + + d->setWordWrap(wordWrap); + d->drop(); + + return d; +} + + +//! Adds an edit box. The returned pointer must not be dropped. +IGUIEditBox* CGUIEnvironment::addEditBox(const wchar_t* text, + const core::rect& rectangle, bool border, + IGUIElement* parent, s32 id) +{ + IGUIEditBox* d = new CGUIEditBox(text, border, this, + parent ? parent : this, id, rectangle); + + d->drop(); + return d; +} + + +//! Adds a spin box to the environment +IGUISpinBox* CGUIEnvironment::addSpinBox(const wchar_t* text, + const core::rect &rectangle, + bool border,IGUIElement* parent, s32 id) +{ + IGUISpinBox* d = new CGUISpinBox(text, border,this, + parent ? parent : this, id, rectangle); + + d->drop(); + return d; +} + + +//! Adds a tab control to the environment. +IGUITabControl* CGUIEnvironment::addTabControl(const core::rect& rectangle, + IGUIElement* parent, bool fillbackground, bool border, s32 id) +{ + IGUITabControl* t = new CGUITabControl(this, parent ? parent : this, + rectangle, fillbackground, border, id); + t->drop(); + return t; +} + + +//! Adds tab to the environment. +IGUITab* CGUIEnvironment::addTab(const core::rect& rectangle, + IGUIElement* parent, s32 id) +{ + IGUITab* t = new CGUITab(-1, this, parent ? parent : this, + rectangle, id); + t->drop(); + return t; +} + + +//! Adds a context menu to the environment. +IGUIContextMenu* CGUIEnvironment::addContextMenu(const core::rect& rectangle, + IGUIElement* parent, s32 id) +{ + IGUIContextMenu* c = new CGUIContextMenu(this, + parent ? parent : this, id, rectangle, true); + c->drop(); + return c; +} + + +//! Adds a menu to the environment. +IGUIContextMenu* CGUIEnvironment::addMenu(IGUIElement* parent, s32 id) +{ + if (!parent) + parent = this; + + IGUIContextMenu* c = new CGUIMenu(this, + parent, id, core::rect(0,0, + parent->getAbsolutePosition().getWidth(), + parent->getAbsolutePosition().getHeight())); + + c->drop(); + return c; +} + + +//! Adds a toolbar to the environment. It is like a menu is always placed on top +//! in its parent, and contains buttons. +IGUIToolBar* CGUIEnvironment::addToolBar(IGUIElement* parent, s32 id) +{ + if (!parent) + parent = this; + + IGUIToolBar* b = new CGUIToolBar(this, parent, id, core::rect(0,0,10,10)); + b->drop(); + return b; +} + + +//! Adds an element for fading in or out. +IGUIInOutFader* CGUIEnvironment::addInOutFader(const core::rect* rectangle, IGUIElement* parent, s32 id) +{ + core::rect rect; + + if (rectangle) + rect = *rectangle; + else if (Driver) + rect = core::rect(core::position2d(0,0), core::dimension2di(Driver->getScreenSize())); + + if (!parent) + parent = this; + + IGUIInOutFader* fader = new CGUIInOutFader(this, parent, id, rect); + fader->drop(); + return fader; +} + + +//! Adds a combo box to the environment. +IGUIComboBox* CGUIEnvironment::addComboBox(const core::rect& rectangle, + IGUIElement* parent, s32 id) +{ + IGUIComboBox* t = new CGUIComboBox(this, parent ? parent : this, + id, rectangle); + t->drop(); + return t; +} + + +//! returns the font +IGUIFont* CGUIEnvironment::getFont(const io::path& filename) +{ + // search existing font + + SFont f; + f.NamedPath.setPath(filename); + + s32 index = Fonts.binary_search(f); + if (index != -1) + return Fonts[index].Font; + + // font doesn't exist, attempt to load it + + // does the file exist? + + if (!FileSystem->existFile(filename)) + { + os::Printer::log("Could not load font because the file does not exist", f.NamedPath.getPath(), ELL_ERROR); + return 0; + } + + IGUIFont* ifont=0; + io::IXMLReader *xml = FileSystem->createXMLReader(filename ); + if (xml) + { + // this is an XML font, but we need to know what type + EGUI_FONT_TYPE t = EGFT_CUSTOM; + + bool found=false; + while(!found && xml->read()) + { + if (xml->getNodeType() == io::EXN_ELEMENT) + { + if (core::stringw(L"font") == xml->getNodeName()) + { + if (core::stringw(L"vector") == xml->getAttributeValue(L"type")) + { + t = EGFT_VECTOR; + found=true; + } + else if (core::stringw(L"bitmap") == xml->getAttributeValue(L"type")) + { + t = EGFT_BITMAP; + found=true; + } + else found=true; + } + } + } + + if (t==EGFT_BITMAP) + { + CGUIFont* font = new CGUIFont(this, filename); + ifont = (IGUIFont*)font; + // change working directory, for loading textures + io::path workingDir = FileSystem->getWorkingDirectory(); + FileSystem->changeWorkingDirectoryTo(FileSystem->getFileDir(f.NamedPath.getPath())); + + // load the font + if (!font->load(xml)) + { + font->drop(); + font = 0; + ifont = 0; + } + // change working dir back again + FileSystem->changeWorkingDirectoryTo( workingDir ); + } + else if (t==EGFT_VECTOR) + { + // todo: vector fonts + os::Printer::log("Unable to load font, XML vector fonts are not supported yet", f.NamedPath, ELL_ERROR); + + //CGUIFontVector* font = new CGUIFontVector(Driver); + //ifont = (IGUIFont*)font; + //if (!font->load(xml)) + } + xml->drop(); + } + + + if (!ifont) + { + + CGUIFont* font = new CGUIFont(this, f.NamedPath.getPath() ); + ifont = (IGUIFont*)font; + if (!font->load(f.NamedPath.getPath())) + { + font->drop(); + return 0; + } + } + + // add to fonts. + + f.Font = ifont; + Fonts.push_back(f); + + return ifont; +} + + +//! add an externally loaded font +IGUIFont* CGUIEnvironment::addFont(const io::path& name, IGUIFont* font) +{ + if (font) + { + SFont f; + f.NamedPath.setPath(name); + s32 index = Fonts.binary_search(f); + if (index != -1) + return Fonts[index].Font; + f.Font = font; + Fonts.push_back(f); + font->grab(); + } + return font; +} + +//! remove loaded font +void CGUIEnvironment::removeFont(IGUIFont* font) +{ + if ( !font ) + return; + for ( u32 i=0; idrop(); + Fonts.erase(i); + return; + } + } +} + +//! returns default font +IGUIFont* CGUIEnvironment::getBuiltInFont() const +{ + if (Fonts.empty()) + return 0; + + return Fonts[0].Font; +} + + +IGUISpriteBank* CGUIEnvironment::getSpriteBank(const io::path& filename) +{ + // search for the file name + + SSpriteBank b; + b.NamedPath.setPath(filename); + + s32 index = Banks.binary_search(b); + if (index != -1) + return Banks[index].Bank; + + // we don't have this sprite bank, we should load it + if (!FileSystem->existFile(b.NamedPath.getPath())) + { + if ( filename != DefaultFontName ) + { + os::Printer::log("Could not load sprite bank because the file does not exist", b.NamedPath.getPath(), ELL_DEBUG); + } + return 0; + } + + // todo: load it! + + return 0; +} + + +IGUISpriteBank* CGUIEnvironment::addEmptySpriteBank(const io::path& name) +{ + // no duplicate names allowed + + SSpriteBank b; + b.NamedPath.setPath(name); + + const s32 index = Banks.binary_search(b); + if (index != -1) + return 0; + + // create a new sprite bank + + b.Bank = new CGUISpriteBank(this); + Banks.push_back(b); + + return b.Bank; +} + + +//! Creates the image list from the given texture. +IGUIImageList* CGUIEnvironment::createImageList( video::ITexture* texture, + core::dimension2d imageSize, bool useAlphaChannel ) +{ + CGUIImageList* imageList = new CGUIImageList( Driver ); + if( !imageList->createImageList( texture, imageSize, useAlphaChannel ) ) + { + imageList->drop(); + return 0; + } + + return imageList; +} + +//! Returns the root gui element. +IGUIElement* CGUIEnvironment::getRootGUIElement() +{ + return this; +} + + +//! Returns the next element in the tab group starting at the focused element +IGUIElement* CGUIEnvironment::getNextElement(bool reverse, bool group) +{ + // start the search at the root of the current tab group + IGUIElement *startPos = Focus ? Focus->getTabGroup() : 0; + s32 startOrder = -1; + + // if we're searching for a group + if (group && startPos) + { + startOrder = startPos->getTabOrder(); + } + else + if (!group && Focus && !Focus->isTabGroup()) + { + startOrder = Focus->getTabOrder(); + if (startOrder == -1) + { + // this element is not part of the tab cycle, + // but its parent might be... + IGUIElement *el = Focus; + while (el && el->getParent() && startOrder == -1) + { + el = el->getParent(); + startOrder = el->getTabOrder(); + } + + } + } + + if (group || !startPos) + startPos = this; // start at the root + + // find the element + IGUIElement *closest = 0; + IGUIElement *first = 0; + startPos->getNextElement(startOrder, reverse, group, first, closest); + + if (closest) + return closest; // we found an element + else if (first) + return first; // go to the end or the start + else if (group) + return this; // no group found? root group + else + return 0; +} + + +//! creates an GUI Environment +IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs, + video::IVideoDriver* Driver, + IOSOperator* op) +{ + return new CGUIEnvironment(fs, Driver, op); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.d new file mode 100644 index 0000000..e4563c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.d @@ -0,0 +1,2 @@ +CGUIEnvironment.o: CGUIEnvironment.cpp CGUIEnvironment.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.h new file mode 100644 index 0000000..6b3be3b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIEnvironment.h @@ -0,0 +1,323 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_ENVIRONMENT_H_INCLUDED__ +#define __C_GUI_ENVIRONMENT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IGUIElement.h" +#include "irrArray.h" +#include "IFileSystem.h" +#include "IOSOperator.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; +} +namespace gui +{ + +class CGUIEnvironment : public IGUIEnvironment, public IGUIElement +{ +public: + + //! constructor + CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* driver, IOSOperator* op); + + //! destructor + virtual ~CGUIEnvironment(); + + //! draws all gui elements + virtual void drawAll(); + + //! returns the current video driver + virtual video::IVideoDriver* getVideoDriver() const; + + //! returns pointer to the filesystem + virtual io::IFileSystem* getFileSystem() const; + + //! returns a pointer to the OS operator + virtual IOSOperator* getOSOperator() const; + + //! posts an input event to the environment + virtual bool postEventFromUser(const SEvent& event); + + //! This sets a new event receiver for gui events. Usually you do not have to + //! use this method, it is used by the internal engine. + virtual void setUserEventReceiver(IEventReceiver* evr); + + //! removes all elements from the environment + virtual void clear(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! returns the current gui skin + virtual IGUISkin* getSkin() const; + + //! Sets a new GUI Skin + virtual void setSkin(IGUISkin* skin); + + //! Creates a new GUI Skin based on a template. + /** \return Returns a pointer to the created skin. + If you no longer need the skin, you should call IGUISkin::drop(). + See IReferenceCounted::drop() for more information. */ + virtual IGUISkin* createSkin(EGUI_SKIN_TYPE type); + + //! Creates the image list from the given texture. + virtual IGUIImageList* createImageList( video::ITexture* texture, + core::dimension2d imageSize, bool useAlphaChannel ); + + //! returns the font + virtual IGUIFont* getFont(const io::path& filename); + + //! add an externally loaded font + virtual IGUIFont* addFont(const io::path& name, IGUIFont* font); + + //! remove loaded font + virtual void removeFont(IGUIFont* font); + + //! returns default font + virtual IGUIFont* getBuiltInFont() const; + + //! returns the sprite bank + virtual IGUISpriteBank* getSpriteBank(const io::path& filename); + + //! returns the sprite bank + virtual IGUISpriteBank* addEmptySpriteBank(const io::path& name); + + //! adds an button. The returned pointer must not be dropped. + virtual IGUIButton* addButton(const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext = 0); + + //! adds a window. The returned pointer must not be dropped. + virtual IGUIWindow* addWindow(const core::rect& rectangle, bool modal = false, + const wchar_t* text=0, IGUIElement* parent=0, s32 id=-1); + + //! adds a modal screen. The returned pointer must not be dropped. + virtual IGUIElement* addModalScreen(IGUIElement* parent); + + //! Adds a message box. + virtual IGUIWindow* addMessageBox(const wchar_t* caption, const wchar_t* text=0, + bool modal = true, s32 flag = EMBF_OK, IGUIElement* parent=0, s32 id=-1, video::ITexture* image=0); + + //! adds a scrollbar. The returned pointer must not be dropped. + virtual IGUIScrollBar* addScrollBar(bool horizontal, const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds an image element. + virtual IGUIImage* addImage(video::ITexture* image, core::position2d pos, + bool useAlphaChannel=true, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! adds an image. The returned pointer must not be dropped. + virtual IGUIImage* addImage(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0, bool useAlphaChannel=true); + + //! adds a checkbox + virtual IGUICheckBox* addCheckBox(bool checked, const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! adds a list box + virtual IGUIListBox* addListBox(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false); + + //! adds a tree view + virtual IGUITreeView* addTreeView(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false, + bool scrollBarVertical = true, bool scrollBarHorizontal = false); + + //! adds an mesh viewer. The returned pointer must not be dropped. + virtual IGUIMeshViewer* addMeshViewer(const core::rect& rectangle, IGUIElement* parent=0, s32 id=-1, const wchar_t* text=0); + + //! Adds a file open dialog. + virtual IGUIFileOpenDialog* addFileOpenDialog(const wchar_t* title = 0, + bool modal=true, IGUIElement* parent=0, s32 id=-1, + bool restoreCWD=false, io::path::char_type* startDir=0); + + //! Adds a color select dialog. + virtual IGUIColorSelectDialog* addColorSelectDialog(const wchar_t* title = 0, bool modal=true, IGUIElement* parent=0, s32 id=-1); + + //! adds a static text. The returned pointer must not be dropped. + virtual IGUIStaticText* addStaticText(const wchar_t* text, const core::rect& rectangle, + bool border=false, bool wordWrap=true, IGUIElement* parent=0, s32 id=-1, bool drawBackground = false); + + //! Adds an edit box. The returned pointer must not be dropped. + virtual IGUIEditBox* addEditBox(const wchar_t* text, const core::rect& rectangle, + bool border=false, IGUIElement* parent=0, s32 id=-1); + + //! Adds a spin box to the environment + virtual IGUISpinBox* addSpinBox(const wchar_t* text, const core::rect& rectangle, + bool border=false,IGUIElement* parent=0, s32 id=-1); + + //! Adds a tab control to the environment. + virtual IGUITabControl* addTabControl(const core::rect& rectangle, + IGUIElement* parent=0, bool fillbackground=false, bool border=true, s32 id=-1); + + //! Adds tab to the environment. + virtual IGUITab* addTab(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds a context menu to the environment. + virtual IGUIContextMenu* addContextMenu(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds a menu to the environment. + virtual IGUIContextMenu* addMenu(IGUIElement* parent=0, s32 id=-1); + + //! Adds a toolbar to the environment. It is like a menu is always placed on top + //! in its parent, and contains buttons. + virtual IGUIToolBar* addToolBar(IGUIElement* parent=0, s32 id=-1); + + //! Adds a combo box to the environment. + virtual IGUIComboBox* addComboBox(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1); + + //! Adds a table element. + virtual IGUITable* addTable(const core::rect& rectangle, + IGUIElement* parent=0, s32 id=-1, bool drawBackground=false); + + //! sets the focus to an element + virtual bool setFocus(IGUIElement* element); + + //! removes the focus from an element + virtual bool removeFocus(IGUIElement* element); + + //! Returns if the element has focus + virtual bool hasFocus(IGUIElement* element) const; + + //! Returns the element with the focus + virtual IGUIElement* getFocus() const; + + //! Returns the element last known to be under the mouse + virtual IGUIElement* getHovered() const; + + //! Adds an element for fading in or out. + virtual IGUIInOutFader* addInOutFader(const core::rect* rectangle=0, IGUIElement* parent=0, s32 id=-1); + + //! Returns the root gui element. + virtual IGUIElement* getRootGUIElement(); + + virtual void OnPostRender( u32 time ); + + //! Returns the default element factory which can create all built in elements + virtual IGUIElementFactory* getDefaultGUIElementFactory() const; + + //! Adds an element factory to the gui environment. + /** Use this to extend the gui environment with new element types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerGUIElementFactory(IGUIElementFactory* factoryToAdd); + + //! Returns amount of registered scene node factories. + virtual u32 getRegisteredGUIElementFactoryCount() const; + + //! Returns a scene node factory by index + virtual IGUIElementFactory* getGUIElementFactory(u32 index) const; + + //! Adds a GUI Element by its name + virtual IGUIElement* addGUIElement(const c8* elementName, IGUIElement* parent=0); + + //! Saves the current gui into a file. + /** \param filename: Name of the file. + \param start: The element to start saving from. + if not specified, the root element will be used */ + virtual bool saveGUI( const io::path& filename, IGUIElement* start=0); + + //! Saves the current gui into a file. + /** \param file: The file to save the GUI to. + \param start: The element to start saving from. + if not specified, the root element will be used */ + virtual bool saveGUI(io::IWriteFile* file, IGUIElement* start=0); + + //! Loads the gui. Note that the current gui is not cleared before. + /** \param filename: Name of the file. + \param parent: The parent of all loaded GUI elements, + if not specified, the root element will be used */ + virtual bool loadGUI(const io::path& filename, IGUIElement* parent=0); + + //! Loads the gui. Note that the current gui is not cleared before. + /** \param file: IReadFile to load the GUI from + \param parent: The parent of all loaded GUI elements, + if not specified, the root element will be used */ + virtual bool loadGUI(io::IReadFile* file, IGUIElement* parent=0); + + //! Writes attributes of the environment + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the environment. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! writes an element + virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* node); + + //! reads an element + virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* node); + +private: + + IGUIElement* getNextElement(bool reverse=false, bool group=false); + + void updateHoveredElement(core::position2d mousePos); + + void loadBuiltInFont(); + + struct SFont + { + io::SNamedPath NamedPath; + IGUIFont* Font; + + bool operator < (const SFont& other) const + { + return (NamedPath < other.NamedPath); + } + }; + + struct SSpriteBank + { + io::SNamedPath NamedPath; + IGUISpriteBank* Bank; + + bool operator < (const SSpriteBank& other) const + { + return (NamedPath < other.NamedPath); + } + }; + + struct SToolTip + { + IGUIStaticText* Element; + u32 LastTime; + u32 EnterTime; + u32 LaunchTime; + u32 RelaunchTime; + }; + + SToolTip ToolTip; + + core::array GUIElementFactoryList; + + core::array Fonts; + core::array Banks; + video::IVideoDriver* Driver; + IGUIElement* Hovered; + IGUIElement* HoveredNoSubelement; // subelements replaced by their parent, so you only have 'real' elements here + IGUIElement* Focus; + core::position2d LastHoveredMousePos; + IGUISkin* CurrentSkin; + io::IFileSystem* FileSystem; + IEventReceiver* UserReceiver; + IOSOperator* Operator; + static const io::path DefaultFontName; +}; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_ENVIRONMENT_H_INCLUDED__ + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp new file mode 100644 index 0000000..47d71b7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.cpp @@ -0,0 +1,446 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIFileOpenDialog.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIStaticText.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "IFileList.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +const s32 FOD_WIDTH = 350; +const s32 FOD_HEIGHT = 250; + + +//! constructor +CGUIFileOpenDialog::CGUIFileOpenDialog(const wchar_t* title, + IGUIEnvironment* environment, IGUIElement* parent, s32 id, + bool restoreCWD, io::path::char_type* startDir) +: IGUIFileOpenDialog(environment, parent, id, + core::rect((parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2, + (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2, + (parent->getAbsolutePosition().getWidth()-FOD_WIDTH)/2+FOD_WIDTH, + (parent->getAbsolutePosition().getHeight()-FOD_HEIGHT)/2+FOD_HEIGHT)), + FileNameText(0), FileList(0), Dragging(false) +{ + #ifdef _DEBUG + IGUIElement::setDebugName("CGUIFileOpenDialog"); + #endif + + Text = title; + + FileSystem = Environment?Environment->getFileSystem():0; + + if (FileSystem) + { + FileSystem->grab(); + + if (restoreCWD) + RestoreDirectory = FileSystem->getWorkingDirectory(); + if (startDir) + { + StartDirectory = startDir; + FileSystem->changeWorkingDirectoryTo(startDir); + } + } + else + return; + + IGUISpriteBank* sprites = 0; + video::SColor color(255,255,255,255); + IGUISkin* skin = Environment->getSkin(); + if (skin) + { + sprites = skin->getSpriteBank(); + color = skin->getColor(EGDC_WINDOW_SYMBOL); + } + + const s32 buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + const s32 posx = RelativeRect.getWidth() - buttonw - 4; + + CloseButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close"); + CloseButton->setSubElement(true); + CloseButton->setTabStop(false); + if (sprites) + { + CloseButton->setSpriteBank(sprites); + CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color); + CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color); + } + CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CloseButton->grab(); + + OKButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 30, RelativeRect.getWidth()-10, 50), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_OK) : L"OK"); + OKButton->setSubElement(true); + OKButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + OKButton->grab(); + + CancelButton = Environment->addButton( + core::rect(RelativeRect.getWidth()-80, 55, RelativeRect.getWidth()-10, 75), + this, -1, skin ? skin->getDefaultText(EGDT_MSG_BOX_CANCEL) : L"Cancel"); + CancelButton->setSubElement(true); + CancelButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + CancelButton->grab(); + + FileBox = Environment->addListBox(core::rect(10, 55, RelativeRect.getWidth()-90, 230), this, -1, true); + FileBox->setSubElement(true); + FileBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + FileBox->grab(); + + FileNameText = Environment->addEditBox(0, core::rect(10, 30, RelativeRect.getWidth()-90, 50), true, this); + FileNameText->setSubElement(true); + FileNameText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + FileNameText->grab(); + + setTabGroup(true); + + fillListBox(); +} + + +//! destructor +CGUIFileOpenDialog::~CGUIFileOpenDialog() +{ + if (CloseButton) + CloseButton->drop(); + + if (OKButton) + OKButton->drop(); + + if (CancelButton) + CancelButton->drop(); + + if (FileBox) + FileBox->drop(); + + if (FileNameText) + FileNameText->drop(); + + if (FileSystem) + { + // revert to original CWD if path was set in constructor + if (RestoreDirectory.size()) + FileSystem->changeWorkingDirectoryTo(RestoreDirectory); + FileSystem->drop(); + } + + if (FileList) + FileList->drop(); +} + + +//! returns the filename of the selected file. Returns NULL, if no file was selected. +const wchar_t* CGUIFileOpenDialog::getFileName() const +{ + return FileName.c_str(); +} + +//! Returns the directory of the selected file. Returns NULL, if no directory was selected. +const io::path& CGUIFileOpenDialog::getDirectoryName() +{ + FileSystem->flattenFilename ( FileDirectory ); + return FileDirectory; +} + + +//! called if an event happened. +bool CGUIFileOpenDialog::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUS_LOST: + Dragging = false; + break; + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == CloseButton || + event.GUIEvent.Caller == CancelButton) + { + sendCancelEvent(); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == OKButton ) + { + if ( FileDirectory != L"" ) + { + sendSelectedEvent( EGET_DIRECTORY_SELECTED ); + } + if ( FileName != L"" ) + { + sendSelectedEvent( EGET_FILE_SELECTED ); + remove(); + return true; + } + } + break; + + case EGET_LISTBOX_CHANGED: + { + s32 selected = FileBox->getSelected(); + if (FileList && FileSystem) + { + if (FileList->isDirectory(selected)) + { + FileName = L""; + FileDirectory = FileList->getFullFileName(selected); + } + else + { + FileDirectory = L""; + FileName = FileList->getFullFileName(selected); + } + return true; + } + } + break; + + case EGET_LISTBOX_SELECTED_AGAIN: + { + const s32 selected = FileBox->getSelected(); + if (FileList && FileSystem) + { + if (FileList->isDirectory(selected)) + { + FileDirectory = FileList->getFullFileName(selected); + FileSystem->changeWorkingDirectoryTo(FileList->getFileName(selected)); + fillListBox(); + FileName = ""; + } + else + { + FileName = FileList->getFullFileName(selected); + } + return true; + } + } + break; + case EGET_EDITBOX_ENTER: + if (event.GUIEvent.Caller == FileNameText) + { + io::path dir( FileNameText->getText () ); + if ( FileSystem->changeWorkingDirectoryTo( dir ) ) + { + fillListBox(); + FileName = L""; + } + return true; + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + return FileBox->OnEvent(event); + case EMIE_LMOUSE_PRESSED_DOWN: + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + Dragging = true; + Environment->setFocus(this); + return true; + case EMIE_LMOUSE_LEFT_UP: + Dragging = false; + return true; + case EMIE_MOUSE_MOVED: + + if ( !event.MouseInput.isLeftPressed () ) + Dragging = false; + + if (Dragging) + { + // gui window should not be dragged outside its parent + if (Parent) + if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || + event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || + event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || + event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1) + + return true; + + move(core::position2d(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + return true; + } + break; + default: + break; + } + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +//! draws the element and its children +void CGUIFileOpenDialog::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + + core::rect rect = AbsoluteRect; + + rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER), + rect, &AbsoluteClippingRect); + + if (Text.size()) + { + rect.UpperLeftCorner.X += 2; + rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; + + IGUIFont* font = skin->getFont(EGDF_WINDOW); + if (font) + font->draw(Text.c_str(), rect, + skin->getColor(EGDC_ACTIVE_CAPTION), + false, true, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! Writes attributes of the element. +/* Not sure if this will really work out properly. Saving paths can be +rather problematic. */ +void CGUIFileOpenDialog::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IGUIFileOpenDialog::serializeAttributes(out,options); + + out->addString("StartDirectory", StartDirectory.c_str()); + out->addBool("RestoreDirectory", (RestoreDirectory.size()!=0)); +} + + +//! Reads attributes of the element +/* Note that thiese paths changes will happen at arbitrary places upon +load of the gui description. This may be undesired. */ +void CGUIFileOpenDialog::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + StartDirectory = in->getAttributeAsString("StartDirectory"); + const bool restore = in->getAttributeAsBool("RestoreDirectory"); + if (restore) + RestoreDirectory = FileSystem->getWorkingDirectory(); + else + RestoreDirectory = ""; + if (StartDirectory.size()) + FileSystem->changeWorkingDirectoryTo(StartDirectory); + + IGUIFileOpenDialog::deserializeAttributes(in,options); +} + + +//! fills the listbox with files. +void CGUIFileOpenDialog::fillListBox() +{ + IGUISkin *skin = Environment->getSkin(); + + if (!FileSystem || !FileBox || !skin) + return; + + if (FileList) + FileList->drop(); + + FileBox->clear(); + + FileList = FileSystem->createFileList(); + core::stringw s; + +#if !defined(_IRR_WINDOWS_CE_PLATFORM_) + setlocale(LC_ALL,""); +#endif + + if (FileList) + { + for (u32 i=0; i < FileList->getFileCount(); ++i) + { + #ifndef _IRR_WCHAR_FILESYSTEM + const c8 *cs = (const c8 *)FileList->getFileName(i).c_str(); + wchar_t *ws = new wchar_t[strlen(cs) + 1]; + int len = mbstowcs(ws,cs,strlen(cs)); + ws[len] = 0; + s = ws; + delete [] ws; + #else + s = FileList->getFileName(i).c_str(); + #endif + FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE)); + } + } + + if (FileNameText) + { + #ifndef _IRR_WCHAR_FILESYSTEM + const c8 *cs = (const c8 *)FileSystem->getWorkingDirectory().c_str(); + wchar_t *ws = new wchar_t[strlen(cs) + 1]; + int len = mbstowcs(ws,cs,strlen(cs)); + ws[len] = 0; + s = ws; + delete [] ws; + #else + s = FileSystem->getWorkingDirectory(); + #endif + + FileDirectory = s; + FileNameText->setText(s.c_str()); + } +} + + +//! sends the event that the file has been selected. +void CGUIFileOpenDialog::sendSelectedEvent( EGUI_EVENT_TYPE type) +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = type; + Parent->OnEvent(event); +} + + +//! sends the event that the file choose process has been canceld +void CGUIFileOpenDialog::sendCancelEvent() +{ + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_FILE_CHOOSE_DIALOG_CANCELLED; + Parent->OnEvent(event); +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.d new file mode 100644 index 0000000..6d3c154 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.d @@ -0,0 +1,2 @@ +CGUIFileOpenDialog.o: CGUIFileOpenDialog.cpp CGUIFileOpenDialog.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.h new file mode 100644 index 0000000..075935a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFileOpenDialog.h @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ +#define __C_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFileOpenDialog.h" +#include "IGUIButton.h" +#include "IGUIListBox.h" +#include "IGUIEditBox.h" +#include "IFileSystem.h" + +namespace irr +{ +namespace gui +{ + + class CGUIFileOpenDialog : public IGUIFileOpenDialog + { + public: + + //! constructor + CGUIFileOpenDialog(const wchar_t* title, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, bool restoreCWD=false, + io::path::char_type* startDir=0); + + //! destructor + virtual ~CGUIFileOpenDialog(); + + //! returns the filename of the selected file. Returns NULL, if no file was selected. + virtual const wchar_t* getFileName() const; + + //! Returns the directory of the selected file. Returns NULL, if no directory was selected. + virtual const io::path& getDirectoryName(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + protected: + + //! fills the listbox with files. + void fillListBox(); + + //! sends the event that the file has been selected. + void sendSelectedEvent( EGUI_EVENT_TYPE type ); + + //! sends the event that the file choose process has been canceld + void sendCancelEvent(); + + core::position2d DragStart; + core::stringw FileName; + io::path FileDirectory; + io::path RestoreDirectory; + io::path StartDirectory; + + IGUIButton* CloseButton; + IGUIButton* OKButton; + IGUIButton* CancelButton; + IGUIListBox* FileBox; + IGUIEditBox* FileNameText; + IGUIElement* EventParent; + io::IFileSystem* FileSystem; + io::IFileList* FileList; + bool Dragging; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_FILE_OPEN_DIALOG_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.cpp new file mode 100644 index 0000000..8c7f85f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.cpp @@ -0,0 +1,589 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIFont.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "os.h" +#include "IGUIEnvironment.h" +#include "IXMLReader.h" +#include "IReadFile.h" +#include "IVideoDriver.h" +#include "IGUISpriteBank.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIFont::CGUIFont(IGUIEnvironment *env, const io::path& filename) +: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0), + MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0) +{ + #ifdef _DEBUG + setDebugName("CGUIFont"); + #endif + + if (Environment) + { + // don't grab environment, to avoid circular references + Driver = Environment->getVideoDriver(); + + SpriteBank = Environment->getSpriteBank(filename); + if (!SpriteBank) // could be default-font which has no file + SpriteBank = Environment->addEmptySpriteBank(filename); + if (SpriteBank) + SpriteBank->grab(); + } + + if (Driver) + Driver->grab(); + + setInvisibleCharacters ( L" " ); +} + + +//! destructor +CGUIFont::~CGUIFont() +{ + if (Driver) + Driver->drop(); + + if (SpriteBank) + { + SpriteBank->drop(); + // TODO: spritebank still exists in gui-environment and should be removed here when it's + // reference-count is 1. Just can't do that from here at the moment. + // But spritebank would not be able to drop textures anyway because those are in texture-cache + // where they can't be removed unless materials start reference-couting 'em. + } +} + + +//! loads a font file from xml +bool CGUIFont::load(io::IXMLReader* xml) +{ + if (!SpriteBank) + return false; + + SpriteBank->clear(); + + while (xml->read()) + { + if (io::EXN_ELEMENT == xml->getNodeType()) + { + if (core::stringw(L"Texture") == xml->getNodeName()) + { + // add a texture + core::stringc fn = xml->getAttributeValue(L"filename"); + u32 i = (u32)xml->getAttributeValueAsInt(L"index"); + core::stringw alpha = xml->getAttributeValue(L"hasAlpha"); + + while (i+1 > SpriteBank->getTextureCount()) + SpriteBank->addTexture(0); + + // disable mipmaps+filtering + bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + // load texture + SpriteBank->setTexture(i, Driver->getTexture(fn)); + + // set previous mip-map+filter state + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap); + + // couldn't load texture, abort. + if (!SpriteBank->getTexture(i)) + { + os::Printer::log("Unable to load all textures in the font, aborting", ELL_ERROR); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + else + { + // colorkey texture rather than alpha channel? + if (alpha == core::stringw("false")) + Driver->makeColorKeyTexture(SpriteBank->getTexture(i), core::position2di(0,0)); + } + } + else if (core::stringw(L"c") == xml->getNodeName()) + { + // adding a character to this font + SFontArea a; + SGUISpriteFrame f; + SGUISprite s; + core::rect rectangle; + + a.underhang = xml->getAttributeValueAsInt(L"u"); + a.overhang = xml->getAttributeValueAsInt(L"o"); + a.spriteno = SpriteBank->getSprites().size(); + s32 texno = xml->getAttributeValueAsInt(L"i"); + + // parse rectangle + core::stringc rectstr = xml->getAttributeValue(L"r"); + wchar_t ch = xml->getAttributeValue(L"c")[0]; + + const c8 *c = rectstr.c_str(); + s32 val; + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.UpperLeftCorner.X = val; + while (*c == L' ' || *c == L',') c++; + + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.UpperLeftCorner.Y = val; + while (*c == L' ' || *c == L',') c++; + + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.LowerRightCorner.X = val; + while (*c == L' ' || *c == L',') c++; + + val = 0; + while (*c >= '0' && *c <= '9') + { + val *= 10; + val += *c - '0'; + c++; + } + rectangle.LowerRightCorner.Y = val; + + CharacterMap.insert(ch,Areas.size()); + + // make frame + f.rectNumber = SpriteBank->getPositions().size(); + f.textureNumber = texno; + + // add frame to sprite + s.Frames.push_back(f); + s.frameTime = 0; + + // add rectangle to sprite bank + SpriteBank->getPositions().push_back(rectangle); + a.width = rectangle.getWidth(); + + // add sprite to sprite bank + SpriteBank->getSprites().push_back(s); + + // add character to font + Areas.push_back(a); + } + } + } + + // set bad character + WrongCharacter = getAreaFromCharacter(L' '); + + setMaxHeight(); + + return true; +} + + +void CGUIFont::setMaxHeight() +{ + if ( !SpriteBank ) + return; + + MaxHeight = 0; + s32 t; + + core::array< core::rect >& p = SpriteBank->getPositions(); + + for (u32 i=0; iMaxHeight) + MaxHeight = t; + } + +} + + +//! loads a font file, native file needed, for texture parsing +bool CGUIFont::load(io::IReadFile* file) +{ + if (!Driver) + return false; + + return loadTexture(Driver->createImageFromFile(file), + file->getFileName()); +} + + +//! loads a font file, native file needed, for texture parsing +bool CGUIFont::load(const io::path& filename) +{ + if (!Driver) + return false; + + return loadTexture(Driver->createImageFromFile( filename ), + filename); +} + + +//! load & prepare font from ITexture +bool CGUIFont::loadTexture(video::IImage* image, const io::path& name) +{ + if (!image || !SpriteBank) + return false; + + s32 lowerRightPositions = 0; + + video::IImage* tmpImage=image; + bool deleteTmpImage=false; + switch(image->getColorFormat()) + { + case video::ECF_R5G6B5: + tmpImage = Driver->createImage(video::ECF_A1R5G5B5,image->getDimension()); + image->copyTo(tmpImage); + deleteTmpImage=true; + break; + case video::ECF_A1R5G5B5: + case video::ECF_A8R8G8B8: + break; + case video::ECF_R8G8B8: + tmpImage = Driver->createImage(video::ECF_A8R8G8B8,image->getDimension()); + image->copyTo(tmpImage); + deleteTmpImage=true; + break; + default: + os::Printer::log("Unknown texture format provided for CGUIFont::loadTexture", ELL_ERROR); + return false; + } + readPositions(tmpImage, lowerRightPositions); + + WrongCharacter = getAreaFromCharacter(L' '); + + // output warnings + if (!lowerRightPositions || !SpriteBank->getSprites().size()) + os::Printer::log("Either no upper or lower corner pixels in the font file. If this font was made using the new font tool, please load the XML file instead. If not, the font may be corrupted.", ELL_ERROR); + else + if (lowerRightPositions != (s32)SpriteBank->getPositions().size()) + os::Printer::log("The amount of upper corner pixels and the lower corner pixels is not equal, font file may be corrupted.", ELL_ERROR); + + bool ret = ( !SpriteBank->getSprites().empty() && lowerRightPositions ); + + if ( ret ) + { + bool flag[2]; + flag[0] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 ); + flag[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS ); + + Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false ); + + SpriteBank->addTexture(Driver->addTexture(name, tmpImage)); + + Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, flag[0] ); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, flag[1] ); + } + if (deleteTmpImage) + tmpImage->drop(); + image->drop(); + + setMaxHeight(); + + return ret; +} + + +void CGUIFont::readPositions(video::IImage* image, s32& lowerRightPositions) +{ + if (!SpriteBank ) + return; + + const core::dimension2d size = image->getDimension(); + + video::SColor colorTopLeft = image->getPixel(0,0); + colorTopLeft.setAlpha(255); + image->setPixel(0,0,colorTopLeft); + video::SColor colorLowerRight = image->getPixel(1,0); + video::SColor colorBackGround = image->getPixel(2,0); + video::SColor colorBackGroundTransparent = 0; + + image->setPixel(1,0,colorBackGround); + + // start parsing + + core::position2d pos(0,0); + for (pos.Y=0; pos.Y<(s32)size.Height; ++pos.Y) + { + for (pos.X=0; pos.X<(s32)size.Width; ++pos.X) + { + const video::SColor c = image->getPixel(pos.X, pos.Y); + if (c == colorTopLeft) + { + image->setPixel(pos.X, pos.Y, colorBackGroundTransparent); + SpriteBank->getPositions().push_back(core::rect(pos, pos)); + } + else + if (c == colorLowerRight) + { + // too many lower right points + if (SpriteBank->getPositions().size()<=(u32)lowerRightPositions) + { + lowerRightPositions = 0; + return; + } + + image->setPixel(pos.X, pos.Y, colorBackGroundTransparent); + SpriteBank->getPositions()[lowerRightPositions].LowerRightCorner = pos; + // add frame to sprite bank + SGUISpriteFrame f; + f.rectNumber = lowerRightPositions; + f.textureNumber = 0; + SGUISprite s; + s.Frames.push_back(f); + s.frameTime = 0; + SpriteBank->getSprites().push_back(s); + // add character to font + SFontArea a; + a.overhang = 0; + a.underhang = 0; + a.spriteno = lowerRightPositions; + a.width = SpriteBank->getPositions()[lowerRightPositions].getWidth(); + Areas.push_back(a); + // map letter to character + wchar_t ch = (wchar_t)(lowerRightPositions + 32); + CharacterMap.set(ch, lowerRightPositions); + + ++lowerRightPositions; + } + else + if (c == colorBackGround) + image->setPixel(pos.X, pos.Y, colorBackGroundTransparent); + } + } +} + + +//! set an Pixel Offset on Drawing ( scale position on width ) +void CGUIFont::setKerningWidth(s32 kerning) +{ + GlobalKerningWidth = kerning; +} + + +//! set an Pixel Offset on Drawing ( scale position on width ) +s32 CGUIFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* previousLetter) const +{ + s32 ret = GlobalKerningWidth; + + if (thisLetter) + { + ret += Areas[getAreaFromCharacter(*thisLetter)].overhang; + + if (previousLetter) + { + ret += Areas[getAreaFromCharacter(*previousLetter)].underhang; + } + } + + return ret; +} + + +//! set an Pixel Offset on Drawing ( scale position on height ) +void CGUIFont::setKerningHeight(s32 kerning) +{ + GlobalKerningHeight = kerning; +} + + +//! set an Pixel Offset on Drawing ( scale position on height ) +s32 CGUIFont::getKerningHeight () const +{ + return GlobalKerningHeight; +} + + +//! returns the sprite number from a given character +u32 CGUIFont::getSpriteNoFromChar(const wchar_t *c) const +{ + return Areas[getAreaFromCharacter(*c)].spriteno; +} + + +s32 CGUIFont::getAreaFromCharacter(const wchar_t c) const +{ + core::map::Node* n = CharacterMap.find(c); + if (n) + return n->getValue(); + else + return WrongCharacter; +} + +void CGUIFont::setInvisibleCharacters( const wchar_t *s ) +{ + Invisible = s; +} + + +//! returns the dimension of text +core::dimension2d CGUIFont::getDimension(const wchar_t* text) const +{ + core::dimension2d dim(0, 0); + core::dimension2d thisLine(0, MaxHeight); + + for (const wchar_t* p = text; *p; ++p) + { + bool lineBreak=false; + if (*p == L'\r') // Mac or Windows breaks + { + lineBreak = true; + if (p[1] == L'\n') // Windows breaks + ++p; + } + else if (*p == L'\n') // Unix breaks + { + lineBreak = true; + } + if (lineBreak) + { + dim.Height += thisLine.Height; + if (dim.Width < thisLine.Width) + dim.Width = thisLine.Width; + thisLine.Width = 0; + continue; + } + + const SFontArea &area = Areas[getAreaFromCharacter(*p)]; + + thisLine.Width += area.underhang; + thisLine.Width += area.width + area.overhang + GlobalKerningWidth; + } + + dim.Height += thisLine.Height; + if (dim.Width < thisLine.Width) + dim.Width = thisLine.Width; + + return dim; +} + +//! draws some text and clips it to the specified rectangle if wanted +void CGUIFont::draw(const core::stringw& text, const core::rect& position, + video::SColor color, + bool hcenter, bool vcenter, const core::rect* clip + ) +{ + if (!Driver || !SpriteBank) + return; + + core::dimension2d textDimension; // NOTE: don't make this u32 or the >> later on can fail when the dimension width is < position width + core::position2d offset = position.UpperLeftCorner; + + if (hcenter || vcenter || clip) + textDimension = getDimension(text.c_str()); + + if (hcenter) + offset.X += (position.getWidth() - textDimension.Width) >> 1; + + if (vcenter) + offset.Y += (position.getHeight() - textDimension.Height) >> 1; + + if (clip) + { + core::rect clippedRect(offset, textDimension); + clippedRect.clipAgainst(*clip); + if (!clippedRect.isValid()) + return; + } + + core::array indices(text.size()); + core::array offsets(text.size()); + + for(u32 i = 0;i < text.size();i++) + { + wchar_t c = text[i]; + + bool lineBreak=false; + if ( c == L'\r') // Mac or Windows breaks + { + lineBreak = true; + if ( text[i + 1] == L'\n') // Windows breaks + c = text[++i]; + } + else if ( c == L'\n') // Unix breaks + { + lineBreak = true; + } + + if (lineBreak) + { + offset.Y += MaxHeight; + offset.X = position.UpperLeftCorner.X; + + if ( hcenter ) + { + offset.X += (position.getWidth() - textDimension.Width) >> 1; + } + continue; + } + + SFontArea& area = Areas[getAreaFromCharacter(c)]; + + offset.X += area.underhang; + if ( Invisible.findFirst ( c ) < 0 ) + { + indices.push_back(area.spriteno); + offsets.push_back(offset); + } + + offset.X += area.width + area.overhang + GlobalKerningWidth; + } + + SpriteBank->draw2DSpriteBatch(indices, offsets, clip, color); +} + + +//! Calculates the index of the character in the text which is on a specific position. +s32 CGUIFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const +{ + s32 x = 0; + s32 idx = 0; + + while (text[idx]) + { + const SFontArea& a = Areas[getAreaFromCharacter(text[idx])]; + + x += a.width + a.overhang + a.underhang + GlobalKerningWidth; + + if (x >= pixel_x) + return idx; + + ++idx; + } + + return -1; +} + + +IGUISpriteBank* CGUIFont::getSpriteBank() const +{ + return SpriteBank; +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.d new file mode 100644 index 0000000..3429d45 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.d @@ -0,0 +1 @@ +CGUIFont.o: CGUIFont.cpp CGUIFont.h ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.h new file mode 100644 index 0000000..ada89c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIFont.h @@ -0,0 +1,118 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_FONT_H_INCLUDED__ +#define __C_GUI_FONT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFontBitmap.h" +#include "irrString.h" +#include "irrMap.h" +#include "IXMLReader.h" +#include "IReadFile.h" +#include "irrArray.h" + +namespace irr +{ + +namespace video +{ + class IVideoDriver; + class IImage; +} + +namespace gui +{ + + class IGUIEnvironment; + +class CGUIFont : public IGUIFontBitmap +{ +public: + + //! constructor + CGUIFont(IGUIEnvironment* env, const io::path& filename); + + //! destructor + virtual ~CGUIFont(); + + //! loads a font from a texture file + bool load(const io::path& filename); + + //! loads a font from a texture file + bool load(io::IReadFile* file); + + //! loads a font from an XML file + bool load(io::IXMLReader* xml); + + //! draws an text and clips it to the specified rectangle if wanted + virtual void draw(const core::stringw& text, const core::rect& position, + video::SColor color, bool hcenter=false, + bool vcenter=false, const core::rect* clip=0); + + //! returns the dimension of a text + virtual core::dimension2d getDimension(const wchar_t* text) const; + + //! Calculates the index of the character in the text which is on a specific position. + virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const; + + //! Returns the type of this font + virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; } + + //! set an Pixel Offset on Drawing ( scale position on width ) + virtual void setKerningWidth (s32 kerning); + virtual void setKerningHeight (s32 kerning); + + //! set an Pixel Offset on Drawing ( scale position on width ) + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const; + virtual s32 getKerningHeight() const; + + //! gets the sprite bank + virtual IGUISpriteBank* getSpriteBank() const; + + //! returns the sprite number from a given character + virtual u32 getSpriteNoFromChar(const wchar_t *c) const; + + virtual void setInvisibleCharacters( const wchar_t *s ); + +private: + + struct SFontArea + { + SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {} + s32 underhang; + s32 overhang; + s32 width; + u32 spriteno; + }; + + //! load & prepare font from ITexture + bool loadTexture(video::IImage * image, const io::path& name); + + void readPositions(video::IImage* texture, s32& lowerRightPositions); + + s32 getAreaFromCharacter (const wchar_t c) const; + void setMaxHeight(); + + core::array Areas; + core::map CharacterMap; + video::IVideoDriver* Driver; + IGUISpriteBank* SpriteBank; + IGUIEnvironment* Environment; + u32 WrongCharacter; + s32 MaxHeight; + s32 GlobalKerningWidth, GlobalKerningHeight; + + core::stringw Invisible; +}; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_FONT_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.cpp new file mode 100644 index 0000000..17d30e0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIImage.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIImage::CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIImage(environment, parent, id, rectangle), Texture(0), Color(255,255,255,255), + UseAlphaChannel(false), ScaleImage(false) +{ + #ifdef _DEBUG + setDebugName("CGUIImage"); + #endif +} + + +//! destructor +CGUIImage::~CGUIImage() +{ + if (Texture) + Texture->drop(); +} + + +//! sets an image +void CGUIImage::setImage(video::ITexture* image) +{ + if (image == Texture) + return; + + if (Texture) + Texture->drop(); + + Texture = image; + + if (Texture) + Texture->grab(); +} + +//! Gets the image texture +video::ITexture* CGUIImage::getImage() const +{ + return Texture; +} + +//! sets the color of the image +void CGUIImage::setColor(video::SColor color) +{ + Color = color; +} + +//! Gets the color of the image +video::SColor CGUIImage::getColor() const +{ + return Color; +} + +//! draws the element and its children +void CGUIImage::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + + if (Texture) + { + if (ScaleImage) + { + const video::SColor Colors[] = {Color,Color,Color,Color}; + + driver->draw2DImage(Texture, AbsoluteRect, + core::rect(core::position2d(0,0), core::dimension2di(Texture->getOriginalSize())), + &AbsoluteClippingRect, Colors, UseAlphaChannel); + } + else + { + driver->draw2DImage(Texture, AbsoluteRect.UpperLeftCorner, + core::rect(core::position2d(0,0), core::dimension2di(Texture->getOriginalSize())), + &AbsoluteClippingRect, Color, UseAlphaChannel); + } + } + else + { + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_DARK_SHADOW), AbsoluteRect, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! sets if the image should use its alpha channel to draw itself +void CGUIImage::setUseAlphaChannel(bool use) +{ + UseAlphaChannel = use; +} + + +//! sets if the image should use its alpha channel to draw itself +void CGUIImage::setScaleImage(bool scale) +{ + ScaleImage = scale; +} + + +//! Returns true if the image is scaled to fit, false if not +bool CGUIImage::isImageScaled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ScaleImage; +} + +//! Returns true if the image is using the alpha channel, false if not +bool CGUIImage::isAlphaChannelUsed() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return UseAlphaChannel; +} + + +//! Writes attributes of the element. +void CGUIImage::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIImage::serializeAttributes(out,options); + + out->addTexture ("Texture", Texture); + out->addBool ("UseAlphaChannel", UseAlphaChannel); + out->addColor ("Color", Color); + out->addBool ("ScaleImage", ScaleImage); + +} + + +//! Reads attributes of the element +void CGUIImage::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIImage::deserializeAttributes(in,options); + + setImage(in->getAttributeAsTexture("Texture")); + setUseAlphaChannel(in->getAttributeAsBool("UseAlphaChannel")); + setColor(in->getAttributeAsColor("Color")); + setScaleImage(in->getAttributeAsBool("ScaleImage")); +} + + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.d new file mode 100644 index 0000000..470bf59 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.d @@ -0,0 +1 @@ +CGUIImage.o: CGUIImage.cpp CGUIImage.h ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.h new file mode 100644 index 0000000..fc6007c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImage.h @@ -0,0 +1,75 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_IMAGE_H_INCLUDED__ +#define __C_GUI_IMAGE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIImage.h" + +namespace irr +{ +namespace gui +{ + + class CGUIImage : public IGUIImage + { + public: + + //! constructor + CGUIImage(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIImage(); + + //! sets an image + virtual void setImage(video::ITexture* image); + + //! Gets the image texture + virtual video::ITexture* getImage() const; + + //! sets the color of the image + virtual void setColor(video::SColor color); + + //! sets if the image should scale to fit the element + virtual void setScaleImage(bool scale); + + //! draws the element and its children + virtual void draw(); + + //! sets if the image should use its alpha channel to draw itself + virtual void setUseAlphaChannel(bool use); + + //! Gets the color of the image + virtual video::SColor getColor() const; + + //! Returns true if the image is scaled to fit, false if not + virtual bool isImageScaled() const; + + //! Returns true if the image is using the alpha channel, false if not + virtual bool isAlphaChannelUsed() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + video::ITexture* Texture; + video::SColor Color; + bool UseAlphaChannel; + bool ScaleImage; + + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_IMAGE_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.cpp new file mode 100644 index 0000000..e02030d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.cpp @@ -0,0 +1,93 @@ +// This file is part of the "Irrlicht Engine". +// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de +// modified by Thomas Alten + +#include "CGUIImageList.h" + + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIImageList::CGUIImageList( video::IVideoDriver* driver ) + : Driver( driver ), + Texture( 0 ), + ImageCount( 0 ), + ImageSize( 0, 0 ), + ImagesPerRow( 0 ), + UseAlphaChannel( false ) +{ + #ifdef _DEBUG + setDebugName( "CGUIImageList" ); + #endif + + if( Driver ) + { + Driver->grab(); + } +} + + + +//! destructor +CGUIImageList::~CGUIImageList() +{ + if( Driver ) + { + Driver->drop(); + } + + if( Texture ) + { + Texture->drop(); + } +} + + +//! Creates the image list from texture. +bool CGUIImageList::createImageList(video::ITexture* texture, + core::dimension2d imageSize, + bool useAlphaChannel) +{ + if( !texture ) + { + return false; + } + + Texture = texture; + Texture->grab(); + + ImageSize = imageSize; + + ImagesPerRow = Texture->getSize().Width / ImageSize.Width; + ImageCount = ImagesPerRow * Texture->getSize().Height / ImageSize.Height; + + UseAlphaChannel = useAlphaChannel; + + return true; +} + +//! Draws an image and clips it to the specified rectangle if wanted +void CGUIImageList::draw( s32 index, const core::position2d& destPos, + const core::rect* clip /*= 0*/ ) +{ + core::rect sourceRect; + + if( !Driver || index < 0 || index >= ImageCount ) + { + return; + } + + sourceRect.UpperLeftCorner.X = ( index % ImagesPerRow ) * ImageSize.Width; + sourceRect.UpperLeftCorner.Y = ( index / ImagesPerRow ) * ImageSize.Height; + sourceRect.LowerRightCorner.X = sourceRect.UpperLeftCorner.X + ImageSize.Width; + sourceRect.LowerRightCorner.Y = sourceRect.UpperLeftCorner.Y + ImageSize.Height; + + Driver->draw2DImage( Texture, destPos, sourceRect, clip, + video::SColor( 255, 255, 255, 255 ), UseAlphaChannel ); +} + +} // end namespace gui +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.d new file mode 100644 index 0000000..08cf913 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.d @@ -0,0 +1,26 @@ +CGUIImageList.o: CGUIImageList.cpp CGUIImageList.h \ + ../../include/IGUIImageList.h ../../include/IGUIElement.h \ + ../../include/IAttributeExchangingObject.h \ + ../../include/IReferenceCounted.h ../../include/irrTypes.h \ + ../../include/IrrCompileConfig.h ../../include/irrList.h \ + ../../include/irrAllocator.h ../../include/irrMath.h \ + ../../include/rect.h ../../include/dimension2d.h \ + ../../include/position2d.h ../../include/vector2d.h \ + ../../include/irrString.h ../../include/IEventReceiver.h \ + ../../include/ILogger.h ../../include/Keycodes.h \ + ../../include/EGUIElementTypes.h ../../include/EGUIAlignment.h \ + ../../include/IAttributes.h ../../include/SColor.h \ + ../../include/vector3d.h ../../include/line2d.h ../../include/line3d.h \ + ../../include/triangle3d.h ../../include/plane3d.h \ + ../../include/aabbox3d.h ../../include/matrix4.h \ + ../../include/quaternion.h ../../include/irrArray.h \ + ../../include/heapsort.h ../../include/IXMLReader.h \ + ../../include/irrXML.h ../../include/EAttributes.h ../../include/path.h \ + ../../include/IVideoDriver.h ../../include/ITexture.h \ + ../../include/IImage.h ../../include/EDriverTypes.h \ + ../../include/SMaterial.h ../../include/EMaterialTypes.h \ + ../../include/EMaterialFlags.h ../../include/SMaterialLayer.h \ + ../../include/IMeshBuffer.h ../../include/S3DVertex.h \ + ../../include/SVertexIndex.h ../../include/EHardwareBufferFlags.h \ + ../../include/EPrimitiveTypes.h ../../include/EDriverFeatures.h \ + ../../include/SExposedVideoData.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.h new file mode 100644 index 0000000..18221c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIImageList.h @@ -0,0 +1,68 @@ +// This file is part of the "Irrlicht Engine". +// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de + +#ifndef __C_GUI_IMAGE_LIST_H_INCLUDED__ +#define __C_GUI_IMAGE_LIST_H_INCLUDED__ + +#include "IGUIImageList.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace gui +{ + +class CGUIImageList : public IGUIImageList +{ +public: + + //! constructor + CGUIImageList( video::IVideoDriver* Driver ); + + //! destructor + virtual ~CGUIImageList(); + + //! Creates the image list from texture. + //! \param texture: The texture to use + //! \param imageSize: Size of a single image + //! \param useAlphaChannel: true if the alpha channel from the texture should be used + //! \return + //! true if the image list was created + bool createImageList( + video::ITexture* texture, + core::dimension2d imageSize, + bool useAlphaChannel ); + + //! Draws an image and clips it to the specified rectangle if wanted + //! \param index: Index of the image + //! \param destPos: Position of the image to draw + //! \param clip: Optional pointer to a rectalgle against which the text will be clipped. + //! If the pointer is null, no clipping will be done. + virtual void draw( s32 index, const core::position2d& destPos, + const core::rect* clip = 0 ); + + //! Returns the count of Images in the list. + //! \return Returns the count of Images in the list. + virtual s32 getImageCount() const + { return ImageCount; } + + //! Returns the size of the images in the list. + //! \return Returns the size of the images in the list. + virtual core::dimension2d getImageSize() const + { return ImageSize; } + +private: + + video::IVideoDriver* Driver; + video::ITexture* Texture; + s32 ImageCount; + core::dimension2d ImageSize; + s32 ImagesPerRow; + bool UseAlphaChannel; +}; + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.cpp new file mode 100644 index 0000000..3f63662 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.cpp @@ -0,0 +1,179 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIInOutFader.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIInOutFader::CGUIInOutFader(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIInOutFader(environment, parent, id, rectangle) +{ + #ifdef _DEBUG + setDebugName("CGUIInOutFader"); + #endif + + Action = EFA_NOTHING; + StartTime = 0; + EndTime = 0; + + setColor(video::SColor(0,0,0,0)); +} + + +//! draws the element and its children +void CGUIInOutFader::draw() +{ + if (!IsVisible || !Action) + return; + + u32 now = os::Timer::getTime(); + if (now > EndTime && Action == EFA_FADE_IN) + { + Action = EFA_NOTHING; + return; + } + + video::IVideoDriver* driver = Environment->getVideoDriver(); + + if (driver) + { + f32 d; + + if (now > EndTime) + d = 0.0f; + else + d = (EndTime - now) / (f32)(EndTime - StartTime); + + video::SColor newCol = FullColor.getInterpolated(TransColor, d); + driver->draw2DRectangle(newCol, AbsoluteRect, &AbsoluteClippingRect); + } + + IGUIElement::draw(); +} + + +//! Gets the color to fade out to or to fade in from. +video::SColor CGUIInOutFader::getColor() const +{ + return Color[1]; +} + + +//! Sets the color to fade out to or to fade in from. +void CGUIInOutFader::setColor(video::SColor color) +{ + video::SColor s = color; + video::SColor d = color; + + s.setAlpha ( 255 ); + d.setAlpha ( 0 ); + setColor ( s,d ); + +/* + Color[0] = color; + + FullColor = Color[0]; + TransColor = Color[0]; + + if (Action == EFA_FADE_OUT) + { + FullColor.setAlpha(0); + TransColor.setAlpha(255); + } + else + if (Action == EFA_FADE_IN) + { + FullColor.setAlpha(255); + TransColor.setAlpha(0); + } +*/ +} + + +void CGUIInOutFader::setColor(video::SColor source, video::SColor dest) +{ + Color[0] = source; + Color[1] = dest; + + if (Action == EFA_FADE_OUT) + { + FullColor = Color[1]; + TransColor = Color[0]; + } + else + if (Action == EFA_FADE_IN) + { + FullColor = Color[0]; + TransColor = Color[1]; + } + +} + + +//! Returns if the fade in or out process is done. +bool CGUIInOutFader::isReady() const +{ + u32 now = os::Timer::getTime(); + bool ret = (now > EndTime); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! Starts the fade in process. +void CGUIInOutFader::fadeIn(u32 time) +{ + StartTime = os::Timer::getTime(); + EndTime = StartTime + time; + Action = EFA_FADE_IN; + setColor(Color[0],Color[1]); +} + + +//! Starts the fade out process. +void CGUIInOutFader::fadeOut(u32 time) +{ + StartTime = os::Timer::getTime(); + EndTime = StartTime + time; + Action = EFA_FADE_OUT; + setColor(Color[0],Color[1]); +} + + +//! Writes attributes of the element. +void CGUIInOutFader::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIInOutFader::serializeAttributes(out,options); + + out->addColor ("FullColor", FullColor); + out->addColor ("TransColor", TransColor); + +} + + +//! Reads attributes of the element +void CGUIInOutFader::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIInOutFader::deserializeAttributes(in,options); + + FullColor = in->getAttributeAsColor("FullColor"); + TransColor = in->getAttributeAsColor("TransColor"); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.d new file mode 100644 index 0000000..207701b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.d @@ -0,0 +1,2 @@ +CGUIInOutFader.o: CGUIInOutFader.cpp CGUIInOutFader.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.h new file mode 100644 index 0000000..4bd6aa9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIInOutFader.h @@ -0,0 +1,75 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_IN_OUT_FADER_H_INCLUDED__ +#define __C_GUI_IN_OUT_FADER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIInOutFader.h" + +namespace irr +{ +namespace gui +{ + + class CGUIInOutFader : public IGUIInOutFader + { + public: + + //! constructor + CGUIInOutFader(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle); + + //! draws the element and its children + virtual void draw(); + + //! Gets the color to fade out to or to fade in from. + virtual video::SColor getColor() const; + + //! Sets the color to fade out to or to fade in from. + virtual void setColor(video::SColor color ); + virtual void setColor(video::SColor source, video::SColor dest); + + //! Starts the fade in process. + virtual void fadeIn(u32 time); + + //! Starts the fade out process. + virtual void fadeOut(u32 time); + + //! Returns if the fade in or out process is done. + virtual bool isReady() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + enum EFadeAction + { + EFA_NOTHING = 0, + EFA_FADE_IN, + EFA_FADE_OUT + }; + + u32 StartTime; + u32 EndTime; + EFadeAction Action; + + video::SColor Color[2]; + video::SColor FullColor; + video::SColor TransColor; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_IN_OUT_FADER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.cpp new file mode 100644 index 0000000..74f7a72 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.cpp @@ -0,0 +1,910 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIListBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIListBox.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "CGUIScrollBar.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip, + bool drawBack, bool moveOverSelect) +: IGUIListBox(environment, parent, id, rectangle), Selected(-1), + ItemHeight(0),ItemHeightOverride(0), + TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), + ScrollBar(0), selectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack), + MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true) +{ + #ifdef _DEBUG + setDebugName("CGUIListBox"); + #endif + + IGUISkin* skin = Environment->getSkin(); + const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE); + + ScrollBar = new CGUIScrollBar(false, Environment, this, -1, + core::rect(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), + !clip); + ScrollBar->setSubElement(true); + ScrollBar->setTabStop(false); + ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + ScrollBar->setVisible(false); + ScrollBar->setPos(0); + + setNotClipped(!clip); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + updateAbsolutePosition(); +} + + +//! destructor +CGUIListBox::~CGUIListBox() +{ + if (ScrollBar) + ScrollBar->drop(); + + if (Font) + Font->drop(); + + if (IconBank) + IconBank->drop(); +} + + +//! returns amount of list items +u32 CGUIListBox::getItemCount() const +{ + return Items.size(); +} + + +//! returns string of a list item. the may be a value from 0 to itemCount-1 +const wchar_t* CGUIListBox::getListItem(u32 id) const +{ + if (id>=Items.size()) + return 0; + + return Items[id].text.c_str(); +} + + +//! Returns the icon of an item +s32 CGUIListBox::getIcon(u32 id) const +{ + if (id>=Items.size()) + return -1; + + return Items[id].icon; +} + + +//! adds a list item, returns id of item +u32 CGUIListBox::addItem(const wchar_t* text) +{ + return addItem(text, -1); +} + + +//! adds a list item, returns id of item +void CGUIListBox::removeItem(u32 id) +{ + if (id >= Items.size()) + return; + + if ((u32)Selected==id) + { + Selected = -1; + } + else if ((u32)Selected > id) + { + Selected -= 1; + selectTime = os::Timer::getTime(); + } + + Items.erase(id); + + recalculateItemHeight(); +} + + +s32 CGUIListBox::getItemAt(s32 xpos, s32 ypos) const +{ + if ( xpos < AbsoluteRect.UpperLeftCorner.X || xpos >= AbsoluteRect.LowerRightCorner.X + || ypos < AbsoluteRect.UpperLeftCorner.Y || ypos >= AbsoluteRect.LowerRightCorner.Y + ) + return -1; + + if ( ItemHeight == 0 ) + return -1; + + s32 item = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight; + if ( item < 0 || item >= (s32)Items.size()) + return -1; + + return item; +} + +//! clears the list +void CGUIListBox::clear() +{ + Items.clear(); + ItemsIconWidth = 0; + Selected = -1; + + if (ScrollBar) + ScrollBar->setPos(0); + + recalculateItemHeight(); +} + + +void CGUIListBox::recalculateItemHeight() +{ + IGUISkin* skin = Environment->getSkin(); + + if (Font != skin->getFont()) + { + if (Font) + Font->drop(); + + Font = skin->getFont(); + if ( 0 == ItemHeightOverride ) + ItemHeight = 0; + + if (Font) + { + if ( 0 == ItemHeightOverride ) + ItemHeight = Font->getDimension(L"A").Height + 4; + + Font->grab(); + } + } + + TotalItemHeight = ItemHeight * Items.size(); + ScrollBar->setMax( core::max_(0, TotalItemHeight - AbsoluteRect.getHeight()) ); + s32 minItemHeight = ItemHeight > 0 ? ItemHeight : 1; + ScrollBar->setSmallStep ( minItemHeight ); + ScrollBar->setLargeStep ( 2*minItemHeight ); + + if ( TotalItemHeight <= AbsoluteRect.getHeight() ) + ScrollBar->setVisible(false); + else + ScrollBar->setVisible(true); +} + + +//! returns id of selected item. returns -1 if no item is selected. +s32 CGUIListBox::getSelected() const +{ + return Selected; +} + + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUIListBox::setSelected(s32 id) +{ + if ((u32)id>=Items.size()) + Selected = -1; + else + Selected = id; + + selectTime = os::Timer::getTime(); + + recalculateScrollPos(); +} + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUIListBox::setSelected(const wchar_t *item) +{ + s32 index = -1; + + if ( item ) + { + for ( index = 0; index < (s32) Items.size(); ++index ) + { + if ( Items[index].text == item ) + break; + } + } + setSelected ( index ); +} + +//! called if an event happened. +bool CGUIListBox::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_DOWN || + event.KeyInput.Key == KEY_UP || + event.KeyInput.Key == KEY_HOME || + event.KeyInput.Key == KEY_END || + event.KeyInput.Key == KEY_NEXT || + event.KeyInput.Key == KEY_PRIOR ) ) + { + s32 oldSelected = Selected; + switch (event.KeyInput.Key) + { + case KEY_DOWN: + Selected += 1; + break; + case KEY_UP: + Selected -= 1; + break; + case KEY_HOME: + Selected = 0; + break; + case KEY_END: + Selected = (s32)Items.size()-1; + break; + case KEY_NEXT: + Selected += AbsoluteRect.getHeight() / ItemHeight; + break; + case KEY_PRIOR: + Selected -= AbsoluteRect.getHeight() / ItemHeight; + break; + default: + break; + } + if (Selected >= (s32)Items.size()) + Selected = Items.size() - 1; + else + if (Selected<0) + Selected = 0; + + recalculateScrollPos(); + + // post the news + + if (oldSelected != Selected && Parent && !Selecting && !MoveOverSelect) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + + return true; + } + else + if (!event.KeyInput.PressedDown && ( event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE ) ) + { + if (Parent) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_SELECTED_AGAIN; + Parent->OnEvent(e); + } + return true; + } + else if (event.KeyInput.PressedDown && event.KeyInput.Char) + { + // change selection based on text as it is typed. + u32 now = os::Timer::getTime(); + + if (now - LastKeyTime < 500) + { + // add to key buffer if it isn't a key repeat + if (!(KeyBuffer.size() == 1 && KeyBuffer[0] == event.KeyInput.Char)) + { + KeyBuffer += L" "; + KeyBuffer[KeyBuffer.size()-1] = event.KeyInput.Char; + } + } + else + { + KeyBuffer = L" "; + KeyBuffer[0] = event.KeyInput.Char; + } + LastKeyTime = now; + + // find the selected item, starting at the current selection + s32 start = Selected; + // dont change selection if the key buffer matches the current item + if (Selected > -1 && KeyBuffer.size() > 1) + { + if (Items[Selected].text.size() >= KeyBuffer.size() && + KeyBuffer.equals_ignore_case(Items[Selected].text.subString(0,KeyBuffer.size()))) + return true; + } + + s32 current; + for (current = start+1; current < (s32)Items.size(); ++current) + { + if (Items[current].text.size() >= KeyBuffer.size()) + { + if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size()))) + { + if (Parent && Selected != current && !Selecting && !MoveOverSelect) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + setSelected(current); + return true; + } + } + } + for (current = 0; current <= start; ++current) + { + if (Items[current].text.size() >= KeyBuffer.size()) + { + if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size()))) + { + if (Parent && Selected != current && !Selecting && !MoveOverSelect) + { + Selected = current; + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + setSelected(current); + return true; + } + } + } + + return true; + } + break; + + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case gui::EGET_SCROLL_BAR_CHANGED: + if (event.GUIEvent.Caller == ScrollBar) + return true; + break; + case gui::EGET_ELEMENT_FOCUS_LOST: + { + if (event.GUIEvent.Caller == this) + Selecting = false; + } + default: + break; + } + break; + + case EET_MOUSE_INPUT_EVENT: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + ScrollBar->setPos(ScrollBar->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1)*-ItemHeight/2); + return true; + + case EMIE_LMOUSE_PRESSED_DOWN: + { + Selecting = true; + return true; + } + + case EMIE_LMOUSE_LEFT_UP: + { + Selecting = false; + + if (isPointInside(p)) + selectNew(event.MouseInput.Y); + + return true; + } + + case EMIE_MOUSE_MOVED: + if (Selecting || MoveOverSelect) + { + if (isPointInside(p)) + { + selectNew(event.MouseInput.Y, true); + return true; + } + } + default: + break; + } + } + break; + case EET_LOG_TEXT_EVENT: + case EET_USER_EVENT: + case EET_JOYSTICK_INPUT_EVENT: + case EGUIET_FORCE_32_BIT: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +void CGUIListBox::selectNew(s32 ypos, bool onlyHover) +{ + u32 now = os::Timer::getTime(); + s32 oldSelected = Selected; + + Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos); + if (Selected<0 && !Items.empty()) + Selected = 0; + + recalculateScrollPos(); + + gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; + selectTime = now; + // post the news + if (Parent && !onlyHover) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = eventType; + Parent->OnEvent(event); + } +} + + +//! Update the position and size of the listbox, and update the scrollbar +void CGUIListBox::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + + recalculateItemHeight(); +} + + +//! draws the element and its children +void CGUIListBox::draw() +{ + if (!IsVisible) + return; + + recalculateItemHeight(); // if the font changed + + IGUISkin* skin = Environment->getSkin(); + + core::rect* clipRect = 0; + + // draw background + core::rect frameRect(AbsoluteRect); + + // draw items + + core::rect clientClip(AbsoluteRect); + clientClip.UpperLeftCorner.Y += 1; + clientClip.UpperLeftCorner.X += 1; + if (ScrollBar->isVisible()) + clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + clientClip.LowerRightCorner.Y -= 1; + clientClip.clipAgainst(AbsoluteClippingRect); + + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true, + DrawBack, frameRect, &AbsoluteClippingRect); + + if (clipRect) + clientClip.clipAgainst(*clipRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X += 1; + if (ScrollBar->isVisible()) + frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + + frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; + + frameRect.UpperLeftCorner.Y -= ScrollBar->getPos(); + frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); + + bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && + frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) + { + if (i == Selected && hl) + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip); + + core::rect textRect = frameRect; + textRect.UpperLeftCorner.X += 3; + + if (Font) + { + if (IconBank && (Items[i].icon > -1)) + { + core::position2di iconPos = textRect.UpperLeftCorner; + iconPos.Y += textRect.getHeight() / 2; + iconPos.X += ItemsIconWidth/2; + + if ( i==Selected && hl ) + { + IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? + getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), + selectTime, os::Timer::getTime(), false, true); + } + else + { + IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), + 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); + } + } + + textRect.UpperLeftCorner.X += ItemsIconWidth+3; + + if ( i==Selected && hl ) + { + Font->draw(Items[i].text.c_str(), textRect, + hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? + getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT), + false, true, &clientClip); + } + else + { + Font->draw(Items[i].text.c_str(), textRect, + hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT), + false, true, &clientClip); + } + + textRect.UpperLeftCorner.X -= ItemsIconWidth+3; + } + } + + frameRect.UpperLeftCorner.Y += ItemHeight; + frameRect.LowerRightCorner.Y += ItemHeight; + } + + IGUIElement::draw(); +} + + +//! adds an list item with an icon +u32 CGUIListBox::addItem(const wchar_t* text, s32 icon) +{ + ListItem i; + i.text = text; + i.icon = icon; + + Items.push_back(i); + recalculateItemHeight(); + recalculateItemWidth(icon); + + return Items.size() - 1; +} + + +void CGUIListBox::setSpriteBank(IGUISpriteBank* bank) +{ + if ( bank == IconBank ) + return; + if (IconBank) + IconBank->drop(); + + IconBank = bank; + if (IconBank) + IconBank->grab(); +} + + +void CGUIListBox::recalculateScrollPos() +{ + if (!AutoScroll) + return; + + const s32 selPos = (Selected == -1 ? TotalItemHeight : Selected * ItemHeight) - ScrollBar->getPos(); + + if (selPos < 0) + { + ScrollBar->setPos(ScrollBar->getPos() + selPos); + } + else + if (selPos > AbsoluteRect.getHeight() - ItemHeight) + { + ScrollBar->setPos(ScrollBar->getPos() + selPos - AbsoluteRect.getHeight() + ItemHeight); + } +} + + +void CGUIListBox::setAutoScrollEnabled(bool scroll) +{ + AutoScroll = scroll; +} + + +bool CGUIListBox::isAutoScrollEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return AutoScroll; +} + + +bool CGUIListBox::getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const +{ + switch ( colorType ) + { + case EGUI_LBC_TEXT: + useColorLabel = "UseColText"; + colorLabel = "ColText"; + break; + case EGUI_LBC_TEXT_HIGHLIGHT: + useColorLabel = "UseColTextHl"; + colorLabel = "ColTextHl"; + break; + case EGUI_LBC_ICON: + useColorLabel = "UseColIcon"; + colorLabel = "ColIcon"; + break; + case EGUI_LBC_ICON_HIGHLIGHT: + useColorLabel = "UseColIconHl"; + colorLabel = "ColIconHl"; + break; + default: + return false; + } + return true; +} + + +//! Writes attributes of the element. +void CGUIListBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIListBox::serializeAttributes(out,options); + + // todo: out->addString ("IconBank", IconBank->getName?); + out->addBool ("DrawBack", DrawBack); + out->addBool ("MoveOverSelect", MoveOverSelect); + out->addBool ("AutoScroll", AutoScroll); + + out->addInt("ItemCount", Items.size()); + for (u32 i=0;iaddString(label.c_str(), Items[i].text.c_str() ); + + for ( s32 c=0; c < (s32)EGUI_LBC_COUNT; ++c ) + { + core::stringc useColorLabel, colorLabel; + if ( !getSerializationLabels((EGUI_LISTBOX_COLOR)c, useColorLabel, colorLabel) ) + return; + label = useColorLabel; label += i; + if ( Items[i].OverrideColors[c].Use ) + { + out->addBool(label.c_str(), true ); + label = colorLabel; label += i; + out->addColor(label.c_str(), Items[i].OverrideColors[c].Color); + } + else + { + out->addBool(label.c_str(), false ); + } + } + } +} + + +//! Reads attributes of the element +void CGUIListBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + clear(); + + DrawBack = in->getAttributeAsBool("DrawBack"); + MoveOverSelect = in->getAttributeAsBool("MoveOverSelect"); + AutoScroll = in->getAttributeAsBool("AutoScroll"); + + IGUIListBox::deserializeAttributes(in,options); + + const s32 count = in->getAttributeAsInt("ItemCount"); + for (s32 i=0; igetAttributeAsStringW(label.c_str()); + + addItem(item.text.c_str(), item.icon); + + for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) + { + core::stringc useColorLabel, colorLabel; + if ( !getSerializationLabels((EGUI_LISTBOX_COLOR)c, useColorLabel, colorLabel) ) + return; + label = useColorLabel; label += i; + Items[i].OverrideColors[c].Use = in->getAttributeAsBool(label.c_str()); + if ( Items[i].OverrideColors[c].Use ) + { + label = colorLabel; label += i; + Items[i].OverrideColors[c].Color = in->getAttributeAsColor(label.c_str()); + } + } + } +} + + +void CGUIListBox::recalculateItemWidth(s32 icon) +{ + if (IconBank && icon > -1 && + IconBank->getSprites().size() > (u32)icon && + IconBank->getSprites()[(u32)icon].Frames.size()) + { + u32 rno = IconBank->getSprites()[(u32)icon].Frames[0].rectNumber; + if (IconBank->getPositions().size() > rno) + { + const s32 w = IconBank->getPositions()[rno].getWidth(); + if (w > ItemsIconWidth) + ItemsIconWidth = w; + } + } +} + + +void CGUIListBox::setItem(u32 index, const wchar_t* text, s32 icon) +{ + if ( index >= Items.size() ) + return; + + Items[index].text = text; + Items[index].icon = icon; + + recalculateItemHeight(); + recalculateItemWidth(icon); +} + + +//! Insert the item at the given index +//! Return the index on success or -1 on failure. +s32 CGUIListBox::insertItem(u32 index, const wchar_t* text, s32 icon) +{ + ListItem i; + i.text = text; + i.icon = icon; + + Items.insert(i, index); + recalculateItemHeight(); + recalculateItemWidth(icon); + + return index; +} + + +void CGUIListBox::swapItems(u32 index1, u32 index2) +{ + if ( index1 >= Items.size() || index2 >= Items.size() ) + return; + + ListItem dummmy = Items[index1]; + Items[index1] = Items[index2]; + Items[index2] = dummmy; +} + + +void CGUIListBox::setItemOverrideColor(u32 index, video::SColor color) +{ + for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) + { + Items[index].OverrideColors[c].Use = true; + Items[index].OverrideColors[c].Color = color; + } +} + + +void CGUIListBox::setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color) +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return; + + Items[index].OverrideColors[colorType].Use = true; + Items[index].OverrideColors[colorType].Color = color; +} + + +void CGUIListBox::clearItemOverrideColor(u32 index) +{ + for (u32 c=0; c < (u32)EGUI_LBC_COUNT; ++c ) + { + Items[index].OverrideColors[c].Use = false; + } +} + + +void CGUIListBox::clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return; + + Items[index].OverrideColors[colorType].Use = false; +} + + +bool CGUIListBox::hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return false; + + return Items[index].OverrideColors[colorType].Use; +} + + +video::SColor CGUIListBox::getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const +{ + if ( (u32)index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return video::SColor(); + + return Items[index].OverrideColors[colorType].Color; +} + + +video::SColor CGUIListBox::getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const +{ + IGUISkin* skin = Environment->getSkin(); + if ( !skin ) + return video::SColor(); + + switch ( colorType ) + { + case EGUI_LBC_TEXT: + return skin->getColor(EGDC_BUTTON_TEXT); + case EGUI_LBC_TEXT_HIGHLIGHT: + return skin->getColor(EGDC_HIGH_LIGHT_TEXT); + case EGUI_LBC_ICON: + return skin->getColor(EGDC_ICON); + case EGUI_LBC_ICON_HIGHLIGHT: + return skin->getColor(EGDC_ICON_HIGH_LIGHT); + default: + return video::SColor(); + } +} + +//! set global itemHeight +void CGUIListBox::setItemHeight( s32 height ) +{ + ItemHeight = height; + ItemHeightOverride = 1; +} + + +//! Sets whether to draw the background +void CGUIListBox::setDrawBackground(bool draw) +{ + DrawBack = draw; +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.d new file mode 100644 index 0000000..07cb1bc --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.d @@ -0,0 +1,2 @@ +CGUIListBox.o: CGUIListBox.cpp CGUIListBox.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.h new file mode 100644 index 0000000..d00921f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIListBox.h @@ -0,0 +1,190 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_LIST_BOX_H_INCLUDED__ +#define __C_GUI_LIST_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIListBox.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + + class IGUIFont; + class IGUIScrollBar; + + class CGUIListBox : public IGUIListBox + { + public: + //! constructor + CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip=true, + bool drawBack=false, bool moveOverSelect=false); + + //! destructor + virtual ~CGUIListBox(); + + //! returns amount of list items + virtual u32 getItemCount() const; + + //! returns string of a list item. the id may be a value from 0 to itemCount-1 + virtual const wchar_t* getListItem(u32 id) const; + + //! adds an list item, returns id of item + virtual u32 addItem(const wchar_t* text); + + //! clears the list + virtual void clear(); + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 id); + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(const wchar_t *item); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! adds an list item with an icon + //! \param text Text of list entry + //! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon + //! \return + //! returns the id of the new created item + virtual u32 addItem(const wchar_t* text, s32 icon); + + //! Returns the icon of an item + virtual s32 getIcon(u32 id) const; + + //! removes an item from the list + virtual void removeItem(u32 id); + + //! get the the id of the item at the given absolute coordinates + virtual s32 getItemAt(s32 xpos, s32 ypos) const; + + //! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of + //! the built-in-font by default. A sprite can be displayed in front of every list item. + //! An icon is an index within the icon sprite bank. Several default icons are available in the + //! skin through getIcon + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! set whether the listbox should scroll to newly selected items + virtual void setAutoScrollEnabled(bool scroll); + + //! returns true if automatic scrolling is enabled, false if not. + virtual bool isAutoScrollEnabled() const; + + //! Update the position and size of the listbox, and update the scrollbar + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + //! set all item colors at given index to color + virtual void setItemOverrideColor(u32 index, video::SColor color); + + //! set all item colors of specified type at given index to color + virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color); + + //! clear all item colors at index + virtual void clearItemOverrideColor(u32 index); + + //! clear item color at index for given colortype + virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType); + + //! has the item at index its color overwritten? + virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; + + //! return the overwrite color at given item index. + virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; + + //! return the default color which is used for the given colorType + virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const; + + //! set the item at the given index + virtual void setItem(u32 index, const wchar_t* text, s32 icon); + + //! Insert the item at the given index + //! Return the index on success or -1 on failure. + virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon); + + //! Swap the items at the given indices + virtual void swapItems(u32 index1, u32 index2); + + //! set global itemHeight + virtual void setItemHeight( s32 height ); + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + + private: + + struct ListItem + { + ListItem() : icon(-1) + {} + + core::stringw text; + s32 icon; + + // A multicolor extension + struct ListItemOverrideColor + { + ListItemOverrideColor() : Use(false) {} + bool Use; + video::SColor Color; + }; + ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT]; + }; + + void recalculateItemHeight(); + void selectNew(s32 ypos, bool onlyHover=false); + void recalculateScrollPos(); + + // extracted that function to avoid copy&paste code + void recalculateItemWidth(s32 icon); + + // get labels used for serialization + bool getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const; + + core::array< ListItem > Items; + s32 Selected; + s32 ItemHeight; + s32 ItemHeightOverride; + s32 TotalItemHeight; + s32 ItemsIconWidth; + gui::IGUIFont* Font; + gui::IGUISpriteBank* IconBank; + gui::IGUIScrollBar* ScrollBar; + u32 selectTime; + u32 LastKeyTime; + core::stringw KeyBuffer; + bool Selecting; + bool DrawBack; + bool MoveOverSelect; + bool AutoScroll; + bool HighlightWhenNotFocused; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.cpp new file mode 100644 index 0000000..6987df8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.cpp @@ -0,0 +1,294 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIMenu.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "IGUIWindow.h" + +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIMenu::CGUIMenu(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle) + : CGUIContextMenu(environment, parent, id, rectangle, false, true) +{ + #ifdef _DEBUG + setDebugName("CGUIMenu"); + #endif + + Type = EGUIET_MENU; + + setNotClipped(false); + + recalculateSize(); +} + + +//! draws the element and its children +void CGUIMenu::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(EGDF_MENU); + + if (font != LastFont) + { + if (LastFont) + LastFont->drop(); + LastFont = font; + if (LastFont) + LastFont->grab(); + + recalculateSize(); + } + + core::rect rect = AbsoluteRect; + + // draw frame + + skin->draw3DToolBar(this, rect, &AbsoluteClippingRect); + + // loop through all menu items + + rect = AbsoluteRect; + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (!Items[i].IsSeparator) + { + rect = getRect(Items[i], AbsoluteRect); + + // draw highlighted + if (i == HighLighted && Items[i].Enabled) + { + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_DARK_SHADOW), + true, true, rect, &AbsoluteClippingRect); + } + // draw text + + EGUI_DEFAULT_COLOR c = EGDC_BUTTON_TEXT; + + if (i == HighLighted) + c = EGDC_HIGH_LIGHT_TEXT; + + if (!Items[i].Enabled) + c = EGDC_GRAY_TEXT; + + if (font) + font->draw(Items[i].Text.c_str(), rect, + skin->getColor(c), true, true, &AbsoluteClippingRect); + } + } + + IGUIElement::draw(); +} + + +//! called if an event happened. +bool CGUIMenu::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case gui::EGET_ELEMENT_FOCUS_LOST: + if (event.GUIEvent.Caller == this && !isMyChild(event.GUIEvent.Element)) + { + closeAllSubMenus(); + HighLighted = -1; + } + break; + case gui::EGET_ELEMENT_FOCUSED: + if (event.GUIEvent.Caller == this && Parent) + { + Parent->bringToFront(this); + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + { + if (!Environment->hasFocus(this)) + { + Environment->setFocus(this); + } + + if (Parent) + Parent->bringToFront(this); + + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + bool shouldCloseSubMenu = hasOpenSubMenu(); + if (!AbsoluteClippingRect.isPointInside(p)) + { + shouldCloseSubMenu = false; + } + highlight(core::position2d(event.MouseInput.X, event.MouseInput.Y), true); + if ( shouldCloseSubMenu ) + { + Environment->removeFocus(this); + } + + return true; + } + case EMIE_LMOUSE_LEFT_UP: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + if (!AbsoluteClippingRect.isPointInside(p)) + { + s32 t = sendClick(p); + if ((t==0 || t==1) && Environment->hasFocus(this)) + Environment->removeFocus(this); + } + + return true; + } + case EMIE_MOUSE_MOVED: + if (Environment->hasFocus(this) && HighLighted >= 0) + { + s32 oldHighLighted = HighLighted; + highlight(core::position2d(event.MouseInput.X, event.MouseInput.Y), true); + if ( HighLighted < 0 ) + HighLighted = oldHighLighted; // keep last hightlight active when moving outside the area + } + return true; + default: + break; + } + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + +void CGUIMenu::recalculateSize() +{ + core::rect clientRect; // client rect of parent + if ( Parent && Parent->hasType(EGUIET_WINDOW) ) + { + clientRect = static_cast(Parent)->getClientRect(); + } + else if ( Parent ) + { + clientRect = core::rect(0,0, Parent->getAbsolutePosition().getWidth(), + Parent->getAbsolutePosition().getHeight()); + } + else + { + clientRect = RelativeRect; + } + + + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(EGDF_MENU); + + if (!font) + { + if (Parent && skin) + RelativeRect = core::rect(clientRect.UpperLeftCorner.X, clientRect.UpperLeftCorner.Y, + clientRect.LowerRightCorner.X, clientRect.UpperLeftCorner.Y+skin->getSize(EGDS_MENU_HEIGHT)); + return; + } + + core::rect rect; + rect.UpperLeftCorner = clientRect.UpperLeftCorner; + s32 height = font->getDimension(L"A").Height + 5; + //if (skin && height < skin->getSize ( EGDS_MENU_HEIGHT )) + // height = skin->getSize(EGDS_MENU_HEIGHT); + s32 width = rect.UpperLeftCorner.X; + s32 i; + + for (i=0; i<(s32)Items.size(); ++i) + { + if (Items[i].IsSeparator) + { + Items[i].Dim.Width = 0; + Items[i].Dim.Height = height; + } + else + { + Items[i].Dim = font->getDimension(Items[i].Text.c_str()); + Items[i].Dim.Width += 20; + } + + Items[i].PosY = width; + width += Items[i].Dim.Width; + } + + width = clientRect.getWidth(); + + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + width; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + height; + + setRelativePosition(rect); + + // recalculate submenus + for (i=0; i<(s32)Items.size(); ++i) + if (Items[i].SubMenu) + { + // move submenu + s32 w = Items[i].SubMenu->getAbsolutePosition().getWidth(); + s32 h = Items[i].SubMenu->getAbsolutePosition().getHeight(); + + Items[i].SubMenu->setRelativePosition( + core::rect(Items[i].PosY, height , + Items[i].PosY+w-5, height+h)); + } +} + + +//! returns the item highlight-area +core::rect CGUIMenu::getHRect(const SItem& i, const core::rect& absolute) const +{ + core::rect r = absolute; + r.UpperLeftCorner.X += i.PosY; + r.LowerRightCorner.X = r.UpperLeftCorner.X + i.Dim.Width; + return r; +} + + +//! Gets drawing rect of Item +core::rect CGUIMenu::getRect(const SItem& i, const core::rect& absolute) const +{ + return getHRect(i, absolute); +} + + +void CGUIMenu::updateAbsolutePosition() +{ + if (Parent) + DesiredRect.LowerRightCorner.X = Parent->getAbsolutePosition().getWidth(); + + IGUIElement::updateAbsolutePosition(); +} + + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.d new file mode 100644 index 0000000..c9ef3e5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.d @@ -0,0 +1 @@ +CGUIMenu.o: CGUIMenu.cpp CGUIMenu.h ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.h new file mode 100644 index 0000000..d1e9526 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMenu.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MENU_H_INCLUDED__ +#define __C_GUI_MENU_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIContextMenu.h" + +namespace irr +{ +namespace gui +{ + + //! GUI menu interface. + class CGUIMenu : public CGUIContextMenu + { + public: + + //! constructor + CGUIMenu(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! draws the element and its children + virtual void draw(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Updates the absolute position. + virtual void updateAbsolutePosition(); + + protected: + + virtual void recalculateSize(); + + //! returns the item highlight-area + virtual core::rect getHRect(const SItem& i, const core::rect& absolute) const; + + //! Gets drawing rect of Item + virtual core::rect getRect(const SItem& i, const core::rect& absolute) const; + }; + +} // end namespace gui +} // end namespace irr + + +#endif // __C_GUI_MENU_H_INCLUDED__ +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.cpp new file mode 100644 index 0000000..d121e34 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.cpp @@ -0,0 +1,171 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIMeshViewer.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IAnimatedMesh.h" +#include "IMesh.h" +#include "os.h" +#include "IGUISkin.h" + +namespace irr +{ + +namespace gui +{ + + +//! constructor +CGUIMeshViewer::CGUIMeshViewer(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIMeshViewer(environment, parent, id, rectangle), Mesh(0) +{ + #ifdef _DEBUG + setDebugName("CGUIMeshViewer"); + #endif +} + + +//! destructor +CGUIMeshViewer::~CGUIMeshViewer() +{ + if (Mesh) + Mesh->drop(); +} + + +//! sets the mesh to be shown +void CGUIMeshViewer::setMesh(scene::IAnimatedMesh* mesh) +{ + if (mesh) + mesh->grab(); + if (Mesh) + Mesh->drop(); + + Mesh = mesh; + + /* This might be used for proper transformation etc. + core::vector3df center(0.0f,0.0f,0.0f); + core::aabbox3d box; + + box = Mesh->getMesh(0)->getBoundingBox(); + center = (box.MaxEdge + box.MinEdge) / 2; + */ +} + + +//! Gets the displayed mesh +scene::IAnimatedMesh* CGUIMeshViewer::getMesh() const +{ + return Mesh; +} + + +//! sets the material +void CGUIMeshViewer::setMaterial(const video::SMaterial& material) +{ + Material = material; +} + + +//! gets the material +const video::SMaterial& CGUIMeshViewer::getMaterial() const +{ + return Material; +} + + +//! called if an event happened. +bool CGUIMeshViewer::OnEvent(const SEvent& event) +{ + return IGUIElement::OnEvent(event); +} + + +//! draws the element and its children +void CGUIMeshViewer::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + core::rect viewPort = AbsoluteRect; + viewPort.LowerRightCorner.X -= 1; + viewPort.LowerRightCorner.Y -= 1; + viewPort.UpperLeftCorner.X += 1; + viewPort.UpperLeftCorner.Y += 1; + + viewPort.clipAgainst(AbsoluteClippingRect); + + // draw the frame + + core::rect frameRect(AbsoluteRect); + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect); + + frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_SHADOW), frameRect, &AbsoluteClippingRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1; + skin->draw2DRectangle(this, skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); + + // draw the mesh + + if (Mesh) + { + //TODO: if outside of screen, dont draw. + // - why is the absolute clipping rect not already the screen? + + core::rect oldViewPort = driver->getViewPort(); + + driver->setViewPort(viewPort); + + core::matrix4 mat; + + //CameraControl->calculateProjectionMatrix(mat); + //driver->setTransform(video::TS_PROJECTION, mat); + + mat.makeIdentity(); + mat.setTranslation(core::vector3df(0,0,0)); + driver->setTransform(video::ETS_WORLD, mat); + + //CameraControl->calculateViewMatrix(mat); + //driver->setTransform(video::TS_VIEW, mat); + + driver->setMaterial(Material); + + u32 frame = 0; + if(Mesh->getFrameCount()) + frame = (os::Timer::getTime()/20)%Mesh->getFrameCount(); + const scene::IMesh* const m = Mesh->getMesh(frame); + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = m->getMeshBuffer(i); + driver->drawVertexPrimitiveList(mb->getVertices(), + mb->getVertexCount(), mb->getIndices(), + mb->getIndexCount()/ 3, mb->getVertexType(), + scene::EPT_TRIANGLES, mb->getIndexType()); + } + + driver->setViewPort(oldViewPort); + } + + IGUIElement::draw(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.d new file mode 100644 index 0000000..f765bf3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.d @@ -0,0 +1,2 @@ +CGUIMeshViewer.o: CGUIMeshViewer.cpp CGUIMeshViewer.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.h new file mode 100644 index 0000000..7827b4b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMeshViewer.h @@ -0,0 +1,61 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MESH_VIEWER_H_INCLUDED__ +#define __C_GUI_MESH_VIEWER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIMeshViewer.h" +#include "SMaterial.h" + +namespace irr +{ + +namespace gui +{ + + class CGUIMeshViewer : public IGUIMeshViewer + { + public: + + //! constructor + CGUIMeshViewer(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIMeshViewer(); + + //! sets the mesh to be shown + virtual void setMesh(scene::IAnimatedMesh* mesh); + + //! Gets the displayed mesh + virtual scene::IAnimatedMesh* getMesh() const; + + //! sets the material + virtual void setMaterial(const video::SMaterial& material); + + //! gets the material + virtual const video::SMaterial& getMaterial() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + private: + + video::SMaterial Material; + scene::IAnimatedMesh* Mesh; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_MESH_VIEWER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp new file mode 100644 index 0000000..57b383d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp @@ -0,0 +1,463 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIMessageBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIButton.h" +#include "IGUIFont.h" +#include "ITexture.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIMessageBox::CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption, + const wchar_t* text, s32 flags, + IGUIElement* parent, s32 id, core::rect rectangle, video::ITexture* image) +: CGUIWindow(environment, parent, id, rectangle), + OkButton(0), CancelButton(0), YesButton(0), NoButton(0), StaticText(0), + Icon(0), IconTexture(image), + Flags(flags), MessageText(text), Pressed(false) +{ + #ifdef _DEBUG + setDebugName("CGUIMessageBox"); + #endif + + // set element type + Type = EGUIET_MESSAGE_BOX; + + // remove focus + Environment->setFocus(0); + + // remove buttons + + getMaximizeButton()->remove(); + getMinimizeButton()->remove(); + + if (caption) + setText(caption); + + Environment->setFocus(this); + + if ( IconTexture ) + IconTexture->grab(); + + refreshControls(); +} + + +//! destructor +CGUIMessageBox::~CGUIMessageBox() +{ + if (StaticText) + StaticText->drop(); + + if (OkButton) + OkButton->drop(); + + if (CancelButton) + CancelButton->drop(); + + if (YesButton) + YesButton->drop(); + + if (NoButton) + NoButton->drop(); + + if (Icon) + Icon->drop(); + + if ( IconTexture ) + IconTexture->drop(); +} + +void CGUIMessageBox::setButton(IGUIButton*& button, bool isAvailable, const core::rect & btnRect, const wchar_t * text, IGUIElement*& focusMe) +{ + // add/remove ok button + if (isAvailable) + { + if (!button) + { + button = Environment->addButton(btnRect, this); + button->setSubElement(true); + button->grab(); + } + else + button->setRelativePosition(btnRect); + + button->setText(text); + + focusMe = button; + } + else if (button) + { + button->drop(); + button->remove(); + button =0; + } +} + +void CGUIMessageBox::refreshControls() +{ + // Layout can be seen as 4 boxes (a layoutmanager would be nice) + // One box at top over the whole width for title + // Two boxes with same height at the middle beside each other for icon and for text + // One box at the bottom for the buttons + + const IGUISkin* skin = Environment->getSkin(); + + const s32 buttonHeight = skin->getSize(EGDS_BUTTON_HEIGHT); + const s32 buttonWidth = skin->getSize(EGDS_BUTTON_WIDTH); + const s32 titleHeight = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH)+2; // titlebar has no own constant + const s32 buttonDistance = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + const s32 borderWidth = skin->getSize(EGDS_MESSAGE_BOX_GAP_SPACE); + + // add the static text for the message + core::rect staticRect; + staticRect.UpperLeftCorner.X = borderWidth; + staticRect.UpperLeftCorner.Y = titleHeight + borderWidth; + staticRect.LowerRightCorner.X = staticRect.UpperLeftCorner.X + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH); + staticRect.LowerRightCorner.Y = staticRect.UpperLeftCorner.Y + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT); + if (!StaticText) + { + StaticText = Environment->addStaticText(MessageText.c_str(), staticRect, false, false, this); + + StaticText->setWordWrap(true); + StaticText->setSubElement(true); + StaticText->grab(); + } + else + { + StaticText->setRelativePosition(staticRect); + StaticText->setText(MessageText.c_str()); + } + + s32 textHeight = StaticText->getTextHeight(); + s32 textWidth = StaticText->getTextWidth() + 6; // +6 because the static itself needs that + const s32 iconHeight = IconTexture ? IconTexture->getOriginalSize().Height : 0; + + if ( textWidth < skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH) ) + textWidth = skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH) + 6; + // no neeed to check for max because it couldn't get larger due to statictextbox. + if ( textHeight < skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT) ) + textHeight = skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT); + if ( textHeight > skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT) ) + textHeight = skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT); + + // content is text + icons + borders (but not titlebar) + s32 contentHeight = textHeight > iconHeight ? textHeight : iconHeight; + contentHeight += borderWidth; + s32 contentWidth = 0; + + // add icon + if ( IconTexture ) + { + core::position2d iconPos; + iconPos.Y = titleHeight + borderWidth; + if ( iconHeight < textHeight ) + iconPos.Y += (textHeight-iconHeight) / 2; + iconPos.X = borderWidth; + + if (!Icon) + { + Icon = Environment->addImage(IconTexture, iconPos, true, this); + Icon->setSubElement(true); + Icon->grab(); + } + else + { + core::rect iconRect( iconPos.X, iconPos.Y, iconPos.X + IconTexture->getOriginalSize().Width, iconPos.Y + IconTexture->getOriginalSize().Height ); + Icon->setRelativePosition(iconRect); + } + + contentWidth += borderWidth + IconTexture->getOriginalSize().Width; + } + else if ( Icon ) + { + Icon->drop(); + Icon->remove(); + Icon = 0; + } + + // position text + core::rect textRect; + textRect.UpperLeftCorner.X = contentWidth + borderWidth; + textRect.UpperLeftCorner.Y = titleHeight + borderWidth; + if ( textHeight < iconHeight ) + textRect.UpperLeftCorner.Y += (iconHeight-textHeight) / 2; + textRect.LowerRightCorner.X = textRect.UpperLeftCorner.X + textWidth; + textRect.LowerRightCorner.Y = textRect.UpperLeftCorner.Y + textHeight; + contentWidth += 2*borderWidth + textWidth; + StaticText->setRelativePosition( textRect ); + + // find out button size needs + s32 countButtons = 0; + if (Flags & EMBF_OK) + ++countButtons; + if (Flags & EMBF_CANCEL) + ++countButtons; + if (Flags & EMBF_YES) + ++countButtons; + if (Flags & EMBF_NO) + ++countButtons; + + s32 buttonBoxWidth = countButtons * buttonWidth + 2 * borderWidth; + if ( countButtons > 1 ) + buttonBoxWidth += (countButtons-1) * buttonDistance; + s32 buttonBoxHeight = buttonHeight + 2 * borderWidth; + + // calc new message box sizes + core::rect tmp = getRelativePosition(); + s32 msgBoxHeight = titleHeight + contentHeight + buttonBoxHeight; + s32 msgBoxWidth = contentWidth > buttonBoxWidth ? contentWidth : buttonBoxWidth; + + // adjust message box position + tmp.UpperLeftCorner.Y = (Parent->getAbsolutePosition().getHeight() - msgBoxHeight) / 2; + tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + msgBoxHeight; + tmp.UpperLeftCorner.X = (Parent->getAbsolutePosition().getWidth() - msgBoxWidth) / 2; + tmp.LowerRightCorner.X = tmp.UpperLeftCorner.X + msgBoxWidth; + setRelativePosition(tmp); + + // add buttons + + core::rect btnRect; + btnRect.UpperLeftCorner.Y = titleHeight + contentHeight + borderWidth; + btnRect.LowerRightCorner.Y = btnRect.UpperLeftCorner.Y + buttonHeight; + btnRect.UpperLeftCorner.X = borderWidth; + if ( contentWidth > buttonBoxWidth ) + btnRect.UpperLeftCorner.X += (contentWidth - buttonBoxWidth) / 2; // center buttons + btnRect.LowerRightCorner.X = btnRect.UpperLeftCorner.X + buttonWidth; + + IGUIElement* focusMe = 0; + setButton(OkButton, (Flags & EMBF_OK) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_OK), focusMe); + if ( Flags & EMBF_OK ) + btnRect += core::position2d(buttonWidth + buttonDistance, 0); + setButton(CancelButton, (Flags & EMBF_CANCEL) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_CANCEL), focusMe); + if ( Flags & EMBF_CANCEL ) + btnRect += core::position2d(buttonWidth + buttonDistance, 0); + setButton(YesButton, (Flags & EMBF_YES) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_YES), focusMe); + if ( Flags & EMBF_YES ) + btnRect += core::position2d(buttonWidth + buttonDistance, 0); + setButton(NoButton, (Flags & EMBF_NO) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_NO), focusMe); + + if (Environment->hasFocus(this) && focusMe) + Environment->setFocus(focusMe); +} + + +//! called if an event happened. +bool CGUIMessageBox::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + SEvent outevent; + outevent.EventType = EET_GUI_EVENT; + outevent.GUIEvent.Caller = this; + outevent.GUIEvent.Element = 0; + + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + + if (event.KeyInput.PressedDown) + { + switch (event.KeyInput.Key) + { + case KEY_RETURN: + if (OkButton) + { + OkButton->setPressed(true); + Pressed = true; + } + break; + case KEY_KEY_Y: + if (YesButton) + { + YesButton->setPressed(true); + Pressed = true; + } + break; + case KEY_KEY_N: + if (NoButton) + { + NoButton->setPressed(true); + Pressed = true; + } + break; + case KEY_ESCAPE: + if (Pressed) + { + // cancel press + if (OkButton) OkButton->setPressed(false); + if (YesButton) YesButton->setPressed(false); + if (NoButton) NoButton->setPressed(false); + Pressed = false; + } + else + if (CancelButton) + { + CancelButton->setPressed(true); + Pressed = true; + } + else + if (CloseButton && CloseButton->isVisible()) + { + CloseButton->setPressed(true); + Pressed = true; + } + break; + default: // no other key is handled here + break; + } + } + else + if (Pressed) + { + if (OkButton && event.KeyInput.Key == KEY_RETURN) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if ((CancelButton || CloseButton) && event.KeyInput.Key == KEY_ESCAPE) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (YesButton && event.KeyInput.Key == KEY_KEY_Y) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (NoButton && event.KeyInput.Key == KEY_KEY_N) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO; + Parent->OnEvent(outevent); + remove(); + return true; + } + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == OkButton) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == CancelButton || + event.GUIEvent.Caller == CloseButton) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == YesButton) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES; + Parent->OnEvent(outevent); + remove(); + return true; + } + else + if (event.GUIEvent.Caller == NoButton) + { + setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC + Environment->setFocus(0); + outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO; + Parent->OnEvent(outevent); + remove(); + return true; + } + } + break; + default: + break; + } + } + + return CGUIWindow::OnEvent(event); +} + + +//! Writes attributes of the element. +void CGUIMessageBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + CGUIWindow::serializeAttributes(out,options); + + out->addBool ("OkayButton", (Flags & EMBF_OK) != 0 ); + out->addBool ("CancelButton", (Flags & EMBF_CANCEL) != 0 ); + out->addBool ("YesButton", (Flags & EMBF_YES) != 0 ); + out->addBool ("NoButton", (Flags & EMBF_NO) != 0 ); + out->addTexture ("Texture", IconTexture); + + out->addString ("MessageText", MessageText.c_str()); +} + + +//! Reads attributes of the element +void CGUIMessageBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Flags = 0; + + Flags = in->getAttributeAsBool("OkayButton") ? EMBF_OK : 0; + Flags |= in->getAttributeAsBool("CancelButton")? EMBF_CANCEL : 0; + Flags |= in->getAttributeAsBool("YesButton") ? EMBF_YES : 0; + Flags |= in->getAttributeAsBool("NoButton") ? EMBF_NO : 0; + + if ( IconTexture ) + { + IconTexture->drop(); + IconTexture = NULL; + } + IconTexture = in->getAttributeAsTexture("Texture"); + if ( IconTexture ) + IconTexture->grab(); + + MessageText = in->getAttributeAsStringW("MessageText").c_str(); + + CGUIWindow::deserializeAttributes(in,options); + + refreshControls(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.d new file mode 100644 index 0000000..01f3f67 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.d @@ -0,0 +1,2 @@ +CGUIMessageBox.o: CGUIMessageBox.cpp CGUIMessageBox.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.h new file mode 100644 index 0000000..6f632c5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MESSAGE_BOX_H_INCLUDED__ +#define __C_GUI_MESSAGE_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIWindow.h" +#include "IGUIStaticText.h" +#include "IGUIImage.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class CGUIMessageBox : public CGUIWindow + { + public: + + //! constructor + CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption, + const wchar_t* text, s32 flag, + IGUIElement* parent, s32 id, core::rect rectangle, video::ITexture* image=0); + + //! destructor + virtual ~CGUIMessageBox(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void refreshControls(); + void setButton(IGUIButton*& button, bool isAvailable, const core::rect & btnRect, const wchar_t * text, IGUIElement*& focusMe); + + IGUIButton* OkButton; + IGUIButton* CancelButton; + IGUIButton* YesButton; + IGUIButton* NoButton; + IGUIStaticText* StaticText; + IGUIImage * Icon; + video::ITexture * IconTexture; + + s32 Flags; + core::stringw MessageText; + bool Pressed; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.cpp new file mode 100644 index 0000000..879cb49 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.cpp @@ -0,0 +1,235 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIModalScreen.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "os.h" +#include "IVideoDriver.h" +#include "IGUISkin.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIModalScreen::CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* parent, s32 id) +: IGUIElement(EGUIET_MODAL_SCREEN, environment, parent, id, core::recti(0, 0, parent->getAbsolutePosition().getWidth(), parent->getAbsolutePosition().getHeight()) ), + MouseDownTime(0) +{ + #ifdef _DEBUG + setDebugName("CGUIModalScreen"); + #endif + setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + + // this element is a tab group + setTabGroup(true); +} + +bool CGUIModalScreen::canTakeFocus(IGUIElement* target) const +{ + return (target && ((const IGUIElement*)target == this // this element can take it + || isMyChild(target) // own children also + || (target->getType() == EGUIET_MODAL_SCREEN ) // other modals also fine (is now on top or explicitely requested) + || (target->getParent() && target->getParent()->getType() == EGUIET_MODAL_SCREEN ))) // children of other modals will do + ; +} + +bool CGUIModalScreen::isVisible() const +{ + // any parent invisible? + IGUIElement * parentElement = getParent(); + while ( parentElement ) + { + if ( !parentElement->isVisible() ) + return false; + parentElement = parentElement->getParent(); + } + + // if we have no children then the modal is probably abused as a way to block input + if ( Children.empty() ) + { + return IGUIElement::isVisible(); + } + + // any child visible? + bool visible = false; + core::list::ConstIterator it = Children.begin(); + for (; it != Children.end(); ++it) + { + if ( (*it)->isVisible() ) + { + visible = true; + break; + } + } + return visible; +} + +bool CGUIModalScreen::isPointInside(const core::position2d& point) const +{ + return true; +} + +//! called if an event happened. +bool CGUIModalScreen::OnEvent(const SEvent& event) +{ + if (!isEnabled() || !isVisible() ) + return IGUIElement::OnEvent(event); + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_ELEMENT_FOCUSED: + if ( event.GUIEvent.Caller == this && isMyChild(event.GUIEvent.Element) ) + { + Environment->removeFocus(0); // can't setFocus otherwise at it still has focus here + Environment->setFocus(event.GUIEvent.Element); + MouseDownTime = os::Timer::getTime(); + return true; + } + if ( !canTakeFocus(event.GUIEvent.Caller)) + { + if ( !Children.empty() ) + Environment->setFocus(*(Children.begin())); + else + Environment->setFocus(this); + } + IGUIElement::OnEvent(event); + return false; + case EGET_ELEMENT_FOCUS_LOST: + if ( !canTakeFocus(event.GUIEvent.Element)) + { + if ( isMyChild(event.GUIEvent.Caller) ) + { + if ( !Children.empty() ) + Environment->setFocus(*(Children.begin())); + else + Environment->setFocus(this); + } + else + { + MouseDownTime = os::Timer::getTime(); + } + return true; + } + else + { + return IGUIElement::OnEvent(event); + } + case EGET_ELEMENT_CLOSED: + // do not interfere with children being removed + return IGUIElement::OnEvent(event); + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + MouseDownTime = os::Timer::getTime(); + } + default: + break; + } + + IGUIElement::OnEvent(event); // anyone knows why events are passed on here? Causes p.e. problems when this is child of a CGUIWindow. + + return true; // absorb everything else +} + + +//! draws the element and its children +void CGUIModalScreen::draw() +{ + IGUISkin *skin = Environment->getSkin(); + + if (!skin) + return; + + u32 now = os::Timer::getTime(); + if (now - MouseDownTime < 300 && (now / 70)%2) + { + core::list::Iterator it = Children.begin(); + core::rect r; + video::SColor c = Environment->getSkin()->getColor(gui::EGDC_3D_HIGH_LIGHT); + + for (; it != Children.end(); ++it) + { + if ((*it)->isVisible()) + { + r = (*it)->getAbsolutePosition(); + r.LowerRightCorner.X += 1; + r.LowerRightCorner.Y += 1; + r.UpperLeftCorner.X -= 1; + r.UpperLeftCorner.Y -= 1; + + skin->draw2DRectangle(this, c, r, &AbsoluteClippingRect); + } + } + } + + IGUIElement::draw(); +} + + +//! Removes a child. +void CGUIModalScreen::removeChild(IGUIElement* child) +{ + IGUIElement::removeChild(child); + + if (Children.empty()) + { + remove(); + } +} + + +//! adds a child +void CGUIModalScreen::addChild(IGUIElement* child) +{ + IGUIElement::addChild(child); + Environment->setFocus(child); +} + + +void CGUIModalScreen::updateAbsolutePosition() +{ + core::rect parentRect(0,0,0,0); + + if (Parent) + { + parentRect = Parent->getAbsolutePosition(); + RelativeRect.UpperLeftCorner.X = 0; + RelativeRect.UpperLeftCorner.Y = 0; + RelativeRect.LowerRightCorner.X = parentRect.getWidth(); + RelativeRect.LowerRightCorner.Y = parentRect.getHeight(); + } + + IGUIElement::updateAbsolutePosition(); +} + + +//! Writes attributes of the element. +void CGUIModalScreen::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIElement::serializeAttributes(out,options); +} + +//! Reads attributes of the element +void CGUIModalScreen::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIElement::deserializeAttributes(in, options); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.d new file mode 100644 index 0000000..87b7a96 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.d @@ -0,0 +1,2 @@ +CGUIModalScreen.o: CGUIModalScreen.cpp CGUIModalScreen.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.h new file mode 100644 index 0000000..8548eb5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIModalScreen.h @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_MODAL_SCREEN_H_INCLUDED__ +#define __C_GUI_MODAL_SCREEN_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIElement.h" + +namespace irr +{ +namespace gui +{ + + class CGUIModalScreen : public IGUIElement + { + public: + + //! constructor + CGUIModalScreen(IGUIEnvironment* environment, IGUIElement* parent, s32 id); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Removes a child. + virtual void removeChild(IGUIElement* child); + + //! Adds a child + virtual void addChild(IGUIElement* child); + + + //! draws the element and its children + virtual void draw(); + + //! Updates the absolute position. + virtual void updateAbsolutePosition(); + + //! Modalscreen is not a typical element, but rather acts like a state for it's children. + //! isVisible is overriden to give this a useful behavior, so that a modal will no longer + //! be active when its parent is invisible or all its children are invisible. + virtual bool isVisible() const; + + //! Modals are infinite so every point is inside + virtual bool isPointInside(const core::position2d& point) const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + virtual bool canTakeFocus(IGUIElement* target) const; + + private: + + u32 MouseDownTime; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.cpp new file mode 100644 index 0000000..b65699e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.cpp @@ -0,0 +1,569 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIScrollBar.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "CGUIButton.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + + +//! constructor +CGUIScrollBar::CGUIScrollBar(bool horizontal, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, + core::rect rectangle, bool noclip) + : IGUIScrollBar(environment, parent, id, rectangle), UpButton(0), + DownButton(0), Dragging(false), Horizontal(horizontal), + DraggedBySlider(false), TrayClick(false), Pos(0), DrawPos(0), + DrawHeight(0), Min(0), Max(100), SmallStep(10), LargeStep(50), DesiredPos(0), + LastChange(0) +{ + #ifdef _DEBUG + setDebugName("CGUIScrollBar"); + #endif + + refreshControls(); + + setNotClipped(noclip); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + setPos(0); +} + + +//! destructor +CGUIScrollBar::~CGUIScrollBar() +{ + if (UpButton) + UpButton->drop(); + + if (DownButton) + DownButton->drop(); +} + + +//! called if an event happened. +bool CGUIScrollBar::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown) + { + const s32 oldPos = Pos; + bool absorb = true; + switch (event.KeyInput.Key) + { + case KEY_LEFT: + case KEY_UP: + setPos(Pos-SmallStep); + break; + case KEY_RIGHT: + case KEY_DOWN: + setPos(Pos+SmallStep); + break; + case KEY_HOME: + setPos(Min); + break; + case KEY_PRIOR: + setPos(Pos-LargeStep); + break; + case KEY_END: + setPos(Max); + break; + case KEY_NEXT: + setPos(Pos+LargeStep); + break; + default: + absorb = false; + } + + if (Pos != oldPos) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + } + if (absorb) + return true; + } + break; + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == UpButton) + setPos(Pos-SmallStep); + else + if (event.GUIEvent.Caller == DownButton) + setPos(Pos+SmallStep); + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + + return true; + } + else + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + if (event.GUIEvent.Caller == this) + Dragging = false; + } + break; + case EET_MOUSE_INPUT_EVENT: + { + const core::position2di p(event.MouseInput.X, event.MouseInput.Y); + bool isInside = isPointInside ( p ); + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + if (Environment->hasFocus(this)) + { + // thanks to a bug report by REAPER + // thanks to tommi by tommi for another bugfix + // everybody needs a little thanking. hallo niko!;-) + setPos( getPos() + + ( (event.MouseInput.Wheel < 0 ? -1 : 1) * SmallStep * (Horizontal ? 1 : -1 ) ) + ); + + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + return true; + } + break; + case EMIE_LMOUSE_PRESSED_DOWN: + { + if (isInside) + { + Dragging = true; + DraggedBySlider = SliderRect.isPointInside(p); + TrayClick = !DraggedBySlider; + DesiredPos = getPosFromMousePos(p); + Environment->setFocus ( this ); + return true; + } + break; + } + case EMIE_LMOUSE_LEFT_UP: + case EMIE_MOUSE_MOVED: + { + if ( !event.MouseInput.isLeftPressed () ) + Dragging = false; + + if ( !Dragging ) + { + if ( event.MouseInput.Event == EMIE_MOUSE_MOVED ) + break; + return isInside; + } + + if ( event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP ) + Dragging = false; + + const s32 newPos = getPosFromMousePos(p); + const s32 oldPos = Pos; + + if (!DraggedBySlider) + { + if ( isInside ) + { + DraggedBySlider = SliderRect.isPointInside(p); + TrayClick = !DraggedBySlider; + } + + if (DraggedBySlider) + { + setPos(newPos); + } + else + { + TrayClick = false; + if (event.MouseInput.Event == EMIE_MOUSE_MOVED) + return isInside; + } + } + + if (DraggedBySlider) + { + setPos(newPos); + } + else + { + DesiredPos = newPos; + } + + if (Pos != oldPos && Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + } + return isInside; + } break; + + default: + break; + } + } break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + +void CGUIScrollBar::OnPostRender(u32 timeMs) +{ + if (Dragging && !DraggedBySlider && TrayClick && timeMs > LastChange + 200) + { + LastChange = timeMs; + + const s32 oldPos = Pos; + + if (DesiredPos >= Pos + LargeStep) + setPos(Pos + LargeStep); + else + if (DesiredPos <= Pos - LargeStep) + setPos(Pos - LargeStep); + else + if (DesiredPos >= Pos - LargeStep && DesiredPos <= Pos + LargeStep) + setPos(DesiredPos); + + if (Pos != oldPos && Parent) + { + SEvent newEvent; + newEvent.EventType = EET_GUI_EVENT; + newEvent.GUIEvent.Caller = this; + newEvent.GUIEvent.Element = 0; + newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; + Parent->OnEvent(newEvent); + } + } + +} + +//! draws the element and its children +void CGUIScrollBar::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + + video::SColor iconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + if ( iconColor != CurrentIconColor ) + { + refreshControls(); + } + + + SliderRect = AbsoluteRect; + + // draws the background + skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), SliderRect, &AbsoluteClippingRect); + + if ( core::isnotzero ( range() ) ) + { + // recalculate slider rectangle + if (Horizontal) + { + SliderRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + DrawPos + RelativeRect.getHeight() - DrawHeight/2; + SliderRect.LowerRightCorner.X = SliderRect.UpperLeftCorner.X + DrawHeight; + } + else + { + SliderRect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + DrawPos + RelativeRect.getWidth() - DrawHeight/2; + SliderRect.LowerRightCorner.Y = SliderRect.UpperLeftCorner.Y + DrawHeight; + } + + skin->draw3DButtonPaneStandard(this, SliderRect, &AbsoluteClippingRect); + } + + // draw buttons + IGUIElement::draw(); +} + + +void CGUIScrollBar::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + // todo: properly resize + refreshControls(); + setPos ( Pos ); +} + +//! +s32 CGUIScrollBar::getPosFromMousePos(const core::position2di &pos) const +{ + f32 w, p; + if (Horizontal) + { + w = RelativeRect.getWidth() - f32(RelativeRect.getHeight())*3.0f; + p = pos.X - AbsoluteRect.UpperLeftCorner.X - RelativeRect.getHeight()*1.5f; + } + else + { + w = RelativeRect.getHeight() - f32(RelativeRect.getWidth())*3.0f; + p = pos.Y - AbsoluteRect.UpperLeftCorner.Y - RelativeRect.getWidth()*1.5f; + } + return (s32) ( p/w * range() ) + Min; +} + + +//! sets the position of the scrollbar +void CGUIScrollBar::setPos(s32 pos) +{ + Pos = core::s32_clamp ( pos, Min, Max ); + + if (Horizontal) + { + f32 f = (RelativeRect.getWidth() - ((f32)RelativeRect.getHeight()*3.0f)) / range(); + DrawPos = (s32)( ( ( Pos - Min ) * f) + ((f32)RelativeRect.getHeight() * 0.5f)); + DrawHeight = RelativeRect.getHeight(); + } + else + { + f32 f = (RelativeRect.getHeight() - ((f32)RelativeRect.getWidth()*3.0f)) / range(); + + DrawPos = (s32)( ( ( Pos - Min ) * f) + ((f32)RelativeRect.getWidth() * 0.5f)); + DrawHeight = RelativeRect.getWidth(); + } + +} + + +//! gets the small step value +s32 CGUIScrollBar::getSmallStep() const +{ + return SmallStep; +} + + +//! sets the small step value +void CGUIScrollBar::setSmallStep(s32 step) +{ + if (step > 0) + SmallStep = step; + else + SmallStep = 10; +} + + +//! gets the small step value +s32 CGUIScrollBar::getLargeStep() const +{ + return LargeStep; +} + + +//! sets the small step value +void CGUIScrollBar::setLargeStep(s32 step) +{ + if (step > 0) + LargeStep = step; + else + LargeStep = 50; +} + + +//! gets the maximum value of the scrollbar. +s32 CGUIScrollBar::getMax() const +{ + return Max; +} + + +//! sets the maximum value of the scrollbar. +void CGUIScrollBar::setMax(s32 max) +{ + Max = max; + if ( Min > Max ) + Min = Max; + + bool enable = core::isnotzero ( range() ); + UpButton->setEnabled(enable); + DownButton->setEnabled(enable); + setPos(Pos); +} + +//! gets the minimum value of the scrollbar. +s32 CGUIScrollBar::getMin() const +{ + return Min; +} + + +//! sets the minimum value of the scrollbar. +void CGUIScrollBar::setMin(s32 min) +{ + Min = min; + if ( Max < Min ) + Max = Min; + + + bool enable = core::isnotzero ( range() ); + UpButton->setEnabled(enable); + DownButton->setEnabled(enable); + setPos(Pos); +} + + +//! gets the current position of the scrollbar +s32 CGUIScrollBar::getPos() const +{ + return Pos; +} + + +//! refreshes the position and text on child buttons +void CGUIScrollBar::refreshControls() +{ + CurrentIconColor = video::SColor(255,255,255,255); + + IGUISkin* skin = Environment->getSkin(); + IGUISpriteBank* sprites = 0; + + if (skin) + { + sprites = skin->getSpriteBank(); + CurrentIconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + } + + if (Horizontal) + { + s32 h = RelativeRect.getHeight(); + if (!UpButton) + { + UpButton = new CGUIButton(Environment, this, -1, core::rect(0,0, h, h), NoClip); + UpButton->setSubElement(true); + UpButton->setTabStop(false); + } + if (sprites) + { + UpButton->setSpriteBank(sprites); + UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor); + UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor); + } + UpButton->setRelativePosition(core::rect(0,0, h, h)); + UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + if (!DownButton) + { + DownButton = new CGUIButton(Environment, this, -1, core::rect(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h), NoClip); + DownButton->setSubElement(true); + DownButton->setTabStop(false); + } + if (sprites) + { + DownButton->setSpriteBank(sprites); + DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor); + DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor); + } + DownButton->setRelativePosition(core::rect(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h)); + DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + } + else + { + s32 w = RelativeRect.getWidth(); + if (!UpButton) + { + UpButton = new CGUIButton(Environment, this, -1, core::rect(0,0, w, w), NoClip); + UpButton->setSubElement(true); + UpButton->setTabStop(false); + } + if (sprites) + { + UpButton->setSpriteBank(sprites); + UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor); + UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor); + } + UpButton->setRelativePosition(core::rect(0,0, w, w)); + UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + if (!DownButton) + { + DownButton = new CGUIButton(Environment, this, -1, core::rect(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()), NoClip); + DownButton->setSubElement(true); + DownButton->setTabStop(false); + } + if (sprites) + { + DownButton->setSpriteBank(sprites); + DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor); + DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor); + } + DownButton->setRelativePosition(core::rect(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight())); + DownButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); + } +} + + +//! Writes attributes of the element. +void CGUIScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIScrollBar::serializeAttributes(out,options); + + out->addBool("Horizontal", Horizontal); + out->addInt ("Value", Pos); + out->addInt ("Min", Min); + out->addInt ("Max", Max); + out->addInt ("SmallStep", SmallStep); + out->addInt ("LargeStep", LargeStep); + // CurrentIconColor - not serialized as continuiously updated +} + + +//! Reads attributes of the element +void CGUIScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIScrollBar::deserializeAttributes(in,options); + + Horizontal = in->getAttributeAsBool("Horizontal"); + setMin(in->getAttributeAsInt("Min")); + setMax(in->getAttributeAsInt("Max")); + setPos(in->getAttributeAsInt("Value")); + setSmallStep(in->getAttributeAsInt("SmallStep")); + setLargeStep(in->getAttributeAsInt("LargeStep")); + // CurrentIconColor - not serialized as continuiously updated + + refreshControls(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.d new file mode 100644 index 0000000..44cf041 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.d @@ -0,0 +1,2 @@ +CGUIScrollBar.o: CGUIScrollBar.cpp CGUIScrollBar.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.h new file mode 100644 index 0000000..0768f37 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIScrollBar.h @@ -0,0 +1,113 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_SCROLL_BAR_H_INCLUDED__ +#define __C_GUI_SCROLL_BAR_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIScrollBar.h" +#include "IGUIButton.h" + +namespace irr +{ +namespace gui +{ + + class CGUIScrollBar : public IGUIScrollBar + { + public: + + //! constructor + CGUIScrollBar(bool horizontal, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, core::rect rectangle, + bool noclip=false); + + //! destructor + virtual ~CGUIScrollBar(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + virtual void OnPostRender(u32 timeMs); + + + //! gets the maximum value of the scrollbar. + virtual s32 getMax() const; + + //! sets the maximum value of the scrollbar. + virtual void setMax(s32 max); + + //! gets the minimum value of the scrollbar. + virtual s32 getMin() const; + + //! sets the minimum value of the scrollbar. + virtual void setMin(s32 min); + + //! gets the small step value + virtual s32 getSmallStep() const; + + //! sets the small step value + virtual void setSmallStep(s32 step); + + //! gets the large step value + virtual s32 getLargeStep() const; + + //! sets the large step value + virtual void setLargeStep(s32 step); + + //! gets the current position of the scrollbar + virtual s32 getPos() const; + + //! sets the position of the scrollbar + virtual void setPos(s32 pos); + + //! updates the rectangle + virtual void updateAbsolutePosition(); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + void refreshControls(); + s32 getPosFromMousePos(const core::position2di &p) const; + + IGUIButton* UpButton; + IGUIButton* DownButton; + + core::rect SliderRect; + + bool Dragging; + bool Horizontal; + bool DraggedBySlider; + bool TrayClick; + s32 Pos; + s32 DrawPos; + s32 DrawHeight; + s32 Min; + s32 Max; + s32 SmallStep; + s32 LargeStep; + s32 DesiredPos; + u32 LastChange; + video::SColor CurrentIconColor; + + f32 range () const { return (f32) ( Max - Min ); } + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.cpp new file mode 100644 index 0000000..b0b2b39 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.cpp @@ -0,0 +1,1019 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUISkin.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "IGUIElement.h" +#include "IVideoDriver.h" +#include "IAttributes.h" + +namespace irr +{ +namespace gui +{ + +CGUISkin::CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver) +: SpriteBank(0), Driver(driver), Type(type) +{ + #ifdef _DEBUG + setDebugName("CGUISkin"); + #endif + + if ((Type == EGST_WINDOWS_CLASSIC) || (Type == EGST_WINDOWS_METALLIC)) + { + Colors[EGDC_3D_DARK_SHADOW] = video::SColor(101,50,50,50); + Colors[EGDC_3D_SHADOW] = video::SColor(101,130,130,130); + Colors[EGDC_3D_FACE] = video::SColor(101,210,210,210); + Colors[EGDC_3D_HIGH_LIGHT] = video::SColor(101,255,255,255); + Colors[EGDC_3D_LIGHT] = video::SColor(101,210,210,210); + Colors[EGDC_ACTIVE_BORDER] = video::SColor(101,16,14,115); + Colors[EGDC_ACTIVE_CAPTION] = video::SColor(255,255,255,255); + Colors[EGDC_APP_WORKSPACE] = video::SColor(101,100,100,100); + Colors[EGDC_BUTTON_TEXT] = video::SColor(240,10,10,10); + Colors[EGDC_GRAY_TEXT] = video::SColor(240,130,130,130); + Colors[EGDC_HIGH_LIGHT] = video::SColor(101,8,36,107); + Colors[EGDC_HIGH_LIGHT_TEXT] = video::SColor(240,255,255,255); + Colors[EGDC_INACTIVE_BORDER] = video::SColor(101,165,165,165); + Colors[EGDC_INACTIVE_CAPTION] = video::SColor(255,30,30,30); + Colors[EGDC_TOOLTIP] = video::SColor(200,0,0,0); + Colors[EGDC_TOOLTIP_BACKGROUND] = video::SColor(200,255,255,225); + Colors[EGDC_SCROLLBAR] = video::SColor(101,230,230,230); + Colors[EGDC_WINDOW] = video::SColor(101,255,255,255); + Colors[EGDC_WINDOW_SYMBOL] = video::SColor(200,10,10,10); + Colors[EGDC_ICON] = video::SColor(200,255,255,255); + Colors[EGDC_ICON_HIGH_LIGHT] = video::SColor(200,8,36,107); + Colors[EGDC_GRAY_WINDOW_SYMBOL] = video::SColor(240,100,100,100); + Colors[EGDC_EDITABLE] = video::SColor(255,255,255,255); + Colors[EGDC_GRAY_EDITABLE] = video::SColor(255,120,120,120); + Colors[EGDC_FOCUSED_EDITABLE] = video::SColor(255,240,240,255); + + + Sizes[EGDS_SCROLLBAR_SIZE] = 14; + Sizes[EGDS_MENU_HEIGHT] = 30; + Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15; + Sizes[EGDS_CHECK_BOX_WIDTH] = 18; + Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200; + Sizes[EGDS_BUTTON_WIDTH] = 80; + Sizes[EGDS_BUTTON_HEIGHT] = 30; + + Sizes[EGDS_TEXT_DISTANCE_X] = 2; + Sizes[EGDS_TEXT_DISTANCE_Y] = 0; + + Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 2; + Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 0; + } + else + { + //0x80a6a8af + Colors[EGDC_3D_DARK_SHADOW] = 0x60767982; + //Colors[EGDC_3D_FACE] = 0xc0c9ccd4; // tab background + Colors[EGDC_3D_FACE] = 0xc0cbd2d9; // tab background + Colors[EGDC_3D_SHADOW] = 0x50e4e8f1; // tab background, and left-top highlight + Colors[EGDC_3D_HIGH_LIGHT] = 0x40c7ccdc; + Colors[EGDC_3D_LIGHT] = 0x802e313a; + Colors[EGDC_ACTIVE_BORDER] = 0x80404040; // window title + Colors[EGDC_ACTIVE_CAPTION] = 0xffd0d0d0; + Colors[EGDC_APP_WORKSPACE] = 0xc0646464; // unused + Colors[EGDC_BUTTON_TEXT] = 0xd0161616; + Colors[EGDC_GRAY_TEXT] = 0x3c141414; + Colors[EGDC_HIGH_LIGHT] = 0x6c606060; + Colors[EGDC_HIGH_LIGHT_TEXT] = 0xd0e0e0e0; + Colors[EGDC_INACTIVE_BORDER] = 0xf0a5a5a5; + Colors[EGDC_INACTIVE_CAPTION] = 0xffd2d2d2; + Colors[EGDC_TOOLTIP] = 0xf00f2033; + Colors[EGDC_TOOLTIP_BACKGROUND] = 0xc0cbd2d9; + Colors[EGDC_SCROLLBAR] = 0xf0e0e0e0; + Colors[EGDC_WINDOW] = 0xf0f0f0f0; + Colors[EGDC_WINDOW_SYMBOL] = 0xd0161616; + Colors[EGDC_ICON] = 0xd0161616; + Colors[EGDC_ICON_HIGH_LIGHT] = 0xd0606060; + Colors[EGDC_GRAY_WINDOW_SYMBOL] = 0x3c101010; + Colors[EGDC_EDITABLE] = 0xf0ffffff; + Colors[EGDC_GRAY_EDITABLE] = 0xf0cccccc; + Colors[EGDC_FOCUSED_EDITABLE] = 0xf0fffff0; + + Sizes[EGDS_SCROLLBAR_SIZE] = 14; + Sizes[EGDS_MENU_HEIGHT] = 48; + Sizes[EGDS_WINDOW_BUTTON_WIDTH] = 15; + Sizes[EGDS_CHECK_BOX_WIDTH] = 18; + Sizes[EGDS_MESSAGE_BOX_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_HEIGHT] = 200; + Sizes[EGDS_BUTTON_WIDTH] = 80; + Sizes[EGDS_BUTTON_HEIGHT] = 30; + + Sizes[EGDS_TEXT_DISTANCE_X] = 3; + Sizes[EGDS_TEXT_DISTANCE_Y] = 2; + + Sizes[EGDS_TITLEBARTEXT_DISTANCE_X] = 3; + Sizes[EGDS_TITLEBARTEXT_DISTANCE_Y] = 2; + } + + Sizes[EGDS_MESSAGE_BOX_GAP_SPACE] = 15; + Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH] = 0; + Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH] = 500; + Sizes[EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT] = 0; + Sizes[EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT] = 99999; + + Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_X] = 1; + Sizes[EGDS_BUTTON_PRESSED_IMAGE_OFFSET_Y] = 1; + Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_X] = 0; + Sizes[EGDS_BUTTON_PRESSED_TEXT_OFFSET_Y] = 2; + + Texts[EGDT_MSG_BOX_OK] = L"OK"; + Texts[EGDT_MSG_BOX_CANCEL] = L"Cancel"; + Texts[EGDT_MSG_BOX_YES] = L"Yes"; + Texts[EGDT_MSG_BOX_NO] = L"No"; + Texts[EGDT_WINDOW_CLOSE] = L"Close"; + Texts[EGDT_WINDOW_RESTORE] = L"Restore"; + Texts[EGDT_WINDOW_MINIMIZE] = L"Minimize"; + Texts[EGDT_WINDOW_MAXIMIZE] = L"Maximize"; + + Icons[EGDI_WINDOW_MAXIMIZE] = 225; + Icons[EGDI_WINDOW_RESTORE] = 226; + Icons[EGDI_WINDOW_CLOSE] = 227; + Icons[EGDI_WINDOW_MINIMIZE] = 228; + Icons[EGDI_CURSOR_UP] = 229; + Icons[EGDI_CURSOR_DOWN] = 230; + Icons[EGDI_CURSOR_LEFT] = 231; + Icons[EGDI_CURSOR_RIGHT] = 232; + Icons[EGDI_MENU_MORE] = 232; + Icons[EGDI_CHECK_BOX_CHECKED] = 233; + Icons[EGDI_DROP_DOWN] = 234; + Icons[EGDI_SMALL_CURSOR_UP] = 235; + Icons[EGDI_SMALL_CURSOR_DOWN] = 236; + Icons[EGDI_RADIO_BUTTON_CHECKED] = 237; + Icons[EGDI_MORE_LEFT] = 238; + Icons[EGDI_MORE_RIGHT] = 239; + Icons[EGDI_MORE_UP] = 240; + Icons[EGDI_MORE_DOWN] = 241; + Icons[EGDI_WINDOW_RESIZE] = 242; + Icons[EGDI_EXPAND] = 243; + Icons[EGDI_COLLAPSE] = 244; + + Icons[EGDI_FILE] = 245; + Icons[EGDI_DIRECTORY] = 246; + + for (u32 i=0; idrop(); + } + + if (SpriteBank) + SpriteBank->drop(); +} + + +//! returns default color +video::SColor CGUISkin::getColor(EGUI_DEFAULT_COLOR color) const +{ + if ((u32)color < EGDC_COUNT) + return Colors[color]; + else + return video::SColor(); +} + + +//! sets a default color +void CGUISkin::setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) +{ + if ((u32)which < EGDC_COUNT) + Colors[which] = newColor; +} + + +//! returns size for the given size type +s32 CGUISkin::getSize(EGUI_DEFAULT_SIZE size) const +{ + if ((u32)size < EGDS_COUNT) + return Sizes[size]; + else + return 0; +} + + +//! sets a default size +void CGUISkin::setSize(EGUI_DEFAULT_SIZE which, s32 size) +{ + if ((u32)which < EGDS_COUNT) + Sizes[which] = size; +} + + +//! returns the default font +IGUIFont* CGUISkin::getFont(EGUI_DEFAULT_FONT which) const +{ + if (((u32)which < EGDF_COUNT) && Fonts[which]) + return Fonts[which]; + else + return Fonts[EGDF_DEFAULT]; +} + + +//! sets a default font +void CGUISkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which) +{ + if ((u32)which >= EGDF_COUNT) + return; + + if (font) + { + font->grab(); + if (Fonts[which]) + Fonts[which]->drop(); + + Fonts[which] = font; + } +} + + +//! gets the sprite bank stored +IGUISpriteBank* CGUISkin::getSpriteBank() const +{ + return SpriteBank; +} + + +//! set a new sprite bank or remove one by passing 0 +void CGUISkin::setSpriteBank(IGUISpriteBank* bank) +{ + if (bank) + bank->grab(); + + if (SpriteBank) + SpriteBank->drop(); + + SpriteBank = bank; +} + + +//! Returns a default icon +u32 CGUISkin::getIcon(EGUI_DEFAULT_ICON icon) const +{ + if ((u32)icon < EGDI_COUNT) + return Icons[icon]; + else + return 0; +} + + +//! Sets a default icon +void CGUISkin::setIcon(EGUI_DEFAULT_ICON icon, u32 index) +{ + if ((u32)icon < EGDI_COUNT) + Icons[icon] = index; +} + + +//! Returns a default text. For example for Message box button captions: +//! "OK", "Cancel", "Yes", "No" and so on. +const wchar_t* CGUISkin::getDefaultText(EGUI_DEFAULT_TEXT text) const +{ + if ((u32)text < EGDT_COUNT) + return Texts[text].c_str(); + else + return Texts[0].c_str(); +} + + +//! Sets a default text. For example for Message box button captions: +//! "OK", "Cancel", "Yes", "No" and so on. +void CGUISkin::setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) +{ + if ((u32)which < EGDT_COUNT) + Texts[which] = newText; +} + + +//! draws a standard 3d button pane +/** Used for drawing for example buttons in normal state. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param rect: Defining area where to draw. +\param clip: Clip area. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. */ +void CGUISkin::draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + if ( Type == EGST_BURNING_SKIN ) + { + rect.UpperLeftCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.X += 1; + rect.LowerRightCorner.Y += 1; + draw3DSunkenPane(element, + getColor( EGDC_WINDOW ).getInterpolated( 0xFFFFFFFF, 0.9f ) + ,false, true, rect, clip); + return; + } + + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = c1.getInterpolated(getColor(EGDC_3D_DARK_SHADOW), 0.4f); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a pressed 3d button pane +/** Used for drawing for example buttons in pressed state. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param rect: Defining area where to draw. +\param clip: Clip area. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. */ +void CGUISkin::draw3DButtonPanePressed(IGUIElement* element, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.LowerRightCorner.X -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.UpperLeftCorner.Y += 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = c1.getInterpolated(getColor(EGDC_3D_DARK_SHADOW), 0.4f); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a sunken 3d pane +/** Used for drawing the background of edit, combo or check boxes. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param bgcolor: Background color. +\param flat: Specifies if the sunken pane should be flat or displayed as sunken +deep into the ground. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DSunkenPane(IGUIElement* element, video::SColor bgcolor, + bool flat, bool fillBackGround, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + if (fillBackGround) + Driver->draw2DRectangle(bgcolor, rect, clip); + + if (flat) + { + // draw flat sunken pane + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // top + + ++rect.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // left + + rect = r; + ++rect.UpperLeftCorner.Y; + rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // right + + rect = r; + ++rect.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + --rect.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // bottom + } + else + { + // draw deep sunken pane + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // top + ++rect.UpperLeftCorner.X; + ++rect.UpperLeftCorner.Y; + --rect.LowerRightCorner.X; + ++rect.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y+1; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); // left + ++rect.UpperLeftCorner.X; + ++rect.UpperLeftCorner.Y; + ++rect.LowerRightCorner.X; + --rect.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect = r; + rect.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + ++rect.UpperLeftCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // right + --rect.UpperLeftCorner.X; + ++rect.UpperLeftCorner.Y; + --rect.LowerRightCorner.X; + --rect.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_LIGHT), rect, clip); + + rect = r; + ++rect.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + --rect.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); // bottom + ++rect.UpperLeftCorner.X; + --rect.UpperLeftCorner.Y; + --rect.LowerRightCorner.X; + --rect.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_LIGHT), rect, clip); + } +} + + +//! draws a window background +// return where to draw title bar text. +core::rect CGUISkin::draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect& r, + const core::rect* clip, + core::rect* checkClientArea) +{ + if (!Driver) + { + if ( checkClientArea ) + { + *checkClientArea = r; + } + return r; + } + + core::rect rect = r; + + // top border + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + } + + // left border + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + } + + // right border dark outer line + rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + } + + // right border bright innner line + rect.UpperLeftCorner.X -= 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y += 1; + rect.LowerRightCorner.Y -= 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + } + + // bottom border dark outer line + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + } + + // bottom border bright inner line + rect.UpperLeftCorner.X += 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.Y -= 1; + if ( !checkClientArea ) + { + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + } + + // client area for background + rect = r; + rect.UpperLeftCorner.X +=1; + rect.UpperLeftCorner.Y +=1; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y -= 2; + if (checkClientArea) + { + *checkClientArea = rect; + } + + if ( !checkClientArea ) + { + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c1 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.9f ); + const video::SColor c2 = getColor(EGDC_WINDOW).getInterpolated ( 0xFFFFFFFF, 0.8f ); + + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } + else + { + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + const video::SColor c1 = getColor(EGDC_3D_FACE); + Driver->draw2DRectangle(rect, c1, c1, c1, c2, clip); + } + } + + // title bar + rect = r; + rect.UpperLeftCorner.X += 2; + rect.UpperLeftCorner.Y += 2; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + getSize(EGDS_WINDOW_BUTTON_WIDTH) + 2; + + if (drawTitleBar ) + { + if (checkClientArea) + { + (*checkClientArea).UpperLeftCorner.Y = rect.LowerRightCorner.Y; + } + else + { + // draw title bar + //if (!UseGradient) + // Driver->draw2DRectangle(titleBarColor, rect, clip); + //else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c = titleBarColor.getInterpolated( video::SColor(titleBarColor.getAlpha(),255,255,255), 0.8f); + Driver->draw2DRectangle(rect, titleBarColor, titleBarColor, c, c, clip); + } + else + { + const video::SColor c = titleBarColor.getInterpolated(video::SColor(titleBarColor.getAlpha(),0,0,0), 0.2f); + Driver->draw2DRectangle(rect, titleBarColor, c, titleBarColor, c, clip); + } + } + } + + return rect; +} + + +//! draws a standard 3d menu pane +/** Used for drawing for menus and context menus. +It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and +EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DMenuPane(IGUIElement* element, + const core::rect& r, const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + if ( Type == EGST_BURNING_SKIN ) + { + rect.UpperLeftCorner.Y -= 3; + draw3DButtonPaneStandard(element, rect, clip); + return; + } + + // in this skin, this is exactly what non pressed buttons look like, + // so we could simply call + // draw3DButtonPaneStandard(element, rect, clip); + // here. + // but if the skin is transparent, this doesn't look that nice. So + // We draw it a little bit better, with some more draw2DRectangle calls, + // but there aren't that much menus visible anyway. + + rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = rect.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), rect, clip); + + rect.UpperLeftCorner.X = r.LowerRightCorner.X - 1; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + rect.UpperLeftCorner.Y = r.UpperLeftCorner.Y; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X -= 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y += 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), rect, clip); + + rect.UpperLeftCorner.X += 1; + rect.LowerRightCorner.X -= 1; + rect.UpperLeftCorner.Y -= 1; + rect.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect = r; + rect.UpperLeftCorner.X +=1; + rect.UpperLeftCorner.Y +=1; + rect.LowerRightCorner.X -= 2; + rect.LowerRightCorner.Y -= 2; + + if (!UseGradient) + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a standard 3d tool bar +/** Used for drawing for toolbars and menus. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DToolBar(IGUIElement* element, + const core::rect& r, + const core::rect* clip) +{ + if (!Driver) + return; + + core::rect rect = r; + + rect.UpperLeftCorner.X = r.UpperLeftCorner.X; + rect.UpperLeftCorner.Y = r.LowerRightCorner.Y - 1; + rect.LowerRightCorner.Y = r.LowerRightCorner.Y; + rect.LowerRightCorner.X = r.LowerRightCorner.X; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), rect, clip); + + rect = r; + rect.LowerRightCorner.Y -= 1; + + if (!UseGradient) + { + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), rect, clip); + } + else + if ( Type == EGST_BURNING_SKIN ) + { + const video::SColor c1 = 0xF0000000 | getColor(EGDC_3D_FACE).color; + const video::SColor c2 = 0xF0000000 | getColor(EGDC_3D_SHADOW).color; + + rect.LowerRightCorner.Y += 1; + Driver->draw2DRectangle(rect, c1, c2, c1, c2, clip); + } + else + { + const video::SColor c1 = getColor(EGDC_3D_FACE); + const video::SColor c2 = getColor(EGDC_3D_SHADOW); + Driver->draw2DRectangle(rect, c1, c1, c2, c2, clip); + } +} + + +//! draws a tab button +/** Used for drawing for tab buttons on top of tabs. +\param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param active: Specifies if the tab is currently active. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DTabButton(IGUIElement* element, bool active, + const core::rect& frameRect, const core::rect* clip, EGUI_ALIGNMENT alignment) +{ + if (!Driver) + return; + + core::rect tr = frameRect; + + if ( alignment == EGUIA_UPPERLEFT ) + { + tr.LowerRightCorner.X -= 2; + tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1; + tr.UpperLeftCorner.X += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw left highlight + tr = frameRect; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + tr.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw grey background + tr = frameRect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y += 1; + tr.LowerRightCorner.X -= 2; + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip); + + // draw right middle gray shadow + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), tr, clip); + } + else + { + tr.LowerRightCorner.X -= 2; + tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1; + tr.UpperLeftCorner.X += 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw left highlight + tr = frameRect; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw grey background + tr = frameRect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y -= 1; + tr.LowerRightCorner.X -= 2; + tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip); + + // draw right middle gray shadow + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X = tr.LowerRightCorner.X - 1; + //tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + + tr.LowerRightCorner.X += 1; + tr.UpperLeftCorner.X += 1; + tr.LowerRightCorner.Y -= 1; + Driver->draw2DRectangle(getColor(EGDC_3D_DARK_SHADOW), tr, clip); + } +} + + +//! draws a tab control body +/** \param element: Pointer to the element which wishes to draw this. This parameter +is usually not used by ISkin, but can be used for example by more complex +implementations to find out how to draw the part exactly. +\param border: Specifies if the border should be drawn. +\param background: Specifies if the background should be drawn. +\param rect: Defining area where to draw. +\param clip: Clip area. */ +void CGUISkin::draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect& rect, const core::rect* clip, s32 tabHeight, EGUI_ALIGNMENT alignment) +{ + if (!Driver) + return; + + core::rect tr = rect; + + if ( tabHeight == -1 ) + tabHeight = getSize(gui::EGDS_BUTTON_HEIGHT); + + // draw border. + if (border) + { + if ( alignment == EGUIA_UPPERLEFT ) + { + // draw left hightlight + tr.UpperLeftCorner.Y += tabHeight + 2; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw right shadow + tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + + // draw lower shadow + tr = rect; + tr.UpperLeftCorner.Y = tr.LowerRightCorner.Y - 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + } + else + { + // draw left hightlight + tr.LowerRightCorner.Y -= tabHeight + 2; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + + // draw right shadow + tr.UpperLeftCorner.X = rect.LowerRightCorner.X - 1; + tr.LowerRightCorner.X = tr.UpperLeftCorner.X + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_SHADOW), tr, clip); + + // draw lower shadow + tr = rect; + tr.LowerRightCorner.Y = tr.UpperLeftCorner.Y + 1; + Driver->draw2DRectangle(getColor(EGDC_3D_HIGH_LIGHT), tr, clip); + } + } + + if (background) + { + if ( alignment == EGUIA_UPPERLEFT ) + { + tr = rect; + tr.UpperLeftCorner.Y += tabHeight + 2; + tr.LowerRightCorner.X -= 1; + tr.UpperLeftCorner.X += 1; + tr.LowerRightCorner.Y -= 1; + } + else + { + tr = rect; + tr.UpperLeftCorner.X += 1; + tr.UpperLeftCorner.Y -= 1; + tr.LowerRightCorner.X -= 1; + tr.LowerRightCorner.Y -= tabHeight + 2; + //tr.UpperLeftCorner.X += 1; + } + + if (!UseGradient) + Driver->draw2DRectangle(getColor(EGDC_3D_FACE), tr, clip); + else + { + video::SColor c1 = getColor(EGDC_3D_FACE); + video::SColor c2 = getColor(EGDC_3D_SHADOW); + Driver->draw2DRectangle(tr, c1, c1, c2, c2, clip); + } + } +} + + +//! draws an icon, usually from the skin's sprite bank +/** \param parent: Pointer to the element which wishes to draw this icon. +This parameter is usually not used by IGUISkin, but can be used for example +by more complex implementations to find out how to draw the part exactly. +\param icon: Specifies the icon to be drawn. +\param position: The position to draw the icon +\param starttime: The time at the start of the animation +\param currenttime: The present time, used to calculate the frame number +\param loop: Whether the animation should loop or not +\param clip: Clip area. */ +void CGUISkin::drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime, u32 currenttime, + bool loop, const core::rect* clip) +{ + if (!SpriteBank) + return; + + bool gray = element && !element->isEnabled(); + SpriteBank->draw2DSprite(Icons[icon], position, clip, + Colors[gray? EGDC_GRAY_WINDOW_SYMBOL : EGDC_WINDOW_SYMBOL], starttime, currenttime, loop, true); +} + + +EGUI_SKIN_TYPE CGUISkin::getType() const +{ + return Type; +} + + +//! draws a 2d rectangle. +void CGUISkin::draw2DRectangle(IGUIElement* element, + const video::SColor &color, const core::rect& pos, + const core::rect* clip) +{ + Driver->draw2DRectangle(color, pos, clip); +} + + +//! Writes attributes of the object. +//! Implement this to expose the attributes of your scene node animator for +//! scripting languages, editors, debuggers or xml serialization purposes. +void CGUISkin::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + u32 i; + for (i=0; iaddColor(GUISkinColorNames[i], Colors[i]); + + for (i=0; iaddInt(GUISkinSizeNames[i], Sizes[i]); + + for (i=0; iaddString(GUISkinTextNames[i], Texts[i].c_str()); + + for (i=0; iaddInt(GUISkinIconNames[i], Icons[i]); +} + + +//! Reads attributes of the object. +//! Implement this to set the attributes of your scene node animator for +//! scripting languages, editors, debuggers or xml deserialization purposes. +void CGUISkin::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + // TODO: This is not nice code for downward compatibility, whenever new values are added and users + // load an old skin the corresponding values will be set to 0. + u32 i; + for (i=0; igetAttributeAsColor(GUISkinColorNames[i]); + + for (i=0; igetAttributeAsInt(GUISkinSizeNames[i]); + + for (i=0; igetAttributeAsStringW(GUISkinTextNames[i]); + + for (i=0; igetAttributeAsInt(GUISkinIconNames[i]); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.d new file mode 100644 index 0000000..8ea1660 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.d @@ -0,0 +1 @@ +CGUISkin.o: CGUISkin.cpp CGUISkin.h ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.h new file mode 100644 index 0000000..903d856 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISkin.h @@ -0,0 +1,249 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_SKIN_H_INCLUDED__ +#define __C_GUI_SKIN_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + class IVideoDriver; +} +namespace gui +{ + + class CGUISkin : public IGUISkin + { + public: + + CGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver); + + //! destructor + virtual ~CGUISkin(); + + //! returns default color + virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const; + + //! sets a default color + virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor); + + //! returns size for the given size type + virtual s32 getSize(EGUI_DEFAULT_SIZE size) const; + + //! sets a default size + virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size); + + //! returns the default font + virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const; + + //! sets a default font + virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT); + + //! sets the sprite bank used for drawing icons + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! gets the sprite bank used for drawing icons + virtual IGUISpriteBank* getSpriteBank() const; + + //! Returns a default icon + /** Returns the sprite index within the sprite bank */ + virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const; + + //! Sets a default icon + /** Sets the sprite index used for drawing icons like arrows, + close buttons and ticks in checkboxes + \param icon: Enum specifying which icon to change + \param index: The sprite index used to draw this icon */ + virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index); + + //! Returns a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const; + + //! Sets a default text. + /** For example for Message box button captions: + "OK", "Cancel", "Yes", "No" and so on. */ + virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText); + + //! draws a standard 3d button pane + /** Used for drawing for example buttons in normal state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. */ + virtual void draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a pressed 3d button pane + /** Used for drawing for example buttons in pressed state. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. */ + virtual void draw3DButtonPanePressed(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a sunken 3d pane + /** Used for drawing the background of edit, combo or check boxes. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param bgcolor: Background color. + \param flat: Specifies if the sunken pane should be flat or displayed as sunken + deep into the ground. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DSunkenPane(IGUIElement* element, + video::SColor bgcolor, bool flat, + bool fillBackGround, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a window background + /** Used for drawing the background of dialogs and windows. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param titleBarColor: Title color. + \param drawTitleBar: True to enable title drawing. + \param rect: Defining area where to draw. + \param clip: Clip area. + \param checkClientArea: When set to non-null the function will not draw anything, + but will instead return the clientArea which can be used for drawing by the calling window. + That is the area without borders and without titlebar. + \return Returns rect where it would be good to draw title bar text. This will + work even when checkClientArea is set to a non-null value.*/ + virtual core::rect draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, video::SColor titleBarColor, + const core::rect& rect, + const core::rect* clip, + core::rect* checkClientArea); + + //! draws a standard 3d menu pane + /** Used for drawing for menus and context menus. + It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and + EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DMenuPane(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a standard 3d tool bar + /** Used for drawing for toolbars and menus. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DToolBar(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + + //! draws a tab button + /** Used for drawing for tab buttons on top of tabs. + \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param active: Specifies if the tab is currently active. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabButton(IGUIElement* element, bool active, + const core::rect& rect, const core::rect* clip=0, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT); + + //! draws a tab control body + /** \param element: Pointer to the element which wishes to draw this. This parameter + is usually not used by ISkin, but can be used for example by more complex + implementations to find out how to draw the part exactly. + \param border: Specifies if the border should be drawn. + \param background: Specifies if the background should be drawn. + \param rect: Defining area where to draw. + \param clip: Clip area. */ + virtual void draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect& rect, const core::rect* clip=0, s32 tabHeight=-1, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT); + + //! draws an icon, usually from the skin's sprite bank + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param icon: Specifies the icon to be drawn. + \param position: The position to draw the icon + \param starttime: The time at the start of the animation + \param currenttime: The present time, used to calculate the frame number + \param loop: Whether the animation should loop or not + \param clip: Clip area. */ + virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const core::position2di position, + u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect* clip=0); + + + //! draws a 2d rectangle. + /** \param element: Pointer to the element which wishes to draw this icon. + This parameter is usually not used by IGUISkin, but can be used for example + by more complex implementations to find out how to draw the part exactly. + \param color: Color of the rectangle to draw. The alpha component specifies how + transparent the rectangle will be. + \param pos: Position of the rectangle. + \param clip: Pointer to rectangle against which the rectangle will be clipped. + If the pointer is null, no clipping will be performed. */ + virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color, + const core::rect& pos, const core::rect* clip = 0); + + + //! get the type of this skin + virtual EGUI_SKIN_TYPE getType() const; + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + private: + + video::SColor Colors[EGDC_COUNT]; + s32 Sizes[EGDS_COUNT]; + u32 Icons[EGDI_COUNT]; + IGUIFont* Fonts[EGDF_COUNT]; + IGUISpriteBank* SpriteBank; + core::stringw Texts[EGDT_COUNT]; + video::IVideoDriver* Driver; + bool UseGradient; + + EGUI_SKIN_TYPE Type; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.cpp new file mode 100644 index 0000000..b440699 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.cpp @@ -0,0 +1,327 @@ +// Copyright (C) 2006-2012 Michael Zeilfelder +// This file uses the licence of the Irrlicht Engine. + +#include "CGUISpinBox.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIEditBox.h" +#include "CGUIButton.h" +#include "IGUIEnvironment.h" +#include "IEventReceiver.h" +#include "fast_atof.h" +#include + + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUISpinBox::CGUISpinBox(const wchar_t* text, bool border,IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle) +: IGUISpinBox(environment, parent, id, rectangle), + EditBox(0), ButtonSpinUp(0), ButtonSpinDown(0), StepSize(1.f), + RangeMin(-FLT_MAX), RangeMax(FLT_MAX), FormatString(L"%f"), + DecimalPlaces(-1) +{ + #ifdef _DEBUG + setDebugName("CGUISpinBox"); + #endif + + CurrentIconColor = video::SColor(255,255,255,255); + s32 ButtonWidth = 16; + + ButtonSpinDown = Environment->addButton( + core::rect(rectangle.getWidth() - ButtonWidth, rectangle.getHeight()/2 +1, + rectangle.getWidth(), rectangle.getHeight()), this); + ButtonSpinDown->grab(); + ButtonSpinDown->setSubElement(true); + ButtonSpinDown->setTabStop(false); + ButtonSpinDown->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_CENTER, EGUIA_LOWERRIGHT); + + ButtonSpinUp = Environment->addButton( + core::rect(rectangle.getWidth() - ButtonWidth, 0, + rectangle.getWidth(), rectangle.getHeight()/2), this); + ButtonSpinUp->grab(); + ButtonSpinUp->setSubElement(true); + ButtonSpinUp->setTabStop(false); + ButtonSpinUp->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_CENTER); + + const core::rect rectEdit(0, 0, rectangle.getWidth() - ButtonWidth - 1, rectangle.getHeight()); + EditBox = Environment->addEditBox(text, rectEdit, border, this, -1); + EditBox->grab(); + EditBox->setSubElement(true); + EditBox->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + + refreshSprites(); +} + + +//! destructor +CGUISpinBox::~CGUISpinBox() +{ + if (ButtonSpinUp) + ButtonSpinUp->drop(); + if (ButtonSpinDown) + ButtonSpinDown->drop(); + if (EditBox) + EditBox->drop(); +} + +void CGUISpinBox::refreshSprites() +{ + IGUISpriteBank *sb = 0; + if (Environment && Environment->getSkin()) + { + sb = Environment->getSkin()->getSpriteBank(); + } + + if (sb) + { + IGUISkin * skin = Environment->getSkin(); + CurrentIconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + ButtonSpinDown->setSpriteBank(sb); + ButtonSpinDown->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), CurrentIconColor); + ButtonSpinDown->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_DOWN), CurrentIconColor); + ButtonSpinUp->setSpriteBank(sb); + ButtonSpinUp->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_SMALL_CURSOR_UP), CurrentIconColor); + ButtonSpinUp->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_SMALL_CURSOR_UP), CurrentIconColor); + } + else + { + ButtonSpinDown->setText(L"-"); + ButtonSpinUp->setText(L"+"); + } +} + +IGUIEditBox* CGUISpinBox::getEditBox() const +{ + return EditBox; +} + + +void CGUISpinBox::setValue(f32 val) +{ + wchar_t str[100]; + + swprintf(str, 99, FormatString.c_str(), val); + EditBox->setText(str); + verifyValueRange(); +} + + +f32 CGUISpinBox::getValue() const +{ + const wchar_t* val = EditBox->getText(); + if ( !val ) + return 0.f; + core::stringc tmp(val); + return core::fast_atof(tmp.c_str()); +} + + +void CGUISpinBox::setRange(f32 min, f32 max) +{ + if (maxOnEvent(e); + return true; + } + } + + return IGUIElement::OnEvent(event); +} + + +void CGUISpinBox::draw() +{ + if ( !isVisible() ) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + video::SColor iconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + if ( iconColor != CurrentIconColor ) + { + refreshSprites(); + } + + IGUISpinBox::draw(); +} + +void CGUISpinBox::verifyValueRange() +{ + f32 val = getValue(); + if ( val+core::ROUNDING_ERROR_f32 < RangeMin ) + val = RangeMin; + else if ( val-core::ROUNDING_ERROR_f32 > RangeMax ) + val = RangeMax; + else + return; + + setValue(val); +} + + +//! Sets the new caption of the element +void CGUISpinBox::setText(const wchar_t* text) +{ + EditBox->setText(text); + setValue(getValue()); + verifyValueRange(); +} + + +//! Returns caption of this element. +const wchar_t* CGUISpinBox::getText() const +{ + return EditBox->getText(); +} + + +//! Writes attributes of the element. +void CGUISpinBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IGUIElement::serializeAttributes(out, options); + out->addFloat("Min", getMin()); + out->addFloat("Max", getMax()); + out->addFloat("Step", getStepSize()); + out->addInt("DecimalPlaces", DecimalPlaces); +} + + +//! Reads attributes of the element +void CGUISpinBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IGUIElement::deserializeAttributes(in, options); + setRange(in->getAttributeAsFloat("Min"), in->getAttributeAsFloat("Max")); + setStepSize(in->getAttributeAsFloat("Step")); + setDecimalPlaces(in->getAttributeAsInt("DecimalPlaces")); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.d new file mode 100644 index 0000000..1551c2a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.d @@ -0,0 +1,2 @@ +CGUISpinBox.o: CGUISpinBox.cpp CGUISpinBox.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.h new file mode 100644 index 0000000..e487c0b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpinBox.h @@ -0,0 +1,108 @@ +// Copyright (C) 2006-2012 Michael Zeilfelder +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_SPIN_BOX_H_INCLUDED__ +#define __C_GUI_SPIN_BOX_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISpinBox.h" + +namespace irr +{ +namespace gui +{ + class IGUIEditBox; + class IGUIButton; + + class CGUISpinBox : public IGUISpinBox + { + public: + + //! constructor + CGUISpinBox(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle); + + //! destructor + virtual ~CGUISpinBox(); + + //! Access the edit box used in the spin control + /** \param enable: If set to true, the override color, which can be set + with IGUIEditBox::setOverrideColor is used, otherwise the + EGDC_BUTTON_TEXT color of the skin. */ + virtual IGUIEditBox* getEditBox() const; + + //! set the current value of the spinbox + /** \param val: value to be set in the spinbox */ + virtual void setValue(f32 val); + + //! Get the current value of the spinbox + virtual f32 getValue() const; + + //! set the range of values which can be used in the spinbox + /** \param min: minimum value + \param max: maximum value */ + virtual void setRange(f32 min, f32 max); + + //! get the minimum value which can be used in the spinbox + virtual f32 getMin() const; + + //! get the maximum value which can be used in the spinbox + virtual f32 getMax() const; + + //! step size by which values are changed when pressing the spin buttons + /** \param step: stepsize used for value changes when pressing spin buttons */ + virtual void setStepSize(f32 step=1.f); + + //! returns the step size + virtual f32 getStepSize() const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! Draws the element and its children. + virtual void draw(); + + //! Sets the new caption of the element + virtual void setText(const wchar_t* text); + + //! Returns caption of this element. + virtual const wchar_t* getText() const; + + //! Sets the number of decimal places to display. + //! Note that this also rounds the range to the same number of decimal places. + /** \param places: The number of decimal places to display, use -1 to reset */ + virtual void setDecimalPlaces(s32 places); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + virtual void verifyValueRange(); + void refreshSprites(); + + IGUIEditBox * EditBox; + IGUIButton * ButtonSpinUp; + IGUIButton * ButtonSpinDown; + video::SColor CurrentIconColor; + f32 StepSize; + f32 RangeMin; + f32 RangeMax; + + core::stringw FormatString; + s32 DecimalPlaces; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_SPIN_BOX_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.cpp new file mode 100644 index 0000000..71d8cb4 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.cpp @@ -0,0 +1,250 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUISpriteBank.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "ITexture.h" + +namespace irr +{ +namespace gui +{ + +CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) : + Environment(env), Driver(0) +{ + #ifdef _DEBUG + setDebugName("CGUISpriteBank"); + #endif + + if (Environment) + { + Driver = Environment->getVideoDriver(); + if (Driver) + Driver->grab(); + } +} + + +CGUISpriteBank::~CGUISpriteBank() +{ + // drop textures + for (u32 i=0; idrop(); + + // drop video driver + if (Driver) + Driver->drop(); +} + + +core::array< core::rect >& CGUISpriteBank::getPositions() +{ + return Rectangles; +} + + +core::array< SGUISprite >& CGUISpriteBank::getSprites() +{ + return Sprites; +} + + +u32 CGUISpriteBank::getTextureCount() const +{ + return Textures.size(); +} + + +video::ITexture* CGUISpriteBank::getTexture(u32 index) const +{ + if (index < Textures.size()) + return Textures[index]; + else + return 0; +} + + +void CGUISpriteBank::addTexture(video::ITexture* texture) +{ + if (texture) + texture->grab(); + + Textures.push_back(texture); +} + + +void CGUISpriteBank::setTexture(u32 index, video::ITexture* texture) +{ + while (index >= Textures.size()) + Textures.push_back(0); + + if (texture) + texture->grab(); + + if (Textures[index]) + Textures[index]->drop(); + + Textures[index] = texture; +} + + +//! clear everything +void CGUISpriteBank::clear() +{ + // drop textures + for (u32 i=0; idrop(); + Textures.clear(); + Sprites.clear(); + Rectangles.clear(); +} + +//! Add the texture and use it for a single non-animated sprite. +s32 CGUISpriteBank::addTextureAsSprite(video::ITexture* texture) +{ + if ( !texture ) + return -1; + + addTexture(texture); + u32 textureIndex = getTextureCount() - 1; + + u32 rectangleIndex = Rectangles.size(); + Rectangles.push_back( core::rect(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) ); + + SGUISprite sprite; + sprite.frameTime = 0; + + SGUISpriteFrame frame; + frame.textureNumber = textureIndex; + frame.rectNumber = rectangleIndex; + sprite.Frames.push_back( frame ); + + Sprites.push_back( sprite ); + + return Sprites.size() - 1; +} + +//! draws a sprite in 2d with scale and color +void CGUISpriteBank::draw2DSprite(u32 index, const core::position2di& pos, + const core::rect* clip, const video::SColor& color, + u32 starttime, u32 currenttime, bool loop, bool center) +{ + if (index >= Sprites.size() || Sprites[index].Frames.empty() ) + return; + + // work out frame number + u32 frame = 0; + if (Sprites[index].frameTime) + { + u32 f = ((currenttime - starttime) / Sprites[index].frameTime); + if (loop) + frame = f % Sprites[index].Frames.size(); + else + frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f; + } + + const video::ITexture* tex = Textures[Sprites[index].Frames[frame].textureNumber]; + if (!tex) + return; + + const u32 rn = Sprites[index].Frames[frame].rectNumber; + if (rn >= Rectangles.size()) + return; + + const core::rect& r = Rectangles[rn]; + + if (center) + { + core::position2di p = pos; + p -= r.getSize() / 2; + Driver->draw2DImage(tex, p, r, clip, color, true); + } + else + { + Driver->draw2DImage(tex, pos, r, clip, color, true); + } +} + + +void CGUISpriteBank::draw2DSpriteBatch( const core::array& indices, + const core::array& pos, + const core::rect* clip, + const video::SColor& color, + u32 starttime, u32 currenttime, + bool loop, bool center) +{ + const irr::u32 drawCount = core::min_(indices.size(), pos.size()); + + if( Textures.empty() ) + return; + core::array drawBatches(Textures.size()); + for(u32 i = 0;i < Textures.size();i++) + { + drawBatches.push_back(SDrawBatch()); + drawBatches[i].positions.reallocate(drawCount); + drawBatches[i].sourceRects.reallocate(drawCount); + } + + for(u32 i = 0;i < drawCount;i++) + { + const u32 index = indices[i]; + + if (index >= Sprites.size() || Sprites[index].Frames.empty() ) + continue; + + // work out frame number + u32 frame = 0; + if (Sprites[index].frameTime) + { + u32 f = ((currenttime - starttime) / Sprites[index].frameTime); + if (loop) + frame = f % Sprites[index].Frames.size(); + else + frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f; + } + + const u32 texNum = Sprites[index].Frames[frame].textureNumber; + + SDrawBatch& currentBatch = drawBatches[texNum]; + + const u32 rn = Sprites[index].Frames[frame].rectNumber; + if (rn >= Rectangles.size()) + return; + + const core::rect& r = Rectangles[rn]; + + if (center) + { + core::position2di p = pos[i]; + p -= r.getSize() / 2; + + currentBatch.positions.push_back(p); + currentBatch.sourceRects.push_back(r); + } + else + { + currentBatch.positions.push_back(pos[i]); + currentBatch.sourceRects.push_back(r); + } + } + + for(u32 i = 0;i < drawBatches.size();i++) + { + if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty()) + Driver->draw2DImageBatch(Textures[i], drawBatches[i].positions, + drawBatches[i].sourceRects, clip, color, true); + } +} + +} // namespace gui +} // namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.d new file mode 100644 index 0000000..7ac073a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.d @@ -0,0 +1,2 @@ +CGUISpriteBank.o: CGUISpriteBank.cpp CGUISpriteBank.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.h new file mode 100644 index 0000000..77adb4d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUISpriteBank.h @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_SPRITE_BANK_H_INCLUDED__ +#define __C_GUI_SPRITE_BANK_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISpriteBank.h" + +namespace irr +{ + +namespace video +{ + class IVideoDriver; + class ITexture; +} + +namespace gui +{ + + class IGUIEnvironment; + +//! Sprite bank interface. +class CGUISpriteBank : public IGUISpriteBank +{ +public: + + CGUISpriteBank(IGUIEnvironment* env); + virtual ~CGUISpriteBank(); + + virtual core::array< core::rect >& getPositions(); + virtual core::array< SGUISprite >& getSprites(); + + virtual u32 getTextureCount() const; + virtual video::ITexture* getTexture(u32 index) const; + virtual void addTexture(video::ITexture* texture); + virtual void setTexture(u32 index, video::ITexture* texture); + + //! Add the texture and use it for a single non-animated sprite. + virtual s32 addTextureAsSprite(video::ITexture* texture); + + //! clears sprites, rectangles and textures + virtual void clear(); + + //! Draws a sprite in 2d with position and color + virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect* clip=0, + const video::SColor& color= video::SColor(255,255,255,255), + u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false); + + //! Draws a sprite batch in 2d using an array of positions and a color + virtual void draw2DSpriteBatch(const core::array& indices, const core::array& pos, + const core::rect* clip=0, + const video::SColor& color= video::SColor(255,255,255,255), + u32 starttime=0, u32 currenttime=0, + bool loop=true, bool center=false); + +protected: + + struct SDrawBatch + { + core::array positions; + core::array sourceRects; + u32 textureNumber; + }; + + core::array Sprites; + core::array< core::rect > Rectangles; + core::array Textures; + IGUIEnvironment* Environment; + video::IVideoDriver* Driver; + +}; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif // __C_GUI_SPRITE_BANK_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp new file mode 100644 index 0000000..ea934d3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp @@ -0,0 +1,630 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIStaticText.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIStaticText::CGUIStaticText(const wchar_t* text, bool border, + IGUIEnvironment* environment, IGUIElement* parent, + s32 id, const core::rect& rectangle, + bool background) +: IGUIStaticText(environment, parent, id, rectangle), + HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_UPPERLEFT), + Border(border), OverrideColorEnabled(false), OverrideBGColorEnabled(false), WordWrap(false), Background(background), + RestrainTextInside(true), RightToLeft(false), + OverrideColor(video::SColor(101,255,255,255)), BGColor(video::SColor(101,210,210,210)), + OverrideFont(0), LastBreakFont(0) +{ + #ifdef _DEBUG + setDebugName("CGUIStaticText"); + #endif + + Text = text; + if (environment && environment->getSkin()) + { + BGColor = environment->getSkin()->getColor(gui::EGDC_3D_FACE); + } +} + + +//! destructor +CGUIStaticText::~CGUIStaticText() +{ + if (OverrideFont) + OverrideFont->drop(); +} + + +//! draws the element and its children +void CGUIStaticText::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + + core::rect frameRect(AbsoluteRect); + + // draw background + + if (Background) + { + if ( !OverrideBGColorEnabled ) // skin-colors can change + BGColor = skin->getColor(gui::EGDC_3D_FACE); + + driver->draw2DRectangle(BGColor, frameRect, &AbsoluteClippingRect); + } + + // draw the border + + if (Border) + { + skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect); + frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X); + } + + // draw the text + if (Text.size()) + { + IGUIFont* font = getActiveFont(); + + if (font) + { + if (!WordWrap) + { + if (VAlign == EGUIA_LOWERRIGHT) + { + frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - + font->getDimension(L"A").Height - font->getKerningHeight(); + } + if (HAlign == EGUIA_LOWERRIGHT) + { + frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - + font->getDimension(Text.c_str()).Width; + } + + font->draw(Text.c_str(), frameRect, + OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), + HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, (RestrainTextInside ? &AbsoluteClippingRect : NULL)); + } + else + { + if (font != LastBreakFont) + breakText(); + + core::rect r = frameRect; + s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); + s32 totalHeight = height * BrokenText.size(); + if (VAlign == EGUIA_CENTER) + { + r.UpperLeftCorner.Y = r.getCenter().Y - (totalHeight / 2); + } + else if (VAlign == EGUIA_LOWERRIGHT) + { + r.UpperLeftCorner.Y = r.LowerRightCorner.Y - totalHeight; + } + + for (u32 i=0; igetDimension(BrokenText[i].c_str()).Width; + } + + font->draw(BrokenText[i].c_str(), r, + OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), + HAlign == EGUIA_CENTER, false, (RestrainTextInside ? &AbsoluteClippingRect : NULL)); + + r.LowerRightCorner.Y += height; + r.UpperLeftCorner.Y += height; + } + } + } + } + + IGUIElement::draw(); +} + + +//! Sets another skin independent font. +void CGUIStaticText::setOverrideFont(IGUIFont* font) +{ + if (OverrideFont == font) + return; + + if (OverrideFont) + OverrideFont->drop(); + + OverrideFont = font; + + if (OverrideFont) + OverrideFont->grab(); + + breakText(); +} + +//! Gets the override font (if any) +IGUIFont * CGUIStaticText::getOverrideFont() const +{ + return OverrideFont; +} + +//! Get the font which is used right now for drawing +IGUIFont* CGUIStaticText::getActiveFont() const +{ + if ( OverrideFont ) + return OverrideFont; + IGUISkin* skin = Environment->getSkin(); + if (skin) + return skin->getFont(); + return 0; +} + +//! Sets another color for the text. +void CGUIStaticText::setOverrideColor(video::SColor color) +{ + OverrideColor = color; + OverrideColorEnabled = true; +} + + +//! Sets another color for the text. +void CGUIStaticText::setBackgroundColor(video::SColor color) +{ + BGColor = color; + OverrideBGColorEnabled = true; + Background = true; +} + + +//! Sets whether to draw the background +void CGUIStaticText::setDrawBackground(bool draw) +{ + Background = draw; +} + + +//! Gets the background color +video::SColor CGUIStaticText::getBackgroundColor() const +{ + return BGColor; +} + + +//! Checks if background drawing is enabled +bool CGUIStaticText::isDrawBackgroundEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Background; +} + + +//! Sets whether to draw the border +void CGUIStaticText::setDrawBorder(bool draw) +{ + Border = draw; +} + + +//! Checks if border drawing is enabled +bool CGUIStaticText::isDrawBorderEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Border; +} + + +void CGUIStaticText::setTextRestrainedInside(bool restrainTextInside) +{ + RestrainTextInside = restrainTextInside; +} + + +bool CGUIStaticText::isTextRestrainedInside() const +{ + return RestrainTextInside; +} + + +void CGUIStaticText::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical) +{ + HAlign = horizontal; + VAlign = vertical; +} + + +video::SColor CGUIStaticText::getOverrideColor() const +{ + return OverrideColor; +} + + +//! Sets if the static text should use the overide color or the +//! color in the gui skin. +void CGUIStaticText::enableOverrideColor(bool enable) +{ + OverrideColorEnabled = enable; +} + + +bool CGUIStaticText::isOverrideColorEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return OverrideColorEnabled; +} + + +//! Enables or disables word wrap for using the static text as +//! multiline text control. +void CGUIStaticText::setWordWrap(bool enable) +{ + WordWrap = enable; + breakText(); +} + + +bool CGUIStaticText::isWordWrapEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return WordWrap; +} + + +void CGUIStaticText::setRightToLeft(bool rtl) +{ + if (RightToLeft != rtl) + { + RightToLeft = rtl; + breakText(); + } +} + + +bool CGUIStaticText::isRightToLeft() const +{ + return RightToLeft; +} + + +//! Breaks the single text line. +void CGUIStaticText::breakText() +{ + if (!WordWrap) + return; + + BrokenText.clear(); + + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = getActiveFont(); + if (!font) + return; + + LastBreakFont = font; + + core::stringw line; + core::stringw word; + core::stringw whitespace; + s32 size = Text.size(); + s32 length = 0; + s32 elWidth = RelativeRect.getWidth(); + if (Border) + elWidth -= 2*skin->getSize(EGDS_TEXT_DISTANCE_X); + wchar_t c; + + // We have to deal with right-to-left and left-to-right differently + // However, most parts of the following code is the same, it's just + // some order and boundaries which change. + if (!RightToLeft) + { + // regular (left-to-right) + for (s32 i=0; igetDimension(whitespace.c_str()).Width; + const s32 wordlgth = font->getDimension(word.c_str()).Width; + + if (wordlgth > elWidth) + { + // This word is too long to fit in the available space, look for + // the Unicode Soft HYphen (SHY / 00AD) character for a place to + // break the word at + int where = word.findFirst( wchar_t(0x00AD) ); + if (where != -1) + { + core::stringw first = word.subString(0, where); + core::stringw second = word.subString(where, word.size() - where); + BrokenText.push_back(line + first + L"-"); + const s32 secondLength = font->getDimension(second.c_str()).Width; + + length = secondLength; + line = second; + } + else + { + // No soft hyphen found, so there's nothing more we can do + // break to next line + if (length) + BrokenText.push_back(line); + length = wordlgth; + line = word; + } + } + else if (length && (length + wordlgth + whitelgth > elWidth)) + { + // break to next line + BrokenText.push_back(line); + length = wordlgth; + line = word; + } + else + { + // add word to line + line += whitespace; + line += word; + length += whitelgth + wordlgth; + } + + word = L""; + whitespace = L""; + } + + if ( isWhitespace ) + { + whitespace += c; + } + + // compute line break + if (lineBreak) + { + line += whitespace; + line += word; + BrokenText.push_back(line); + line = L""; + word = L""; + whitespace = L""; + length = 0; + } + } + } + + line += whitespace; + line += word; + BrokenText.push_back(line); + } + else + { + // right-to-left + for (s32 i=size; i>=0; --i) + { + c = Text[i]; + bool lineBreak = false; + + if (c == L'\r') // Mac or Windows breaks + { + lineBreak = true; + if ((i>0) && Text[i-1] == L'\n') // Windows breaks + { + Text.erase(i-1); + --size; + } + c = '\0'; + } + else if (c == L'\n') // Unix breaks + { + lineBreak = true; + c = '\0'; + } + + if (c==L' ' || c==0 || i==0) + { + if (word.size()) + { + // here comes the next whitespace, look if + // we must break the last word to the next line. + const s32 whitelgth = font->getDimension(whitespace.c_str()).Width; + const s32 wordlgth = font->getDimension(word.c_str()).Width; + + if (length && (length + wordlgth + whitelgth > elWidth)) + { + // break to next line + BrokenText.push_back(line); + length = wordlgth; + line = word; + } + else + { + // add word to line + line = whitespace + line; + line = word + line; + length += whitelgth + wordlgth; + } + + word = L""; + whitespace = L""; + } + + if (c != 0) + whitespace = core::stringw(&c, 1) + whitespace; + + // compute line break + if (lineBreak) + { + line = whitespace + line; + line = word + line; + BrokenText.push_back(line); + line = L""; + word = L""; + whitespace = L""; + length = 0; + } + } + else + { + // yippee this is a word.. + word = core::stringw(&c, 1) + word; + } + } + + line = whitespace + line; + line = word + line; + BrokenText.push_back(line); + } +} + + +//! Sets the new caption of this element. +void CGUIStaticText::setText(const wchar_t* text) +{ + IGUIElement::setText(text); + breakText(); +} + + +void CGUIStaticText::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + breakText(); +} + + +//! Returns the height of the text in pixels when it is drawn. +s32 CGUIStaticText::getTextHeight() const +{ + IGUIFont* font = getActiveFont(); + if (!font) + return 0; + + s32 height = font->getDimension(L"A").Height + font->getKerningHeight(); + + if (WordWrap) + height *= BrokenText.size(); + + return height; +} + + +s32 CGUIStaticText::getTextWidth() const +{ + IGUIFont * font = getActiveFont(); + if(!font) + return 0; + + if(WordWrap) + { + s32 widest = 0; + + for(u32 line = 0; line < BrokenText.size(); ++line) + { + s32 width = font->getDimension(BrokenText[line].c_str()).Width; + + if(width > widest) + widest = width; + } + + return widest; + } + else + { + return font->getDimension(Text.c_str()).Width; + } +} + + +//! Writes attributes of the element. +//! Implement this to expose the attributes of your element for +//! scripting languages, editors, debuggers or xml serialization purposes. +void CGUIStaticText::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIStaticText::serializeAttributes(out,options); + + out->addBool ("Border", Border); + out->addBool ("OverrideColorEnabled",OverrideColorEnabled); + out->addBool ("OverrideBGColorEnabled",OverrideBGColorEnabled); + out->addBool ("WordWrap", WordWrap); + out->addBool ("Background", Background); + out->addBool ("RightToLeft", RightToLeft); + out->addBool ("RestrainTextInside", RestrainTextInside); + out->addColor ("OverrideColor", OverrideColor); + out->addColor ("BGColor", BGColor); + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + + // out->addFont ("OverrideFont", OverrideFont); +} + + +//! Reads attributes of the element +void CGUIStaticText::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUIStaticText::deserializeAttributes(in,options); + + Border = in->getAttributeAsBool("Border"); + enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled")); + OverrideBGColorEnabled = in->getAttributeAsBool("OverrideBGColorEnabled"); + setWordWrap(in->getAttributeAsBool("WordWrap")); + Background = in->getAttributeAsBool("Background"); + RightToLeft = in->getAttributeAsBool("RightToLeft"); + RestrainTextInside = in->getAttributeAsBool("RestrainTextInside"); + OverrideColor = in->getAttributeAsColor("OverrideColor"); + BGColor = in->getAttributeAsColor("BGColor"); + + setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames), + (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames)); + + // OverrideFont = in->getAttributeAsFont("OverrideFont"); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.d new file mode 100644 index 0000000..63f9e79 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.d @@ -0,0 +1,2 @@ +CGUIStaticText.o: CGUIStaticText.cpp CGUIStaticText.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.h new file mode 100644 index 0000000..33daa98 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.h @@ -0,0 +1,145 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_STATIC_TEXT_H_INCLUDED__ +#define __C_GUI_STATIC_TEXT_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIStaticText.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class CGUIStaticText : public IGUIStaticText + { + public: + + //! constructor + CGUIStaticText(const wchar_t* text, bool border, IGUIEnvironment* environment, + IGUIElement* parent, s32 id, const core::rect& rectangle, + bool background = false); + + //! destructor + virtual ~CGUIStaticText(); + + //! draws the element and its children + virtual void draw(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont* font=0); + + //! Gets the override font (if any) + virtual IGUIFont* getOverrideFont() const; + + //! Get the font which is used right now for drawing + virtual IGUIFont* getActiveFont() const; + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Sets another color for the background. + virtual void setBackgroundColor(video::SColor color); + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + //! Gets the background color + virtual video::SColor getBackgroundColor() const; + + //! Checks if background drawing is enabled + virtual bool isDrawBackgroundEnabled() const; + + //! Sets whether to draw the border + virtual void setDrawBorder(bool draw); + + //! Checks if border drawing is enabled + virtual bool isDrawBorderEnabled() const; + + //! Sets alignment mode for text + virtual void setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical); + + //! Gets the override color + virtual video::SColor getOverrideColor() const; + + //! Sets if the static text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Checks if an override color is enabled + virtual bool isOverrideColorEnabled() const; + + //! Set whether the text in this label should be clipped if it goes outside bounds + virtual void setTextRestrainedInside(bool restrainedInside); + + //! Checks if the text in this label should be clipped if it goes outside bounds + virtual bool isTextRestrainedInside() const; + + //! Enables or disables word wrap for using the static text as + //! multiline text control. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + virtual bool isWordWrapEnabled() const; + + //! Sets the new caption of this element. + virtual void setText(const wchar_t* text); + + //! Returns the height of the text in pixels when it is drawn. + virtual s32 getTextHeight() const; + + //! Returns the width of the current text, in the current font + virtual s32 getTextWidth() const; + + //! Updates the absolute position, splits text if word wrap is enabled + virtual void updateAbsolutePosition(); + + //! Set whether the string should be interpreted as right-to-left (RTL) text + /** \note This component does not implement the Unicode bidi standard, the + text of the component should be already RTL if you call this. The + main difference when RTL is enabled is that the linebreaks for multiline + elements are performed starting from the end. + */ + virtual void setRightToLeft(bool rtl); + + //! Checks if the text should be interpreted as right-to-left text + virtual bool isRightToLeft() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + //! Breaks the single text line. + void breakText(); + + EGUI_ALIGNMENT HAlign, VAlign; + bool Border; + bool OverrideColorEnabled; + bool OverrideBGColorEnabled; + bool WordWrap; + bool Background; + bool RestrainTextInside; + bool RightToLeft; + + video::SColor OverrideColor, BGColor; + gui::IGUIFont* OverrideFont; + gui::IGUIFont* LastBreakFont; // stored because: if skin changes, line break must be recalculated. + + core::array< core::stringw > BrokenText; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.cpp new file mode 100644 index 0000000..a931d92 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.cpp @@ -0,0 +1,1042 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUITabControl.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "CGUIButton.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" +#include "IVideoDriver.h" +#include "rect.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +// ------------------------------------------------------------------ +// Tab +// ------------------------------------------------------------------ + +//! constructor +CGUITab::CGUITab(s32 number, IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + s32 id) + : IGUITab(environment, parent, id, rectangle), Number(number), + BackColor(0,0,0,0), OverrideTextColorEnabled(false), TextColor(255,0,0,0), + DrawBackground(false) +{ + #ifdef _DEBUG + setDebugName("CGUITab"); + #endif + + const IGUISkin* const skin = environment->getSkin(); + if (skin) + TextColor = skin->getColor(EGDC_BUTTON_TEXT); +} + + +//! Returns number of tab in tabcontrol. Can be accessed +//! later IGUITabControl::getTab() by this number. +s32 CGUITab::getNumber() const +{ + return Number; +} + + +//! Sets the number +void CGUITab::setNumber(s32 n) +{ + Number = n; +} + +void CGUITab::refreshSkinColors() +{ + if ( !OverrideTextColorEnabled ) + { + TextColor = Environment->getSkin()->getColor(EGDC_BUTTON_TEXT); + } +} + +//! draws the element and its children +void CGUITab::draw() +{ + if (!IsVisible) + return; + + IGUISkin *skin = Environment->getSkin(); + + if (skin && DrawBackground) + skin->draw2DRectangle(this, BackColor, AbsoluteRect, &AbsoluteClippingRect); + + IGUIElement::draw(); +} + + +//! sets if the tab should draw its background +void CGUITab::setDrawBackground(bool draw) +{ + DrawBackground = draw; +} + + +//! sets the color of the background, if it should be drawn. +void CGUITab::setBackgroundColor(video::SColor c) +{ + BackColor = c; +} + + +//! sets the color of the text +void CGUITab::setTextColor(video::SColor c) +{ + OverrideTextColorEnabled = true; + TextColor = c; +} + + +video::SColor CGUITab::getTextColor() const +{ + return TextColor; +} + + +//! returns true if the tab is drawing its background, false if not +bool CGUITab::isDrawingBackground() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return DrawBackground; +} + + +//! returns the color of the background +video::SColor CGUITab::getBackgroundColor() const +{ + return BackColor; +} + + +//! Writes attributes of the element. +void CGUITab::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUITab::serializeAttributes(out,options); + + out->addInt ("TabNumber", Number); + out->addBool ("DrawBackground", DrawBackground); + out->addColor ("BackColor", BackColor); + out->addBool ("OverrideTextColorEnabled", OverrideTextColorEnabled); + out->addColor ("TextColor", TextColor); + +} + + +//! Reads attributes of the element +void CGUITab::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + IGUITab::deserializeAttributes(in,options); + + setNumber(in->getAttributeAsInt("TabNumber")); + setDrawBackground(in->getAttributeAsBool("DrawBackground")); + setBackgroundColor(in->getAttributeAsColor("BackColor")); + bool override = in->getAttributeAsBool("OverrideTextColorEnabled"); + setTextColor(in->getAttributeAsColor("TextColor")); + if ( !override ) + { + OverrideTextColorEnabled = false; + } + + if (Parent && Parent->getType() == EGUIET_TAB_CONTROL) + { + ((CGUITabControl*)Parent)->addTab(this); + if (isVisible()) + ((CGUITabControl*)Parent)->setActiveTab(this); + } +} + + +// ------------------------------------------------------------------ +// Tabcontrol +// ------------------------------------------------------------------ + +//! constructor +CGUITabControl::CGUITabControl(IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + bool fillbackground, bool border, s32 id) + : IGUITabControl(environment, parent, id, rectangle), ActiveTab(-1), + Border(border), FillBackground(fillbackground), ScrollControl(false), TabHeight(0), VerticalAlignment(EGUIA_UPPERLEFT), + UpButton(0), DownButton(0), TabMaxWidth(0), CurrentScrollTabIndex(0), TabExtraWidth(20) +{ + #ifdef _DEBUG + setDebugName("CGUITabControl"); + #endif + + IGUISkin* skin = Environment->getSkin(); + IGUISpriteBank* sprites = 0; + + TabHeight = 32; + + if (skin) + { + sprites = skin->getSpriteBank(); + TabHeight = skin->getSize(gui::EGDS_BUTTON_HEIGHT) + 2; + } + + UpButton = Environment->addButton(core::rect(0,0,10,10), this); + + if (UpButton) + { + UpButton->setSpriteBank(sprites); + UpButton->setVisible(false); + UpButton->setSubElement(true); + UpButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + UpButton->setOverrideFont(Environment->getBuiltInFont()); + UpButton->grab(); + } + + DownButton = Environment->addButton(core::rect(0,0,10,10), this); + + if (DownButton) + { + DownButton->setSpriteBank(sprites); + DownButton->setVisible(false); + DownButton->setSubElement(true); + DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + DownButton->setOverrideFont(Environment->getBuiltInFont()); + DownButton->grab(); + } + + setTabVerticalAlignment(EGUIA_UPPERLEFT); + refreshSprites(); +} + +//! destructor +CGUITabControl::~CGUITabControl() +{ + for (u32 i=0; idrop(); + } + + if (UpButton) + UpButton->drop(); + + if (DownButton) + DownButton->drop(); +} + +void CGUITabControl::refreshSprites() +{ + video::SColor color(255,255,255,255); + IGUISkin* skin = Environment->getSkin(); + if (skin) + { + color = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + } + + if (UpButton) + { + UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_LEFT), color); + UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), color); + } + + if (DownButton) + { + DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_RIGHT), color); + DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), color); + } +} + +//! Adds a tab +IGUITab* CGUITabControl::addTab(const wchar_t* caption, s32 id) +{ + CGUITab* tab = new CGUITab(Tabs.size(), Environment, this, calcTabPos(), id); + + tab->setText(caption); + tab->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + tab->setVisible(false); + Tabs.push_back(tab); + + if (ActiveTab == -1) + { + ActiveTab = 0; + tab->setVisible(true); + } + + recalculateScrollBar(); + + return tab; +} + + +//! adds a tab which has been created elsewhere +void CGUITabControl::addTab(CGUITab* tab) +{ + if (!tab) + return; + + // check if its already added + for (u32 i=0; i < Tabs.size(); ++i) + { + if (Tabs[i] == tab) + return; + } + + tab->grab(); + + if (tab->getNumber() == -1) + tab->setNumber((s32)Tabs.size()); + + while (tab->getNumber() >= (s32)Tabs.size()) + Tabs.push_back(0); + + if (Tabs[tab->getNumber()]) + { + Tabs.push_back(Tabs[tab->getNumber()]); + Tabs[Tabs.size()-1]->setNumber(Tabs.size()); + } + Tabs[tab->getNumber()] = tab; + + if (ActiveTab == -1) + ActiveTab = tab->getNumber(); + + + if (tab->getNumber() == ActiveTab) + { + setActiveTab(ActiveTab); + } +} + +//! Insert the tab at the given index +IGUITab* CGUITabControl::insertTab(s32 idx, const wchar_t* caption, s32 id) +{ + if ( idx < 0 || idx > (s32)Tabs.size() ) // idx == Tabs.size() is indeed ok here as core::array can handle that + return NULL; + + CGUITab* tab = new CGUITab(idx, Environment, this, calcTabPos(), id); + + tab->setText(caption); + tab->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + tab->setVisible(false); + Tabs.insert(tab, (u32)idx); + + if (ActiveTab == -1) + { + ActiveTab = 0; + tab->setVisible(true); + } + + for ( u32 i=(u32)idx+1; i < Tabs.size(); ++i ) + { + Tabs[i]->setNumber(i); + } + + recalculateScrollBar(); + + return tab; +} + +//! Removes a tab from the tabcontrol +void CGUITabControl::removeTab(s32 idx) +{ + if ( idx < 0 || idx >= (s32)Tabs.size() ) + return; + + Tabs[(u32)idx]->drop(); + Tabs.erase((u32)idx); + for ( u32 i=(u32)idx; i < Tabs.size(); ++i ) + { + Tabs[i]->setNumber(i); + } +} + +//! Clears the tabcontrol removing all tabs +void CGUITabControl::clear() +{ + for (u32 i=0; idrop(); + } + Tabs.clear(); +} + +//! Returns amount of tabs in the tabcontrol +s32 CGUITabControl::getTabCount() const +{ + return Tabs.size(); +} + + +//! Returns a tab based on zero based index +IGUITab* CGUITabControl::getTab(s32 idx) const +{ + if ((u32)idx >= Tabs.size()) + return 0; + + return Tabs[idx]; +} + + +//! called if an event happened. +bool CGUITabControl::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case EGET_BUTTON_CLICKED: + if (event.GUIEvent.Caller == UpButton) + { + scrollLeft(); + return true; + } + else if (event.GUIEvent.Caller == DownButton) + { + scrollRight(); + return true; + } + + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + // todo: dragging tabs around + return true; + case EMIE_LMOUSE_LEFT_UP: + { + s32 idx = getTabAt(event.MouseInput.X, event.MouseInput.Y); + if ( idx >= 0 ) + { + setActiveTab(idx); + return true; + } + break; + } + default: + break; + } + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +void CGUITabControl::scrollLeft() +{ + if ( CurrentScrollTabIndex > 0 ) + --CurrentScrollTabIndex; + recalculateScrollBar(); +} + + +void CGUITabControl::scrollRight() +{ + if ( CurrentScrollTabIndex < (s32)(Tabs.size()) - 1 ) + { + if ( needScrollControl(CurrentScrollTabIndex, true) ) + ++CurrentScrollTabIndex; + } + recalculateScrollBar(); +} + +s32 CGUITabControl::calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl) const +{ + if ( !font ) + return 0; + + s32 len = font->getDimension(text).Width + TabExtraWidth; + if ( TabMaxWidth > 0 && len > TabMaxWidth ) + len = TabMaxWidth; + + // check if we miss the place to draw the tab-button + if ( withScrollControl && ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 ) + { + s32 tabMinWidth = font->getDimension(L"A").Width; + if ( TabExtraWidth > 0 && TabExtraWidth > tabMinWidth ) + tabMinWidth = TabExtraWidth; + + if ( ScrollControl && pos+tabMinWidth <= UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 ) + { + len = UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 - pos; + } + } + return len; +} + +bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl) +{ + if ( startIndex >= (s32)Tabs.size() ) + startIndex -= 1; + + if ( startIndex < 0 ) + startIndex = 0; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return false; + + IGUIFont* font = skin->getFont(); + + core::rect frameRect(AbsoluteRect); + + if (Tabs.empty()) + return false; + + if (!font) + return false; + + s32 pos = frameRect.UpperLeftCorner.X + 2; + + for (s32 i=startIndex; i<(s32)Tabs.size(); ++i) + { + // get Text + const wchar_t* text = 0; + if (Tabs[i]) + text = Tabs[i]->getText(); + + // get text length + s32 len = calcTabWidth(pos, font, text, false); // always without withScrollControl here or len would be shortened + + frameRect.LowerRightCorner.X += len; + + frameRect.UpperLeftCorner.X = pos; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; + pos += len; + + if ( withScrollControl && pos > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2) + return true; + + if ( !withScrollControl && pos > AbsoluteRect.LowerRightCorner.X ) + return true; + } + + return false; +} + + +core::rect CGUITabControl::calcTabPos() +{ + core::rect r; + r.UpperLeftCorner.X = 0; + r.LowerRightCorner.X = AbsoluteRect.getWidth(); + if ( Border ) + { + ++r.UpperLeftCorner.X; + --r.LowerRightCorner.X; + } + + if ( VerticalAlignment == EGUIA_UPPERLEFT ) + { + r.UpperLeftCorner.Y = TabHeight+2; + r.LowerRightCorner.Y = AbsoluteRect.getHeight()-1; + if ( Border ) + { + --r.LowerRightCorner.Y; + } + } + else + { + r.UpperLeftCorner.Y = 0; + r.LowerRightCorner.Y = AbsoluteRect.getHeight()-(TabHeight+2); + if ( Border ) + { + ++r.UpperLeftCorner.Y; + } + } + + return r; +} + + +//! draws the element and its children +void CGUITabControl::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + IGUIFont* font = skin->getFont(); + video::IVideoDriver* driver = Environment->getVideoDriver(); + + core::rect frameRect(AbsoluteRect); + + if (Tabs.empty()) + driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), frameRect, &AbsoluteClippingRect); + + if (!font) + return; + + if ( VerticalAlignment == EGUIA_UPPERLEFT ) + { + frameRect.UpperLeftCorner.Y += 2; + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + TabHeight; + } + else + { + frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - TabHeight - 1; + frameRect.LowerRightCorner.Y -= 2; + } + + core::rect tr; + s32 pos = frameRect.UpperLeftCorner.X + 2; + + bool needLeftScroll = CurrentScrollTabIndex > 0; + bool needRightScroll = false; + + // left and right pos of the active tab + s32 left = 0; + s32 right = 0; + + //const wchar_t* activetext = 0; + CGUITab *activeTab = 0; + + for (u32 i=CurrentScrollTabIndex; igetText(); + + // get text length + s32 len = calcTabWidth(pos, font, text, true); + if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 ) + { + needRightScroll = true; + break; + } + + frameRect.LowerRightCorner.X += len; + frameRect.UpperLeftCorner.X = pos; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; + + pos += len; + + if ( text ) + Tabs[i]->refreshSkinColors(); + + if ((s32)i == ActiveTab) + { + left = frameRect.UpperLeftCorner.X; + right = frameRect.LowerRightCorner.X; + //activetext = text; + activeTab = Tabs[i]; + } + else + { + skin->draw3DTabButton(this, false, frameRect, &AbsoluteClippingRect, VerticalAlignment); + + // draw text + core::rect textClipRect(frameRect); // TODO: exact size depends on borders in draw3DTabButton which we don't get with current interface + textClipRect.clipAgainst(AbsoluteClippingRect); + font->draw(text, frameRect, Tabs[i]->getTextColor(), + true, true, &textClipRect); + } + } + + // draw active tab + if (left != 0 && right != 0 && activeTab != 0) + { + // draw upper highlight frame + if ( VerticalAlignment == EGUIA_UPPERLEFT ) + { + frameRect.UpperLeftCorner.X = left-2; + frameRect.LowerRightCorner.X = right+2; + frameRect.UpperLeftCorner.Y -= 2; + + skin->draw3DTabButton(this, true, frameRect, &AbsoluteClippingRect, VerticalAlignment); + + // draw text + core::rect textClipRect(frameRect); // TODO: exact size depends on borders in draw3DTabButton which we don't get with current interface + textClipRect.clipAgainst(AbsoluteClippingRect); + font->draw(activeTab->getText(), frameRect, activeTab->getTextColor(), + true, true, &textClipRect); + + tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; + tr.LowerRightCorner.X = left - 1; + tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1; + tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y; + driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); + + tr.UpperLeftCorner.X = right; + tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; + driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); + } + else + { + + frameRect.UpperLeftCorner.X = left-2; + frameRect.LowerRightCorner.X = right+2; + frameRect.LowerRightCorner.Y += 2; + + skin->draw3DTabButton(this, true, frameRect, &AbsoluteClippingRect, VerticalAlignment); + + // draw text + font->draw(activeTab->getText(), frameRect, activeTab->getTextColor(), + true, true, &frameRect); + + tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; + tr.LowerRightCorner.X = left - 1; + tr.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - 1; + tr.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y; + driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), tr, &AbsoluteClippingRect); + + tr.UpperLeftCorner.X = right; + tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; + driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), tr, &AbsoluteClippingRect); + } + } + else + { + if ( VerticalAlignment == EGUIA_UPPERLEFT ) + { + tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; + tr.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; + tr.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - 1; + tr.LowerRightCorner.Y = frameRect.LowerRightCorner.Y; + driver->draw2DRectangle(skin->getColor(EGDC_3D_HIGH_LIGHT), tr, &AbsoluteClippingRect); + } + else + { + tr.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X; + tr.LowerRightCorner.X = 1000; + tr.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - 1; + tr.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y; + driver->draw2DRectangle(skin->getColor(EGDC_3D_DARK_SHADOW), tr, &AbsoluteClippingRect); + } + } + + skin->draw3DTabBody(this, Border, FillBackground, AbsoluteRect, &AbsoluteClippingRect, TabHeight, VerticalAlignment); + + // enable scrollcontrols on need + if ( UpButton ) + UpButton->setEnabled(needLeftScroll); + if ( DownButton ) + DownButton->setEnabled(needRightScroll); + refreshSprites(); + + IGUIElement::draw(); +} + + +//! Set the height of the tabs +void CGUITabControl::setTabHeight( s32 height ) +{ + if ( height < 0 ) + height = 0; + + TabHeight = height; + + recalculateScrollButtonPlacement(); + recalculateScrollBar(); +} + + +//! Get the height of the tabs +s32 CGUITabControl::getTabHeight() const +{ + return TabHeight; +} + +//! set the maximal width of a tab. Per default width is 0 which means "no width restriction". +void CGUITabControl::setTabMaxWidth(s32 width ) +{ + TabMaxWidth = width; +} + +//! get the maximal width of a tab +s32 CGUITabControl::getTabMaxWidth() const +{ + return TabMaxWidth; +} + + +//! Set the extra width added to tabs on each side of the text +void CGUITabControl::setTabExtraWidth( s32 extraWidth ) +{ + if ( extraWidth < 0 ) + extraWidth = 0; + + TabExtraWidth = extraWidth; + + recalculateScrollBar(); +} + + +//! Get the extra width added to tabs on each side of the text +s32 CGUITabControl::getTabExtraWidth() const +{ + return TabExtraWidth; +} + + +void CGUITabControl::recalculateScrollBar() +{ + if (!UpButton || !DownButton) + return; + + ScrollControl = needScrollControl() || CurrentScrollTabIndex > 0; + + if (ScrollControl) + { + UpButton->setVisible( true ); + DownButton->setVisible( true ); + } + else + { + UpButton->setVisible( false ); + DownButton->setVisible( false ); + } + + bringToFront( UpButton ); + bringToFront( DownButton ); +} + +//! Set the alignment of the tabs +void CGUITabControl::setTabVerticalAlignment( EGUI_ALIGNMENT alignment ) +{ + VerticalAlignment = alignment; + + recalculateScrollButtonPlacement(); + recalculateScrollBar(); + + core::rect r(calcTabPos()); + for ( u32 i=0; isetRelativePosition(r); + } +} + +void CGUITabControl::recalculateScrollButtonPlacement() +{ + IGUISkin* skin = Environment->getSkin(); + s32 ButtonSize = 16; + s32 ButtonHeight = TabHeight - 2; + if ( ButtonHeight < 0 ) + ButtonHeight = TabHeight; + if (skin) + { + ButtonSize = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + if (ButtonSize > TabHeight) + ButtonSize = TabHeight; + } + + s32 ButtonX = RelativeRect.getWidth() - (s32)(2.5f*(f32)ButtonSize) - 1; + s32 ButtonY = 0; + + if (VerticalAlignment == EGUIA_UPPERLEFT) + { + ButtonY = 2 + (TabHeight / 2) - (ButtonHeight / 2); + UpButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + } + else + { + ButtonY = RelativeRect.getHeight() - (TabHeight / 2) - (ButtonHeight / 2) - 2; + UpButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); + DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT); + } + + UpButton->setRelativePosition(core::rect(ButtonX, ButtonY, ButtonX+ButtonSize, ButtonY+ButtonHeight)); + ButtonX += ButtonSize + 1; + DownButton->setRelativePosition(core::rect(ButtonX, ButtonY, ButtonX+ButtonSize, ButtonY+ButtonHeight)); +} + +//! Get the alignment of the tabs +EGUI_ALIGNMENT CGUITabControl::getTabVerticalAlignment() const +{ + return VerticalAlignment; +} + + +s32 CGUITabControl::getTabAt(s32 xpos, s32 ypos) const +{ + core::position2di p(xpos, ypos); + IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(); + + core::rect frameRect(AbsoluteRect); + + if ( VerticalAlignment == EGUIA_UPPERLEFT ) + { + frameRect.UpperLeftCorner.Y += 2; + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + TabHeight; + } + else + { + frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y - TabHeight; + } + + s32 pos = frameRect.UpperLeftCorner.X + 2; + + if (!frameRect.isPointInside(p)) + return -1; + + for (s32 i=CurrentScrollTabIndex; i<(s32)Tabs.size(); ++i) + { + // get Text + const wchar_t* text = 0; + if (Tabs[i]) + text = Tabs[i]->getText(); + + // get text length + s32 len = calcTabWidth(pos, font, text, true); + if ( ScrollControl && pos+len > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2 ) + return -1; + + frameRect.UpperLeftCorner.X = pos; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; + + pos += len; + + if (frameRect.isPointInside(p)) + { + return i; + } + } + return -1; +} + +//! Returns which tab is currently active +s32 CGUITabControl::getActiveTab() const +{ + return ActiveTab; +} + + +//! Brings a tab to front. +bool CGUITabControl::setActiveTab(s32 idx) +{ + if ((u32)idx >= Tabs.size()) + return false; + + bool changed = (ActiveTab != idx); + + ActiveTab = idx; + + for (s32 i=0; i<(s32)Tabs.size(); ++i) + if (Tabs[i]) + Tabs[i]->setVisible( i == ActiveTab ); + + if (changed) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_TAB_CHANGED; + Parent->OnEvent(event); + } + + return true; +} + + +bool CGUITabControl::setActiveTab(IGUITab *tab) +{ + for (s32 i=0; i<(s32)Tabs.size(); ++i) + if (Tabs[i] == tab) + return setActiveTab(i); + return false; +} + + +//! Removes a child. +void CGUITabControl::removeChild(IGUIElement* child) +{ + bool isTab = false; + + u32 i=0; + // check if it is a tab + while (idrop(); + Tabs.erase(i); + isTab = true; + } + else + ++i; + } + + // reassign numbers + if (isTab) + { + for (i=0; isetNumber(i); + } + + // remove real element + IGUIElement::removeChild(child); + + recalculateScrollBar(); +} + + +//! Update the position of the element, decides scroll button status +void CGUITabControl::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + recalculateScrollBar(); +} + + +//! Writes attributes of the element. +void CGUITabControl::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUITabControl::serializeAttributes(out,options); + + out->addInt ("ActiveTab", ActiveTab); + out->addBool("Border", Border); + out->addBool("FillBackground", FillBackground); + out->addInt ("TabHeight", TabHeight); + out->addInt ("TabMaxWidth", TabMaxWidth); + out->addEnum("TabVerticalAlignment", s32(VerticalAlignment), GUIAlignmentNames); +} + + +//! Reads attributes of the element +void CGUITabControl::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ + Border = in->getAttributeAsBool("Border"); + FillBackground = in->getAttributeAsBool("FillBackground"); + + ActiveTab = -1; + + setTabHeight(in->getAttributeAsInt("TabHeight")); + TabMaxWidth = in->getAttributeAsInt("TabMaxWidth"); + + IGUITabControl::deserializeAttributes(in,options); + + setActiveTab(in->getAttributeAsInt("ActiveTab")); + setTabVerticalAlignment( static_cast(in->getAttributeAsEnumeration("TabVerticalAlignment" , GUIAlignmentNames)) ); +} + + +} // end namespace irr +} // end namespace gui + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.d new file mode 100644 index 0000000..c29cc2c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.d @@ -0,0 +1,2 @@ +CGUITabControl.o: CGUITabControl.cpp CGUITabControl.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.h new file mode 100644 index 0000000..dd6c5ae --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITabControl.h @@ -0,0 +1,202 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_TAB_CONTROL_H_INCLUDED__ +#define __C_GUI_TAB_CONTROL_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUITabControl.h" +#include "irrArray.h" +#include "IGUISkin.h" + +namespace irr +{ +namespace gui +{ + class CGUITabControl; + class IGUIButton; + + // A tab, onto which other gui elements could be added. + class CGUITab : public IGUITab + { + public: + + //! constructor + CGUITab(s32 number, IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + s32 id); + + //! destructor + //virtual ~CGUITab(); + + //! Returns number of this tab in tabcontrol. Can be accessed + //! later IGUITabControl::getTab() by this number. + virtual s32 getNumber() const; + + //! Sets the number + virtual void setNumber(s32 n); + + //! draws the element and its children + virtual void draw(); + + //! sets if the tab should draw its background + virtual void setDrawBackground(bool draw=true); + + //! sets the color of the background, if it should be drawn. + virtual void setBackgroundColor(video::SColor c); + + //! sets the color of the text + virtual void setTextColor(video::SColor c); + + //! returns true if the tab is drawing its background, false if not + virtual bool isDrawingBackground() const; + + //! returns the color of the background + virtual video::SColor getBackgroundColor() const; + + virtual video::SColor getTextColor() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + //! only for internal use by CGUITabControl + void refreshSkinColors(); + + private: + + s32 Number; + video::SColor BackColor; + bool OverrideTextColorEnabled; + video::SColor TextColor; + bool DrawBackground; + }; + + + //! A standard tab control + class CGUITabControl : public IGUITabControl + { + public: + + //! destructor + CGUITabControl(IGUIEnvironment* environment, + IGUIElement* parent, const core::rect& rectangle, + bool fillbackground=true, bool border=true, s32 id=-1); + + //! destructor + virtual ~CGUITabControl(); + + //! Adds a tab + virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1); + + //! Adds a tab that has already been created + virtual void addTab(CGUITab* tab); + + //! Insert the tab at the given index + virtual IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1); + + //! Removes a tab from the tabcontrol + virtual void removeTab(s32 idx); + + //! Clears the tabcontrol removing all tabs + virtual void clear(); + + //! Returns amount of tabs in the tabcontrol + virtual s32 getTabCount() const; + + //! Returns a tab based on zero based index + virtual IGUITab* getTab(s32 idx) const; + + //! Brings a tab to front. + virtual bool setActiveTab(s32 idx); + + //! Brings a tab to front. + virtual bool setActiveTab(IGUITab *tab); + + //! Returns which tab is currently active + virtual s32 getActiveTab() const; + + //! get the the id of the tab at the given absolute coordinates + virtual s32 getTabAt(s32 xpos, s32 ypos) const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Removes a child. + virtual void removeChild(IGUIElement* child); + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + //! Set the height of the tabs + virtual void setTabHeight( s32 height ); + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + //! Get the height of the tabs + virtual s32 getTabHeight() const; + + //! set the maximal width of a tab. Per default width is 0 which means "no width restriction". + virtual void setTabMaxWidth(s32 width ); + + //! get the maximal width of a tab + virtual s32 getTabMaxWidth() const; + + //! Set the alignment of the tabs + //! note: EGUIA_CENTER is not an option + virtual void setTabVerticalAlignment( gui::EGUI_ALIGNMENT alignment ); + + //! Get the alignment of the tabs + virtual gui::EGUI_ALIGNMENT getTabVerticalAlignment() const; + + //! Set the extra width added to tabs on each side of the text + virtual void setTabExtraWidth( s32 extraWidth ); + + //! Get the extra width added to tabs on each side of the text + virtual s32 getTabExtraWidth() const; + + //! Update the position of the element, decides scroll button status + virtual void updateAbsolutePosition(); + + private: + + void scrollLeft(); + void scrollRight(); + bool needScrollControl( s32 startIndex=0, bool withScrollControl=false ); + s32 calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl ) const; + core::rect calcTabPos(); + + void recalculateScrollButtonPlacement(); + void recalculateScrollBar(); + void refreshSprites(); + + core::array Tabs; // CGUITab* because we need setNumber (which is certainly not nice) + s32 ActiveTab; + bool Border; + bool FillBackground; + bool ScrollControl; + s32 TabHeight; + gui::EGUI_ALIGNMENT VerticalAlignment; + IGUIButton* UpButton; + IGUIButton* DownButton; + s32 TabMaxWidth; + s32 CurrentScrollTabIndex; + s32 TabExtraWidth; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.cpp new file mode 100644 index 0000000..a045aac --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.cpp @@ -0,0 +1,1256 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// 07.10.2005 - Multicolor-Listbox added by A. Buschhueter (Acki) +// A_Buschhueter@gmx.de + +#include "CGUITable.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "CGUIScrollBar.h" +#include "os.h" + +#define ARROW_PAD 15 + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUITable::CGUITable(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, const core::rect& rectangle, bool clip, + bool drawBack, bool moveOverSelect) +: IGUITable(environment, parent, id, rectangle), Font(0), + VerticalScrollBar(0), HorizontalScrollBar(0), + Clip(clip), DrawBack(drawBack), MoveOverSelect(moveOverSelect), + Selecting(false), CurrentResizedColumn(-1), ResizeStart(0), ResizableColumns(true), + ItemHeight(0), TotalItemHeight(0), TotalItemWidth(0), Selected(-1), + CellHeightPadding(2), CellWidthPadding(5), ActiveTab(-1), + CurrentOrdering(EGOM_NONE), DrawFlags(EGTDF_ROWS | EGTDF_COLUMNS | EGTDF_ACTIVE_ROW ) +{ + #ifdef _DEBUG + setDebugName("CGUITable"); + #endif + + VerticalScrollBar = Environment->addScrollBar(false, core::rect(0, 0, 100, 100), this, -1); + if (VerticalScrollBar) + { + VerticalScrollBar->grab(); + VerticalScrollBar->setNotClipped(false); + VerticalScrollBar->setSubElement(true); + } + + HorizontalScrollBar = Environment->addScrollBar(true, core::rect(0, 0, 100, 100), this, -1); + if ( HorizontalScrollBar ) + { + HorizontalScrollBar->grab(); + HorizontalScrollBar->setNotClipped(false); + HorizontalScrollBar->setSubElement(true); + } + + refreshControls(); +} + + +//! destructor +CGUITable::~CGUITable() +{ + if (VerticalScrollBar) + VerticalScrollBar->drop(); + if ( HorizontalScrollBar ) + HorizontalScrollBar->drop(); + + if (Font) + Font->drop(); +} + + +void CGUITable::addColumn(const wchar_t* caption, s32 columnIndex) +{ + Column tabHeader; + tabHeader.Name = caption; + tabHeader.Width = Font->getDimension(caption).Width + (CellWidthPadding * 2) + ARROW_PAD; + tabHeader.OrderingMode = EGCO_NONE; + + if ( columnIndex < 0 || columnIndex >= (s32)Columns.size() ) + { + Columns.push_back(tabHeader); + for ( u32 i=0; i < Rows.size(); ++i ) + { + Cell cell; + Rows[i].Items.push_back(cell); + } + } + else + { + Columns.insert(tabHeader, columnIndex); + for ( u32 i=0; i < Rows.size(); ++i ) + { + Cell cell; + Rows[i].Items.insert(cell, columnIndex); + } + } + + if (ActiveTab == -1) + ActiveTab = 0; + + recalculateWidths(); +} + + +//! remove a column from the table +void CGUITable::removeColumn(u32 columnIndex) +{ + if ( columnIndex < Columns.size() ) + { + Columns.erase(columnIndex); + for ( u32 i=0; i < Rows.size(); ++i ) + { + Rows[i].Items.erase(columnIndex); + } + } + if ( (s32)columnIndex <= ActiveTab ) + ActiveTab = Columns.size() ? 0 : -1; + + recalculateWidths(); +} + + +s32 CGUITable::getColumnCount() const +{ + return Columns.size(); +} + + +s32 CGUITable::getRowCount() const +{ + return Rows.size(); +} + + +bool CGUITable::setActiveColumn(s32 idx, bool doOrder ) +{ + if (idx < 0 || idx >= (s32)Columns.size()) + return false; + + bool changed = (ActiveTab != idx); + + ActiveTab = idx; + if ( ActiveTab < 0 ) + return false; + + if ( doOrder ) + { + switch ( Columns[idx].OrderingMode ) + { + case EGCO_NONE: + CurrentOrdering = EGOM_NONE; + break; + + case EGCO_CUSTOM: + CurrentOrdering = EGOM_NONE; + if (Parent) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_TABLE_HEADER_CHANGED; + Parent->OnEvent(event); + } + + break; + + case EGCO_ASCENDING: + CurrentOrdering = EGOM_ASCENDING; + break; + + case EGCO_DESCENDING: + CurrentOrdering = EGOM_DESCENDING; + break; + + case EGCO_FLIP_ASCENDING_DESCENDING: + CurrentOrdering = EGOM_ASCENDING == CurrentOrdering ? EGOM_DESCENDING : EGOM_ASCENDING; + break; + default: + CurrentOrdering = EGOM_NONE; + } + + orderRows(getActiveColumn(), CurrentOrdering); + } + + if (changed) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = EGET_TABLE_HEADER_CHANGED; + Parent->OnEvent(event); + } + + return true; +} + + +s32 CGUITable::getActiveColumn() const +{ + return ActiveTab; +} + + +EGUI_ORDERING_MODE CGUITable::getActiveColumnOrdering() const +{ + return CurrentOrdering; +} + + +void CGUITable::setColumnWidth(u32 columnIndex, u32 width) +{ + if ( columnIndex < Columns.size() ) + { + const u32 MIN_WIDTH = Font->getDimension(Columns[columnIndex].Name.c_str() ).Width + (CellWidthPadding * 2); + if ( width < MIN_WIDTH ) + width = MIN_WIDTH; + + Columns[columnIndex].Width = width; + + for ( u32 i=0; i < Rows.size(); ++i ) + { + breakText( Rows[i].Items[columnIndex].Text, Rows[i].Items[columnIndex].BrokenText, Columns[columnIndex].Width ); + } + } + recalculateWidths(); +} + +//! Get the width of a column +u32 CGUITable::getColumnWidth(u32 columnIndex) const +{ + if ( columnIndex >= Columns.size() ) + return 0; + + return Columns[columnIndex].Width; +} + +void CGUITable::setResizableColumns(bool resizable) +{ + ResizableColumns = resizable; +} + + +bool CGUITable::hasResizableColumns() const +{ + return ResizableColumns; +} + + +u32 CGUITable::addRow(u32 rowIndex) +{ + if ( rowIndex > Rows.size() ) + { + rowIndex = Rows.size(); + } + + Row row; + + if ( rowIndex == Rows.size() ) + Rows.push_back(row); + else + Rows.insert(row, rowIndex); + + Rows[rowIndex].Items.reallocate(Columns.size()); + for ( u32 i = 0 ; i < Columns.size() ; ++i ) + { + Rows[rowIndex].Items.push_back(Cell()); + } + + recalculateHeights(); + return rowIndex; +} + + +void CGUITable::removeRow(u32 rowIndex) +{ + if ( rowIndex > Rows.size() ) + return; + + Rows.erase( rowIndex ); + + if ( !(Selected < s32(Rows.size())) ) + Selected = Rows.size() - 1; + + recalculateHeights(); +} + + +//! adds an list item, returns id of item +void CGUITable::setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text) +{ + if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) + { + Rows[rowIndex].Items[columnIndex].Text = text; + breakText( Rows[rowIndex].Items[columnIndex].Text, Rows[rowIndex].Items[columnIndex].BrokenText, Columns[columnIndex].Width ); + + IGUISkin* skin = Environment->getSkin(); + if ( skin ) + Rows[rowIndex].Items[columnIndex].Color = skin->getColor(EGDC_BUTTON_TEXT); + } +} + +void CGUITable::setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text, video::SColor color) +{ + if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) + { + Rows[rowIndex].Items[columnIndex].Text = text; + breakText( Rows[rowIndex].Items[columnIndex].Text, Rows[rowIndex].Items[columnIndex].BrokenText, Columns[columnIndex].Width ); + Rows[rowIndex].Items[columnIndex].Color = color; + Rows[rowIndex].Items[columnIndex].IsOverrideColor = true; + } +} + + +void CGUITable::setCellColor(u32 rowIndex, u32 columnIndex, video::SColor color) +{ + if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) + { + Rows[rowIndex].Items[columnIndex].Color = color; + Rows[rowIndex].Items[columnIndex].IsOverrideColor = true; + } +} + + +void CGUITable::setCellData(u32 rowIndex, u32 columnIndex, void *data) +{ + if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) + { + Rows[rowIndex].Items[columnIndex].Data = data; + } +} + + +const wchar_t* CGUITable::getCellText(u32 rowIndex, u32 columnIndex ) const +{ + if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) + { + return Rows[rowIndex].Items[columnIndex].Text.c_str(); + } + + return 0; +} + + +void* CGUITable::getCellData(u32 rowIndex, u32 columnIndex ) const +{ + if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) + { + return Rows[rowIndex].Items[columnIndex].Data; + } + + return 0; +} + + +//! clears the list +void CGUITable::clear() +{ + Selected = -1; + Rows.clear(); + Columns.clear(); + + if (VerticalScrollBar) + VerticalScrollBar->setPos(0); + if ( HorizontalScrollBar ) + HorizontalScrollBar->setPos(0); + + recalculateHeights(); + recalculateWidths(); +} + + +void CGUITable::clearRows() +{ + Selected = -1; + Rows.clear(); + + if (VerticalScrollBar) + VerticalScrollBar->setPos(0); + + recalculateHeights(); +} + + +/*! +*/ +s32 CGUITable::getSelected() const +{ + return Selected; +} + +//! set wich row is currently selected +void CGUITable::setSelected( s32 index ) +{ + Selected = -1; + if ( index >= 0 && index < (s32) Rows.size() ) + Selected = index; +} + + +void CGUITable::recalculateWidths() +{ + TotalItemWidth=0; + for ( u32 i=0; i < Columns.size(); ++i ) + { + TotalItemWidth += Columns[i].Width; + } + checkScrollbars(); +} + + +void CGUITable::recalculateHeights() +{ + TotalItemHeight = 0; + IGUISkin* skin = Environment->getSkin(); + if (Font != skin->getFont()) + { + if (Font) + Font->drop(); + + Font = skin->getFont(); + + ItemHeight = 0; + + if(Font) + { + ItemHeight = Font->getDimension(L"A").Height + (CellHeightPadding * 2); + Font->grab(); + } + } + TotalItemHeight = ItemHeight * Rows.size(); // header is not counted, because we only want items + checkScrollbars(); +} + + +// automatic enabled/disabling and resizing of scrollbars +void CGUITable::checkScrollbars() +{ + IGUISkin* skin = Environment->getSkin(); + if ( !HorizontalScrollBar || !VerticalScrollBar || !skin) + return; + + s32 scrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE); + bool wasHorizontalScrollBarVisible = HorizontalScrollBar->isVisible(); + bool wasVerticalScrollBarVisible = VerticalScrollBar->isVisible(); + HorizontalScrollBar->setVisible(false); + VerticalScrollBar->setVisible(false); + + // CAREFUL: near identical calculations for tableRect and clientClip are also done in draw + // area of table used for drawing without scrollbars + core::rect tableRect(AbsoluteRect); + tableRect.UpperLeftCorner.X += 1; + tableRect.UpperLeftCorner.Y += 1; + s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight; + + // area of for the items (without header and without scrollbars) + core::rect clientClip(tableRect); + clientClip.UpperLeftCorner.Y = headerBottom + 1; + + // needs horizontal scroll be visible? + if( TotalItemWidth > clientClip.getWidth() ) + { + clientClip.LowerRightCorner.Y -= scrollBarSize; + HorizontalScrollBar->setVisible(true); + HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth())); + } + + // needs vertical scroll be visible? + if( TotalItemHeight > clientClip.getHeight() ) + { + clientClip.LowerRightCorner.X -= scrollBarSize; + VerticalScrollBar->setVisible(true); + VerticalScrollBar->setMax(core::max_(0,TotalItemHeight - clientClip.getHeight())); + + // check horizontal again because we have now smaller clientClip + if ( !HorizontalScrollBar->isVisible() ) + { + if( TotalItemWidth > clientClip.getWidth() ) + { + clientClip.LowerRightCorner.Y -= scrollBarSize; + HorizontalScrollBar->setVisible(true); + HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth())); + } + } + } + + // find the correct size for the vertical scrollbar + if ( VerticalScrollBar->isVisible() ) + { + if (!wasVerticalScrollBarVisible ) + VerticalScrollBar->setPos(0); + + if ( HorizontalScrollBar->isVisible() ) + { + VerticalScrollBar->setRelativePosition( + core::rect(RelativeRect.getWidth() - scrollBarSize, 1, + RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+scrollBarSize) ) ); + } + else + { + VerticalScrollBar->setRelativePosition( + core::rect(RelativeRect.getWidth() - scrollBarSize, 1, + RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); + } + } + + // find the correct size for the horizontal scrollbar + if ( HorizontalScrollBar->isVisible() ) + { + if ( !wasHorizontalScrollBarVisible ) + HorizontalScrollBar->setPos(0); + + if ( VerticalScrollBar->isVisible() ) + { + HorizontalScrollBar->setRelativePosition( core::rect(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-(1+scrollBarSize), RelativeRect.getHeight()-1) ); + } + else + { + HorizontalScrollBar->setRelativePosition( core::rect(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); + } + } +} + + +void CGUITable::refreshControls() +{ + updateAbsolutePosition(); + + if ( VerticalScrollBar ) + VerticalScrollBar->setVisible(false); + + if ( HorizontalScrollBar ) + HorizontalScrollBar->setVisible(false); + + recalculateHeights(); + recalculateWidths(); +} + + +//! called if an event happened. +bool CGUITable::OnEvent(const SEvent &event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case gui::EGET_SCROLL_BAR_CHANGED: + if (event.GUIEvent.Caller == VerticalScrollBar) + { + // current position will get read out in draw + return true; + } + if (event.GUIEvent.Caller == HorizontalScrollBar) + { + // current position will get read out in draw + return true; + } + break; + case gui::EGET_ELEMENT_FOCUS_LOST: + { + CurrentResizedColumn = -1; + Selecting = false; + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + { + if ( !isEnabled() ) + return false; + + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + VerticalScrollBar->setPos(VerticalScrollBar->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1)*-10); + return true; + + case EMIE_LMOUSE_PRESSED_DOWN: + + if (Environment->hasFocus(this) && + VerticalScrollBar->isVisible() && + VerticalScrollBar->getAbsolutePosition().isPointInside(p) && + VerticalScrollBar->OnEvent(event)) + return true; + + if (Environment->hasFocus(this) && + HorizontalScrollBar->isVisible() && + HorizontalScrollBar->getAbsolutePosition().isPointInside(p) && + HorizontalScrollBar->OnEvent(event)) + return true; + + if ( dragColumnStart( event.MouseInput.X, event.MouseInput.Y ) ) + { + Environment->setFocus(this); + return true; + } + + if ( selectColumnHeader( event.MouseInput.X, event.MouseInput.Y ) ) + return true; + + Selecting = true; + Environment->setFocus(this); + return true; + + case EMIE_LMOUSE_LEFT_UP: + + CurrentResizedColumn = -1; + Selecting = false; + if (!getAbsolutePosition().isPointInside(p)) + { + Environment->removeFocus(this); + } + + if (Environment->hasFocus(this) && + VerticalScrollBar->isVisible() && + VerticalScrollBar->getAbsolutePosition().isPointInside(p) && + VerticalScrollBar->OnEvent(event)) + { + return true; + } + + if (Environment->hasFocus(this) && + HorizontalScrollBar->isVisible() && + HorizontalScrollBar->getAbsolutePosition().isPointInside(p) && + HorizontalScrollBar->OnEvent(event)) + { + return true; + } + + selectNew(event.MouseInput.Y); + return true; + + case EMIE_MOUSE_MOVED: + if ( CurrentResizedColumn >= 0 ) + { + if ( dragColumnUpdate(event.MouseInput.X) ) + { + return true; + } + } + if (Selecting || MoveOverSelect) + { + if (getAbsolutePosition().isPointInside(p)) + { + selectNew(event.MouseInput.Y); + return true; + } + } + break; + default: + break; + } + } + break; + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +void CGUITable::setColumnOrdering(u32 columnIndex, EGUI_COLUMN_ORDERING mode) +{ + if ( columnIndex < Columns.size() ) + Columns[columnIndex].OrderingMode = mode; +} + + +void CGUITable::swapRows(u32 rowIndexA, u32 rowIndexB) +{ + if ( rowIndexA >= Rows.size() ) + return; + + if ( rowIndexB >= Rows.size() ) + return; + + Row swap = Rows[rowIndexA]; + Rows[rowIndexA] = Rows[rowIndexB]; + Rows[rowIndexB] = swap; + + if ( Selected == s32(rowIndexA) ) + Selected = rowIndexB; + else if( Selected == s32(rowIndexB) ) + Selected = rowIndexA; + +} + + +bool CGUITable::dragColumnStart(s32 xpos, s32 ypos) +{ + if ( !ResizableColumns ) + return false; + + if ( ypos > ( AbsoluteRect.UpperLeftCorner.Y + ItemHeight ) ) + return false; + + const s32 CLICK_AREA = 12; // to left and right of line which can be dragged + s32 pos = AbsoluteRect.UpperLeftCorner.X+1; + + if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) + pos -= HorizontalScrollBar->getPos(); + + pos += TotalItemWidth; + + // have to search from the right as otherwise lines could no longer be resized when a column width is 0 + for ( s32 i = (s32)Columns.size()-1; i >= 0 ; --i ) + { + u32 colWidth = Columns[i].Width; + + if ( xpos >= (pos - CLICK_AREA) && xpos < ( pos + CLICK_AREA ) ) + { + CurrentResizedColumn = i; + ResizeStart = xpos; + return true; + } + + pos -= colWidth; + } + + return false; +} + + +bool CGUITable::dragColumnUpdate(s32 xpos) +{ + if ( !ResizableColumns || CurrentResizedColumn < 0 || CurrentResizedColumn >= s32(Columns.size()) ) + { + CurrentResizedColumn = -1; + return false; + } + + s32 width = s32(Columns[CurrentResizedColumn].Width) + (xpos-ResizeStart); + if ( width < 0 ) + width = 0; + setColumnWidth(CurrentResizedColumn, u32(width)); + ResizeStart = xpos; + + return false; +} + + +bool CGUITable::selectColumnHeader(s32 xpos, s32 ypos) +{ + if ( ypos > ( AbsoluteRect.UpperLeftCorner.Y + ItemHeight ) ) + return false; + + s32 pos = AbsoluteRect.UpperLeftCorner.X+1; + + if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) + pos -= HorizontalScrollBar->getPos(); + + for ( u32 i = 0 ; i < Columns.size() ; ++i ) + { + u32 colWidth = Columns[i].Width; + + if ( xpos >= pos && xpos < ( pos + s32(colWidth) ) ) + { + setActiveColumn( i, true ); + + return true; + } + + pos += colWidth; + } + + return false; +} + + +void CGUITable::orderRows(s32 columnIndex, EGUI_ORDERING_MODE mode) +{ + Row swap; + + if ( columnIndex == -1 ) + columnIndex = getActiveColumn(); + if ( columnIndex < 0 ) + return; + + if ( mode == EGOM_ASCENDING ) + { + for ( s32 i = 0 ; i < s32(Rows.size()) - 1 ; ++i ) + { + for ( s32 j = 0 ; j < s32(Rows.size()) - i - 1 ; ++j ) + { + if ( Rows[j+1].Items[columnIndex].Text < Rows[j].Items[columnIndex].Text ) + { + swap = Rows[j]; + Rows[j] = Rows[j+1]; + Rows[j+1] = swap; + + if ( Selected == j ) + Selected = j+1; + else if( Selected == j+1 ) + Selected = j; + } + } + } + } + else if ( mode == EGOM_DESCENDING ) + { + for ( s32 i = 0 ; i < s32(Rows.size()) - 1 ; ++i ) + { + for ( s32 j = 0 ; j < s32(Rows.size()) - i - 1 ; ++j ) + { + if ( Rows[j].Items[columnIndex].Text < Rows[j+1].Items[columnIndex].Text) + { + swap = Rows[j]; + Rows[j] = Rows[j+1]; + Rows[j+1] = swap; + + if ( Selected == j ) + Selected = j+1; + else if( Selected == j+1 ) + Selected = j; + } + } + } + } +} + + +void CGUITable::selectNew(s32 ypos, bool onlyHover) +{ + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + s32 oldSelected = Selected; + + if ( ypos < ( AbsoluteRect.UpperLeftCorner.Y + ItemHeight ) ) + return; + + // find new selected item. + if (ItemHeight!=0) + Selected = ((ypos - AbsoluteRect.UpperLeftCorner.Y - ItemHeight - 1) + VerticalScrollBar->getPos()) / ItemHeight; + + if (Selected >= (s32)Rows.size()) + Selected = Rows.size() - 1; + else if (Selected<0) + Selected = 0; + + // post the news + if (Parent && !onlyHover) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = (Selected != oldSelected) ? EGET_TABLE_CHANGED : EGET_TABLE_SELECTED_AGAIN; + Parent->OnEvent(event); + } +} + + +//! draws the element and its children +void CGUITable::draw() +{ + if (!IsVisible) + return; + + irr::video::IVideoDriver* driver = Environment->getVideoDriver(); + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + IGUIFont* font = skin->getFont(); + if (!font) + return; + + // CAREFUL: near identical calculations for tableRect and clientClip are also done in checkScrollbars and selectColumnHeader + // Area of table used for drawing without scrollbars + core::rect tableRect(AbsoluteRect); + tableRect.UpperLeftCorner.X += 1; + tableRect.UpperLeftCorner.Y += 1; + if ( VerticalScrollBar && VerticalScrollBar->isVisible() ) + tableRect.LowerRightCorner.X -= skin->getSize(EGDS_SCROLLBAR_SIZE); + if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) + tableRect.LowerRightCorner.Y -= skin->getSize(EGDS_SCROLLBAR_SIZE); + + s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight; + + // area of for the items (without header and without scrollbars) + core::rect clientClip(tableRect); + clientClip.UpperLeftCorner.Y = headerBottom + 1; + clientClip.clipAgainst(AbsoluteClippingRect); + + // draw background for whole element + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true, DrawBack, AbsoluteRect, &AbsoluteClippingRect); + + // scrolledTableClient is the area where the table items would be if it could be drawn completely + core::rect scrolledTableClient(tableRect); + scrolledTableClient.UpperLeftCorner.Y = headerBottom + 1; + scrolledTableClient.LowerRightCorner.Y = scrolledTableClient.UpperLeftCorner.Y + TotalItemHeight; + scrolledTableClient.LowerRightCorner.X = scrolledTableClient.UpperLeftCorner.X + TotalItemWidth; + if ( VerticalScrollBar && VerticalScrollBar->isVisible() ) + { + scrolledTableClient.UpperLeftCorner.Y -= VerticalScrollBar->getPos(); + scrolledTableClient.LowerRightCorner.Y -= VerticalScrollBar->getPos(); + } + if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) + { + scrolledTableClient.UpperLeftCorner.X -= HorizontalScrollBar->getPos(); + scrolledTableClient.LowerRightCorner.X -= HorizontalScrollBar->getPos(); + } + + // rowRect is around the scrolled row + core::rect rowRect(scrolledTableClient); + rowRect.LowerRightCorner.Y = rowRect.UpperLeftCorner.Y + ItemHeight; + + u32 pos; + for ( u32 i = 0 ; i < Rows.size() ; ++i ) + { + if (rowRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && + rowRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) + { + // draw row seperator + if ( DrawFlags & EGTDF_ROWS ) + { + core::rect lineRect(rowRect); + lineRect.UpperLeftCorner.Y = lineRect.LowerRightCorner.Y - 1; + driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), lineRect, &clientClip); + } + + core::rect textRect(rowRect); + pos = rowRect.UpperLeftCorner.X; + + // draw selected row background highlighted + if ((s32)i == Selected && DrawFlags & EGTDF_ACTIVE_ROW ) + driver->draw2DRectangle(skin->getColor(EGDC_HIGH_LIGHT), rowRect, &clientClip); + + for ( u32 j = 0 ; j < Columns.size() ; ++j ) + { + textRect.UpperLeftCorner.X = pos + CellWidthPadding; + textRect.LowerRightCorner.X = pos + Columns[j].Width - CellWidthPadding; + + // draw item text + if ((s32)i == Selected) + { + font->draw(Rows[i].Items[j].BrokenText.c_str(), textRect, skin->getColor(isEnabled() ? EGDC_HIGH_LIGHT_TEXT : EGDC_GRAY_TEXT), false, true, &clientClip); + } + else + { + if ( !Rows[i].Items[j].IsOverrideColor ) // skin-colors can change + Rows[i].Items[j].Color = skin->getColor(EGDC_BUTTON_TEXT); + font->draw(Rows[i].Items[j].BrokenText.c_str(), textRect, isEnabled() ? Rows[i].Items[j].Color : skin->getColor(EGDC_GRAY_TEXT), false, true, &clientClip); + } + + pos += Columns[j].Width; + } + } + + rowRect.UpperLeftCorner.Y += ItemHeight; + rowRect.LowerRightCorner.Y += ItemHeight; + } + + core::rect columnSeparator(clientClip); + pos = scrolledTableClient.UpperLeftCorner.X; + + core::rect tableClip(tableRect); + tableClip.clipAgainst(AbsoluteClippingRect); + + for (u32 i = 0 ; i < Columns.size() ; ++i ) + { + const wchar_t* text = Columns[i].Name.c_str(); + u32 colWidth = Columns[i].Width; + + //core::dimension2d dim = font->getDimension(text); + + core::rect columnrect(pos, tableRect.UpperLeftCorner.Y, pos + colWidth, headerBottom); + + // draw column background + skin->draw3DButtonPaneStandard(this, columnrect, &tableClip); + + // draw column seperator + if ( DrawFlags & EGTDF_COLUMNS ) + { + columnSeparator.UpperLeftCorner.X = pos; + columnSeparator.LowerRightCorner.X = pos + 1; + driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), columnSeparator, &tableClip); + } + + // draw header column text + columnrect.UpperLeftCorner.X += CellWidthPadding; + font->draw(text, columnrect, skin->getColor( isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), false, true, &tableClip); + + // draw icon for active column tab + if ( (s32)i == ActiveTab ) + { + if ( CurrentOrdering == EGOM_ASCENDING ) + { + columnrect.UpperLeftCorner.X = columnrect.LowerRightCorner.X - CellWidthPadding - ARROW_PAD / 2 + 2; + columnrect.UpperLeftCorner.Y += 7; + skin->drawIcon(this,EGDI_CURSOR_UP,columnrect.UpperLeftCorner,0,0,false,&tableClip); + } + else + { + columnrect.UpperLeftCorner.X = columnrect.LowerRightCorner.X - CellWidthPadding - ARROW_PAD / 2 + 2; + columnrect.UpperLeftCorner.Y += 7; + skin->drawIcon(this,EGDI_CURSOR_DOWN,columnrect.UpperLeftCorner,0,0,false,&tableClip); + } + } + + pos += colWidth; + } + + // fill up header background up to the right side + core::rect columnrect(pos, tableRect.UpperLeftCorner.Y, tableRect.LowerRightCorner.X , headerBottom); + skin->draw3DButtonPaneStandard(this, columnrect, &tableClip); + + IGUIElement::draw(); +} + + +void CGUITable::breakText(const core::stringw& text, core::stringw& brokenText, u32 cellWidth) +{ + IGUISkin* skin = Environment->getSkin(); + + if (!skin) + return; + + if (!Font) + return; + + IGUIFont* font = skin->getFont(); + if (!font) + return; + + core::stringw line, lineDots; + wchar_t c[2]; + c[1] = L'\0'; + + const u32 maxLength = cellWidth - (CellWidthPadding * 2); + const u32 maxLengthDots = cellWidth - (CellWidthPadding * 2) - font->getDimension(L"...").Width; + const u32 size = text.size(); + u32 pos = 0; + + u32 i; + + for (i=0; igetDimension(c).Width; + if ( pos > maxLength ) + break; + + if ( font->getDimension( (line + c).c_str() ).Width > maxLengthDots ) + lineDots = line; + + line += c[0]; + } + + if ( i < size ) + brokenText = lineDots + L"..."; + else + brokenText = line; +} + + +//! Set some flags influencing the layout of the table +void CGUITable::setDrawFlags(s32 flags) +{ + DrawFlags = flags; +} + + +//! Get the flags which influence the layout of the table +s32 CGUITable::getDrawFlags() const +{ + return DrawFlags; +} + + +//! Writes attributes of the element. +void CGUITable::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IGUITable::serializeAttributes(out, options); + + out->addInt("ColumnCount", Columns.size()); + u32 i; + for (i=0;iaddString(label.c_str(), Columns[i].Name.c_str() ); + label = "Column"; label += i; label += "width"; + out->addInt(label.c_str(), Columns[i].Width ); + label = "Column"; label += i; label += "OrderingMode"; + out->addEnum(label.c_str(), Columns[i].OrderingMode, GUIColumnOrderingNames); + } + + out->addInt("RowCount", Rows.size()); + for (i=0;iaddInt(label.c_str(), Rows[i].Height ); + + //label = "Row"; label += i; label += "ItemCount"; + //out->addInt(label.c_str(), Rows[i].Items.size()); + u32 c; + for ( c=0; c < Rows[i].Items.size(); ++c ) + { + label = "Row"; label += i; label += "cell"; label += c; label += "text"; + out->addString(label.c_str(), Rows[i].Items[c].Text.c_str() ); + // core::stringw BrokenText; // can be recalculated + label = "Row"; label += i; label += "cell"; label += c; label += "color"; + out->addColor(label.c_str(), Rows[i].Items[c].Color ); + label = "Row"; label += i; label += "cell"; label += c; label += "IsOverrideColor"; + out->addColor(label.c_str(), Rows[i].Items[c].IsOverrideColor ); + // void *data; // can't be serialized + } + } + + // s32 ItemHeight; // can be calculated + // TotalItemHeight // calculated + // TotalItemWidth // calculated + // gui::IGUIFont* Font; // font is just the current font from environment + // gui::IGUIScrollBar* VerticalScrollBar; // not serialized + // gui::IGUIScrollBar* HorizontalScrollBar; // not serialized + + out->addBool ("Clip", Clip); + out->addBool ("DrawBack", DrawBack); + out->addBool ("MoveOverSelect", MoveOverSelect); + + // s32 CurrentResizedColumn; // runtime info - depends on user action + out->addBool ("ResizableColumns", ResizableColumns); + + // s32 Selected; // runtime info - depends on user action + out->addInt("CellWidthPadding", CellWidthPadding ); + out->addInt("CellHeightPadding", CellHeightPadding ); + // s32 ActiveTab; // runtime info - depends on user action + // bool Selecting; // runtime info - depends on user action + out->addEnum("CurrentOrdering", CurrentOrdering, GUIOrderingModeNames); + out->addInt("DrawFlags", DrawFlags); +} + + +//! Reads attributes of the element +void CGUITable::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IGUITable::deserializeAttributes(in, options); + + Columns.clear(); + u32 columnCount = in->getAttributeAsInt("ColumnCount"); + u32 i; + for (i=0;igetAttributeAsString(label.c_str()).c_str()); + label = "Column"; label += i; label += "width"; + column.Width = in->getAttributeAsInt(label.c_str()); + label = "Column"; label += i; label += "OrderingMode"; + + column.OrderingMode = EGCO_NONE; + s32 co = in->getAttributeAsEnumeration(label.c_str(), GUIColumnOrderingNames); + if (co > 0) + column.OrderingMode = EGUI_COLUMN_ORDERING(co); + + Columns.push_back(column); + } + + Rows.clear(); + u32 rowCount = in->getAttributeAsInt("RowCount"); + for (i=0; igetAttributeAsInt(label.c_str() ); + + Rows.push_back(row); + + //label = "Row"; label += i; label += "ItemCount"; + //u32 itemCount = in->getAttributeAsInt(label.c_str()); + u32 c; + for ( c=0; c < columnCount; ++c ) + { + Cell cell; + + label = "Row"; label += i; label += "cell"; label += c; label += "text"; + cell.Text = core::stringw(in->getAttributeAsString(label.c_str()).c_str()); + breakText( cell.Text, cell.BrokenText, Columns[c].Width ); + label = "Row"; label += i; label += "cell"; label += c; label += "color"; + cell.Color = in->getAttributeAsColor(label.c_str()); + label = "Row"; label += i; label += "cell"; label += c; label += "IsOverrideColor"; + cell.IsOverrideColor = in->getAttributeAsBool(label.c_str()); + + cell.Data = NULL; + + Rows[Rows.size()-1].Items.push_back(cell); + } + } + + ItemHeight = 0; // calculated + TotalItemHeight = 0; // calculated + TotalItemWidth = 0; // calculated + + // force font recalculation + if ( Font ) + { + Font->drop(); + Font = 0; + } + + Clip = in->getAttributeAsBool("Clip"); + DrawBack = in->getAttributeAsBool("DrawBack"); + MoveOverSelect = in->getAttributeAsBool("MoveOverSelect"); + + CurrentResizedColumn = -1; + ResizeStart = 0; + ResizableColumns = in->getAttributeAsBool("ResizableColumns"); + + Selected = -1; + CellWidthPadding = in->getAttributeAsInt("CellWidthPadding"); + CellHeightPadding = in->getAttributeAsInt("CellHeightPadding"); + ActiveTab = -1; + Selecting = false; + + CurrentOrdering = (EGUI_ORDERING_MODE) in->getAttributeAsEnumeration("CurrentOrdering", GUIOrderingModeNames); + DrawFlags = in->getAttributeAsInt("DrawFlags"); + + refreshControls(); +} + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.d new file mode 100644 index 0000000..7714577 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.d @@ -0,0 +1 @@ +CGUITable.o: CGUITable.cpp CGUITable.h ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.h new file mode 100644 index 0000000..69cfea5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITable.h @@ -0,0 +1,224 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// 07.10.2005 - Multicolor-Listbox addet by A. Buschhueter (Acki) +// A_Buschhueter@gmx.de + +#ifndef __C_GUI_TABLE_BAR_H_INCLUDED__ +#define __C_GUI_TABLE_BAR_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUITable.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + + class IGUIFont; + class IGUIScrollBar; + + class CGUITable : public IGUITable + { + public: + //! constructor + CGUITable(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, const core::rect& rectangle, bool clip=true, + bool drawBack=false, bool moveOverSelect=true); + + //! destructor + ~CGUITable(); + + //! Adds a column + //! If columnIndex is outside the current range, do push new colum at the end + virtual void addColumn(const wchar_t* caption, s32 columnIndex=-1); + + //! remove a column from the table + virtual void removeColumn(u32 columnIndex); + + //! Returns the number of columns in the table control + virtual s32 getColumnCount() const; + + //! Makes a column active. This will trigger an ordering process. + /** \param idx: The id of the column to make active. + \return True if successful. */ + virtual bool setActiveColumn(s32 columnIndex, bool doOrder=false); + + //! Returns which header is currently active + virtual s32 getActiveColumn() const; + + //! Returns the ordering used by the currently active column + virtual EGUI_ORDERING_MODE getActiveColumnOrdering() const; + + //! set a column width + virtual void setColumnWidth(u32 columnIndex, u32 width); + + //! Get the width of a column + virtual u32 getColumnWidth(u32 columnIndex) const; + + //! columns can be resized by drag 'n drop + virtual void setResizableColumns(bool resizable); + + //! can columns be resized by dran 'n drop? + virtual bool hasResizableColumns() const; + + //! This tells the table control which ordering mode should be used when + //! a column header is clicked. + /** \param columnIndex: The index of the column header. + \param state: If true, a EGET_TABLE_HEADER_CHANGED message will be sent and you can order the table data as you whish.*/ + //! \param mode: One of the modes defined in EGUI_COLUMN_ORDERING + virtual void setColumnOrdering(u32 columnIndex, EGUI_COLUMN_ORDERING mode); + + //! Returns which row is currently selected + virtual s32 getSelected() const; + + //! set wich row is currently selected + virtual void setSelected( s32 index ); + + //! Returns amount of rows in the tabcontrol + virtual s32 getRowCount() const; + + //! adds a row to the table + /** \param rowIndex: zero based index of rows. The row will be + inserted at this position. If a row already exists + there, it will be placed after it. If the row is larger + than the actual number of rows by more than one, it + won't be created. Note that if you create a row that is + not at the end, there might be performance issues*/ + virtual u32 addRow(u32 rowIndex); + + //! Remove a row from the table + virtual void removeRow(u32 rowIndex); + + //! clear the table rows, but keep the columns intact + virtual void clearRows(); + + //! Swap two row positions. This is useful for a custom ordering algo. + virtual void swapRows(u32 rowIndexA, u32 rowIndexB); + + //! This tells the table to start ordering all the rows. You + //! need to explicitly tell the table to reorder the rows when + //! a new row is added or the cells data is changed. This makes + //! the system more flexible and doesn't make you pay the cost + //! of ordering when adding a lot of rows. + //! \param columnIndex: When set to -1 the active column is used. + virtual void orderRows(s32 columnIndex=-1, EGUI_ORDERING_MODE mode=EGOM_NONE); + + + //! Set the text of a cell + virtual void setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text); + + //! Set the text of a cell, and set a color of this cell. + virtual void setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text, video::SColor color); + + //! Set the data of a cell + //! data will not be serialized. + virtual void setCellData(u32 rowIndex, u32 columnIndex, void *data); + + //! Set the color of a cell text + virtual void setCellColor(u32 rowIndex, u32 columnIndex, video::SColor color); + + //! Get the text of a cell + virtual const wchar_t* getCellText(u32 rowIndex, u32 columnIndex ) const; + + //! Get the data of a cell + virtual void* getCellData(u32 rowIndex, u32 columnIndex ) const; + + //! clears the table, deletes all items in the table + virtual void clear(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent &event); + + //! draws the element and its children + virtual void draw(); + + //! Set flags, as defined in EGUI_TABLE_DRAW_FLAGS, which influence the layout + virtual void setDrawFlags(s32 flags); + + //! Get the flags, as defined in EGUI_TABLE_DRAW_FLAGS, which influence the layout + virtual s32 getDrawFlags() const; + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + protected: + virtual void refreshControls(); + virtual void checkScrollbars(); + + private: + + struct Cell + { + Cell() : IsOverrideColor(false), Data(0) {} + core::stringw Text; + core::stringw BrokenText; + bool IsOverrideColor; + video::SColor Color; + void *Data; + }; + + struct Row + { + Row() {} + core::array Items; + }; + + struct Column + { + Column() : Width(0), OrderingMode(EGCO_NONE) {} + core::stringw Name; + u32 Width; + EGUI_COLUMN_ORDERING OrderingMode; + }; + + void breakText(const core::stringw &text, core::stringw & brokenText, u32 cellWidth); + void selectNew(s32 ypos, bool onlyHover=false); + bool selectColumnHeader(s32 xpos, s32 ypos); + bool dragColumnStart(s32 xpos, s32 ypos); + bool dragColumnUpdate(s32 xpos); + void recalculateHeights(); + void recalculateWidths(); + + core::array< Column > Columns; + core::array< Row > Rows; + gui::IGUIFont* Font; + gui::IGUIScrollBar* VerticalScrollBar; + gui::IGUIScrollBar* HorizontalScrollBar; + bool Clip; + bool DrawBack; + bool MoveOverSelect; + bool Selecting; + s32 CurrentResizedColumn; + s32 ResizeStart; + bool ResizableColumns; + + s32 ItemHeight; + s32 TotalItemHeight; + s32 TotalItemWidth; + s32 Selected; + s32 CellHeightPadding; + s32 CellWidthPadding; + s32 ActiveTab; + EGUI_ORDERING_MODE CurrentOrdering; + s32 DrawFlags; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.cpp new file mode 100644 index 0000000..9671c04 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.cpp @@ -0,0 +1,176 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIToolBar.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIFont.h" +#include "CGUIButton.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIToolBar::CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +:IGUIToolBar(environment, parent, id, rectangle), ButtonX(5) +{ + #ifdef _DEBUG + setDebugName("CGUIToolBar"); + #endif + + // calculate position and find other menubars + s32 y = 0; + s32 parentwidth = 100; + + if (parent) + { + parentwidth = Parent->getAbsolutePosition().getWidth(); + + const core::list& children = parent->getChildren(); + core::list::ConstIterator it = children.begin(); + for (; it != children.end(); ++it) + { + core::rect r = (*it)->getAbsolutePosition(); + if (r.UpperLeftCorner.X == 0 && r.UpperLeftCorner.Y <= y && + r.LowerRightCorner.X == parentwidth) + y = r.LowerRightCorner.Y; + } + } + + core::rect rr; + rr.UpperLeftCorner.X = 0; + rr.UpperLeftCorner.Y = y; + s32 height = Environment->getSkin()->getSize ( EGDS_MENU_HEIGHT ); + + /*IGUISkin* skin = Environment->getSkin(); + IGUIFont* font = skin->getFont(); + if (font) + { + s32 t = font->getDimension(L"A").Height + 5; + if (t > height) + height = t; + }*/ + + rr.LowerRightCorner.X = parentwidth; + rr.LowerRightCorner.Y = rr.UpperLeftCorner.Y + height; + setRelativePosition(rr); +} + + +//! called if an event happened. +bool CGUIToolBar::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + if (event.EventType == EET_MOUSE_INPUT_EVENT && + event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) + { + if (AbsoluteClippingRect.isPointInside(core::position2di(event.MouseInput.X, event.MouseInput.Y))) + return true; + } + } + + return IGUIElement::OnEvent(event); +} + + +//! draws the element and its children +void CGUIToolBar::draw() +{ + if (!IsVisible) + return; + + IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + + core::rect rect = AbsoluteRect; + core::rect* clip = &AbsoluteClippingRect; + + // draw frame + skin->draw3DToolBar(this, rect, clip); + + IGUIElement::draw(); +} + + +//! Updates the absolute position. +void CGUIToolBar::updateAbsolutePosition() +{ + if (Parent) + { + DesiredRect.UpperLeftCorner.X = 0; + DesiredRect.LowerRightCorner.X = Parent->getAbsolutePosition().getWidth(); + } + + IGUIElement::updateAbsolutePosition(); +} + + +//! Adds a button to the tool bar +IGUIButton* CGUIToolBar::addButton(s32 id, const wchar_t* text,const wchar_t* tooltiptext, + video::ITexture* img, video::ITexture* pressed, bool isPushButton, + bool useAlphaChannel) +{ + ButtonX += 3; + + core::rect rectangle(ButtonX,2,ButtonX+1,3); + if ( img ) + { + const core::dimension2du &size = img->getOriginalSize(); + rectangle.LowerRightCorner.X = rectangle.UpperLeftCorner.X + size.Width + 8; + rectangle.LowerRightCorner.Y = rectangle.UpperLeftCorner.Y + size.Height + 6; + } + + if ( text ) + { + IGUISkin* skin = Environment->getSkin(); + IGUIFont * font = skin->getFont(EGDF_BUTTON); + if ( font ) + { + core::dimension2d dim = font->getDimension(text); + if ( (s32)dim.Width > rectangle.getWidth() ) + rectangle.LowerRightCorner.X = rectangle.UpperLeftCorner.X + dim.Width + 8; + if ( (s32)dim.Height > rectangle.getHeight() ) + rectangle.LowerRightCorner.Y = rectangle.UpperLeftCorner.Y + dim.Height + 6; + } + } + + ButtonX += rectangle.getWidth(); + + IGUIButton* button = new CGUIButton(Environment, this, id, rectangle); + button->drop(); + + if (text) + button->setText(text); + + if (tooltiptext) + button->setToolTipText(tooltiptext); + + if (img) + button->setImage(img); + + if (pressed) + button->setPressedImage(pressed); + + if (isPushButton) + button->setIsPushButton(isPushButton); + + if (useAlphaChannel) + button->setUseAlphaChannel(useAlphaChannel); + + return button; +} + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.d new file mode 100644 index 0000000..7cc3692 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.d @@ -0,0 +1,2 @@ +CGUIToolBar.o: CGUIToolBar.cpp CGUIToolBar.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.h new file mode 100644 index 0000000..3f419e7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIToolBar.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_TOOL_BAR_H_INCLUDED__ +#define __C_GUI_TOOL_BAR_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIToolbar.h" + +namespace irr +{ +namespace gui +{ + + //! Stays at the top of its parent like the menu bar and contains tool buttons + class CGUIToolBar : public IGUIToolBar + { + public: + + //! constructor + CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! Updates the absolute position. + virtual void updateAbsolutePosition(); + + //! Adds a button to the tool bar + virtual IGUIButton* addButton(s32 id=-1, const wchar_t* text=0,const wchar_t* tooltiptext=0, + video::ITexture* img=0, video::ITexture* pressed=0, + bool isPushButton=false, bool useAlphaChannel=false); + + private: + + s32 ButtonX; + }; + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp new file mode 100644 index 0000000..779b8cd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp @@ -0,0 +1,1101 @@ +// This file is part of the "Irrlicht Engine". +// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de +// expaned by burningwater + +#include "CGUITreeView.h" + +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "CGUIScrollBar.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +CGUITreeViewNode::CGUITreeViewNode( CGUITreeView* owner, CGUITreeViewNode* parent ) + : Owner(owner), Parent(parent), ImageIndex(-1), SelectedImageIndex(-1), + Data(0), Data2(0), Expanded(false) +{ +#ifdef _DEBUG + setDebugName( "CGUITreeView" ); +#endif +} + +CGUITreeViewNode::~CGUITreeViewNode() +{ + if( Owner && this == Owner->getSelected() ) + { + setSelected( false ); + } + + clearChildren(); + + if( Data2 ) + { + Data2->drop(); + } +} + +IGUITreeView* CGUITreeViewNode::getOwner() const +{ + return Owner; +} + +IGUITreeViewNode* CGUITreeViewNode::getParent() const +{ + return Parent; +} + +void CGUITreeViewNode::setText( const wchar_t* text ) +{ + Text = text; +} + +void CGUITreeViewNode::setIcon( const wchar_t* icon ) +{ + Icon = icon; +} + +void CGUITreeViewNode::clearChildren() +{ + core::list::Iterator it; + + for( it = Children.begin(); it != Children.end(); it++ ) + { + ( *it )->drop(); + } + Children.clear(); +} + +IGUITreeViewNode* CGUITreeViewNode::addChildBack( + const wchar_t* text, + const wchar_t* icon /*= 0*/, + s32 imageIndex /*= -1*/, + s32 selectedImageIndex /*= -1*/, + void* data /*= 0*/, + IReferenceCounted* data2 /*= 0*/ ) +{ + CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this ); + + Children.push_back( newChild ); + newChild->Text = text; + newChild->Icon = icon; + newChild->ImageIndex = imageIndex; + newChild->SelectedImageIndex = selectedImageIndex; + newChild->Data = data; + newChild->Data2 = data2; + if( data2 ) + { + data2->grab(); + } + return newChild; +} + +IGUITreeViewNode* CGUITreeViewNode::addChildFront( + const wchar_t* text, + const wchar_t* icon /*= 0*/, + s32 imageIndex /*= -1*/, + s32 selectedImageIndex /*= -1*/, + void* data /*= 0*/, + IReferenceCounted* data2 /*= 0*/ ) +{ + CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this ); + + Children.push_front( newChild ); + newChild->Text = text; + newChild->Icon = icon; + newChild->ImageIndex = imageIndex; + newChild->SelectedImageIndex = selectedImageIndex; + newChild->Data = data; + newChild->Data2 = data2; + if( data2 ) + { + data2->grab(); + } + return newChild; +} + +IGUITreeViewNode* CGUITreeViewNode::insertChildAfter( + IGUITreeViewNode* other, + const wchar_t* text, + const wchar_t* icon /*= 0*/, + s32 imageIndex /*= -1*/, + s32 selectedImageIndex /*= -1*/, + void* data /*= 0*/, + IReferenceCounted* data2/* = 0*/ ) +{ + core::list::Iterator itOther; + CGUITreeViewNode* newChild = 0; + + for( itOther = Children.begin(); itOther != Children.end(); itOther++ ) + { + if( other == *itOther ) + { + newChild = new CGUITreeViewNode( Owner, this ); + newChild->Text = text; + newChild->Icon = icon; + newChild->ImageIndex = imageIndex; + newChild->SelectedImageIndex = selectedImageIndex; + newChild->Data = data; + newChild->Data2 = data2; + if( data2 ) + { + data2->grab(); + } + Children.insert_after( itOther, newChild ); + break; + } + } + return newChild; +} + +IGUITreeViewNode* CGUITreeViewNode::insertChildBefore( + IGUITreeViewNode* other, + const wchar_t* text, + const wchar_t* icon /*= 0*/, + s32 imageIndex /*= -1*/, + s32 selectedImageIndex /*= -1*/, + void* data /*= 0*/, + IReferenceCounted* data2/* = 0*/ ) +{ + core::list::Iterator itOther; + CGUITreeViewNode* newChild = 0; + + for( itOther = Children.begin(); itOther != Children.end(); itOther++ ) + { + if( other == *itOther ) + { + newChild = new CGUITreeViewNode( Owner, this ); + newChild->Text = text; + newChild->Icon = icon; + newChild->ImageIndex = imageIndex; + newChild->SelectedImageIndex = selectedImageIndex; + newChild->Data = data; + newChild->Data2 = data2; + if( data2 ) + { + data2->grab(); + } + Children.insert_before( itOther, newChild ); + break; + } + } + return newChild; +} + +IGUITreeViewNode* CGUITreeViewNode::getFirstChild() const +{ + if( Children.empty() ) + { + return 0; + } + else + { + return *( Children.begin() ); + } +} + +IGUITreeViewNode* CGUITreeViewNode::getLastChild() const +{ + if( Children.empty() ) + { + return 0; + } + else + { + return *( Children.getLast() ); + } +} + +IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const +{ + core::list::Iterator itThis; + core::list::Iterator itOther; + CGUITreeViewNode* other = 0; + + if( Parent ) + { + for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ ) + { + if( this == *itThis ) + { + if( itThis != Parent->Children.begin() ) + { + other = *itOther; + } + break; + } + itOther = itThis; + } + } + return other; +} + +IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const +{ + core::list::Iterator itThis; + CGUITreeViewNode* other = 0; + + if( Parent ) + { + for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ ) + { + if( this == *itThis ) + { + if( itThis != Parent->Children.getLast() ) + { + other = *( ++itThis ); + } + break; + } + } + } + return other; +} + +IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const +{ + IGUITreeViewNode* next = 0; + IGUITreeViewNode* node = 0; + + node = const_cast( this ); + + if( node->getExpanded() && node->hasChildren() ) + { + next = node->getFirstChild(); + } + else + { + next = node->getNextSibling(); + } + while( !next && node->getParent() ) + { + next = node->getParent()->getNextSibling(); + if( !next ) + { + node = node->getParent(); + } + } + + return next; +} + +bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* child ) +{ + core::list::Iterator itChild; + bool deleted = false; + + for( itChild = Children.begin(); itChild != Children.end(); itChild++ ) + { + if( child == *itChild ) + { + child->drop(); + Children.erase( itChild ); + deleted = true; + break; + } + } + return deleted; +} + +bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* child ) +{ + core::list::Iterator itChild; + core::list::Iterator itOther; + CGUITreeViewNode* nodeTmp; + bool moved = false; + + for( itChild = Children.begin(); itChild != Children.end(); itChild++ ) + { + if( child == *itChild ) + { + if( itChild != Children.begin() ) + { + nodeTmp = *itChild; + *itChild = *itOther; + *itOther = nodeTmp; + moved = true; + } + break; + } + itOther = itChild; + } + return moved; +} + +bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* child ) +{ + core::list::Iterator itChild; + core::list::Iterator itOther; + CGUITreeViewNode* nodeTmp; + bool moved = false; + + for( itChild = Children.begin(); itChild != Children.end(); itChild++ ) + { + if( child == *itChild ) + { + if( itChild != Children.getLast() ) + { + itOther = itChild; + ++itOther; + nodeTmp = *itChild; + *itChild = *itOther; + *itOther = nodeTmp; + moved = true; + } + break; + } + } + return moved; +} + +void CGUITreeViewNode::setExpanded( bool expanded ) +{ + Expanded = expanded; +} + +void CGUITreeViewNode::setSelected( bool selected ) +{ + if( Owner ) + { + if( selected ) + { + Owner->Selected = this; + } + else + { + if( Owner->Selected == this ) + { + Owner->Selected = 0; + } + } + } +} + +bool CGUITreeViewNode::getSelected() const +{ + if( Owner ) + { + return Owner->Selected == (IGUITreeViewNode*)this; + } + else + { + return false; + } +} + +bool CGUITreeViewNode::isRoot() const +{ + return ( Owner && ( this == Owner->Root ) ); +} + +s32 CGUITreeViewNode::getLevel() const +{ + if( Parent ) + { + return Parent->getLevel() + 1; + } + else + { + return 0; + } +} + +bool CGUITreeViewNode::isVisible() const +{ + if( Parent ) + { + return Parent->getExpanded() && Parent->isVisible(); + } + else + { + return true; + } +} + + +//! constructor +CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip, + bool drawBack,bool scrollBarVertical, bool scrollBarHorizontal) + : IGUITreeView( environment, parent, id, rectangle ), + Root(0), Selected(0), + ItemHeight( 0 ), + IndentWidth( 0 ), + TotalItemHeight( 0 ), + TotalItemWidth ( 0 ), + Font( 0 ), + IconFont( 0 ), + ScrollBarH( 0 ), + ScrollBarV( 0 ), + ImageList( 0 ), + LastEventNode( 0 ), + LinesVisible( true ), + Selecting( false ), + Clip( clip ), + DrawBack( drawBack ), + ImageLeftOfIcon( true ) +{ +#ifdef _DEBUG + setDebugName( "CGUITreeView" ); +#endif + + IGUISkin* skin = Environment->getSkin(); + s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE ); + + if ( scrollBarVertical ) + { + ScrollBarV = new CGUIScrollBar( false, Environment, this, 0, + core::rect( RelativeRect.getWidth() - s, + 0, + RelativeRect.getWidth(), + RelativeRect.getHeight() - (scrollBarHorizontal ? s : 0 ) + ), + !clip ); + ScrollBarV->drop(); + + ScrollBarV->setSubElement(true); + ScrollBarV->setPos( 0 ); + ScrollBarV->grab(); + } + + if ( scrollBarHorizontal ) + { + ScrollBarH = new CGUIScrollBar( true, Environment, this, 1, + core::rect( 0, RelativeRect.getHeight() - s, RelativeRect.getWidth() - s, RelativeRect.getHeight() ), + !clip ); + ScrollBarH->drop(); + + ScrollBarH->setSubElement(true); + ScrollBarH->setPos( 0 ); + ScrollBarH->grab(); + } + + Root = new CGUITreeViewNode( this, 0 ); + Root->Expanded = true; + + recalculateItemHeight(); +} + + +//! destructor +CGUITreeView::~CGUITreeView() +{ + if( ScrollBarV ) + { + ScrollBarV->drop(); + } + + if( ScrollBarH ) + { + ScrollBarH->drop(); + } + + if( Font ) + { + Font->drop(); + } + + if( IconFont ) + { + IconFont->drop(); + } + + if( ImageList ) + { + ImageList->drop(); + } + + if( Root ) + { + Root->drop(); + } +} + +void CGUITreeView::recalculateItemHeight() +{ + IGUISkin* skin = Environment->getSkin(); + IGUITreeViewNode* node; + + if( Font != skin->getFont() ) + { + if( Font ) + { + Font->drop(); + } + + Font = skin->getFont(); + ItemHeight = 0; + + if( Font ) + { + ItemHeight = Font->getDimension( L"A" ).Height + 4; + Font->grab(); + } + + if( IconFont ) + { + s32 height = IconFont->getDimension( L" " ).Height; + if( height > ItemHeight ) + { + ItemHeight = height; + } + } + if( ImageList ) + { + if( ImageList->getImageSize().Height + 1 > ItemHeight ) + { + ItemHeight = ImageList->getImageSize().Height + 1; + } + } + } + + IndentWidth = ItemHeight; + if( IndentWidth < 9 ) + { + IndentWidth = 9; + } + else if( IndentWidth > 15 ) + { + IndentWidth = 15; + } + else + { + if( ( ( IndentWidth >> 1 ) << 1 ) - IndentWidth == 0 ) + { + --IndentWidth; + } + } + + TotalItemHeight = 0; + TotalItemWidth = AbsoluteRect.getWidth() * 2; + node = Root->getFirstChild(); + while( node ) + { + TotalItemHeight += ItemHeight; + node = node->getNextVisible(); + } + + if ( ScrollBarV ) + ScrollBarV->setMax( core::max_(0,TotalItemHeight - AbsoluteRect.getHeight()) ); + + if ( ScrollBarH ) + ScrollBarH->setMax( core::max_(0, TotalItemWidth - AbsoluteRect.getWidth()) ); + +} + +//! called if an event happened. +bool CGUITreeView::OnEvent( const SEvent &event ) +{ + if ( isEnabled() ) + { + switch( event.EventType ) + { + case EET_GUI_EVENT: + switch( event.GUIEvent.EventType ) + { + case gui::EGET_SCROLL_BAR_CHANGED: + if( event.GUIEvent.Caller == ScrollBarV || event.GUIEvent.Caller == ScrollBarH ) + { + //s32 pos = ( ( gui::IGUIScrollBar* )event.GUIEvent.Caller )->getPos(); + return true; + } + break; + case gui::EGET_ELEMENT_FOCUS_LOST: + { + Selecting = false; + return false; + } + break; + default: + break; + } + break; + case EET_MOUSE_INPUT_EVENT: + { + core::position2d p( event.MouseInput.X, event.MouseInput.Y ); + + switch( event.MouseInput.Event ) + { + case EMIE_MOUSE_WHEEL: + if ( ScrollBarV ) + ScrollBarV->setPos( ScrollBarV->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1) * -10 ); + return true; + break; + + case EMIE_LMOUSE_PRESSED_DOWN: + + if (Environment->hasFocus(this) && !AbsoluteClippingRect.isPointInside(p) ) + { + Environment->removeFocus(this); + return false; + } + + if( Environment->hasFocus( this ) && + ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) || + ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) ) + ) + ) + { + return true; + } + + Selecting = true; + Environment->setFocus( this ); + return true; + break; + + case EMIE_LMOUSE_LEFT_UP: + if( Environment->hasFocus( this ) && + ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) || + ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) ) + ) + ) + { + return true; + } + + Selecting = false; + Environment->removeFocus( this ); + mouseAction( event.MouseInput.X, event.MouseInput.Y ); + return true; + break; + + case EMIE_MOUSE_MOVED: + if( Selecting ) + { + if( getAbsolutePosition().isPointInside( p ) ) + { + mouseAction( event.MouseInput.X, event.MouseInput.Y, true ); + return true; + } + } + break; + default: + break; + } + } + break; + default: + break; + } + } + + return Parent ? Parent->OnEvent( event ) : false; +} + +/*! +*/ +void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ ) +{ + IGUITreeViewNode* oldSelected = Selected; + IGUITreeViewNode* hitNode = 0; + s32 selIdx=-1; + s32 n; + IGUITreeViewNode* node; + SEvent event; + + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + + xpos -= AbsoluteRect.UpperLeftCorner.X; + ypos -= AbsoluteRect.UpperLeftCorner.Y; + + // find new selected item. + if( ItemHeight != 0 && ScrollBarV ) + { + selIdx = ( ( ypos - 1 ) + ScrollBarV->getPos() ) / ItemHeight; + } + + hitNode = 0; + node = Root->getFirstChild(); + n = 0; + while( node ) + { + if( selIdx == n ) + { + hitNode = node; + break; + } + node = node->getNextVisible(); + ++n; + } + + if( hitNode && xpos > hitNode->getLevel() * IndentWidth ) + { + Selected = hitNode; + } + + if( hitNode && !onlyHover + && xpos < hitNode->getLevel() * IndentWidth + && xpos > ( hitNode->getLevel() - 1 ) * IndentWidth + && hitNode->hasChildren() ) + { + hitNode->setExpanded( !hitNode->getExpanded() ); + + // post expand/collaps news + if( hitNode->getExpanded() ) + { + event.GUIEvent.EventType = EGET_TREEVIEW_NODE_EXPAND; + } + else + { + event.GUIEvent.EventType = EGET_TREEVIEW_NODE_COLLAPS; + } + LastEventNode = hitNode; + Parent->OnEvent( event ); + LastEventNode = 0; + } + + if( Selected && !Selected->isVisible() ) + { + Selected = 0; + } + + // post selection news + + if( Parent && !onlyHover && Selected != oldSelected ) + { + if( oldSelected ) + { + event.GUIEvent.EventType = EGET_TREEVIEW_NODE_DESELECT; + LastEventNode = oldSelected; + Parent->OnEvent( event ); + LastEventNode = 0; + } + if( Selected ) + { + event.GUIEvent.EventType = EGET_TREEVIEW_NODE_SELECT; + LastEventNode = Selected; + Parent->OnEvent( event ); + LastEventNode = 0; + } + } +} + + +//! draws the element and its children +void CGUITreeView::draw() +{ + if( !IsVisible ) + { + return; + } + + recalculateItemHeight(); // if the font changed + + IGUISkin* skin = Environment->getSkin(); + irr::video::IVideoDriver* driver = Environment->getVideoDriver(); + + core::rect* clipRect = 0; + if( Clip ) + { + clipRect = &AbsoluteClippingRect; + } + + // draw background + core::rect frameRect( AbsoluteRect ); + + if( DrawBack ) + { + driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, + clipRect ); + } + + // draw the border + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect, + clipRect ); + + frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect, + clipRect ); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, + clipRect ); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1; + frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; + driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, + clipRect ); + + + // draw items + + core::rect clientClip( AbsoluteRect ); + clientClip.UpperLeftCorner.Y += 1; + clientClip.UpperLeftCorner.X += 1; + clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; + clientClip.LowerRightCorner.Y -= 1; + + if ( ScrollBarV ) + clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE ); + if ( ScrollBarH ) + clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE ); + + if( clipRect ) + { + clientClip.clipAgainst( *clipRect ); + } + + frameRect = AbsoluteRect; + frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE ); + frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; + + if ( ScrollBarV ) + { + frameRect.UpperLeftCorner.Y -= ScrollBarV->getPos(); + frameRect.LowerRightCorner.Y -= ScrollBarV->getPos(); + } + + if ( ScrollBarH ) + { + frameRect.UpperLeftCorner.X -= ScrollBarH->getPos(); + frameRect.LowerRightCorner.X -= ScrollBarH->getPos(); + } + + IGUITreeViewNode* node = Root->getFirstChild(); + while( node ) + { + frameRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + 1 + node->getLevel() * IndentWidth; + + if( frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y + && frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y ) + { + if( node == Selected ) + { + driver->draw2DRectangle( skin->getColor( EGDC_HIGH_LIGHT ), frameRect, &clientClip ); + } + + if( node->hasChildren() ) + { + core::rect rc; + core::rect expanderRect; + + expanderRect.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth + 2; + expanderRect.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() - ( IndentWidth - 4 ) ) >> 1 ); + expanderRect.LowerRightCorner.X = expanderRect.UpperLeftCorner.X + IndentWidth - 4; + expanderRect.LowerRightCorner.Y = expanderRect.UpperLeftCorner.Y + IndentWidth - 4; + + // box upper line + rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X; + rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y; + rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X; + rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + + // box left line + rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X; + rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y; + rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; + rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + + // box right line + rc.UpperLeftCorner.X = expanderRect.LowerRightCorner.X - 1; + rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y; + rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; + rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + + // box bottom line + rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X; + rc.UpperLeftCorner.Y = expanderRect.LowerRightCorner.Y - 1; + rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X; + rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + + // horizontal '-' line + rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + 2; + rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + ( expanderRect.getHeight() >> 1 ); + rc.LowerRightCorner.X = rc.UpperLeftCorner.X + expanderRect.getWidth() - 4; + rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; + driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc, + clipRect ); + + if( !node->getExpanded() ) + { + // vertical '+' line + rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + ( expanderRect.getWidth() >> 1 ); + rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + 2; + rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; + rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + expanderRect.getHeight() - 4; + driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc, + clipRect ); + } + } + + core::rect textRect = frameRect; + + if( Font ) + { + EGUI_DEFAULT_COLOR textCol = EGDC_GRAY_TEXT; + if ( isEnabled() ) + textCol = ( node == Selected ) ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT; + + s32 iconWidth = 0; + for( s32 n = 0; n < 2; ++n ) + { + s32 index = node->getImageIndex(); + if( ( ImageList && index >= 0 ) + && ( ( ImageLeftOfIcon && n == 0 ) + || ( !ImageLeftOfIcon && n == 1 ) ) ) + { + index = node->getSelectedImageIndex(); + if( node != Selected || index < 0 ) + { + index = node->getImageIndex(); + } + ImageList->draw( + index, + core::position2d( + textRect.UpperLeftCorner.X, + textRect.UpperLeftCorner.Y + ( ( textRect.getHeight() - ImageList->getImageSize().Height ) >> 1 ) ), + &clientClip ); + iconWidth += ImageList->getImageSize().Width + 3; + textRect.UpperLeftCorner.X += ImageList->getImageSize().Width + 3; + } + else if( ( IconFont && reinterpret_cast( node )->Icon.size() ) + && ( ( ImageLeftOfIcon && n == 1 ) + || ( !ImageLeftOfIcon && n == 0 ) ) ) + { + IconFont->draw( node->getIcon(), textRect, skin->getColor(textCol), false, true, &clientClip ); + iconWidth += IconFont->getDimension( node->getIcon() ).Width + 3; + textRect.UpperLeftCorner.X += IconFont->getDimension( node->getIcon() ).Width + 3; + } + } + + Font->draw( node->getText(), textRect, skin->getColor(textCol), false, true, &clientClip ); + + textRect.UpperLeftCorner.X -= iconWidth; + } + + // draw the lines if neccessary + if( LinesVisible ) + { + core::rect rc; + + // horizontal line + rc.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth - ( IndentWidth >> 1 ) - 1; + rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() ) >> 1 ); + if( node->hasChildren() ) + { + rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - IndentWidth; + } + else + { + rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - 2; + } + rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + + if( node->getParent() != Root ) + { + // vertical line + if( node == node->getParent()->getFirstChild() ) + { + rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( ( frameRect.getHeight() - IndentWidth ) >> 1 ); + } + else + { + rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 ); + } + rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + + // the vertical lines of all parents + IGUITreeViewNode* nodeTmp = node->getParent(); + rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 ); + for( s32 n = 0; n < node->getLevel() - 2; ++n ) + { + rc.UpperLeftCorner.X -= IndentWidth; + rc.LowerRightCorner.X -= IndentWidth; + if( nodeTmp != nodeTmp->getParent()->getLastChild() ) + { + driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, + clipRect ); + } + nodeTmp = nodeTmp->getParent(); + } + } + } + } + + frameRect.UpperLeftCorner.Y += ItemHeight; + frameRect.LowerRightCorner.Y += ItemHeight; + + node = node->getNextVisible(); + } + + IGUIElement::draw(); +} + +//! Sets the font which should be used as icon font. This font is set to the Irrlicht engine +//! built-in-font by default. Icons can be displayed in front of every list item. +//! An icon is a string, displayed with the icon font. When using the build-in-font of the +//! Irrlicht engine as icon font, the icon strings defined in GUIIcons.h can be used. +void CGUITreeView::setIconFont( IGUIFont* font ) +{ + s32 height; + + if ( font ) + font->grab(); + if ( IconFont ) + { + IconFont->drop(); + } + + IconFont = font; + if( IconFont ) + { + height = IconFont->getDimension( L" " ).Height; + if( height > ItemHeight ) + { + ItemHeight = height; + } + } +} + +//! Sets the image list which should be used for the image and selected image of every node. +//! The default is 0 (no images). +void CGUITreeView::setImageList( IGUIImageList* imageList ) +{ + if (imageList ) + imageList->grab(); + if( ImageList ) + { + ImageList->drop(); + } + + ImageList = imageList; + if( ImageList ) + { + if( ImageList->getImageSize().Height + 1 > ItemHeight ) + { + ItemHeight = ImageList->getImageSize().Height + 1; + } + } +} + +} // end namespace gui +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_GUI_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.d new file mode 100644 index 0000000..99cf790 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.d @@ -0,0 +1,19 @@ +CGUITreeView.o: CGUITreeView.cpp CGUITreeView.h \ + ../../include/IGUITreeView.h ../../include/IGUIElement.h \ + ../../include/IAttributeExchangingObject.h \ + ../../include/IReferenceCounted.h ../../include/irrTypes.h \ + ../../include/IrrCompileConfig.h ../../include/irrList.h \ + ../../include/irrAllocator.h ../../include/irrMath.h \ + ../../include/rect.h ../../include/dimension2d.h \ + ../../include/position2d.h ../../include/vector2d.h \ + ../../include/irrString.h ../../include/IEventReceiver.h \ + ../../include/ILogger.h ../../include/Keycodes.h \ + ../../include/EGUIElementTypes.h ../../include/EGUIAlignment.h \ + ../../include/IAttributes.h ../../include/SColor.h \ + ../../include/vector3d.h ../../include/line2d.h ../../include/line3d.h \ + ../../include/triangle3d.h ../../include/plane3d.h \ + ../../include/aabbox3d.h ../../include/matrix4.h \ + ../../include/quaternion.h ../../include/irrArray.h \ + ../../include/heapsort.h ../../include/IXMLReader.h \ + ../../include/irrXML.h ../../include/EAttributes.h ../../include/path.h \ + ../../include/IGUIImageList.h ../../include/irrList.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.h new file mode 100644 index 0000000..36b0280 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.h @@ -0,0 +1,331 @@ +// This file is part of the "Irrlicht Engine". +// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de + +#ifndef __C_GUI_TREE_VIEW_H_INCLUDED__ +#define __C_GUI_TREE_VIEW_H_INCLUDED__ + +#include "IGUITreeView.h" +#include "irrList.h" + + +namespace irr +{ +namespace gui +{ + // forward declarations + class IGUIFont; + class IGUIScrollBar; + class CGUITreeView; + + //! Node for gui tree view + class CGUITreeViewNode : public IGUITreeViewNode + { + friend class CGUITreeView; + + public: + //! constructor + CGUITreeViewNode( CGUITreeView* owner, CGUITreeViewNode* parent ); + + //! destructor + ~CGUITreeViewNode(); + + //! returns the owner (tree view) of this node + virtual IGUITreeView* getOwner() const; + + //! Returns the parent node of this node. + virtual IGUITreeViewNode* getParent() const; + + //! returns the text of the node + virtual const wchar_t* getText() const + { return Text.c_str(); } + + //! sets the text of the node + virtual void setText( const wchar_t* text ); + + //! returns the icon text of the node + virtual const wchar_t* getIcon() const + { return Icon.c_str(); } + + //! sets the icon text of the node + virtual void setIcon( const wchar_t* icon ); + + //! returns the image index of the node + virtual u32 getImageIndex() const + { return ImageIndex; } + + //! sets the image index of the node + virtual void setImageIndex( u32 imageIndex ) + { ImageIndex = imageIndex; } + + //! returns the image index of the node + virtual u32 getSelectedImageIndex() const + { return SelectedImageIndex; } + + //! sets the image index of the node + virtual void setSelectedImageIndex( u32 imageIndex ) + { SelectedImageIndex = imageIndex; } + + //! returns the user data (void*) of this node + virtual void* getData() const + { return Data; } + + //! sets the user data (void*) of this node + virtual void setData( void* data ) + { Data = data; } + + //! returns the user data2 (IReferenceCounted) of this node + virtual IReferenceCounted* getData2() const + { return Data2; } + + //! sets the user data2 (IReferenceCounted) of this node + virtual void setData2( IReferenceCounted* data ) + { + if( Data2 ) + { + Data2->drop(); + } + Data2 = data; + if( Data2 ) + { + Data2->grab(); + } + } + + //! returns the child item count + virtual u32 getChildCount() const + { return Children.getSize(); } + + //! removes all children (recursive) from this node + virtual void clearChildren(); + + //! returns true if this node has child nodes + virtual bool hasChildren() const + { return !Children.empty(); } + + //! Adds a new node behind the last child node. + //! \param text text of the new node + //! \param icon icon text of the new node + //! \param imageIndex index of the image for the new node (-1 = none) + //! \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + //! \param data user data (void*) of the new node + //! \param data2 user data2 (IReferenceCounted*) of the new node + //! \return + //! returns the new node + virtual IGUITreeViewNode* addChildBack( + const wchar_t* text, + const wchar_t* icon = 0, + s32 imageIndex = -1, + s32 selectedImageIndex = -1, + void* data = 0, + IReferenceCounted* data2 = 0); + + //! Adds a new node before the first child node. + //! \param text text of the new node + //! \param icon icon text of the new node + //! \param imageIndex index of the image for the new node (-1 = none) + //! \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + //! \param data user data (void*) of the new node + //! \param data2 user data2 (IReferenceCounted*) of the new node + //! \return + //! returns the new node + virtual IGUITreeViewNode* addChildFront( + const wchar_t* text, + const wchar_t* icon = 0, + s32 imageIndex = -1, + s32 selectedImageIndex = -1, + void* data = 0, + IReferenceCounted* data2 = 0 ); + + //! Adds a new node behind the other node. + //! The other node has also te be a child node from this node. + //! \param text text of the new node + //! \param icon icon text of the new node + //! \param imageIndex index of the image for the new node (-1 = none) + //! \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + //! \param data user data (void*) of the new node + //! \param data2 user data2 (IReferenceCounted*) of the new node + //! \return + //! returns the new node or 0 if other is no child node from this + virtual IGUITreeViewNode* insertChildAfter( + IGUITreeViewNode* other, + const wchar_t* text, + const wchar_t* icon = 0, + s32 imageIndex = -1, + s32 selectedImageIndex = -1, + void* data = 0, + IReferenceCounted* data2 = 0 ); + + //! Adds a new node before the other node. + //! The other node has also te be a child node from this node. + //! \param text text of the new node + //! \param icon icon text of the new node + //! \param imageIndex index of the image for the new node (-1 = none) + //! \param selectedImageIndex index of the selected image for the new node (-1 = same as imageIndex) + //! \param data user data (void*) of the new node + //! \param data2 user data2 (IReferenceCounted*) of the new node + //! \return + //! returns the new node or 0 if other is no child node from this + virtual IGUITreeViewNode* insertChildBefore( + IGUITreeViewNode* other, + const wchar_t* text, + const wchar_t* icon = 0, + s32 imageIndex = -1, + s32 selectedImageIndex = -1, + void* data = 0, + IReferenceCounted* data2 = 0 ); + + //! Return the first child note from this node. + virtual IGUITreeViewNode* getFirstChild() const; + + //! Return the last child note from this node. + virtual IGUITreeViewNode* getLastChild() const; + + //! Returns the preverse sibling node from this node. + virtual IGUITreeViewNode* getPrevSibling() const; + + //! Returns the next sibling node from this node. + virtual IGUITreeViewNode* getNextSibling() const; + + //! Returns the next visible (expanded, may be out of scrolling) node from this node. + virtual IGUITreeViewNode* getNextVisible() const; + + //! Deletes a child node. + virtual bool deleteChild( IGUITreeViewNode* child ); + + //! Moves a child node one position up. + virtual bool moveChildUp( IGUITreeViewNode* child ); + + //! Moves a child node one position down. + virtual bool moveChildDown( IGUITreeViewNode* child ); + + //! Returns true if the node is expanded (children are visible). + virtual bool getExpanded() const + { return Expanded; } + + //! Sets if the node is expanded. + virtual void setExpanded( bool expanded ); + + //! Returns true if the node is currently selected. + virtual bool getSelected() const; + + //! Sets this node as selected. + virtual void setSelected( bool selected ); + + //! Returns true if this node is the root node. + virtual bool isRoot() const; + + //! Returns the level of this node. + virtual s32 getLevel() const; + + //! Returns true if this node is visible (all parents are expanded). + virtual bool isVisible() const; + + private: + + CGUITreeView* Owner; + CGUITreeViewNode* Parent; + core::stringw Text; + core::stringw Icon; + s32 ImageIndex; + s32 SelectedImageIndex; + void* Data; + IReferenceCounted* Data2; + bool Expanded; + core::list Children; + }; + + + //! Default tree view GUI element. + class CGUITreeView : public IGUITreeView + { + friend class CGUITreeViewNode; + + public: + //! constructor + CGUITreeView( IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip = true, + bool drawBack = false, bool scrollBarVertical = true, bool scrollBarHorizontal = true ); + + //! destructor + virtual ~CGUITreeView(); + + //! returns the root node (not visible) from the tree. + virtual IGUITreeViewNode* getRoot() const + { return Root; } + + //! returns the selected node of the tree or 0 if none is selected + virtual IGUITreeViewNode* getSelected() const + { return Selected; } + + //! returns true if the tree lines are visible + virtual bool getLinesVisible() const + { return LinesVisible; } + + //! sets if the tree lines are visible + virtual void setLinesVisible( bool visible ) + { LinesVisible = visible; } + + //! called if an event happened. + virtual bool OnEvent( const SEvent &event ); + + //! draws the element and its children + virtual void draw(); + + //! Sets the font which should be used as icon font. This font is set to the Irrlicht engine + //! built-in-font by default. Icons can be displayed in front of every list item. + //! An icon is a string, displayed with the icon font. When using the build-in-font of the + //! Irrlicht engine as icon font, the icon strings defined in GUIIcons.h can be used. + virtual void setIconFont( IGUIFont* font ); + + //! Sets the image list which should be used for the image and selected image of every node. + //! The default is 0 (no images). + virtual void setImageList( IGUIImageList* imageList ); + + //! Returns the image list which is used for the nodes. + virtual IGUIImageList* getImageList() const + { return ImageList; } + + //! Sets if the image is left of the icon. Default is true. + virtual void setImageLeftOfIcon( bool bLeftOf ) + { ImageLeftOfIcon = bLeftOf; } + + //! Returns if the Image is left of the icon. Default is true. + virtual bool getImageLeftOfIcon() const + { return ImageLeftOfIcon; } + + //! Returns the node which is associated to the last event. + virtual IGUITreeViewNode* getLastEventNode() const + { return LastEventNode; } + + private: + //! calculates the heigth of an node and of all visible nodes. + void recalculateItemHeight(); + + //! executes an mouse action (like selectNew of CGUIListBox) + void mouseAction( s32 xpos, s32 ypos, bool onlyHover = false ); + + CGUITreeViewNode* Root; + IGUITreeViewNode* Selected; + s32 ItemHeight; + s32 IndentWidth; + s32 TotalItemHeight; + s32 TotalItemWidth; + IGUIFont* Font; + IGUIFont* IconFont; + IGUIScrollBar* ScrollBarH; + IGUIScrollBar* ScrollBarV; + IGUIImageList* ImageList; + IGUITreeViewNode* LastEventNode; + bool LinesVisible; + bool Selecting; + bool Clip; + bool DrawBack; + bool ImageLeftOfIcon; + }; + + +} // end namespace gui +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.cpp new file mode 100644 index 0000000..9769750 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.cpp @@ -0,0 +1,404 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGUIWindow.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIButton.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) +: IGUIWindow(environment, parent, id, rectangle), Dragging(false), IsDraggable(true), DrawBackground(true), DrawTitlebar(true), IsActive(false) +{ + #ifdef _DEBUG + setDebugName("CGUIWindow"); + #endif + + IGUISkin* skin = 0; + if (environment) + skin = environment->getSkin(); + + CurrentIconColor = video::SColor(255,255,255,255); + + s32 buttonw = 15; + if (skin) + { + buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH); + } + s32 posx = RelativeRect.getWidth() - buttonw - 4; + + CloseButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" ); + CloseButton->setSubElement(true); + CloseButton->setTabStop(false); + CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + posx -= buttonw + 2; + + RestoreButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_RESTORE) : L"Restore" ); + RestoreButton->setVisible(false); + RestoreButton->setSubElement(true); + RestoreButton->setTabStop(false); + RestoreButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + posx -= buttonw + 2; + + MinButton = Environment->addButton(core::rect(posx, 3, posx + buttonw, 3 + buttonw), this, -1, + L"", skin ? skin->getDefaultText(EGDT_WINDOW_MINIMIZE) : L"Minimize" ); + MinButton->setVisible(false); + MinButton->setSubElement(true); + MinButton->setTabStop(false); + MinButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT); + + MinButton->grab(); + RestoreButton->grab(); + CloseButton->grab(); + + // this element is a tab group + setTabGroup(true); + setTabStop(true); + setTabOrder(-1); + + refreshSprites(); + updateClientRect(); +} + + +//! destructor +CGUIWindow::~CGUIWindow() +{ + if (MinButton) + MinButton->drop(); + + if (RestoreButton) + RestoreButton->drop(); + + if (CloseButton) + CloseButton->drop(); +} + +void CGUIWindow::refreshSprites() +{ + if (!Environment) + return; + IGUISkin* skin = Environment->getSkin(); + if ( !skin ) + return; + + IGUISpriteBank* sprites = skin->getSpriteBank(); + if ( !sprites ) + return; + + CurrentIconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); + + if (sprites) + { + CloseButton->setSpriteBank(sprites); + CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), CurrentIconColor); + CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), CurrentIconColor); + + RestoreButton->setSpriteBank(sprites); + RestoreButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESTORE), CurrentIconColor); + RestoreButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESTORE), CurrentIconColor); + + MinButton->setSpriteBank(sprites); + MinButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_MINIMIZE), CurrentIconColor); + MinButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_MINIMIZE), CurrentIconColor); + } +} + +//! called if an event happened. +bool CGUIWindow::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + + switch(event.EventType) + { + case EET_GUI_EVENT: + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) + { + Dragging = false; + IsActive = false; + } + else + if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED) + { + if (Parent && ((event.GUIEvent.Caller == this) || isMyChild(event.GUIEvent.Caller))) + { + Parent->bringToFront(this); + IsActive = true; + } + else + { + IsActive = false; + } + } + else + if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + if (event.GUIEvent.Caller == CloseButton) + { + if (Parent) + { + // send close event to parent + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_ELEMENT_CLOSED; + + // if the event was not absorbed + if (!Parent->OnEvent(e)) + remove(); + + return true; + + } + else + { + remove(); + return true; + } + } + } + break; + case EET_MOUSE_INPUT_EVENT: + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + Dragging = IsDraggable; + if (Parent) + Parent->bringToFront(this); + return true; + case EMIE_LMOUSE_LEFT_UP: + Dragging = false; + return true; + case EMIE_MOUSE_MOVED: + if (!event.MouseInput.isLeftPressed()) + Dragging = false; + + if (Dragging) + { + // gui window should not be dragged outside its parent + if (Parent && + (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 || + event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 || + event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 || + event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)) + return true; + + move(core::position2d(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y)); + DragStart.X = event.MouseInput.X; + DragStart.Y = event.MouseInput.Y; + return true; + } + break; + default: + break; + } + default: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +//! Updates the absolute position. +void CGUIWindow::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); +} + + +//! draws the element and its children +void CGUIWindow::draw() +{ + if (IsVisible) + { + IGUISkin* skin = Environment->getSkin(); + + + // update each time because the skin is allowed to change this always. + updateClientRect(); + + if ( CurrentIconColor != skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL) ) + refreshSprites(); + + core::rect rect = AbsoluteRect; + + // draw body fast + if (DrawBackground) + { + rect = skin->draw3DWindowBackground(this, DrawTitlebar, + skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER), + AbsoluteRect, &AbsoluteClippingRect); + + if (DrawTitlebar && Text.size()) + { + rect.UpperLeftCorner.X += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_X); + rect.UpperLeftCorner.Y += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_Y); + rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5; + + IGUIFont* font = skin->getFont(EGDF_WINDOW); + if (font) + { + font->draw(Text.c_str(), rect, + skin->getColor(IsActive ? EGDC_ACTIVE_CAPTION:EGDC_INACTIVE_CAPTION), + false, true, &AbsoluteClippingRect); + } + } + } + } + + IGUIElement::draw(); +} + + +//! Returns pointer to the close button +IGUIButton* CGUIWindow::getCloseButton() const +{ + return CloseButton; +} + + +//! Returns pointer to the minimize button +IGUIButton* CGUIWindow::getMinimizeButton() const +{ + return MinButton; +} + + +//! Returns pointer to the maximize button +IGUIButton* CGUIWindow::getMaximizeButton() const +{ + return RestoreButton; +} + + +//! Returns true if the window is draggable, false if not +bool CGUIWindow::isDraggable() const +{ + return IsDraggable; +} + + +//! Sets whether the window is draggable +void CGUIWindow::setDraggable(bool draggable) +{ + IsDraggable = draggable; + + if (Dragging && !IsDraggable) + Dragging = false; +} + + +//! Set if the window background will be drawn +void CGUIWindow::setDrawBackground(bool draw) +{ + DrawBackground = draw; +} + + +//! Get if the window background will be drawn +bool CGUIWindow::getDrawBackground() const +{ + return DrawBackground; +} + + +//! Set if the window titlebar will be drawn +void CGUIWindow::setDrawTitlebar(bool draw) +{ + DrawTitlebar = draw; +} + + +//! Get if the window titlebar will be drawn +bool CGUIWindow::getDrawTitlebar() const +{ + return DrawTitlebar; +} + + +void CGUIWindow::updateClientRect() +{ + if (! DrawBackground ) + { + ClientRect = core::rect(0,0, AbsoluteRect.getWidth(), AbsoluteRect.getHeight()); + return; + } + IGUISkin* skin = Environment->getSkin(); + skin->draw3DWindowBackground(this, DrawTitlebar, + skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER), + AbsoluteRect, &AbsoluteClippingRect, &ClientRect); + ClientRect -= AbsoluteRect.UpperLeftCorner; +} + + +//! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars) +core::rect CGUIWindow::getClientRect() const +{ + return ClientRect; +} + + +//! Writes attributes of the element. +void CGUIWindow::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const +{ + IGUIWindow::serializeAttributes(out,options); + + out->addBool("IsDraggable", IsDraggable); + out->addBool("DrawBackground", DrawBackground); + out->addBool("DrawTitlebar", DrawTitlebar); + + // Currently we can't just serialize attributes of sub-elements. + // To do this we either + // a) allow further serialization after attribute serialiation (second function, callback or event) + // b) add an IGUIElement attribute + // c) extend the attribute system to allow attributes to have sub-attributes + // We just serialize the most important info for now until we can do one of the above solutions. + out->addBool("IsCloseVisible", CloseButton->isVisible()); + out->addBool("IsMinVisible", MinButton->isVisible()); + out->addBool("IsRestoreVisible", RestoreButton->isVisible()); +} + + +//! Reads attributes of the element +void CGUIWindow::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) +{ +IGUIWindow::deserializeAttributes(in,options); + + Dragging = false; + IsActive = false; + IsDraggable = in->getAttributeAsBool("IsDraggable"); + DrawBackground = in->getAttributeAsBool("DrawBackground"); + DrawTitlebar = in->getAttributeAsBool("DrawTitlebar"); + + CloseButton->setVisible(in->getAttributeAsBool("IsCloseVisible")); + MinButton->setVisible(in->getAttributeAsBool("IsMinVisible")); + RestoreButton->setVisible(in->getAttributeAsBool("IsRestoreVisible")); + + updateClientRect(); +} + + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.d b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.d new file mode 100644 index 0000000..de3a6d4 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.d @@ -0,0 +1,2 @@ +CGUIWindow.o: CGUIWindow.cpp CGUIWindow.h \ + ../../include/IrrCompileConfig.h diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.h new file mode 100644 index 0000000..980da59 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIWindow.h @@ -0,0 +1,99 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GUI_WINDOW_H_INCLUDED__ +#define __C_GUI_WINDOW_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_GUI_ + +#include "IGUIWindow.h" + +namespace irr +{ +namespace gui +{ + class IGUIButton; + + class CGUIWindow : public IGUIWindow + { + public: + + //! constructor + CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle); + + //! destructor + virtual ~CGUIWindow(); + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! update absolute position + virtual void updateAbsolutePosition(); + + //! draws the element and its children + virtual void draw(); + + //! Returns pointer to the close button + virtual IGUIButton* getCloseButton() const; + + //! Returns pointer to the minimize button + virtual IGUIButton* getMinimizeButton() const; + + //! Returns pointer to the maximize button + virtual IGUIButton* getMaximizeButton() const; + + //! Returns true if the window is draggable, false if not + virtual bool isDraggable() const; + + //! Sets whether the window is draggable + virtual void setDraggable(bool draggable); + + //! Set if the window background will be drawn + virtual void setDrawBackground(bool draw); + + //! Get if the window background will be drawn + virtual bool getDrawBackground() const; + + //! Set if the window titlebar will be drawn + //! Note: If the background is not drawn, then the titlebar is automatically also not drawn + virtual void setDrawTitlebar(bool draw); + + //! Get if the window titlebar will be drawn + virtual bool getDrawTitlebar() const; + + //! Returns the rectangle of the drawable area (without border and without titlebar) + virtual core::rect getClientRect() const; + + //! Writes attributes of the element. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the element + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + protected: + + void updateClientRect(); + void refreshSprites(); + + IGUIButton* CloseButton; + IGUIButton* MinButton; + IGUIButton* RestoreButton; + core::rect ClientRect; + video::SColor CurrentIconColor; + + core::position2d DragStart; + bool Dragging, IsDraggable; + bool DrawBackground; + bool DrawTitlebar; + bool IsActive; + }; + +} // end namespace gui +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_GUI_ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.cpp new file mode 100644 index 0000000..c592833 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.cpp @@ -0,0 +1,892 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CGeometryCreator.h" +#include "SAnimatedMesh.h" +#include "SMeshBuffer.h" +#include "SMesh.h" +#include "IMesh.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +IMesh* CGeometryCreator::createCubeMesh(const core::vector3df& size) const +{ + SMeshBuffer* buffer = new SMeshBuffer(); + + // Create indices + const u16 u[36] = { 0,2,1, 0,3,2, 1,5,4, 1,2,5, 4,6,7, 4,5,6, + 7,3,0, 7,6,3, 9,5,2, 9,8,5, 0,11,10, 0,10,7}; + + buffer->Indices.set_used(36); + + for (u32 i=0; i<36; ++i) + buffer->Indices[i] = u[i]; + + + // Create vertices + video::SColor clr(255,255,255,255); + + buffer->Vertices.reallocate(12); + + buffer->Vertices.push_back(video::S3DVertex(0,0,0, -1,-1,-1, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1,-1,-1, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,1,0, 1, 1,-1, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 1,-1, clr, 0, 0)); + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1,-1, 1, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,1,1, 1, 1, 1, clr, 0, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 1, 1, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,0,1, -1,-1, 1, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 1, 1, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 1,-1, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1,-1, 1, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1,-1,-1, clr, 0, 0)); + + // Recalculate bounding box + buffer->BoundingBox.reset(0,0,0); + + for (u32 i=0; i<12; ++i) + { + buffer->Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); + buffer->Vertices[i].Pos *= size; + buffer->BoundingBox.addInternalPoint(buffer->Vertices[i].Pos); + } + + SMesh* mesh = new SMesh; + mesh->addMeshBuffer(buffer); + buffer->drop(); + + mesh->recalculateBoundingBox(); + return mesh; +} + + +// creates a hill plane +IMesh* CGeometryCreator::createHillPlaneMesh( + const core::dimension2d& tileSize, + const core::dimension2d& tc, video::SMaterial* material, + f32 hillHeight, const core::dimension2d& ch, + const core::dimension2d& textureRepeatCount) const +{ + core::dimension2d tileCount = tc; + core::dimension2d countHills = ch; + + if (countHills.Width < 0.01f) + countHills.Width = 1.f; + if (countHills.Height < 0.01f) + countHills.Height = 1.f; + + // center + const core::position2d center((tileSize.Width * tileCount.Width) * 0.5f, (tileSize.Height * tileCount.Height) * 0.5f); + + // texture coord step + const core::dimension2d tx( + textureRepeatCount.Width / tileCount.Width, + textureRepeatCount.Height / tileCount.Height); + + // add one more point in each direction for proper tile count + ++tileCount.Height; + ++tileCount.Width; + + SMeshBuffer* buffer = new SMeshBuffer(); + video::S3DVertex vtx; + vtx.Color.set(255,255,255,255); + + // create vertices from left-front to right-back + u32 x; + + f32 sx=0.f, tsx=0.f; + for (x=0; xVertices.push_back(vtx); + sy += tileSize.Height; + tsy += tx.Height; + } + sx += tileSize.Width; + tsx += tx.Width; + } + + // create indices + + for (x=0; xIndices.push_back(current); + buffer->Indices.push_back(current + 1); + buffer->Indices.push_back(current + tileCount.Height); + + buffer->Indices.push_back(current + 1); + buffer->Indices.push_back(current + 1 + tileCount.Height); + buffer->Indices.push_back(current + tileCount.Height); + } + } + + // recalculate normals + for (u32 i=0; iIndices.size(); i+=3) + { + const core::vector3df normal = core::plane3d( + buffer->Vertices[buffer->Indices[i+0]].Pos, + buffer->Vertices[buffer->Indices[i+1]].Pos, + buffer->Vertices[buffer->Indices[i+2]].Pos).Normal; + + buffer->Vertices[buffer->Indices[i+0]].Normal = normal; + buffer->Vertices[buffer->Indices[i+1]].Normal = normal; + buffer->Vertices[buffer->Indices[i+2]].Normal = normal; + } + + if (material) + buffer->Material = *material; + + buffer->recalculateBoundingBox(); + buffer->setHardwareMappingHint(EHM_STATIC); + + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + mesh->recalculateBoundingBox(); + buffer->drop(); + return mesh; +} + + +IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture, + video::IImage* heightmap, const core::dimension2d& stretchSize, + f32 maxHeight, video::IVideoDriver* driver, + const core::dimension2d& maxVtxBlockSize, + bool debugBorders) const +{ + if (!texture || !heightmap) + return 0; + + // debug border + const s32 borderSkip = debugBorders ? 0 : 1; + + video::S3DVertex vtx; + vtx.Color.set(255,255,255,255); + + SMesh* mesh = new SMesh(); + + const u32 tm = os::Timer::getRealTime()/1000; + const core::dimension2d hMapSize= heightmap->getDimension(); + const core::dimension2d tMapSize= texture->getDimension(); + const core::position2d thRel(static_cast(tMapSize.Width) / hMapSize.Width, static_cast(tMapSize.Height) / hMapSize.Height); + maxHeight /= 255.0f; // height step per color value + + core::position2d processed(0,0); + while (processed.Y blockSize = maxVtxBlockSize; + if (processed.X + blockSize.Width > hMapSize.Width) + blockSize.Width = hMapSize.Width - processed.X; + if (processed.Y + blockSize.Height > hMapSize.Height) + blockSize.Height = hMapSize.Height - processed.Y; + + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->setHardwareMappingHint(scene::EHM_STATIC); + buffer->Vertices.reallocate(blockSize.getArea()); + // add vertices of vertex block + u32 y; + core::vector2df pos(0.f, processed.Y*stretchSize.Height); + const core::vector2df bs(1.f/blockSize.Width, 1.f/blockSize.Height); + core::vector2df tc(0.f, 0.5f*bs.Y); + for (y=0; ygetPixel(x+processed.X, y+processed.Y).getAverage() * maxHeight; + + vtx.Pos.set(pos.X, height, pos.Y); + vtx.TCoords.set(tc); + buffer->Vertices.push_back(vtx); + pos.X += stretchSize.Width; + tc.X += bs.X; + } + pos.Y += stretchSize.Height; + tc.Y += bs.Y; + } + + buffer->Indices.reallocate((blockSize.Height-1)*(blockSize.Width-1)*6); + // add indices of vertex block + s32 c1 = 0; + for (y=0; yIndices.push_back(c); + buffer->Indices.push_back(c + blockSize.Width); + buffer->Indices.push_back(c + 1); + + buffer->Indices.push_back(c + 1); + buffer->Indices.push_back(c + blockSize.Width); + buffer->Indices.push_back(c + 1 + blockSize.Width); + } + c1 += blockSize.Width; + } + + // recalculate normals + for (u32 i=0; iIndices.size(); i+=3) + { + const core::vector3df normal = core::plane3d( + buffer->Vertices[buffer->Indices[i+0]].Pos, + buffer->Vertices[buffer->Indices[i+1]].Pos, + buffer->Vertices[buffer->Indices[i+2]].Pos).Normal; + + buffer->Vertices[buffer->Indices[i+0]].Normal = normal; + buffer->Vertices[buffer->Indices[i+1]].Normal = normal; + buffer->Vertices[buffer->Indices[i+2]].Normal = normal; + } + + if (buffer->Vertices.size()) + { + c8 textureName[64]; + // create texture for this block + video::IImage* img = driver->createImage(texture->getColorFormat(), core::dimension2d(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y))); + texture->copyTo(img, core::position2di(0,0), core::recti( + core::position2d(core::floor32(processed.X*thRel.X), core::floor32(processed.Y*thRel.Y)), + core::dimension2d(core::floor32(blockSize.Width*thRel.X), core::floor32(blockSize.Height*thRel.Y))), 0); + + sprintf(textureName, "terrain%u_%u", tm, mesh->getMeshBufferCount()); + + buffer->Material.setTexture(0, driver->addTexture(textureName, img)); + + if (buffer->Material.getTexture(0)) + { + c8 tmp[255]; + sprintf(tmp, "Generated terrain texture (%dx%d): %s", + buffer->Material.getTexture(0)->getSize().Width, + buffer->Material.getTexture(0)->getSize().Height, + textureName); + os::Printer::log(tmp); + } + else + os::Printer::log("Could not create terrain texture.", textureName, ELL_ERROR); + + img->drop(); + } + + buffer->recalculateBoundingBox(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + // keep on processing + processed.X += maxVtxBlockSize.Width - borderSkip; + } + + // keep on processing + processed.X = 0; + processed.Y += maxVtxBlockSize.Height - borderSkip; + } + + mesh->recalculateBoundingBox(); + return mesh; +} + + +/* + a cylinder, a cone and a cross + point up on (0,1.f, 0.f ) +*/ +IMesh* CGeometryCreator::createArrowMesh(const u32 tesselationCylinder, + const u32 tesselationCone, + const f32 height, + const f32 cylinderHeight, + const f32 width0, + const f32 width1, + const video::SColor vtxColor0, + const video::SColor vtxColor1) const +{ + SMesh* mesh = (SMesh*)createCylinderMesh(width0, cylinderHeight, tesselationCylinder, vtxColor0, false); + + IMesh* mesh2 = createConeMesh(width1, height-cylinderHeight, tesselationCone, vtxColor1, vtxColor0); + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh2->getMeshBuffer(i); + for (u32 j=0; jgetVertexCount(); ++j) + buffer->getPosition(j).Y += cylinderHeight; + buffer->setDirty(EBT_VERTEX); + buffer->recalculateBoundingBox(); + mesh->addMeshBuffer(buffer); + } + mesh2->drop(); + mesh->setHardwareMappingHint(EHM_STATIC); + + mesh->recalculateBoundingBox(); + return mesh; +} + + +/* A sphere with proper normals and texture coords */ +IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY) const +{ + // thanks to Alfaz93 who made his code available for Irrlicht on which + // this one is based! + + // we are creating the sphere mesh here. + + if (polyCountX < 2) + polyCountX = 2; + if (polyCountY < 2) + polyCountY = 2; + while (polyCountX * polyCountY > 32767) // prevent u16 overflow + { + polyCountX /= 2; + polyCountY /= 2; + } + + const u32 polyCountXPitch = polyCountX+1; // get to same vertex on next level + + SMeshBuffer* buffer = new SMeshBuffer(); + + buffer->Indices.reallocate((polyCountX * polyCountY) * 6); + + const video::SColor clr(255, 255,255,255); + + u32 level = 0; + + for (u32 p1 = 0; p1 < polyCountY-1; ++p1) + { + //main quads, top to bottom + for (u32 p2 = 0; p2 < polyCountX - 1; ++p2) + { + const u32 curr = level + p2; + buffer->Indices.push_back(curr + polyCountXPitch); + buffer->Indices.push_back(curr); + buffer->Indices.push_back(curr + 1); + buffer->Indices.push_back(curr + polyCountXPitch); + buffer->Indices.push_back(curr+1); + buffer->Indices.push_back(curr + 1 + polyCountXPitch); + } + + // the connectors from front to end + buffer->Indices.push_back(level + polyCountX - 1 + polyCountXPitch); + buffer->Indices.push_back(level + polyCountX - 1); + buffer->Indices.push_back(level + polyCountX); + + buffer->Indices.push_back(level + polyCountX - 1 + polyCountXPitch); + buffer->Indices.push_back(level + polyCountX); + buffer->Indices.push_back(level + polyCountX + polyCountXPitch); + level += polyCountXPitch; + } + + const u32 polyCountSq = polyCountXPitch * polyCountY; // top point + const u32 polyCountSq1 = polyCountSq + 1; // bottom point + const u32 polyCountSqM1 = (polyCountY - 1) * polyCountXPitch; // last row's first vertex + + for (u32 p2 = 0; p2 < polyCountX - 1; ++p2) + { + // create triangles which are at the top of the sphere + + buffer->Indices.push_back(polyCountSq); + buffer->Indices.push_back(p2 + 1); + buffer->Indices.push_back(p2); + + // create triangles which are at the bottom of the sphere + + buffer->Indices.push_back(polyCountSqM1 + p2); + buffer->Indices.push_back(polyCountSqM1 + p2 + 1); + buffer->Indices.push_back(polyCountSq1); + } + + // create final triangle which is at the top of the sphere + + buffer->Indices.push_back(polyCountSq); + buffer->Indices.push_back(polyCountX); + buffer->Indices.push_back(polyCountX-1); + + // create final triangle which is at the bottom of the sphere + + buffer->Indices.push_back(polyCountSqM1 + polyCountX - 1); + buffer->Indices.push_back(polyCountSqM1); + buffer->Indices.push_back(polyCountSq1); + + // calculate the angle which separates all points in a circle + const f64 AngleX = 2 * core::PI / polyCountX; + const f64 AngleY = core::PI / polyCountY; + + u32 i=0; + f64 axz; + + // we don't start at 0. + + f64 ay = 0;//AngleY / 2; + + buffer->Vertices.set_used((polyCountXPitch * polyCountY) + 2); + for (u32 y = 0; y < polyCountY; ++y) + { + ay += AngleY; + const f64 sinay = sin(ay); + axz = 0; + + // calculate the necessary vertices without the doubled one + for (u32 xz = 0;xz < polyCountX; ++xz) + { + // calculate points position + + const core::vector3df pos(static_cast(radius * cos(axz) * sinay), + static_cast(radius * cos(ay)), + static_cast(radius * sin(axz) * sinay)); + // for spheres the normal is the position + core::vector3df normal(pos); + normal.normalize(); + + // calculate texture coordinates via sphere mapping + // tu is the same on each level, so only calculate once + f32 tu = 0.5f; + if (y==0) + { + if (normal.Y != -1.0f && normal.Y != 1.0f) + tu = static_cast(acos(core::clamp(normal.X/sinay, -1.0, 1.0)) * 0.5 *core::RECIPROCAL_PI64); + if (normal.Z < 0.0f) + tu=1-tu; + } + else + tu = buffer->Vertices[i-polyCountXPitch].TCoords.X; + buffer->Vertices[i] = video::S3DVertex(pos.X, pos.Y, pos.Z, + normal.X, normal.Y, normal.Z, + clr, tu, + static_cast(ay*core::RECIPROCAL_PI64)); + ++i; + axz += AngleX; + } + // This is the doubled vertex on the initial position + buffer->Vertices[i] = video::S3DVertex(buffer->Vertices[i-polyCountX]); + buffer->Vertices[i].TCoords.X=1.0f; + ++i; + } + + // the vertex at the top of the sphere + buffer->Vertices[i] = video::S3DVertex(0.0f,radius,0.0f, 0.0f,1.0f,0.0f, clr, 0.5f, 0.0f); + + // the vertex at the bottom of the sphere + ++i; + buffer->Vertices[i] = video::S3DVertex(0.0f,-radius,0.0f, 0.0f,-1.0f,0.0f, clr, 0.5f, 1.0f); + + // recalculate bounding box + + buffer->BoundingBox.reset(buffer->Vertices[i].Pos); + buffer->BoundingBox.addInternalPoint(buffer->Vertices[i-1].Pos); + buffer->BoundingBox.addInternalPoint(radius,0.0f,0.0f); + buffer->BoundingBox.addInternalPoint(-radius,0.0f,0.0f); + buffer->BoundingBox.addInternalPoint(0.0f,0.0f,radius); + buffer->BoundingBox.addInternalPoint(0.0f,0.0f,-radius); + + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + mesh->setHardwareMappingHint(EHM_STATIC); + mesh->recalculateBoundingBox(); + return mesh; +} + + +/* A cylinder with proper normals and texture coords */ +IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, + u32 tesselation, const video::SColor& color, + bool closeTop, f32 oblique) const +{ + SMeshBuffer* buffer = new SMeshBuffer(); + + const f32 recTesselation = core::reciprocal((f32)tesselation); + const f32 recTesselationHalf = recTesselation * 0.5f; + const f32 angleStep = (core::PI * 2.f ) * recTesselation; + const f32 angleStepHalf = angleStep*0.5f; + + u32 i; + video::S3DVertex v; + v.Color = color; + buffer->Vertices.reallocate(tesselation*4+4+(closeTop?2:1)); + buffer->Indices.reallocate((tesselation*2+1)*(closeTop?12:9)); + f32 tcx = 0.f; + for ( i = 0; i <= tesselation; ++i ) + { + const f32 angle = angleStep * i; + v.Pos.X = radius * cosf(angle); + v.Pos.Y = 0.f; + v.Pos.Z = radius * sinf(angle); + v.Normal = v.Pos; + v.Normal.normalize(); + v.TCoords.X=tcx; + v.TCoords.Y=0.f; + buffer->Vertices.push_back(v); + + v.Pos.X += oblique; + v.Pos.Y = length; + v.Normal = v.Pos; + v.Normal.normalize(); + v.TCoords.Y=1.f; + buffer->Vertices.push_back(v); + + v.Pos.X = radius * cosf(angle + angleStepHalf); + v.Pos.Y = 0.f; + v.Pos.Z = radius * sinf(angle + angleStepHalf); + v.Normal = v.Pos; + v.Normal.normalize(); + v.TCoords.X=tcx+recTesselationHalf; + v.TCoords.Y=0.f; + buffer->Vertices.push_back(v); + + v.Pos.X += oblique; + v.Pos.Y = length; + v.Normal = v.Pos; + v.Normal.normalize(); + v.TCoords.Y=1.f; + buffer->Vertices.push_back(v); + tcx += recTesselation; + } + + // indices for the main hull part + const u32 nonWrappedSize = tesselation* 4; + for (i=0; i != nonWrappedSize; i += 2) + { + buffer->Indices.push_back(i + 2); + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(i + 1); + + buffer->Indices.push_back(i + 2); + buffer->Indices.push_back(i + 1); + buffer->Indices.push_back(i + 3); + } + + // two closing quads between end and start + buffer->Indices.push_back(0); + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(i + 1); + + buffer->Indices.push_back(0); + buffer->Indices.push_back(i + 1); + buffer->Indices.push_back(1); + + // close down + v.Pos.X = 0.f; + v.Pos.Y = 0.f; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = -1.f; + v.Normal.Z = 0.f; + v.TCoords.X = 1.f; + v.TCoords.Y = 1.f; + buffer->Vertices.push_back(v); + + u32 index = buffer->Vertices.size() - 1; + + for ( i = 0; i != nonWrappedSize; i += 2 ) + { + buffer->Indices.push_back(index); + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(i + 2); + } + + buffer->Indices.push_back(index); + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(0); + + if (closeTop) + { + // close top + v.Pos.X = oblique; + v.Pos.Y = length; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = 1.f; + v.Normal.Z = 0.f; + v.TCoords.X = 0.f; + v.TCoords.Y = 0.f; + buffer->Vertices.push_back(v); + + index = buffer->Vertices.size() - 1; + + for ( i = 0; i != nonWrappedSize; i += 2 ) + { + buffer->Indices.push_back(i + 1); + buffer->Indices.push_back(index); + buffer->Indices.push_back(i + 3); + } + + buffer->Indices.push_back(i + 1); + buffer->Indices.push_back(index); + buffer->Indices.push_back(1); + } + + buffer->recalculateBoundingBox(); + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + mesh->setHardwareMappingHint(EHM_STATIC); + mesh->recalculateBoundingBox(); + buffer->drop(); + return mesh; +} + + +/* A cone with proper normals and texture coords */ +IMesh* CGeometryCreator::createConeMesh(f32 radius, f32 length, u32 tesselation, + const video::SColor& colorTop, + const video::SColor& colorBottom, + f32 oblique) const +{ + SMeshBuffer* buffer = new SMeshBuffer(); + + const f32 angleStep = (core::PI * 2.f ) / tesselation; + const f32 angleStepHalf = angleStep*0.5f; + + video::S3DVertex v; + u32 i; + + v.Color = colorTop; + for ( i = 0; i != tesselation; ++i ) + { + f32 angle = angleStep * f32(i); + + v.Pos.X = radius * cosf(angle); + v.Pos.Y = 0.f; + v.Pos.Z = radius * sinf(angle); + v.Normal = v.Pos; + v.Normal.normalize(); + buffer->Vertices.push_back(v); + + angle += angleStepHalf; + v.Pos.X = radius * cosf(angle); + v.Pos.Y = 0.f; + v.Pos.Z = radius * sinf(angle); + v.Normal = v.Pos; + v.Normal.normalize(); + buffer->Vertices.push_back(v); + } + const u32 nonWrappedSize = buffer->Vertices.size() - 1; + + // close top + v.Pos.X = oblique; + v.Pos.Y = length; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = 1.f; + v.Normal.Z = 0.f; + buffer->Vertices.push_back(v); + + u32 index = buffer->Vertices.size() - 1; + + for ( i = 0; i != nonWrappedSize; i += 1 ) + { + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(index); + buffer->Indices.push_back(i + 1); + } + + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(index); + buffer->Indices.push_back(0); + + // close down + v.Color = colorBottom; + v.Pos.X = 0.f; + v.Pos.Y = 0.f; + v.Pos.Z = 0.f; + v.Normal.X = 0.f; + v.Normal.Y = -1.f; + v.Normal.Z = 0.f; + buffer->Vertices.push_back(v); + + index = buffer->Vertices.size() - 1; + + for ( i = 0; i != nonWrappedSize; i += 1 ) + { + buffer->Indices.push_back(index); + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(i + 1); + } + + buffer->Indices.push_back(index); + buffer->Indices.push_back(i + 0); + buffer->Indices.push_back(0); + + buffer->recalculateBoundingBox(); + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + buffer->drop(); + + mesh->setHardwareMappingHint(EHM_STATIC); + mesh->recalculateBoundingBox(); + return mesh; +} + + +void CGeometryCreator::addToBuffer(const video::S3DVertex& v, SMeshBuffer* Buffer) const +{ + const s32 tnidx = Buffer->Vertices.linear_reverse_search(v); + const bool alreadyIn = (tnidx != -1); + u16 nidx = (u16)tnidx; + if (!alreadyIn) + { + nidx = (u16)Buffer->Vertices.size(); + Buffer->Indices.push_back(nidx); + Buffer->Vertices.push_back(v); + } + else + Buffer->Indices.push_back(nidx); +} + + +IMesh* CGeometryCreator::createVolumeLightMesh( + const u32 subdivideU, const u32 subdivideV, + const video::SColor footColor, const video::SColor tailColor, + const f32 lpDistance, const core::vector3df& lightDim) const +{ + SMeshBuffer* Buffer = new SMeshBuffer(); + Buffer->setHardwareMappingHint(EHM_STATIC); + + const core::vector3df lightPoint(0, -(lpDistance*lightDim.Y), 0); + const f32 ax = lightDim.X * 0.5f; // X Axis + const f32 az = lightDim.Z * 0.5f; // Z Axis + + Buffer->Vertices.clear(); + Buffer->Vertices.reallocate(6+12*(subdivideU+subdivideV)); + Buffer->Indices.clear(); + Buffer->Indices.reallocate(6+12*(subdivideU+subdivideV)); + //draw the bottom foot.. the glowing region + addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, footColor, 0, 1),Buffer); + addToBuffer(video::S3DVertex( ax, 0, az, 0,0,0, footColor, 1, 1),Buffer); + addToBuffer(video::S3DVertex( ax, 0,-az, 0,0,0, footColor, 1, 0),Buffer); + + addToBuffer(video::S3DVertex( ax, 0,-az, 0,0,0, footColor, 1, 0),Buffer); + addToBuffer(video::S3DVertex(-ax, 0,-az, 0,0,0, footColor, 0, 0),Buffer); + addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, footColor, 0, 1),Buffer); + + f32 tu = 0.f; + const f32 tuStep = 1.f/subdivideU; + f32 bx = -ax; + const f32 bxStep = lightDim.X * tuStep; + // Slices in X/U space + for (u32 i = 0; i <= subdivideU; ++i) + { + // These are the two endpoints for a slice at the foot + core::vector3df end1(bx, 0.0f, -az); + core::vector3df end2(bx, 0.0f, az); + + end1 -= lightPoint; // get a vector from point to lightsource + end1.normalize(); // normalize vector + end1 *= lightDim.Y; // multiply it out by shootlength + + end1.X += bx; // Add the original point location to the vector + end1.Z -= az; + + // Do it again for the other point. + end2 -= lightPoint; + end2.normalize(); + end2 *= lightDim.Y; + + end2.X += bx; + end2.Z += az; + + addToBuffer(video::S3DVertex(bx , 0, az, 0,0,0, footColor, tu, 1),Buffer); + addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, footColor, tu, 0),Buffer); + addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, tailColor, tu, 1),Buffer); + + addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, footColor, tu, 0),Buffer); + addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, tailColor, tu, 0),Buffer); + addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, tailColor, tu, 1),Buffer); + + //back side + addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, tailColor, tu, 1),Buffer); + addToBuffer(video::S3DVertex(-bx , 0, -az, 0,0,0, footColor, tu, 1),Buffer); + addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, footColor, tu, 0),Buffer); + + addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, footColor, tu, 0),Buffer); + addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, tailColor, tu, 0),Buffer); + addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, tailColor, tu, 1),Buffer); + tu += tuStep; + bx += bxStep; + } + + f32 tv = 0.f; + const f32 tvStep = 1.f/subdivideV; + f32 bz = -az; + const f32 bzStep = lightDim.Z * tvStep; + // Slices in Z/V space + for(u32 i = 0; i <= subdivideV; ++i) + { + // These are the two endpoints for a slice at the foot + core::vector3df end1(-ax, 0.0f, bz); + core::vector3df end2(ax, 0.0f, bz); + + end1 -= lightPoint; // get a vector from point to lightsource + end1.normalize(); // normalize vector + end1 *= lightDim.Y; // multiply it out by shootlength + + end1.X -= ax; // Add the original point location to the vector + end1.Z += bz; + + // Do it again for the other point. + end2 -= lightPoint; + end2.normalize(); + end2 *= lightDim.Y; + + end2.X += ax; + end2.Z += bz; + + addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, footColor, 0, tv),Buffer); + addToBuffer(video::S3DVertex(ax , 0, bz, 0,0,0, footColor, 1, tv),Buffer); + addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, tailColor, 1, tv),Buffer); + + addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, tailColor, 1, tv),Buffer); + addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, tailColor, 0, tv),Buffer); + addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, footColor, 0, tv),Buffer); + + //back side + addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, footColor, 0, tv),Buffer); + addToBuffer(video::S3DVertex(-ax , 0, -bz, 0,0,0, footColor, 1, tv),Buffer); + addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, tailColor, 1, tv),Buffer); + + addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, tailColor, 1, tv),Buffer); + addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, tailColor, 0, tv),Buffer); + addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, footColor, 0, tv),Buffer); + tv += tvStep; + bz += bzStep; + } + + Buffer->recalculateBoundingBox(); + + Buffer->Material.MaterialType = video::EMT_ONETEXTURE_BLEND; + Buffer->Material.MaterialTypeParam = pack_textureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X ); + + Buffer->Material.Lighting = false; + Buffer->Material.ZWriteEnable = false; + + Buffer->setDirty(EBT_VERTEX_AND_INDEX); + + Buffer->recalculateBoundingBox(); + SMesh* mesh = new SMesh(); + mesh->addMeshBuffer(Buffer); + Buffer->drop(); + + mesh->recalculateBoundingBox(); + return mesh; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.h new file mode 100644 index 0000000..326e11c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGeometryCreator.h @@ -0,0 +1,65 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_GEOMETRY_CREATOR_H_INCLUDED__ +#define __C_GEOMETRY_CREATOR_H_INCLUDED__ + +#include "IGeometryCreator.h" +#include "SMeshBuffer.h" + +namespace irr +{ + +namespace scene +{ + +//! class for creating geometry on the fly +class CGeometryCreator : public IGeometryCreator +{ + void addToBuffer(const video::S3DVertex& v, SMeshBuffer* Buffer) const; +public: + IMesh* createCubeMesh(const core::vector3df& size) const; + + IMesh* createHillPlaneMesh( + const core::dimension2d& tileSize, const core::dimension2d& tileCount, + video::SMaterial* material, f32 hillHeight, const core::dimension2d& countHills, + const core::dimension2d& textureRepeatCount) const; + + IMesh* createTerrainMesh(video::IImage* texture, + video::IImage* heightmap, const core::dimension2d& stretchSize, + f32 maxHeight, video::IVideoDriver* driver, + const core::dimension2d& defaultVertexBlockSize, + bool debugBorders=false) const; + + IMesh* createArrowMesh(const u32 tesselationCylinder, + const u32 tesselationCone, const f32 height, + const f32 cylinderHeight, const f32 width0, + const f32 width1, const video::SColor vtxColor0, + const video::SColor vtxColor1) const; + + IMesh* createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY) const; + + IMesh* createCylinderMesh(f32 radius, f32 length, u32 tesselation, + const video::SColor& color=0xffffffff, + bool closeTop=true, f32 oblique=0.f) const; + + IMesh* createConeMesh(f32 radius, f32 length, u32 tesselation, + const video::SColor& colorTop=0xffffffff, + const video::SColor& colorBottom=0xffffffff, + f32 oblique=0.f) const; + + IMesh* createVolumeLightMesh( + const u32 subdivideU=32, const u32 subdivideV=32, + const video::SColor footColor=0xffffffff, + const video::SColor tailColor=0xffffffff, + const f32 lpDistance = 8.f, + const core::vector3df& lightDim = core::vector3df(1.f,1.2f,1.f)) const; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImage.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImage.cpp new file mode 100644 index 0000000..d567732 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImage.cpp @@ -0,0 +1,462 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImage.h" +#include "irrString.h" +#include "CColorConverter.h" +#include "CBlit.h" + +namespace irr +{ +namespace video +{ + +//! Constructor of empty image +CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d& size) +:Data(0), Size(size), Format(format), DeleteMemory(true) +{ + initData(); +} + + +//! Constructor from raw data +CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d& size, void* data, + bool ownForeignMemory, bool deleteForeignMemory) +: Data(0), Size(size), Format(format), DeleteMemory(deleteForeignMemory) +{ + if (ownForeignMemory) + { + Data = (u8*)0xbadf00d; + initData(); + Data = (u8*)data; + } + else + { + Data = 0; + initData(); + memcpy(Data, data, Size.Height * Pitch); + } +} + + +//! assumes format and size has been set and creates the rest +void CImage::initData() +{ +#ifdef _DEBUG + setDebugName("CImage"); +#endif + BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8; + + // Pitch should be aligned... + Pitch = BytesPerPixel * Size.Width; + + if (!Data) + { + DeleteMemory=true; + Data = new u8[Size.Height * Pitch]; + } +} + + +//! destructor +CImage::~CImage() +{ + if ( DeleteMemory ) + delete [] Data; +} + + +//! Returns width and height of image data. +const core::dimension2d& CImage::getDimension() const +{ + return Size; +} + + +//! Returns bits per pixel. +u32 CImage::getBitsPerPixel() const +{ + return getBitsPerPixelFromFormat(Format); +} + + +//! Returns bytes per pixel +u32 CImage::getBytesPerPixel() const +{ + return BytesPerPixel; +} + + +//! Returns image data size in bytes +u32 CImage::getImageDataSizeInBytes() const +{ + return Pitch * Size.Height; +} + + +//! Returns image data size in pixels +u32 CImage::getImageDataSizeInPixels() const +{ + return Size.Width * Size.Height; +} + + +//! returns mask for red value of a pixel +u32 CImage::getRedMask() const +{ + switch(Format) + { + case ECF_A1R5G5B5: + return 0x1F<<10; + case ECF_R5G6B5: + return 0x1F<<11; + case ECF_R8G8B8: + return 0x00FF0000; + case ECF_A8R8G8B8: + return 0x00FF0000; + default: + return 0x0; + } +} + + +//! returns mask for green value of a pixel +u32 CImage::getGreenMask() const +{ + switch(Format) + { + case ECF_A1R5G5B5: + return 0x1F<<5; + case ECF_R5G6B5: + return 0x3F<<5; + case ECF_R8G8B8: + return 0x0000FF00; + case ECF_A8R8G8B8: + return 0x0000FF00; + default: + return 0x0; + } +} + + +//! returns mask for blue value of a pixel +u32 CImage::getBlueMask() const +{ + switch(Format) + { + case ECF_A1R5G5B5: + return 0x1F; + case ECF_R5G6B5: + return 0x1F; + case ECF_R8G8B8: + return 0x000000FF; + case ECF_A8R8G8B8: + return 0x000000FF; + default: + return 0x0; + } +} + + +//! returns mask for alpha value of a pixel +u32 CImage::getAlphaMask() const +{ + switch(Format) + { + case ECF_A1R5G5B5: + return 0x1<<15; + case ECF_R5G6B5: + return 0x0; + case ECF_R8G8B8: + return 0x0; + case ECF_A8R8G8B8: + return 0xFF000000; + default: + return 0x0; + } +} + + +//! sets a pixel +void CImage::setPixel(u32 x, u32 y, const SColor &color, bool blend) +{ + if (x >= Size.Width || y >= Size.Height) + return; + + switch(Format) + { + case ECF_A1R5G5B5: + { + u16 * dest = (u16*) (Data + ( y * Pitch ) + ( x << 1 )); + *dest = video::A8R8G8B8toA1R5G5B5( color.color ); + } break; + + case ECF_R5G6B5: + { + u16 * dest = (u16*) (Data + ( y * Pitch ) + ( x << 1 )); + *dest = video::A8R8G8B8toR5G6B5( color.color ); + } break; + + case ECF_R8G8B8: + { + u8* dest = Data + ( y * Pitch ) + ( x * 3 ); + dest[0] = (u8)color.getRed(); + dest[1] = (u8)color.getGreen(); + dest[2] = (u8)color.getBlue(); + } break; + + case ECF_A8R8G8B8: + { + u32 * dest = (u32*) (Data + ( y * Pitch ) + ( x << 2 )); + *dest = blend ? PixelBlend32 ( *dest, color.color ) : color.color; + } break; +#ifndef _DEBUG + default: + break; +#endif + } +} + + +//! returns a pixel +SColor CImage::getPixel(u32 x, u32 y) const +{ + if (x >= Size.Width || y >= Size.Height) + return SColor(0); + + switch(Format) + { + case ECF_A1R5G5B5: + return A1R5G5B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]); + case ECF_R5G6B5: + return R5G6B5toA8R8G8B8(((u16*)Data)[y*Size.Width + x]); + case ECF_A8R8G8B8: + return ((u32*)Data)[y*Size.Width + x]; + case ECF_R8G8B8: + { + u8* p = Data+(y*3)*Size.Width + (x*3); + return SColor(255,p[0],p[1],p[2]); + } +#ifndef _DEBUG + default: + break; +#endif + } + + return SColor(0); +} + + +//! returns the color format +ECOLOR_FORMAT CImage::getColorFormat() const +{ + return Format; +} + + +//! copies this surface into another at given position +void CImage::copyTo(IImage* target, const core::position2d& pos) +{ + Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0); +} + + +//! copies this surface partially into another at given position +void CImage::copyTo(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect) +{ + Blit(BLITTER_TEXTURE, target, clipRect, &pos, this, &sourceRect, 0); +} + + +//! copies this surface into another, using the alpha mask, a cliprect and a color to add with +void CImage::copyToWithAlpha(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const SColor &color, const core::rect* clipRect) +{ + // color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF + Blit(color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND, + target, clipRect, &pos, this, &sourceRect, color.color); +} + + +//! copies this surface into another, scaling it to the target image size +// note: this is very very slow. +void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch) +{ + if (!target || !width || !height) + return; + + const u32 bpp=getBitsPerPixelFromFormat(format)/8; + if (0==pitch) + pitch = width*bpp; + + if (Format==format && Size.Width==width && Size.Height==height) + { + if (pitch==Pitch) + { + memcpy(target, Data, height*pitch); + return; + } + else + { + u8* tgtpos = (u8*) target; + u8* srcpos = Data; + const u32 bwidth = width*bpp; + const u32 rest = pitch-bwidth; + for (u32 y=0; y& targetSize = target->getDimension(); + + if (targetSize==Size) + { + copyTo(target); + return; + } + + copyToScaling(target->lock(), targetSize.Width, targetSize.Height, target->getColorFormat()); + target->unlock(); +} + + +//! copies this surface into another, scaling it to fit it. +void CImage::copyToScalingBoxFilter(IImage* target, s32 bias, bool blend) +{ + const core::dimension2d destSize = target->getDimension(); + + const f32 sourceXStep = (f32) Size.Width / (f32) destSize.Width; + const f32 sourceYStep = (f32) Size.Height / (f32) destSize.Height; + + target->lock(); + + s32 fx = core::ceil32( sourceXStep ); + s32 fy = core::ceil32( sourceYStep ); + f32 sx; + f32 sy; + + sy = 0.f; + for ( u32 y = 0; y != destSize.Height; ++y ) + { + sx = 0.f; + for ( u32 x = 0; x != destSize.Width; ++x ) + { + target->setPixel( x, y, + getPixelBox( core::floor32(sx), core::floor32(sy), fx, fy, bias ), blend ); + sx += sourceXStep; + } + sy += sourceYStep; + } + + target->unlock(); +} + + +//! fills the surface with given color +void CImage::fill(const SColor &color) +{ + u32 c; + + switch ( Format ) + { + case ECF_A1R5G5B5: + c = color.toA1R5G5B5(); + c |= c << 16; + break; + case ECF_R5G6B5: + c = video::A8R8G8B8toR5G6B5( color.color ); + c |= c << 16; + break; + case ECF_A8R8G8B8: + c = color.color; + break; + case ECF_R8G8B8: + { + u8 rgb[3]; + CColorConverter::convert_A8R8G8B8toR8G8B8(&color, 1, rgb); + const u32 size = getImageDataSizeInBytes(); + for (u32 i=0; i> sdiv ) + bias, 0, 255 ); + r = core::s32_clamp( ( r >> sdiv ) + bias, 0, 255 ); + g = core::s32_clamp( ( g >> sdiv ) + bias, 0, 255 ); + b = core::s32_clamp( ( b >> sdiv ) + bias, 0, 255 ); + + c.set( a, r, g, b ); + return c; +} + + +} // end namespace video +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImage.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImage.h new file mode 100644 index 0000000..82b34c7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImage.h @@ -0,0 +1,127 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_H_INCLUDED__ +#define __C_IMAGE_H_INCLUDED__ + +#include "IImage.h" +#include "rect.h" + +namespace irr +{ +namespace video +{ + +//! IImage implementation with a lot of special image operations for +//! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice. +class CImage : public IImage +{ +public: + + //! constructor from raw image data + /** \param useForeignMemory: If true, the image will use the data pointer + directly and own it from now on, which means it will also try to delete [] the + data when the image will be destructed. If false, the memory will by copied. */ + CImage(ECOLOR_FORMAT format, const core::dimension2d& size, + void* data, bool ownForeignMemory=true, bool deleteMemory = true); + + //! constructor for empty image + CImage(ECOLOR_FORMAT format, const core::dimension2d& size); + + //! destructor + virtual ~CImage(); + + //! Lock function. + virtual void* lock() + { + return Data; + } + + //! Unlock function. + virtual void unlock() {} + + //! Returns width and height of image data. + virtual const core::dimension2d& getDimension() const; + + //! Returns bits per pixel. + virtual u32 getBitsPerPixel() const; + + //! Returns bytes per pixel + virtual u32 getBytesPerPixel() const; + + //! Returns image data size in bytes + virtual u32 getImageDataSizeInBytes() const; + + //! Returns image data size in pixels + virtual u32 getImageDataSizeInPixels() const; + + //! returns mask for red value of a pixel + virtual u32 getRedMask() const; + + //! returns mask for green value of a pixel + virtual u32 getGreenMask() const; + + //! returns mask for blue value of a pixel + virtual u32 getBlueMask() const; + + //! returns mask for alpha value of a pixel + virtual u32 getAlphaMask() const; + + //! returns a pixel + virtual SColor getPixel(u32 x, u32 y) const; + + //! sets a pixel + virtual void setPixel(u32 x, u32 y, const SColor &color, bool blend = false ); + + //! returns the color format + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of image + virtual u32 getPitch() const { return Pitch; } + + //! copies this surface into another, scaling it to fit. + virtual void copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT format, u32 pitch=0); + + //! copies this surface into another, scaling it to fit. + virtual void copyToScaling(IImage* target); + + //! copies this surface into another + virtual void copyTo(IImage* target, const core::position2d& pos=core::position2d(0,0)); + + //! copies this surface into another + virtual void copyTo(IImage* target, const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect=0); + + //! copies this surface into another, using the alpha mask, an cliprect and a color to add with + virtual void copyToWithAlpha(IImage* target, const core::position2d& pos, + const core::rect& sourceRect, const SColor &color, + const core::rect* clipRect = 0); + + //! copies this surface into another, scaling it to fit, appyling a box filter + virtual void copyToScalingBoxFilter(IImage* target, s32 bias = 0, bool blend = false); + + //! fills the surface with given color + virtual void fill(const SColor &color); + +private: + + //! assumes format and size has been set and creates the rest + void initData(); + + inline SColor getPixelBox ( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const; + + u8* Data; + core::dimension2d Size; + u32 BytesPerPixel; + u32 Pitch; + ECOLOR_FORMAT Format; + + bool DeleteMemory; +}; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.cpp new file mode 100644 index 0000000..2ccb64c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.cpp @@ -0,0 +1,372 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderBMP.h" + +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ + +#include "IReadFile.h" +#include "SColor.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderBMP::CImageLoaderBMP() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderBMP"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderBMP::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "bmp" ); +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile* file) const +{ + u16 headerID; + file->read(&headerID, sizeof(u16)); +#ifdef __BIG_ENDIAN__ + headerID = os::Byteswap::byteswap(headerID); +#endif + return headerID == 0x4d42; +} + + +void CImageLoaderBMP::decompress8BitRLE(u8*& bmpData, s32 size, s32 width, s32 height, s32 pitch) const +{ + u8* p = bmpData; + u8* newBmp = new u8[(width+pitch)*height]; + u8* d = newBmp; + u8* destEnd = newBmp + (width+pitch)*height; + s32 line = 0; + + while (bmpData - p < size && d < destEnd) + { + if (*p == 0) + { + ++p; + + switch(*p) + { + case 0: // end of line + ++p; + ++line; + d = newBmp + (line*(width+pitch)); + break; + case 1: // end of bmp + delete [] bmpData; + bmpData = newBmp; + return; + case 2: + ++p; d +=(u8)*p; // delta + ++p; d += ((u8)*p)*(width+pitch); + ++p; + break; + default: + { + // absolute mode + s32 count = (u8)*p; ++p; + s32 readAdditional = ((2-(count%2))%2); + s32 i; + + for (i=0; i> readShift) & 0x0f; + readShift -= 4; + if (readShift < 0) + { + ++*p; + readShift = 4; + } + + u8 mask = 0x0f << shift; + *d = (*d & (~mask)) | ((color << shift) & mask); + + shift -= 4; + if (shift < 0) + { + shift = 4; + ++d; + } + + } + + for (i=0; i> 4) & 0x0f; + ++p; + + for (s32 i=0; iread(&header, sizeof(header)); + +#ifdef __BIG_ENDIAN__ + header.Id = os::Byteswap::byteswap(header.Id); + header.FileSize = os::Byteswap::byteswap(header.FileSize); + header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset); + header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize); + header.Width = os::Byteswap::byteswap(header.Width); + header.Height = os::Byteswap::byteswap(header.Height); + header.Planes = os::Byteswap::byteswap(header.Planes); + header.BPP = os::Byteswap::byteswap(header.BPP); + header.Compression = os::Byteswap::byteswap(header.Compression); + header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize); + header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX); + header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY); + header.Colors = os::Byteswap::byteswap(header.Colors); + header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors); +#endif + + s32 pitch = 0; + + //! return if the header is false + + if (header.Id != 0x4d42) + return 0; + + if (header.Compression > 2) // we'll only handle RLE-Compression + { + os::Printer::log("Compression mode not supported.", ELL_ERROR); + return 0; + } + + // adjust bitmap data size to dword boundary + header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4; + + // read palette + + long pos = file->getPos(); + s32 paletteSize = (header.BitmapDataOffset - pos) / 4; + + s32* paletteData = 0; + if (paletteSize) + { + paletteData = new s32[paletteSize]; + file->read(paletteData, paletteSize * sizeof(s32)); +#ifdef __BIG_ENDIAN__ + for (s32 i=0; i(file->getSize()) - header.BitmapDataOffset; + } + + file->seek(header.BitmapDataOffset); + + f32 t = (header.Width) * (header.BPP / 8.0f); + s32 widthInBytes = (s32)t; + t -= widthInBytes; + if (t!=0.0f) + ++widthInBytes; + + s32 lineData = widthInBytes + ((4-(widthInBytes%4)))%4; + pitch = lineData - widthInBytes; + + u8* bmpData = new u8[header.BitmapDataSize]; + file->read(bmpData, header.BitmapDataSize); + + // decompress data if needed + switch(header.Compression) + { + case 1: // 8 bit rle + decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch); + break; + case 2: // 4 bit rle + decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch); + break; + } + + // create surface + + // no default constructor from packed area! ARM problem! + core::dimension2d dim; + dim.Width = header.Width; + dim.Height = header.Height; + + IImage* image = 0; + switch(header.BPP) + { + case 1: + image = new CImage(ECF_A1R5G5B5, dim); + if (image) + CColorConverter::convert1BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true); + break; + case 4: + image = new CImage(ECF_A1R5G5B5, dim); + if (image) + CColorConverter::convert4BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true); + break; + case 8: + image = new CImage(ECF_A1R5G5B5, dim); + if (image) + CColorConverter::convert8BitTo16Bit(bmpData, (s16*)image->lock(), header.Width, header.Height, paletteData, pitch, true); + break; + case 16: + image = new CImage(ECF_A1R5G5B5, dim); + if (image) + CColorConverter::convert16BitTo16Bit((s16*)bmpData, (s16*)image->lock(), header.Width, header.Height, pitch, true); + break; + case 24: + image = new CImage(ECF_R8G8B8, dim); + if (image) + CColorConverter::convert24BitTo24Bit(bmpData, (u8*)image->lock(), header.Width, header.Height, pitch, true, true); + break; + case 32: // thx to Reinhard Ostermeier + image = new CImage(ECF_A8R8G8B8, dim); + if (image) + CColorConverter::convert32BitTo32Bit((s32*)bmpData, (s32*)image->lock(), header.Width, header.Height, pitch, true); + break; + }; + if (image) + image->unlock(); + + // clean up + + delete [] paletteData; + delete [] bmpData; + + return image; +} + + +//! creates a loader which is able to load windows bitmaps +IImageLoader* createImageLoaderBMP() +{ + return new CImageLoaderBMP; +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.h new file mode 100644 index 0000000..9321ecc --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderBMP.h @@ -0,0 +1,100 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_BMP_H_INCLUDED__ +#define __C_IMAGE_LOADER_BMP_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#include "IImageLoader.h" + + +namespace irr +{ +namespace video +{ + +#if defined(_IRR_COMPILE_WITH_BMP_LOADER_) || defined(_IRR_COMPILE_WITH_BMP_WRITER_) + + +// byte-align structures +#include "irrpack.h" + + struct SBMPHeader + { + u16 Id; // BM - Windows 3.1x, 95, NT, 98, 2000, ME, XP + // BA - OS/2 Bitmap Array + // CI - OS/2 Color Icon + // CP - OS/2 Color Pointer + // IC - OS/2 Icon + // PT - OS/2 Pointer + u32 FileSize; + u32 Reserved; + u32 BitmapDataOffset; + u32 BitmapHeaderSize; // should be 28h for windows bitmaps or + // 0Ch for OS/2 1.x or F0h for OS/2 2.x + u32 Width; + u32 Height; + u16 Planes; + u16 BPP; // 1: Monochrome bitmap + // 4: 16 color bitmap + // 8: 256 color bitmap + // 16: 16bit (high color) bitmap + // 24: 24bit (true color) bitmap + // 32: 32bit (true color) bitmap + + u32 Compression; // 0: none (Also identified by BI_RGB) + // 1: RLE 8-bit / pixel (Also identified by BI_RLE4) + // 2: RLE 4-bit / pixel (Also identified by BI_RLE8) + // 3: Bitfields (Also identified by BI_BITFIELDS) + + u32 BitmapDataSize; // Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary. + u32 PixelPerMeterX; + u32 PixelPerMeterY; + u32 Colors; + u32 ImportantColors; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +#endif // defined with loader or writer + +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ + +/*! + Surface Loader for Windows bitmaps +*/ +class CImageLoaderBMP : public IImageLoader +{ +public: + + //! constructor + CImageLoaderBMP(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + void decompress8BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const; + + void decompress4BitRLE(u8*& BmpData, s32 size, s32 width, s32 height, s32 pitch) const; +}; + + +#endif // compiled with loader + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.cpp new file mode 100644 index 0000000..646abd2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.cpp @@ -0,0 +1,712 @@ +// Copyright (C) 2002-2012 Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +/* + Based on Code from Copyright (c) 2003 Randy Reddig + Based on code from Nvidia's DDS example: + http://www.nvidia.com/object/dxtc_decompression_code.html + + mainly c to cpp +*/ + + +#include "CImageLoaderDDS.h" + +#ifdef _IRR_COMPILE_WITH_DDS_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "irrString.h" + + +namespace irr +{ + +namespace video +{ + +namespace +{ + +/*! + DDSDecodePixelFormat() + determines which pixel format the dds texture is in +*/ +void DDSDecodePixelFormat( ddsBuffer *dds, eDDSPixelFormat *pf ) +{ + /* dummy check */ + if( dds == NULL || pf == NULL ) + return; + + /* extract fourCC */ + const u32 fourCC = dds->pixelFormat.fourCC; + + /* test it */ + if( fourCC == 0 ) + *pf = DDS_PF_ARGB8888; + else if( fourCC == *((u32*) "DXT1") ) + *pf = DDS_PF_DXT1; + else if( fourCC == *((u32*) "DXT2") ) + *pf = DDS_PF_DXT2; + else if( fourCC == *((u32*) "DXT3") ) + *pf = DDS_PF_DXT3; + else if( fourCC == *((u32*) "DXT4") ) + *pf = DDS_PF_DXT4; + else if( fourCC == *((u32*) "DXT5") ) + *pf = DDS_PF_DXT5; + else + *pf = DDS_PF_UNKNOWN; +} + + +/*! +DDSGetInfo() +extracts relevant info from a dds texture, returns 0 on success +*/ +s32 DDSGetInfo( ddsBuffer *dds, s32 *width, s32 *height, eDDSPixelFormat *pf ) +{ + /* dummy test */ + if( dds == NULL ) + return -1; + + /* test dds header */ + if( *((s32*) dds->magic) != *((s32*) "DDS ") ) + return -1; + if( DDSLittleLong( dds->size ) != 124 ) + return -1; + + /* extract width and height */ + if( width != NULL ) + *width = DDSLittleLong( dds->width ); + if( height != NULL ) + *height = DDSLittleLong( dds->height ); + + /* get pixel format */ + DDSDecodePixelFormat( dds, pf ); + + /* return ok */ + return 0; +} + + +/*! + DDSGetColorBlockColors() + extracts colors from a dds color block +*/ +void DDSGetColorBlockColors( ddsColorBlock *block, ddsColor colors[ 4 ] ) +{ + u16 word; + + + /* color 0 */ + word = DDSLittleShort( block->colors[ 0 ] ); + colors[ 0 ].a = 0xff; + + /* extract rgb bits */ + colors[ 0 ].b = (u8) word; + colors[ 0 ].b <<= 3; + colors[ 0 ].b |= (colors[ 0 ].b >> 5); + word >>= 5; + colors[ 0 ].g = (u8) word; + colors[ 0 ].g <<= 2; + colors[ 0 ].g |= (colors[ 0 ].g >> 5); + word >>= 6; + colors[ 0 ].r = (u8) word; + colors[ 0 ].r <<= 3; + colors[ 0 ].r |= (colors[ 0 ].r >> 5); + + /* same for color 1 */ + word = DDSLittleShort( block->colors[ 1 ] ); + colors[ 1 ].a = 0xff; + + /* extract rgb bits */ + colors[ 1 ].b = (u8) word; + colors[ 1 ].b <<= 3; + colors[ 1 ].b |= (colors[ 1 ].b >> 5); + word >>= 5; + colors[ 1 ].g = (u8) word; + colors[ 1 ].g <<= 2; + colors[ 1 ].g |= (colors[ 1 ].g >> 5); + word >>= 6; + colors[ 1 ].r = (u8) word; + colors[ 1 ].r <<= 3; + colors[ 1 ].r |= (colors[ 1 ].r >> 5); + + /* use this for all but the super-freak math method */ + if( block->colors[ 0 ] > block->colors[ 1 ] ) + { + /* four-color block: derive the other two colors. + 00 = color 0, 01 = color 1, 10 = color 2, 11 = color 3 + these two bit codes correspond to the 2-bit fields + stored in the 64-bit block. */ + + word = ((u16) colors[ 0 ].r * 2 + (u16) colors[ 1 ].r ) / 3; + /* no +1 for rounding */ + /* as bits have been shifted to 888 */ + colors[ 2 ].r = (u8) word; + word = ((u16) colors[ 0 ].g * 2 + (u16) colors[ 1 ].g) / 3; + colors[ 2 ].g = (u8) word; + word = ((u16) colors[ 0 ].b * 2 + (u16) colors[ 1 ].b) / 3; + colors[ 2 ].b = (u8) word; + colors[ 2 ].a = 0xff; + + word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r * 2) / 3; + colors[ 3 ].r = (u8) word; + word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g * 2) / 3; + colors[ 3 ].g = (u8) word; + word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b * 2) / 3; + colors[ 3 ].b = (u8) word; + colors[ 3 ].a = 0xff; + } + else + { + /* three-color block: derive the other color. + 00 = color 0, 01 = color 1, 10 = color 2, + 11 = transparent. + These two bit codes correspond to the 2-bit fields + stored in the 64-bit block */ + + word = ((u16) colors[ 0 ].r + (u16) colors[ 1 ].r) / 2; + colors[ 2 ].r = (u8) word; + word = ((u16) colors[ 0 ].g + (u16) colors[ 1 ].g) / 2; + colors[ 2 ].g = (u8) word; + word = ((u16) colors[ 0 ].b + (u16) colors[ 1 ].b) / 2; + colors[ 2 ].b = (u8) word; + colors[ 2 ].a = 0xff; + + /* random color to indicate alpha */ + colors[ 3 ].r = 0x00; + colors[ 3 ].g = 0xff; + colors[ 3 ].b = 0xff; + colors[ 3 ].a = 0x00; + } +} + + +/* +DDSDecodeColorBlock() +decodes a dds color block +fixme: make endian-safe +*/ + +void DDSDecodeColorBlock( u32 *pixel, ddsColorBlock *block, s32 width, u32 colors[ 4 ] ) +{ + s32 r, n; + u32 bits; + u32 masks[] = { 3, 12, 3 << 4, 3 << 6 }; /* bit masks = 00000011, 00001100, 00110000, 11000000 */ + s32 shift[] = { 0, 2, 4, 6 }; + + + /* r steps through lines in y */ + for( r = 0; r < 4; r++, pixel += (width - 4) ) /* no width * 4 as u32 ptr inc will * 4 */ + { + /* width * 4 bytes per pixel per line, each j dxtc row is 4 lines of pixels */ + + /* n steps through pixels */ + for( n = 0; n < 4; n++ ) + { + bits = block->row[ r ] & masks[ n ]; + bits >>= shift[ n ]; + + switch( bits ) + { + case 0: + *pixel = colors[ 0 ]; + pixel++; + break; + + case 1: + *pixel = colors[ 1 ]; + pixel++; + break; + + case 2: + *pixel = colors[ 2 ]; + pixel++; + break; + + case 3: + *pixel = colors[ 3 ]; + pixel++; + break; + + default: + /* invalid */ + pixel++; + break; + } + } + } +} + + +/* +DDSDecodeAlphaExplicit() +decodes a dds explicit alpha block +*/ +void DDSDecodeAlphaExplicit( u32 *pixel, ddsAlphaBlockExplicit *alphaBlock, s32 width, u32 alphaZero ) +{ + s32 row, pix; + u16 word; + ddsColor color; + + + /* clear color */ + color.r = 0; + color.g = 0; + color.b = 0; + + /* walk rows */ + for( row = 0; row < 4; row++, pixel += (width - 4) ) + { + word = DDSLittleShort( alphaBlock->row[ row ] ); + + /* walk pixels */ + for( pix = 0; pix < 4; pix++ ) + { + /* zero the alpha bits of image pixel */ + *pixel &= alphaZero; + color.a = word & 0x000F; + color.a = color.a | (color.a << 4); + *pixel |= *((u32*) &color); + word >>= 4; /* move next bits to lowest 4 */ + pixel++; /* move to next pixel in the row */ + } + } +} + + + +/* +DDSDecodeAlpha3BitLinear() +decodes interpolated alpha block +*/ +void DDSDecodeAlpha3BitLinear( u32 *pixel, ddsAlphaBlock3BitLinear *alphaBlock, s32 width, u32 alphaZero ) +{ + + s32 row, pix; + u32 stuff; + u8 bits[ 4 ][ 4 ]; + u16 alphas[ 8 ]; + ddsColor aColors[ 4 ][ 4 ]; + + /* get initial alphas */ + alphas[ 0 ] = alphaBlock->alpha0; + alphas[ 1 ] = alphaBlock->alpha1; + + /* 8-alpha block */ + if( alphas[ 0 ] > alphas[ 1 ] ) + { + /* 000 = alpha_0, 001 = alpha_1, others are interpolated */ + alphas[ 2 ] = ( 6 * alphas[ 0 ] + alphas[ 1 ]) / 7; /* bit code 010 */ + alphas[ 3 ] = ( 5 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 7; /* bit code 011 */ + alphas[ 4 ] = ( 4 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 7; /* bit code 100 */ + alphas[ 5 ] = ( 3 * alphas[ 0 ] + 4 * alphas[ 1 ]) / 7; /* bit code 101 */ + alphas[ 6 ] = ( 2 * alphas[ 0 ] + 5 * alphas[ 1 ]) / 7; /* bit code 110 */ + alphas[ 7 ] = ( alphas[ 0 ] + 6 * alphas[ 1 ]) / 7; /* bit code 111 */ + } + + /* 6-alpha block */ + else + { + /* 000 = alpha_0, 001 = alpha_1, others are interpolated */ + alphas[ 2 ] = (4 * alphas[ 0 ] + alphas[ 1 ]) / 5; /* bit code 010 */ + alphas[ 3 ] = (3 * alphas[ 0 ] + 2 * alphas[ 1 ]) / 5; /* bit code 011 */ + alphas[ 4 ] = (2 * alphas[ 0 ] + 3 * alphas[ 1 ]) / 5; /* bit code 100 */ + alphas[ 5 ] = ( alphas[ 0 ] + 4 * alphas[ 1 ]) / 5; /* bit code 101 */ + alphas[ 6 ] = 0; /* bit code 110 */ + alphas[ 7 ] = 255; /* bit code 111 */ + } + + /* decode 3-bit fields into array of 16 bytes with same value */ + + /* first two rows of 4 pixels each */ + stuff = *((u32*) &(alphaBlock->stuff[ 0 ])); + + bits[ 0 ][ 0 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 0 ][ 1 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 0 ][ 2 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 0 ][ 3 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 1 ][ 0 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 1 ][ 1 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 1 ][ 2 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 1 ][ 3 ] = (u8) (stuff & 0x00000007); + + /* last two rows */ + stuff = *((u32*) &(alphaBlock->stuff[ 3 ])); /* last 3 bytes */ + + bits[ 2 ][ 0 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 2 ][ 1 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 2 ][ 2 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 2 ][ 3 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 3 ][ 0 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 3 ][ 1 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 3 ][ 2 ] = (u8) (stuff & 0x00000007); + stuff >>= 3; + bits[ 3 ][ 3 ] = (u8) (stuff & 0x00000007); + + /* decode the codes into alpha values */ + for( row = 0; row < 4; row++ ) + { + for( pix=0; pix < 4; pix++ ) + { + aColors[ row ][ pix ].r = 0; + aColors[ row ][ pix ].g = 0; + aColors[ row ][ pix ].b = 0; + aColors[ row ][ pix ].a = (u8) alphas[ bits[ row ][ pix ] ]; + } + } + + /* write out alpha values to the image bits */ + for( row = 0; row < 4; row++, pixel += width-4 ) + { + for( pix = 0; pix < 4; pix++ ) + { + /* zero the alpha bits of image pixel */ + *pixel &= alphaZero; + + /* or the bits into the prev. nulled alpha */ + *pixel |= *((u32*) &(aColors[ row ][ pix ])); + pixel++; + } + } +} + + +/* +DDSDecompressDXT1() +decompresses a dxt1 format texture +*/ +s32 DDSDecompressDXT1( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) +{ + s32 x, y, xBlocks, yBlocks; + u32 *pixel; + ddsColorBlock *block; + ddsColor colors[ 4 ]; + + /* setup */ + xBlocks = width / 4; + yBlocks = height / 4; + + /* walk y */ + for( y = 0; y < yBlocks; y++ ) + { + /* 8 bytes per block */ + block = (ddsColorBlock*) (dds->data + y * xBlocks * 8); + + /* walk x */ + for( x = 0; x < xBlocks; x++, block++ ) + { + DDSGetColorBlockColors( block, colors ); + pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4); + DDSDecodeColorBlock( pixel, block, width, (u32*) colors ); + } + } + + /* return ok */ + return 0; +} + + +/* +DDSDecompressDXT3() +decompresses a dxt3 format texture +*/ + +s32 DDSDecompressDXT3( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) +{ + s32 x, y, xBlocks, yBlocks; + u32 *pixel, alphaZero; + ddsColorBlock *block; + ddsAlphaBlockExplicit *alphaBlock; + ddsColor colors[ 4 ]; + + /* setup */ + xBlocks = width / 4; + yBlocks = height / 4; + + /* create zero alpha */ + colors[ 0 ].a = 0; + colors[ 0 ].r = 0xFF; + colors[ 0 ].g = 0xFF; + colors[ 0 ].b = 0xFF; + alphaZero = *((u32*) &colors[ 0 ]); + + /* walk y */ + for( y = 0; y < yBlocks; y++ ) + { + /* 8 bytes per block, 1 block for alpha, 1 block for color */ + block = (ddsColorBlock*) (dds->data + y * xBlocks * 16); + + /* walk x */ + for( x = 0; x < xBlocks; x++, block++ ) + { + /* get alpha block */ + alphaBlock = (ddsAlphaBlockExplicit*) block; + + /* get color block */ + block++; + DDSGetColorBlockColors( block, colors ); + + /* decode color block */ + pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4); + DDSDecodeColorBlock( pixel, block, width, (u32*) colors ); + + /* overwrite alpha bits with alpha block */ + DDSDecodeAlphaExplicit( pixel, alphaBlock, width, alphaZero ); + } + } + + /* return ok */ + return 0; +} + + +/* +DDSDecompressDXT5() +decompresses a dxt5 format texture +*/ +s32 DDSDecompressDXT5( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) +{ + s32 x, y, xBlocks, yBlocks; + u32 *pixel, alphaZero; + ddsColorBlock *block; + ddsAlphaBlock3BitLinear *alphaBlock; + ddsColor colors[ 4 ]; + + /* setup */ + xBlocks = width / 4; + yBlocks = height / 4; + + /* create zero alpha */ + colors[ 0 ].a = 0; + colors[ 0 ].r = 0xFF; + colors[ 0 ].g = 0xFF; + colors[ 0 ].b = 0xFF; + alphaZero = *((u32*) &colors[ 0 ]); + + /* walk y */ + for( y = 0; y < yBlocks; y++ ) + { + /* 8 bytes per block, 1 block for alpha, 1 block for color */ + block = (ddsColorBlock*) (dds->data + y * xBlocks * 16); + + /* walk x */ + for( x = 0; x < xBlocks; x++, block++ ) + { + /* get alpha block */ + alphaBlock = (ddsAlphaBlock3BitLinear*) block; + + /* get color block */ + block++; + DDSGetColorBlockColors( block, colors ); + + /* decode color block */ + pixel = (u32*) (pixels + x * 16 + (y * 4) * width * 4); + DDSDecodeColorBlock( pixel, block, width, (u32*) colors ); + + /* overwrite alpha bits with alpha block */ + DDSDecodeAlpha3BitLinear( pixel, alphaBlock, width, alphaZero ); + } + } + + /* return ok */ + return 0; +} + + +/* +DDSDecompressDXT2() +decompresses a dxt2 format texture (fixme: un-premultiply alpha) +*/ +s32 DDSDecompressDXT2( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) +{ + /* decompress dxt3 first */ + const s32 r = DDSDecompressDXT3( dds, width, height, pixels ); + + /* return to sender */ + return r; +} + + +/* +DDSDecompressDXT4() +decompresses a dxt4 format texture (fixme: un-premultiply alpha) +*/ +s32 DDSDecompressDXT4( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) +{ + /* decompress dxt5 first */ + const s32 r = DDSDecompressDXT5( dds, width, height, pixels ); + + /* return to sender */ + return r; +} + + +/* +DDSDecompressARGB8888() +decompresses an argb 8888 format texture +*/ +s32 DDSDecompressARGB8888( ddsBuffer *dds, s32 width, s32 height, u8 *pixels ) +{ + /* setup */ + u8* in = dds->data; + u8* out = pixels; + + /* walk y */ + for(s32 y = 0; y < height; y++) + { + /* walk x */ + for(s32 x = 0; x < width; x++) + { + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + } + } + + /* return ok */ + return 0; +} + + +/* +DDSDecompress() +decompresses a dds texture into an rgba image buffer, returns 0 on success +*/ +s32 DDSDecompress( ddsBuffer *dds, u8 *pixels ) +{ + s32 width, height; + eDDSPixelFormat pf; + + /* get dds info */ + s32 r = DDSGetInfo( dds, &width, &height, &pf ); + if ( r ) + return r; + + /* decompress */ + switch( pf ) + { + case DDS_PF_ARGB8888: + /* fixme: support other [a]rgb formats */ + r = DDSDecompressARGB8888( dds, width, height, pixels ); + break; + + case DDS_PF_DXT1: + r = DDSDecompressDXT1( dds, width, height, pixels ); + break; + + case DDS_PF_DXT2: + r = DDSDecompressDXT2( dds, width, height, pixels ); + break; + + case DDS_PF_DXT3: + r = DDSDecompressDXT3( dds, width, height, pixels ); + break; + + case DDS_PF_DXT4: + r = DDSDecompressDXT4( dds, width, height, pixels ); + break; + + case DDS_PF_DXT5: + r = DDSDecompressDXT5( dds, width, height, pixels ); + break; + + default: + case DDS_PF_UNKNOWN: + memset( pixels, 0xFF, width * height * 4 ); + r = -1; + break; + } + + /* return to sender */ + return r; +} + +} // end anonymous namespace + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderDDS::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "dds" ); +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderDDS::isALoadableFileFormat(io::IReadFile* file) const +{ + if (!file) + return false; + + ddsBuffer header; + file->read(&header, sizeof(header)); + + s32 width, height; + eDDSPixelFormat pixelFormat; + + return (0 == DDSGetInfo( &header, &width, &height, &pixelFormat)); +} + + +//! creates a surface from the file +IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const +{ + u8 *memFile = new u8 [ file->getSize() ]; + file->read ( memFile, file->getSize() ); + + ddsBuffer *header = (ddsBuffer*) memFile; + IImage* image = 0; + s32 width, height; + eDDSPixelFormat pixelFormat; + + if ( 0 == DDSGetInfo( header, &width, &height, &pixelFormat) ) + { + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + + if ( DDSDecompress( header, (u8*) image->lock() ) == -1) + { + image->unlock(); + image->drop(); + image = 0; + } + } + + delete [] memFile; + if ( image ) + image->unlock(); + + return image; +} + + +//! creates a loader which is able to load dds images +IImageLoader* createImageLoaderDDS() +{ + return new CImageLoaderDDS(); +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.h new file mode 100644 index 0000000..f8c3516 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderDDS.h @@ -0,0 +1,296 @@ +// Copyright (C) 2002-2012 Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_DDS_H_INCLUDED__ +#define __C_IMAGE_LOADER_DDS_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#if defined(_IRR_COMPILE_WITH_DDS_LOADER_) + +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + +/* dependencies */ +/* dds definition */ +enum eDDSPixelFormat +{ + DDS_PF_ARGB8888, + DDS_PF_DXT1, + DDS_PF_DXT2, + DDS_PF_DXT3, + DDS_PF_DXT4, + DDS_PF_DXT5, + DDS_PF_UNKNOWN +}; + +/* 16bpp stuff */ +#define DDS_LOW_5 0x001F; +#define DDS_MID_6 0x07E0; +#define DDS_HIGH_5 0xF800; +#define DDS_MID_555 0x03E0; +#define DDS_HI_555 0x7C00; + + +// byte-align structures +#include "irrpack.h" + +/* structures */ +struct ddsColorKey +{ + u32 colorSpaceLowValue; + u32 colorSpaceHighValue; +} PACK_STRUCT; + +struct ddsCaps +{ + u32 caps1; + u32 caps2; + u32 caps3; + u32 caps4; +} PACK_STRUCT; + +struct ddsMultiSampleCaps +{ + u16 flipMSTypes; + u16 bltMSTypes; +} PACK_STRUCT; + + +struct ddsPixelFormat +{ + u32 size; + u32 flags; + u32 fourCC; + union + { + u32 rgbBitCount; + u32 yuvBitCount; + u32 zBufferBitDepth; + u32 alphaBitDepth; + u32 luminanceBitCount; + u32 bumpBitCount; + u32 privateFormatBitCount; + }; + union + { + u32 rBitMask; + u32 yBitMask; + u32 stencilBitDepth; + u32 luminanceBitMask; + u32 bumpDuBitMask; + u32 operations; + }; + union + { + u32 gBitMask; + u32 uBitMask; + u32 zBitMask; + u32 bumpDvBitMask; + ddsMultiSampleCaps multiSampleCaps; + }; + union + { + u32 bBitMask; + u32 vBitMask; + u32 stencilBitMask; + u32 bumpLuminanceBitMask; + }; + union + { + u32 rgbAlphaBitMask; + u32 yuvAlphaBitMask; + u32 luminanceAlphaBitMask; + u32 rgbZBitMask; + u32 yuvZBitMask; + }; +} PACK_STRUCT; + + +struct ddsBuffer +{ + /* magic: 'dds ' */ + c8 magic[ 4 ]; + + /* directdraw surface */ + u32 size; + u32 flags; + u32 height; + u32 width; + union + { + s32 pitch; + u32 linearSize; + }; + u32 backBufferCount; + union + { + u32 mipMapCount; + u32 refreshRate; + u32 srcVBHandle; + }; + u32 alphaBitDepth; + u32 reserved; + void *surface; + union + { + ddsColorKey ckDestOverlay; + u32 emptyFaceColor; + }; + ddsColorKey ckDestBlt; + ddsColorKey ckSrcOverlay; + ddsColorKey ckSrcBlt; + union + { + ddsPixelFormat pixelFormat; + u32 fvf; + }; + ddsCaps caps; + u32 textureStage; + + /* data (Varying size) */ + u8 data[ 4 ]; +} PACK_STRUCT; + + +struct ddsColorBlock +{ + u16 colors[ 2 ]; + u8 row[ 4 ]; +} PACK_STRUCT; + + +struct ddsAlphaBlockExplicit +{ + u16 row[ 4 ]; +} PACK_STRUCT; + + +struct ddsAlphaBlock3BitLinear +{ + u8 alpha0; + u8 alpha1; + u8 stuff[ 6 ]; +} PACK_STRUCT; + + +struct ddsColor +{ + u8 r, g, b, a; +} PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + +/* endian tomfoolery */ +typedef union +{ + f32 f; + c8 c[ 4 ]; +} +floatSwapUnion; + + +#ifndef __BIG_ENDIAN__ +#ifdef _SGI_SOURCE +#define __BIG_ENDIAN__ +#endif +#endif + + +#ifdef __BIG_ENDIAN__ + + s32 DDSBigLong( s32 src ) { return src; } + s16 DDSBigShort( s16 src ) { return src; } + f32 DDSBigFloat( f32 src ) { return src; } + + s32 DDSLittleLong( s32 src ) + { + return ((src & 0xFF000000) >> 24) | + ((src & 0x00FF0000) >> 8) | + ((src & 0x0000FF00) << 8) | + ((src & 0x000000FF) << 24); + } + + s16 DDSLittleShort( s16 src ) + { + return ((src & 0xFF00) >> 8) | + ((src & 0x00FF) << 8); + } + + f32 DDSLittleFloat( f32 src ) + { + floatSwapUnion in,out; + in.f = src; + out.c[ 0 ] = in.c[ 3 ]; + out.c[ 1 ] = in.c[ 2 ]; + out.c[ 2 ] = in.c[ 1 ]; + out.c[ 3 ] = in.c[ 0 ]; + return out.f; + } + +#else /*__BIG_ENDIAN__*/ + + s32 DDSLittleLong( s32 src ) { return src; } + s16 DDSLittleShort( s16 src ) { return src; } + f32 DDSLittleFloat( f32 src ) { return src; } + + s32 DDSBigLong( s32 src ) + { + return ((src & 0xFF000000) >> 24) | + ((src & 0x00FF0000) >> 8) | + ((src & 0x0000FF00) << 8) | + ((src & 0x000000FF) << 24); + } + + s16 DDSBigShort( s16 src ) + { + return ((src & 0xFF00) >> 8) | + ((src & 0x00FF) << 8); + } + + f32 DDSBigFloat( f32 src ) + { + floatSwapUnion in,out; + in.f = src; + out.c[ 0 ] = in.c[ 3 ]; + out.c[ 1 ] = in.c[ 2 ]; + out.c[ 2 ] = in.c[ 1 ]; + out.c[ 3 ] = in.c[ 0 ]; + return out.f; + } + +#endif /*__BIG_ENDIAN__*/ + + +/*! + Surface Loader for DDS images +*/ +class CImageLoaderDDS : public IImageLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; +}; + + +} // end namespace video +} // end namespace irr + +#endif // compiled with DDS loader +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.cpp new file mode 100644 index 0000000..8fc5222 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.cpp @@ -0,0 +1,306 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderJPG.h" + +#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ + +#include "IReadFile.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +// Static members +io::path CImageLoaderJPG::Filename; + +//! constructor +CImageLoaderJPG::CImageLoaderJPG() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderJPG"); + #endif +} + + + +//! destructor +CImageLoaderJPG::~CImageLoaderJPG() +{ +} + + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderJPG::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "jpg", "jpeg" ); +} + + +#ifdef _IRR_COMPILE_WITH_LIBJPEG_ + + // struct for handling jpeg errors + struct irr_jpeg_error_mgr + { + // public jpeg error fields + struct jpeg_error_mgr pub; + + // for longjmp, to return to caller on a fatal error + jmp_buf setjmp_buffer; + }; + +void CImageLoaderJPG::init_source (j_decompress_ptr cinfo) +{ + // DO NOTHING +} + + + +boolean CImageLoaderJPG::fill_input_buffer (j_decompress_ptr cinfo) +{ + // DO NOTHING + return 1; +} + + + +void CImageLoaderJPG::skip_input_data (j_decompress_ptr cinfo, long count) +{ + jpeg_source_mgr * src = cinfo->src; + if(count > 0) + { + src->bytes_in_buffer -= count; + src->next_input_byte += count; + } +} + + + +void CImageLoaderJPG::term_source (j_decompress_ptr cinfo) +{ + // DO NOTHING +} + + +void CImageLoaderJPG::error_exit (j_common_ptr cinfo) +{ + // unfortunately we need to use a goto rather than throwing an exception + // as gcc crashes under linux crashes when using throw from within + // extern c code + + // Always display the message + (*cinfo->err->output_message) (cinfo); + + // cinfo->err really points to a irr_error_mgr struct + irr_jpeg_error_mgr *myerr = (irr_jpeg_error_mgr*) cinfo->err; + + longjmp(myerr->setjmp_buffer, 1); +} + + +void CImageLoaderJPG::output_message(j_common_ptr cinfo) +{ + // display the error message. + c8 temp1[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, temp1); + core::stringc errMsg("JPEG FATAL ERROR in "); + errMsg += core::stringc(Filename); + os::Printer::log(errMsg.c_str(),temp1, ELL_ERROR); +} +#endif // _IRR_COMPILE_WITH_LIBJPEG_ + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const +{ + #ifndef _IRR_COMPILE_WITH_LIBJPEG_ + return false; + #else + + if (!file) + return false; + + s32 jfif = 0; + file->seek(6); + file->read(&jfif, sizeof(s32)); + return (jfif == 0x4a464946 || jfif == 0x4649464a); + + #endif +} + +//! creates a surface from the file +IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const +{ + #ifndef _IRR_COMPILE_WITH_LIBJPEG_ + os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG); + return 0; + #else + + if (!file) + return 0; + + Filename = file->getFileName(); + + u8 **rowPtr=0; + u8* input = new u8[file->getSize()]; + file->read(input, file->getSize()); + + // allocate and initialize JPEG decompression object + struct jpeg_decompress_struct cinfo; + struct irr_jpeg_error_mgr jerr; + + //We have to set up the error handler first, in case the initialization + //step fails. (Unlikely, but it could happen if you are out of memory.) + //This routine fills in the contents of struct jerr, and returns jerr's + //address which we place into the link field in cinfo. + + cinfo.err = jpeg_std_error(&jerr.pub); + cinfo.err->error_exit = error_exit; + cinfo.err->output_message = output_message; + + // compatibility fudge: + // we need to use setjmp/longjmp for error handling as gcc-linux + // crashes when throwing within external c code + if (setjmp(jerr.setjmp_buffer)) + { + // If we get here, the JPEG code has signaled an error. + // We need to clean up the JPEG object and return. + + jpeg_destroy_decompress(&cinfo); + + delete [] input; + // if the row pointer was created, we delete it. + if (rowPtr) + delete [] rowPtr; + + // return null pointer + return 0; + } + + // Now we can initialize the JPEG decompression object. + jpeg_create_decompress(&cinfo); + + // specify data source + jpeg_source_mgr jsrc; + + // Set up data pointer + jsrc.bytes_in_buffer = file->getSize(); + jsrc.next_input_byte = (JOCTET*)input; + cinfo.src = &jsrc; + + jsrc.init_source = init_source; + jsrc.fill_input_buffer = fill_input_buffer; + jsrc.skip_input_data = skip_input_data; + jsrc.resync_to_restart = jpeg_resync_to_restart; + jsrc.term_source = term_source; + + // Decodes JPG input from whatever source + // Does everything AFTER jpeg_create_decompress + // and BEFORE jpeg_destroy_decompress + // Caller is responsible for arranging these + setting up cinfo + + // read file parameters with jpeg_read_header() + jpeg_read_header(&cinfo, TRUE); + + bool useCMYK=false; + if (cinfo.jpeg_color_space==JCS_CMYK) + { + cinfo.out_color_space=JCS_CMYK; + cinfo.out_color_components=4; + useCMYK=true; + } + else + { + cinfo.out_color_space=JCS_RGB; + cinfo.out_color_components=3; + } + cinfo.output_gamma=2.2; + cinfo.do_fancy_upsampling=FALSE; + + // Start decompressor + jpeg_start_decompress(&cinfo); + + // Get image data + u16 rowspan = cinfo.image_width * cinfo.out_color_components; + u32 width = cinfo.image_width; + u32 height = cinfo.image_height; + + // Allocate memory for buffer + u8* output = new u8[rowspan * height]; + + // Here we use the library's state variable cinfo.output_scanline as the + // loop counter, so that we don't have to keep track ourselves. + // Create array of row pointers for lib + rowPtr = new u8* [height]; + + for( u32 i = 0; i < height; i++ ) + rowPtr[i] = &output[ i * rowspan ]; + + u32 rowsRead = 0; + + while( cinfo.output_scanline < cinfo.output_height ) + rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead ); + + delete [] rowPtr; + // Finish decompression + + jpeg_finish_decompress(&cinfo); + + // Release JPEG decompression object + // This is an important step since it will release a good deal of memory. + jpeg_destroy_decompress(&cinfo); + + // convert image + IImage* image = 0; + if (useCMYK) + { + image = new CImage(ECF_R8G8B8, + core::dimension2d(width, height)); + const u32 size = 3*width*height; + u8* data = (u8*)image->lock(); + if (data) + { + for (u32 i=0,j=0; iunlock(); + delete [] output; + } + else + image = new CImage(ECF_R8G8B8, + core::dimension2d(width, height), output); + + delete [] input; + + return image; + + #endif +} + + + +//! creates a loader which is able to load jpeg images +IImageLoader* createImageLoaderJPG() +{ + return new CImageLoaderJPG(); +} + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.h new file mode 100644 index 0000000..d3d0633 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderJPG.h @@ -0,0 +1,116 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_JPG_H_INCLUDED__ +#define __C_IMAGE_LOADER_JPG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ + +#include "IImageLoader.h" + +#include // required for jpeglib.h +#ifdef _IRR_COMPILE_WITH_LIBJPEG_ +extern "C" { + #ifndef _IRR_USE_NON_SYSTEM_JPEG_LIB_ + #include // use system lib + #else + #include "jpeglib/jpeglib.h" // use irrlicht jpeglib + #endif + #include +} +#endif // _IRR_COMPILE_WITH_LIBJPEG_ + + +namespace irr +{ +namespace video +{ + + +//! Surface Loader for JPG images +class CImageLoaderJPG : public IImageLoader +{ +public: + + //! constructor + CImageLoaderJPG(); + + //! destructor + virtual ~CImageLoaderJPG(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + #ifdef _IRR_COMPILE_WITH_LIBJPEG_ + // several methods used via function pointers by jpeglib + + /* Receives control for a fatal error. Information sufficient to + generate the error message has been stored in cinfo->err; call + output_message to display it. Control must NOT return to the caller; + generally this routine will exit() or longjmp() somewhere. + Typically you would override this routine to get rid of the exit() + default behavior. Note that if you continue processing, you should + clean up the JPEG object with jpeg_abort() or jpeg_destroy(). + */ + static void error_exit (j_common_ptr cinfo); + + /* output error messages via Irrlicht logger. */ + static void output_message(j_common_ptr cinfo); + + /* Initialize source. This is called by jpeg_read_header() before any + data is actually read. Unlike init_destination(), it may leave + bytes_in_buffer set to 0 (in which case a fill_input_buffer() call + will occur immediately). */ + static void init_source (j_decompress_ptr cinfo); + + /* This is called whenever bytes_in_buffer has reached zero and more + data is wanted. In typical applications, it should read fresh data + into the buffer (ignoring the current state of next_input_byte and + bytes_in_buffer), reset the pointer & count to the start of the + buffer, and return TRUE indicating that the buffer has been reloaded. + It is not necessary to fill the buffer entirely, only to obtain at + least one more byte. bytes_in_buffer MUST be set to a positive value + if TRUE is returned. A FALSE return should only be used when I/O + suspension is desired (this mode is discussed in the next section). */ + static boolean fill_input_buffer (j_decompress_ptr cinfo); + + /* Skip num_bytes worth of data. The buffer pointer and count should + be advanced over num_bytes input bytes, refilling the buffer as + needed. This is used to skip over a potentially large amount of + uninteresting data (such as an APPn marker). In some applications + it may be possible to optimize away the reading of the skipped data, + but it's not clear that being smart is worth much trouble; large + skips are uncommon. bytes_in_buffer may be zero on return. + A zero or negative skip count should be treated as a no-op. */ + static void skip_input_data (j_decompress_ptr cinfo, long num_bytes); + + /* Terminate source --- called by jpeg_finish_decompress() after all + data has been read. Often a no-op. */ + static void term_source (j_decompress_ptr cinfo); + + // Copy filename to have it around for error-messages + static io::path Filename; + + #endif // _IRR_COMPILE_WITH_LIBJPEG_ +}; + + +} // end namespace video +} // end namespace irr + + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.cpp new file mode 100644 index 0000000..50ddf6e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.cpp @@ -0,0 +1,231 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPCX.h" + +#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ + +#include "IReadFile.h" +#include "SColor.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPCX::CImageLoaderPCX() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPCX"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPCX::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "pcx" ); +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPCX::isALoadableFileFormat(io::IReadFile* file) const +{ + u8 headerID; + file->read(&headerID, sizeof(headerID)); + return headerID == 0x0a; +} + + +//! creates a image from the file +IImage* CImageLoaderPCX::loadImage(io::IReadFile* file) const +{ + SPCXHeader header; + s32* paletteData = 0; + + file->read(&header, sizeof(header)); + #ifdef __BIG_ENDIAN__ + header.XMin = os::Byteswap::byteswap(header.XMin); + header.YMin = os::Byteswap::byteswap(header.YMin); + header.XMax = os::Byteswap::byteswap(header.XMax); + header.YMax = os::Byteswap::byteswap(header.YMax); + header.HorizDPI = os::Byteswap::byteswap(header.HorizDPI); + header.VertDPI = os::Byteswap::byteswap(header.VertDPI); + header.BytesPerLine = os::Byteswap::byteswap(header.BytesPerLine); + header.PaletteType = os::Byteswap::byteswap(header.PaletteType); + header.HScrSize = os::Byteswap::byteswap(header.HScrSize); + header.VScrSize = os::Byteswap::byteswap(header.VScrSize); + #endif + + //! return if the header is wrong + if (header.Manufacturer != 0x0a && header.Encoding != 0x01) + return 0; + + // return if this isn't a supported type + if ((header.BitsPerPixel != 8) && (header.BitsPerPixel != 4) && (header.BitsPerPixel != 1)) + { + os::Printer::log("Unsupported bits per pixel in PCX file.", + file->getFileName(), irr::ELL_WARNING); + return 0; + } + + // read palette + if( (header.BitsPerPixel == 8) && (header.Planes == 1) ) + { + // the palette indicator (usually a 0x0c is found infront of the actual palette data) + // is ignored because some exporters seem to forget to write it. This would result in + // no image loaded before, now only wrong colors will be set. + const long pos = file->getPos(); + file->seek( file->getSize()-256*3, false ); + + u8 *tempPalette = new u8[768]; + paletteData = new s32[256]; + file->read( tempPalette, 768 ); + + for( s32 i=0; i<256; i++ ) + { + paletteData[i] = (0xff000000 | + (tempPalette[i*3+0] << 16) | + (tempPalette[i*3+1] << 8) | + (tempPalette[i*3+2])); + } + + delete [] tempPalette; + + file->seek(pos); + } + else if( header.BitsPerPixel == 4 ) + { + paletteData = new s32[16]; + for( s32 i=0; i<16; i++ ) + { + paletteData[i] = (0xff000000 | + (header.Palette[i*3+0] << 16) | + (header.Palette[i*3+1] << 8) | + (header.Palette[i*3+2])); + } + } + + // read image data + const s32 width = header.XMax - header.XMin + 1; + const s32 height = header.YMax - header.YMin + 1; + const s32 imagebytes = header.BytesPerLine * header.Planes * header.BitsPerPixel * height / 8; + u8* PCXData = new u8[imagebytes]; + + u8 cnt, value; + s32 lineoffset=0, linestart=0, nextmode=1; + for(s32 offset = 0; offset < imagebytes; offset += cnt) + { + file->read(&cnt, 1); + if( !((cnt & 0xc0) == 0xc0) ) + { + value = cnt; + cnt = 1; + } + else + { + cnt &= 0x3f; + file->read(&value, 1); + } + if (header.Planes==1) + memset(PCXData+offset, value, cnt); + else + { + for (u8 i=0; i=3*header.BytesPerLine) + { + lineoffset=nextmode; + if (++nextmode==3) + nextmode=0; + if (lineoffset==0) + linestart += 3*header.BytesPerLine; + } + } + } + } + + // create image + video::IImage* image = 0; + s32 pad = (header.BytesPerLine - width * header.BitsPerPixel / 8) * header.Planes; + + if (pad < 0) + pad = -pad; + + if (header.BitsPerPixel==8) + { + switch(header.Planes) // TODO: Other formats + { + case 1: + image = new CImage(ECF_A1R5G5B5, core::dimension2d(width, height)); + if (image) + CColorConverter::convert8BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad); + break; + case 3: + image = new CImage(ECF_R8G8B8, core::dimension2d(width, height)); + if (image) + CColorConverter::convert24BitTo24Bit(PCXData, (u8*)image->lock(), width, height, pad); + break; + } + } + else if (header.BitsPerPixel==4) + { + if (header.Planes==1) + { + image = new CImage(ECF_A1R5G5B5, core::dimension2d(width, height)); + if (image) + CColorConverter::convert4BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad); + } + } + else if (header.BitsPerPixel==1) + { + if (header.Planes==4) + { + image = new CImage(ECF_A1R5G5B5, core::dimension2d(width, height)); + if (image) + CColorConverter::convert4BitTo16Bit(PCXData, (s16*)image->lock(), width, height, paletteData, pad); + } + else if (header.Planes==1) + { + image = new CImage(ECF_A1R5G5B5, core::dimension2d(width, height)); + if (image) + CColorConverter::convert1BitTo16Bit(PCXData, (s16*)image->lock(), width, height, pad); + } + } + if (image) + image->unlock(); + + // clean up + + delete [] paletteData; + delete [] PCXData; + + return image; +} + + +//! creates a loader which is able to load pcx images +IImageLoader* createImageLoaderPCX() +{ + return new CImageLoaderPCX(); +} + + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.h new file mode 100644 index 0000000..4bd3b7f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPCX.h @@ -0,0 +1,82 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_PCX_H_INCLUDED__ +#define __C_IMAGE_LOADER_PCX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + +#if defined(_IRR_COMPILE_WITH_PCX_LOADER_) || defined(_IRR_COMPILE_WITH_PCX_WRITER_) + +// byte-align structures +#include "irrpack.h" + + struct SPCXHeader + { + u8 Manufacturer; + u8 Version; + u8 Encoding; + u8 BitsPerPixel; + u16 XMin; + u16 YMin; + u16 XMax; + u16 YMax; + u16 HorizDPI; + u16 VertDPI; + u8 Palette[48]; + u8 Reserved; + u8 Planes; + u16 BytesPerLine; + u16 PaletteType; + u16 HScrSize; + u16 VScrSize; + u8 Filler[54]; + } PACK_STRUCT; + + +// Default alignment +#include "irrunpack.h" + +#endif // compile with loader or writer + +#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ + +/*! + Image Loader for Windows PCX bitmaps. + This loader was written and sent in by Dean P. Macri. I modified + only some small bits of it. +*/ +class CImageLoaderPCX : public IImageLoader +{ +public: + + //! constructor + CImageLoaderPCX(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +}; + +#endif // compile with loader + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp new file mode 100644 index 0000000..3dbbe1c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.cpp @@ -0,0 +1,290 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPNG.h" + +#ifdef _IRR_COMPILE_WITH_PNG_LOADER_ + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + #ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include // use system lib png + #else // _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include "libpng/png.h" // use irrlicht included lib png + #endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ +#endif // _IRR_COMPILE_WITH_LIBPNG_ + +#include "CImage.h" +#include "CReadFile.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ +// PNG function for error handling +static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) +{ + os::Printer::log("PNG fatal error", msg, ELL_ERROR); + longjmp(png_jmpbuf(png_ptr), 1); +} + +// PNG function for warning handling +static void png_cpexcept_warn(png_structp png_ptr, png_const_charp msg) +{ + os::Printer::log("PNG warning", msg, ELL_WARNING); +} + +// PNG function for file reading +void PNGAPI user_read_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + // changed by zola { + io::IReadFile* file=(io::IReadFile*)png_get_io_ptr(png_ptr); + check=(png_size_t) file->read((void*)data,(u32)length); + // } + + if (check != length) + png_error(png_ptr, "Read Error"); +} +#endif // _IRR_COMPILE_WITH_LIBPNG_ + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPng::isALoadableFileExtension(const io::path& filename) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + return core::hasFileExtension ( filename, "png" ); +#else + return false; +#endif // _IRR_COMPILE_WITH_LIBPNG_ +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + if (!file) + return false; + + png_byte buffer[8]; + // Read the first few bytes of the PNG file + if (file->read(buffer, 8) != 8) + return false; + + // Check if it really is a PNG file + return !png_sig_cmp(buffer, 0, 8); +#else + return false; +#endif // _IRR_COMPILE_WITH_LIBPNG_ +} + + +// load in the image data +IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + if (!file) + return 0; + + video::IImage* image = 0; + //Used to point to image rows + u8** RowPointers = 0; + + png_byte buffer[8]; + // Read the first few bytes of the PNG file + if( file->read(buffer, 8) != 8 ) + { + os::Printer::log("LOAD PNG: can't read file\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // Check if it really is a PNG file + if( png_sig_cmp(buffer, 0, 8) ) + { + os::Printer::log("LOAD PNG: not really a png\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // Allocate the png read struct + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warn); + if (!png_ptr) + { + os::Printer::log("LOAD PNG: Internal PNG create read struct failure\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // Allocate the png info struct + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + os::Printer::log("LOAD PNG: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 0; + } + + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + if (RowPointers) + delete [] RowPointers; + return 0; + } + + // changed by zola so we don't need to have public FILE pointers + png_set_read_fn(png_ptr, file, user_read_data_fcn); + + png_set_sig_bytes(png_ptr, 8); // Tell png that we read the signature + + png_read_info(png_ptr, info_ptr); // Read the info section of the png file + + u32 Width; + u32 Height; + s32 BitDepth; + s32 ColorType; + { + // Use temporary variables to avoid passing casted pointers + png_uint_32 w,h; + // Extract info + png_get_IHDR(png_ptr, info_ptr, + &w, &h, + &BitDepth, &ColorType, NULL, NULL, NULL); + Width=w; + Height=h; + } + + // Convert palette color to true color + if (ColorType==PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + // Convert low bit colors to 8 bit colors + if (BitDepth < 8) + { + if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_expand_gray_1_2_4_to_8(png_ptr); + else + png_set_packing(png_ptr); + } + + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + + // Convert high bit colors to 8 bit colors + if (BitDepth == 16) + png_set_strip_16(png_ptr); + + // Convert gray color to true color + if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + int intent; + const double screen_gamma = 2.2; + + if (png_get_sRGB(png_ptr, info_ptr, &intent)) + png_set_gamma(png_ptr, screen_gamma, 0.45455); + else + { + double image_gamma; + if (png_get_gAMA(png_ptr, info_ptr, &image_gamma)) + png_set_gamma(png_ptr, screen_gamma, image_gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + } + + // Update the changes in between, as we need to get the new color type + // for proper processing of the RGBA type + png_read_update_info(png_ptr, info_ptr); + { + // Use temporary variables to avoid passing casted pointers + png_uint_32 w,h; + // Extract info + png_get_IHDR(png_ptr, info_ptr, + &w, &h, + &BitDepth, &ColorType, NULL, NULL, NULL); + Width=w; + Height=h; + } + + // Convert RGBA to BGRA + if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) + { +#ifdef __BIG_ENDIAN__ + png_set_swap_alpha(png_ptr); +#else + png_set_bgr(png_ptr); +#endif + } + + // Create the image structure to be filled by png data + if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA) + image = new CImage(ECF_A8R8G8B8, core::dimension2d(Width, Height)); + else + image = new CImage(ECF_R8G8B8, core::dimension2d(Width, Height)); + if (!image) + { + os::Printer::log("LOAD PNG: Internal PNG create image struct failure\n", file->getFileName(), ELL_ERROR); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return 0; + } + + // Create array of pointers to rows in image data + RowPointers = new png_bytep[Height]; + if (!RowPointers) + { + os::Printer::log("LOAD PNG: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); + png_destroy_read_struct(&png_ptr, NULL, NULL); + delete image; + return 0; + } + + // Fill array of pointers to rows in image data + unsigned char* data = (unsigned char*)image->lock(); + for (u32 i=0; igetPitch(); + } + + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + delete [] RowPointers; + image->unlock(); + delete [] image; + return 0; + } + + // Read data using the library function that handles all transformations including interlacing + png_read_image(png_ptr, RowPointers); + + png_read_end(png_ptr, NULL); + delete [] RowPointers; + image->unlock(); + png_destroy_read_struct(&png_ptr,&info_ptr, 0); // Clean up memory + + return image; +#else + return 0; +#endif // _IRR_COMPILE_WITH_LIBPNG_ +} + + +IImageLoader* createImageLoaderPNG() +{ + return new CImageLoaderPng(); +} + + +}// end namespace irr +}//end namespace video + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.h new file mode 100644 index 0000000..a3faac2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPNG.h @@ -0,0 +1,45 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// this file was created by rt (www.tomkorp.com), based on ttk's png-reader +// i wanted to be able to read in PNG images with irrlicht :) +// why? lossless compression with 8-bit alpha channel! + +#ifndef __C_IMAGE_LOADER_PNG_H_INCLUDED__ +#define __C_IMAGE_LOADER_PNG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PNG_LOADER_ + +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + +//! Surface Loader for PNG files +class CImageLoaderPng : public IImageLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".png") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.cpp new file mode 100644 index 0000000..a0776fa --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPPM.h" + +#ifdef _IRR_COMPILE_WITH_PPM_LOADER_ + +#include "IReadFile.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "fast_atof.h" +#include "coreutil.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPPM::CImageLoaderPPM() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPPM"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPPM::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "ppm", "pgm", "pbm" ); +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPPM::isALoadableFileFormat(io::IReadFile* file) const +{ + c8 id[2]={0}; + file->read(&id, 2); + return (id[0]=='P' && id[1]>'0' && id[1]<'7'); +} + + +//! creates a surface from the file +IImage* CImageLoaderPPM::loadImage(io::IReadFile* file) const +{ + IImage* image; + + if (file->getSize() < 12) + return 0; + + c8 id[2]; + file->read(&id, 2); + + if (id[0]!='P' || id[1]<'1' || id[1]>'6') + return 0; + + const u8 format = id[1] - '0'; + const bool binary = format>3; + + core::stringc token; + getNextToken(file, token); + const u32 width = core::strtoul10(token.c_str()); + + getNextToken(file, token); + const u32 height = core::strtoul10(token.c_str()); + + u8* data = 0; + const u32 size = width*height; + if (format==1 || format==4) + { + skipToNextToken(file); // go to start of data + + const u32 bytesize = size/8+(size & 3)?1:0; + if (binary) + { + if (file->getSize()-file->getPos() < (long)bytesize) + return 0; + data = new u8[bytesize]; + file->read(data, bytesize); + } + else + { + if (file->getSize()-file->getPos() < (long)(2*size)) // optimistic test + return 0; + data = new u8[bytesize]; + memset(data, 0, bytesize); + u32 shift=0; + for (u32 i=0; i(width, height)); + if (image) + CColorConverter::convert1BitTo16Bit(data, (s16*)image->lock(), width, height); + } + else + { + getNextToken(file, token); + const u32 maxDepth = core::strtoul10(token.c_str()); + if (maxDepth > 255) // no double bytes yet + return 0; + + skipToNextToken(file); // go to start of data + + if (format==2 || format==5) + { + if (binary) + { + if (file->getSize()-file->getPos() < (long)size) + return 0; + data = new u8[size]; + file->read(data, size); + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; igetSize()-file->getPos() < (long)(2*size)) // optimistic test + return 0; + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; igetSize()-file->getPos() < (long)bytesize) + return 0; + data = new u8[bytesize]; + file->read(data, bytesize); + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; igetSize()-file->getPos() < (long)(2*bytesize)) // optimistic test + return 0; + image = new CImage(ECF_A8R8G8B8, core::dimension2d(width, height)); + if (image) + { + u8* ptr = (u8*)image->lock(); + for (u32 i=0; iunlock(); + + delete [] data; + + return image; +} + + +//! read the next token from file +void CImageLoaderPPM::getNextToken(io::IReadFile* file, core::stringc& token) const +{ + token = ""; + c8 c; + while(file->getPos()getSize()) + { + file->read(&c, 1); + if (c=='#') + { + while (c!='\n' && c!='\r' && (file->getPos()getSize())) + file->read(&c, 1); + } + else if (!core::isspace(c)) + { + token.append(c); + break; + } + } + while(file->getPos()getSize()) + { + file->read(&c, 1); + if (c=='#') + { + while (c!='\n' && c!='\r' && (file->getPos()getSize())) + file->read(&c, 1); + } + else if (!core::isspace(c)) + token.append(c); + else + break; + } +} + + +//! skip to next token (skip whitespace) +void CImageLoaderPPM::skipToNextToken(io::IReadFile* file) const +{ + c8 c; + while(file->getPos()getSize()) + { + file->read(&c, 1); + if (c=='#') + { + while (c!='\n' && c!='\r' && (file->getPos()getSize())) + file->read(&c, 1); + } + else if (!core::isspace(c)) + { + file->seek(-1, true); // put back + break; + } + } +} + + +//! creates a loader which is able to load windows bitmaps +IImageLoader* createImageLoaderPPM() +{ + return new CImageLoaderPPM; +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.h new file mode 100644 index 0000000..3c015a8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPPM.h @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_PPM_H_INCLUDED__ +#define __C_IMAGE_LOADER_PPM_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PPM_LOADER_ + +#include "IImageLoader.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +/*! + Surface Loader for SUN Pixmaps +*/ +class CImageLoaderPPM : public IImageLoader +{ +public: + + //! constructor + CImageLoaderPPM(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + //! read the next token from file + void getNextToken(io::IReadFile* file, core::stringc& token) const; + //! skip to next token (skip whitespace) + void skipToNextToken(io::IReadFile* file) const; +}; + +} // end namespace video +} // end namespace irr + + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp new file mode 100644 index 0000000..3eb5c3b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderPSD.cpp @@ -0,0 +1,375 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderPSD.h" + +#ifdef _IRR_COMPILE_WITH_PSD_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CImage.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +//! constructor +CImageLoaderPSD::CImageLoaderPSD() +{ + #ifdef _DEBUG + setDebugName("CImageLoaderPSD"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderPSD::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "psd" ); +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderPSD::isALoadableFileFormat(io::IReadFile* file) const +{ + if (!file) + return false; + + u8 type[3]; + file->read(&type, sizeof(u8)*3); + return (type[2]==2); // we currently only handle tgas of type 2. +} + + + +//! creates a surface from the file +IImage* CImageLoaderPSD::loadImage(io::IReadFile* file) const +{ + u32* imageData = 0; + + PsdHeader header; + file->read(&header, sizeof(PsdHeader)); + +#ifndef __BIG_ENDIAN__ + header.version = os::Byteswap::byteswap(header.version); + header.channels = os::Byteswap::byteswap(header.channels); + header.height = os::Byteswap::byteswap(header.height); + header.width = os::Byteswap::byteswap(header.width); + header.depth = os::Byteswap::byteswap(header.depth); + header.mode = os::Byteswap::byteswap(header.mode); +#endif + + if (header.signature[0] != '8' || + header.signature[1] != 'B' || + header.signature[2] != 'P' || + header.signature[3] != 'S') + return 0; + + if (header.version != 1) + { + os::Printer::log("Unsupported PSD file version", file->getFileName(), ELL_ERROR); + return 0; + } + + if (header.mode != 3 || header.depth != 8) + { + os::Printer::log("Unsupported PSD color mode or depth.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip color mode data + + u32 l; + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to image resources.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip image resources + + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to layer and mask.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // skip layer & mask + + file->read(&l, sizeof(u32)); +#ifndef __BIG_ENDIAN__ + l = os::Byteswap::byteswap(l); +#endif + if (!file->seek(l, true)) + { + os::Printer::log("Error seeking file pos to image data section.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // read image data + + u16 compressionType; + file->read(&compressionType, sizeof(u16)); +#ifndef __BIG_ENDIAN__ + compressionType = os::Byteswap::byteswap(compressionType); +#endif + + if (compressionType != 1 && compressionType != 0) + { + os::Printer::log("Unsupported psd compression mode.\n", file->getFileName(), ELL_ERROR); + return 0; + } + + // create image data block + + imageData = new u32[header.width * header.height]; + + bool res = false; + + if (compressionType == 0) + res = readRawImageData(file, header, imageData); // RAW image data + else + res = readRLEImageData(file, header, imageData); // RLE compressed data + + video::IImage* image = 0; + + if (res) + { + // create surface + image = new CImage(ECF_A8R8G8B8, + core::dimension2d(header.width, header.height), imageData); + } + + if (!image) + delete [] imageData; + imageData = 0; + + return image; +} + + +bool CImageLoaderPSD::readRawImageData(io::IReadFile* file, const PsdHeader& header, u32* imageData) const +{ + u8* tmpData = new u8[header.width * header.height]; + + for (s32 channel=0; channelread(tmpData, sizeof(c8) * header.width * header.height)) + { + os::Printer::log("Error reading color channel\n", file->getFileName(), ELL_ERROR); + break; + } + + s16 shift = getShiftFromChannel((c8)channel, header); + if (shift != -1) + { + u32 mask = 0xff << shift; + + for (u32 x=0; xread(&rleCount[y], sizeof(u16))) + { + delete [] tmpData; + delete [] rleCount; + os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); + return false; + } + +#ifndef __BIG_ENDIAN__ + rleCount[y] = os::Byteswap::byteswap(rleCount[y]); +#endif + size += rleCount[y]; + } + + s8 *buf = new s8[size]; + if (!file->read(buf, size)) + { + delete [] rleCount; + delete [] buf; + delete [] tmpData; + os::Printer::log("Error reading rle rows\n", file->getFileName(), ELL_ERROR); + return false; + } + + u16 *rcount=rleCount; + + s8 rh; + u16 bytesRead; + u8 *dest; + s8 *pBuf = buf; + + // decompress packbit rle + + for (s32 channel=0; channel= 0) + { + ++rh; + + while (rh--) + { + *dest = *pBuf++; + ++bytesRead; + ++dest; + } + } + else + if (rh > -128) + { + rh = -rh +1; + + while (rh--) + { + *dest = *pBuf; + ++dest; + } + + ++pBuf; + ++bytesRead; + } + } + } + + s16 shift = getShiftFromChannel((c8)channel, header); + + if (shift != -1) + { + u32 mask = 0xff << shift; + + for (u32 x=0; xgetFileName(), ELL_ERROR); + } + else if (rgb.Header.Colormap != 0) + { + os::Printer::log("Dithered, Screen and Colormap RGB files are not supported", file->getFileName(), ELL_ERROR); + } + else if (rgb.Header.Storage == 1 && !readOffsetTables(file, rgb)) + { + os::Printer::log("Failed to read RLE table in RGB file", file->getFileName(), ELL_ERROR); + } + else if (!rgb.allocateTemps()) + { + os::Printer::log("Out of memory in RGB file loader", file->getFileName(), ELL_ERROR); + } + else + { + // read and process the file to rgbData + processFile(file, rgb); + +/* + ZSIZE Description + 1 BW (grayscale) image + 3 RGB image + 4 RGBa image with one alpha channel + + When the Alpha channel is present, I am not sure with RGB files if + it's a precomputed RGB color or it needs to be completely calculated. My guess + would be that it's not precomputed for two reasons. + + 1. the loss of precision when calculating the fraction, then storing the result as an int + 2. the loss of the original color data when the image might be composited with another. Yes + the original color data could be computed, however, not without another loss in precision + + Also, I don't know where to find the background color + Pixmin and Pixmax are apparently the min and max alpha blend values (0-100%) + + Complete Alpha blending computation + The actual resulting merged color is computed this way: + (image color â—Š alpha) + (background color â—Š (100% - alpha)). + + Using precomputed blending + (image color) + (background color â—Š (100% - alpha)). + + Alternatively, the RGB files could use another blending technique entirely +*/ + + switch (rgb.Header.Zsize) + { + case 1: + // BW (grayscale) image + paletteData = new s32[256]; + for (int n=0; n<256; n++) + paletteData[n] = n; + + image = new CImage(ECF_A1R5G5B5, core::dimension2d(rgb.Header.Xsize, rgb.Header.Ysize)); + if (image) + CColorConverter::convert8BitTo16Bit(rgb.rgbData, (s16*)image->lock(), rgb.Header.Xsize, rgb.Header.Ysize, paletteData, 0, true); + break; + case 3: + // RGB image + // one byte per COLOR VALUE, eg, 24bpp + image = new CImage(ECF_R8G8B8, core::dimension2d(rgb.Header.Xsize, rgb.Header.Ysize)); + if (image) + CColorConverter::convert24BitTo24Bit(rgb.rgbData, (u8*)image->lock(), rgb.Header.Xsize, rgb.Header.Ysize, 0, true, false); + break; + case 4: + // RGBa image with one alpha channel (32bpp) + // image is stored in rgbData as RGBA + + converttoARGB(reinterpret_cast(rgb.rgbData), rgb.Header.Ysize * rgb.Header.Xsize); + + image = new CImage(ECF_A8R8G8B8, core::dimension2d(rgb.Header.Xsize, rgb.Header.Ysize)); + if (image) + CColorConverter::convert32BitTo32Bit((s32*)rgb.rgbData, (s32*)image->lock(), rgb.Header.Xsize, rgb.Header.Ysize, 0, true); + + break; + default: + // Format unknown + os::Printer::log("Unsupported pixel format in RGB file", file->getFileName(), ELL_ERROR); + } + + if (image) + image->unlock(); + } + } + + // and tidy up allocated memory + delete [] paletteData; + + return image; +} + +// returns true on success +bool CImageLoaderRGB::readHeader(io::IReadFile* file, rgbStruct& rgb) const +{ + if ( file->read(&rgb.Header, sizeof(rgb.Header)) < s32(sizeof(rgb.Header)) ) + return false; + + // test for INTEL or BIG ENDIAN processor + // if INTEL, then swap the byte order on 16 bit INT's to make them BIG ENDIAN + // because that is the native format for the .rgb file +#ifndef __BIG_ENDIAN__ + rgb.Header.Magic = os::Byteswap::byteswap(rgb.Header.Magic); + rgb.Header.Storage = os::Byteswap::byteswap(rgb.Header.Storage); + rgb.Header.Dimension = os::Byteswap::byteswap(rgb.Header.Dimension); + rgb.Header.Xsize = os::Byteswap::byteswap(rgb.Header.Xsize); + rgb.Header.Ysize = os::Byteswap::byteswap(rgb.Header.Ysize); + rgb.Header.Zsize = os::Byteswap::byteswap(rgb.Header.Zsize); + rgb.Header.Pixmin = os::Byteswap::byteswap(rgb.Header.Pixmin); + rgb.Header.Pixmax = os::Byteswap::byteswap(rgb.Header.Pixmax); + rgb.Header.Colormap = os::Byteswap::byteswap(rgb.Header.Colormap); +#endif + + // calculate the size of the buffer needed: XSIZE * YSIZE * ZSIZE * BPC + rgb.ImageSize = (rgb.Header.Xsize)*(rgb.Header.Ysize)*(rgb.Header.Zsize)*(rgb.Header.BPC); + + return true; +} + + +bool CImageLoaderRGB::checkFormat(io::IReadFile* file, rgbStruct& rgb) const +{ + if (!readHeader(file, rgb)) + return false; + + return (rgb.Header.Magic == 0x1DA); +} + +/* +If the image is stored using run length encoding, offset tables follow the Header that +describe what the file offsets are to the RLE for each scanline. This information only +applies if the value for STORAGE above is 1. + + Size | Type | Name | Description + + tablen longs | long | STARTTAB | Start table + tablen longs | long | LENGTHTAB | Length table + +One entry in each table is needed for each scanline of RLE data. The total number of scanlines in the image (tablen) is determined by the product of the YSIZE and ZSIZE. There are two tables of longs that are written. Each consists of tablen longs of data. The first table has the file offsets to the RLE data for each scanline in the image. In a file with more than 1 channel (ZSIZE > 1) this table first has all the offsets for the scanlines in the first channel, followed be offsets for the scanlines in the second channel, etc. The second table has the RLE data length for each scanline in the image. In a file with more than 1 channel (ZSIZE > 1) this table first has all the RLE data lengths for the scanlines in the first channel, followed be RLE data lengths for the scanlines in the second channel, etc. + +To find the the file offset, and the number of bytes in the RLE data for a particular scanline, these +two arrays may be read in and indexed as follows: + +To read in the tables: + + unsigned long *starttab, *lengthtab; + + tablen = YSIZE*ZSIZE*sizeof(long); + starttab = (unsigned long *)mymalloc(tablen); + lengthtab = (unsigned long *)mymalloc(tablen); + fseek(rgb->inf,512,SEEK_SET); + readlongtab(rgb->inf,starttab); + readlongtab(rgb->inf,lengthtab); + +To find the file offset and RLE data length for a scanline: + +rowno is an integer in the range 0 to YSIZE-1 channo is an integer in the range 0 to ZSIZE-1 + + rleoffset = starttab[rowno+channo*YSIZE] + rlelength = lengthtab[rowno+channo*YSIZE] + +It is possible for two identical rows (scanlines) to share compressed data. A completely +white image could be written as a single compressed row and having all table entries point +to that row. Another little hack that should work is if you are writing out a RGB RLE file, +and a particular scanline is achromatic (greyscale), you could just make the r, g and b rows +point to the same data!! + + RETURNS: on success true, else returns false +*/ + +bool CImageLoaderRGB::readOffsetTables(io::IReadFile* file, rgbStruct& rgb) const +{ + rgb.TableLen = rgb.Header.Ysize * rgb.Header.Zsize ; // calc size of tables + + // return error if unable to allocate tables + rgb.StartTable = new u32[rgb.TableLen]; + if (!rgb.StartTable) + return false; + rgb.LengthTable = new u32[rgb.TableLen]; + if (!rgb.LengthTable) + return false; + + file->seek(512); + file->read(rgb.StartTable, rgb.TableLen* sizeof(u32)); + file->read(rgb.LengthTable, rgb.TableLen* sizeof(u32)); + + // if we are on an INTEL platform, swap the bytes +#ifndef __BIG_ENDIAN__ + const u32 length = rgb.TableLen; + for (u32 i=0; i=0; --i) +#endif + { + // check the number of channels and read a row of data + if (rgb.Header.Zsize >= 1) + readRGBrow( rgb.tmpR, i, 0, file, rgb); + if (rgb.Header.Zsize >= 2) + readRGBrow( rgb.tmpG, i, 1, file, rgb); + if (rgb.Header.Zsize >= 3) + readRGBrow( rgb.tmpB, i, 2, file, rgb); + if (rgb.Header.Zsize >= 4) + readRGBrow( rgb.tmpA, i, 3, file, rgb); + + // cycle thru all values for this row + for (u16 j = 0; j < rgb.Header.Xsize; ++j) + { + if(rgb.Header.BPC == 1) + { + // ONE byte per color + if (rgb.Header.Zsize >= 1) + *ptr++ = rgb.tmpR[j]; + if (rgb.Header.Zsize >= 2) + *ptr++ = rgb.tmpG[j]; + if (rgb.Header.Zsize >= 3) + *ptr++ = rgb.tmpB[j]; + if (rgb.Header.Zsize >= 4) + *ptr++ = rgb.tmpA[j]; + } + else + { + // TWO bytes per color + if( rgb.Header.Zsize >= 1 ) + { + // two bytes of color data + tempShort = (u16 *) (ptr); + *tempShort = *( (u16 *) (rgb.tmpR) + j); + tempShort++; + ptr = ( u8 *)(tempShort); + } + if( rgb.Header.Zsize >= 2 ) + { + tempShort = ( u16 *) (ptr); + *tempShort = *( ( u16 *) (rgb.tmpG) + j); + tempShort++; + ptr = ( u8 *) (tempShort); + } + if( rgb.Header.Zsize >= 3 ) + { + tempShort = ( u16 *) (ptr); + *tempShort = *( ( u16 *) (rgb.tmpB) + j); + tempShort++; + ptr = ( u8 *)(tempShort); + } + if( rgb.Header.Zsize >= 4 ) + { + tempShort = ( u16 *) (ptr); + *tempShort = *( ( u16 *) (rgb.tmpA) + j); + tempShort++; + ptr = ( u8 *)(tempShort); + } + } // end if(rgb.Header.BPC == 1) + } // end for + } // end for +} + + +/* + This information only applies if the value for STORAGE is 1. If the image is + stored using run length encoding, the image data follows the offset/length tables. + The RLE data is not in any particular order. The offset tables are used to + locate the rle data for any scanline. + + The RLE data must be read in from the file and expanded into pixel data in the following manner: + + If BPC is 1, then there is one byte per pixel. In this case the RLE data should be + read into an array of chars. To expand data, the low order seven bits of the first + byte: bits[6..0] are used to form a count. If the high order bit of the first byte + is 1: bit[7], then the count is used to specify how many bytes to copy from the RLE + data buffer to the destination. Otherwise, if the high order bit of the first byte + is 0: bit[7], then the count is used to specify how many times to repeat the value + of the following byte, in the destination. This process continues until a count + of 0 is found. This should decompress exactly XSIZE pixels. + + + One entry in each table is needed for each scanline of RLE data. The total number of + scanlines in the image (tablen) is determined by the product of the YSIZE and ZSIZE. + There are two tables of longs that are written. Each consists of tablen longs of data. + The first table has the file offsets to the RLE data for each scanline in the image. In + a file with more than 1 channel (ZSIZE > 1) this table first has all the offsets for the + scanlines in the first channel, followed be offsets for the scanlines in the second + channel, etc. The second table has the RLE data length for each scanline in the image. + In a file with more than 1 channel (ZSIZE > 1) this table first has all the RLE data + lengths for the scanlines in the first channel, followed be RLE data lengths for the + scanlines in the second channel, etc. + + Return a row of data, expanding RLE compression if necessary +*/ +void CImageLoaderRGB::readRGBrow(u8 *buf, int y, int z, io::IReadFile* file, rgbStruct& rgb) const +{ + if (rgb.Header.Storage != 1) + { + // stored VERBATIM + + file->seek(512+(y*rgb.Header.Xsize * rgb.Header.BPC)+(z* rgb.Header.Xsize * rgb.Header.Ysize * rgb.Header.BPC)); + file->read(buf, rgb.Header.Xsize * rgb.Header.BPC); + +#ifndef __BIG_ENDIAN__ + if (rgb.Header.BPC != 1) + { + u16* tmpbuf = reinterpret_cast(buf); + for (u16 i=0; iseek((long) rgb.StartTable[y+z * rgb.Header.Ysize]); + file->read(rgb.tmp, rgb.LengthTable[y+z * rgb.Header.Ysize]); + + // rgb.tmp has the data + + u16 pixel; + u16 *tempShort; + u8* iPtr = rgb.tmp; + u8* oPtr = buf; + while (true) + { + // if BPC = 1, then one byte per pixel + if (rgb.Header.BPC == 1) + { + pixel = *iPtr++; + } + else + { + // BPC = 2, so two bytes per pixel + tempShort = (u16 *) iPtr; + pixel = *tempShort; + tempShort++; + iPtr = (u8 *) tempShort; + } + +#ifndef __BIG_ENDIAN__ + if (rgb.Header.BPC != 1) + pixel = os::Byteswap::byteswap(pixel); +#endif + + s32 count = (s32)(pixel & 0x7F); + + // limit the count value to the remaining row size + if (oPtr + count*rgb.Header.BPC > buf + rgb.Header.Xsize * rgb.Header.BPC) + { + count = ( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC; + } + + if (count<=0) + break; + else if (pixel & 0x80) + { + // repeat the byte pointed to by iPtr, count times + while (count--) + { + if(rgb.Header.BPC == 1) + { + *oPtr++ = *iPtr++; + } + else + { + // write pixel from iPtr to oPtr, move both two bytes ahead + tempShort = (u16 *) (iPtr); + pixel = *tempShort; + tempShort++; + iPtr = (u8 *) (tempShort); +#ifndef __BIG_ENDIAN__ + pixel = os::Byteswap::byteswap(pixel); +#endif + tempShort = (u16 *) (oPtr); + *tempShort = pixel; + tempShort++; + oPtr = (u8 *) (tempShort); + } + } + } + else + { + if (rgb.Header.BPC == 1) + { + pixel = *iPtr++; + } + else + { + tempShort = (u16 *) (iPtr); + pixel = *tempShort; + tempShort++; + iPtr = (u8 *) (tempShort); + } + +#ifndef __BIG_ENDIAN__ + if (rgb.Header.BPC != 1) + pixel = os::Byteswap::byteswap(pixel); +#endif + + while (count--) + { + if(rgb.Header.BPC == 1) + { + *oPtr++ = (u8) pixel; + } + else + { + tempShort = (u16 *) (oPtr); + *tempShort = pixel; + tempShort++; + oPtr = (u8 *) (tempShort); + } + } + } // else if (pixel & 0x80) + } // while (true) +} + + +// we have 1 byte per COLOR VALUE, eg 24bpp and 1 alpha channel +// color values are stored as RGBA, convert to ARGB +// todo: replace with CColorConverter method +void CImageLoaderRGB::converttoARGB(u32* in, const u32 size) const +{ + for (u32 x=0; x < size; ++x) + { + *in=(*in>>8)|(*in<<24); + ++in; + } +} + + +//! creates a loader which is able to load SGI RGB images +IImageLoader* createImageLoaderRGB() +{ + return new CImageLoaderRGB; +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.h new file mode 100644 index 0000000..1fe6454 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderRGB.h @@ -0,0 +1,165 @@ +// Copyright (C) 2009-2012 Gary Conway +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + + +/* + Author: Gary Conway (Viper) - co-author of the ZIP file format, Feb 1989, + see the story at http://www.idcnet.us/ziphistory.html + Website: http://idcnet.us + Email: codeslinger@vipergc.com + Created: March 1, 2009 + Version: 1.0 + Updated: +*/ + +#ifndef __C_IMAGE_LOADER_RGB_H_INCLUDED__ +#define __C_IMAGE_LOADER_RGB_H_INCLUDED__ + +// define _IRR_RGB_FILE_INVERTED_IMAGE_ to preserve the inverted format of the RGB file +// commenting this out will invert the inverted image,resulting in the image being upright +#define _IRR_RGB_FILE_INVERTED_IMAGE_ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_RGB_LOADER_ + +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + +// byte-align structures +#include "irrpack.h" + + // the RGB image file header structure + + struct SRGBHeader + { + u16 Magic; // IRIS image file magic number + u8 Storage; // Storage format + u8 BPC; // Number of bytes per pixel channel + u16 Dimension; // Number of dimensions + u16 Xsize; // X size in pixels + u16 Ysize; // Y size in pixels + u16 Zsize; // Z size in pixels + u32 Pixmin; // Minimum pixel value + u32 Pixmax; // Maximum pixel value + u32 Dummy1; // ignored + char Imagename[80];// Image name + u32 Colormap; // Colormap ID +// char Dummy2[404];// Ignored + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + // this structure holds context specific data about the file being loaded. + + typedef struct _RGBdata + { + u8 *tmp, + *tmpR, + *tmpG, + *tmpB, + *tmpA; + + + u32 *StartTable; // compressed data table, holds file offsets + u32 *LengthTable; // length for the above data, hold lengths for above + u32 TableLen; // len of above tables + + SRGBHeader Header; // define the .rgb file header + u32 ImageSize; + u8 *rgbData; + + public: + _RGBdata() : tmp(0), tmpR(0), tmpG(0), tmpB(0), tmpA(0), + StartTable(0), LengthTable(0), TableLen(0), ImageSize(0), rgbData(0) + { + } + + ~_RGBdata() + { + delete [] tmp; + delete [] tmpR; + delete [] tmpG; + delete [] tmpB; + delete [] tmpA; + delete [] StartTable; + delete [] LengthTable; + delete [] rgbData; + } + + bool allocateTemps() + { + tmp = tmpR = tmpG = tmpB = tmpA = 0; + tmp = new u8 [Header.Xsize * 256 * Header.BPC]; + if (!tmp) + return false; + + if (Header.Zsize >= 1) + { + tmpR = new u8[Header.Xsize * Header.BPC]; + if (!tmpR) + return false; + } + if (Header.Zsize >= 2) + { + tmpG = new u8[Header.Xsize * Header.BPC]; + if (!tmpG) + return false; + } + if (Header.Zsize >= 3) + { + tmpB = new u8[Header.Xsize * Header.BPC]; + if (!tmpB) + return false; + } + if (Header.Zsize >= 4) + { + tmpA = new u8[Header.Xsize * Header.BPC]; + if (!tmpA) + return false; + } + return true; + } + } rgbStruct; + + +//! Surface Loader for Silicon Graphics RGB files +class CImageLoaderRGB : public IImageLoader +{ +public: + + //! constructor + CImageLoaderRGB(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + bool readHeader(io::IReadFile* file, rgbStruct& rgb) const; + void readRGBrow(u8 *buf, int y, int z, io::IReadFile* file, rgbStruct& rgb) const; + void processFile(io::IReadFile *file, rgbStruct& rgb) const; + bool checkFormat(io::IReadFile *file, rgbStruct& rgb) const; + bool readOffsetTables(io::IReadFile* file, rgbStruct& rgb) const; + void converttoARGB(u32* in, const u32 size) const; +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_RGB_LOADER_ +#endif // __C_IMAGE_LOADER_RGB_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.cpp new file mode 100644 index 0000000..5f2549b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.cpp @@ -0,0 +1,239 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderTGA.h" + +#ifdef _IRR_COMPILE_WITH_TGA_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CColorConverter.h" +#include "CImage.h" +#include "irrString.h" + + +namespace irr +{ +namespace video +{ + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".tga") +bool CImageLoaderTGA::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "tga" ); +} + + +//! loads a compressed tga. +u8 *CImageLoaderTGA::loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const +{ + // This was written and sent in by Jon Pry, thank you very much! + // I only changed the formatting a little bit. + + s32 bytesPerPixel = header.PixelDepth/8; + s32 imageSize = header.ImageHeight * header.ImageWidth * bytesPerPixel; + u8* data = new u8[imageSize]; + s32 currentByte = 0; + + while(currentByte < imageSize) + { + u8 chunkheader = 0; + file->read(&chunkheader, sizeof(u8)); // Read The Chunk's Header + + if(chunkheader < 128) // If The Chunk Is A 'RAW' Chunk + { + chunkheader++; // Add 1 To The Value To Get Total Number Of Raw Pixels + + file->read(&data[currentByte], bytesPerPixel * chunkheader); + currentByte += bytesPerPixel * chunkheader; + } + else + { + // thnx to neojzs for some fixes with this code + + // If It's An RLE Header + chunkheader -= 127; // Subtract 127 To Get Rid Of The ID Bit + + s32 dataOffset = currentByte; + file->read(&data[dataOffset], bytesPerPixel); + + currentByte += bytesPerPixel; + + for(s32 counter = 1; counter < chunkheader; counter++) + { + for(s32 elementCounter=0; elementCounter < bytesPerPixel; elementCounter++) + data[currentByte + elementCounter] = data[dataOffset + elementCounter]; + + currentByte += bytesPerPixel; + } + } + } + + return data; +} + + + +//! returns true if the file maybe is able to be loaded by this class +bool CImageLoaderTGA::isALoadableFileFormat(io::IReadFile* file) const +{ + if (!file) + return false; + + STGAFooter footer; + memset(&footer, 0, sizeof(STGAFooter)); + file->seek(file->getSize()-sizeof(STGAFooter)); + file->read(&footer, sizeof(STGAFooter)); + return (!strcmp(footer.Signature,"TRUEVISION-XFILE.")); // very old tgas are refused. +} + + + +//! creates a surface from the file +IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const +{ + STGAHeader header; + u32 *palette = 0; + + file->read(&header, sizeof(STGAHeader)); + +#ifdef __BIG_ENDIAN__ + header.ColorMapLength = os::Byteswap::byteswap(header.ColorMapLength); + header.ImageWidth = os::Byteswap::byteswap(header.ImageWidth); + header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight); +#endif + + // skip image identification field + if (header.IdLength) + file->seek(header.IdLength, true); + + if (header.ColorMapType) + { + // create 32 bit palette + palette = new u32[ header.ColorMapLength]; + + // read color map + u8 * colorMap = new u8[header.ColorMapEntrySize/8 * header.ColorMapLength]; + file->read(colorMap,header.ColorMapEntrySize/8 * header.ColorMapLength); + + // convert to 32-bit palette + switch ( header.ColorMapEntrySize ) + { + case 16: + CColorConverter::convert_A1R5G5B5toA8R8G8B8(colorMap, header.ColorMapLength, palette); + break; + case 24: + CColorConverter::convert_B8G8R8toA8R8G8B8(colorMap, header.ColorMapLength, palette); + break; + case 32: + CColorConverter::convert_B8G8R8A8toA8R8G8B8(colorMap, header.ColorMapLength, palette); + break; + } + delete [] colorMap; + } + + // read image + + u8* data = 0; + + if ( header.ImageType == 1 || // Uncompressed, color-mapped images. + header.ImageType == 2 || // Uncompressed, RGB images + header.ImageType == 3 // Uncompressed, black and white images + ) + { + const s32 imageSize = header.ImageHeight * header.ImageWidth * header.PixelDepth/8; + data = new u8[imageSize]; + file->read(data, imageSize); + } + else + if(header.ImageType == 10) + { + // Runlength encoded RGB images + data = loadCompressedImage(file, header); + } + else + { + os::Printer::log("Unsupported TGA file type", file->getFileName(), ELL_ERROR); + delete [] palette; + return 0; + } + + IImage* image = 0; + + switch(header.PixelDepth) + { + case 8: + { + if (header.ImageType==3) // grey image + { + image = new CImage(ECF_R8G8B8, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert8BitTo24Bit((u8*)data, + (u8*)image->lock(), + header.ImageWidth,header.ImageHeight, + 0, 0, (header.ImageDescriptor&0x20)==0); + } + else + { + image = new CImage(ECF_A1R5G5B5, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert8BitTo16Bit((u8*)data, + (s16*)image->lock(), + header.ImageWidth,header.ImageHeight, + (s32*) palette, 0, + (header.ImageDescriptor&0x20)==0); + } + } + break; + case 16: + image = new CImage(ECF_A1R5G5B5, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert16BitTo16Bit((s16*)data, + (s16*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0); + break; + case 24: + image = new CImage(ECF_R8G8B8, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert24BitTo24Bit( + (u8*)data, (u8*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0, true); + break; + case 32: + image = new CImage(ECF_A8R8G8B8, + core::dimension2d(header.ImageWidth, header.ImageHeight)); + if (image) + CColorConverter::convert32BitTo32Bit((s32*)data, + (s32*)image->lock(), header.ImageWidth, header.ImageHeight, 0, (header.ImageDescriptor&0x20)==0); + break; + default: + os::Printer::log("Unsupported TGA format", file->getFileName(), ELL_ERROR); + break; + } + if (image) + image->unlock(); + + delete [] data; + delete [] palette; + + return image; +} + + +//! creates a loader which is able to load tgas +IImageLoader* createImageLoaderTGA() +{ + return new CImageLoaderTGA(); +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.h new file mode 100644 index 0000000..d744b6e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderTGA.h @@ -0,0 +1,82 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IMAGE_LOADER_TGA_H_INCLUDED__ +#define __C_IMAGE_LOADER_TGA_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#include "IImageLoader.h" + + +namespace irr +{ +namespace video +{ + +#if defined(_IRR_COMPILE_WITH_TGA_LOADER_) || defined(_IRR_COMPILE_WITH_TGA_WRITER_) + +// byte-align structures +#include "irrpack.h" + + // these structs are also used in the TGA writer + struct STGAHeader{ + u8 IdLength; + u8 ColorMapType; + u8 ImageType; + u8 FirstEntryIndex[2]; + u16 ColorMapLength; + u8 ColorMapEntrySize; + u8 XOrigin[2]; + u8 YOrigin[2]; + u16 ImageWidth; + u16 ImageHeight; + u8 PixelDepth; + u8 ImageDescriptor; + } PACK_STRUCT; + + struct STGAFooter + { + u32 ExtensionOffset; + u32 DeveloperOffset; + c8 Signature[18]; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +#endif // compiled with loader or reader + +#ifdef _IRR_COMPILE_WITH_TGA_LOADER_ + +/*! + Surface Loader for targa images +*/ +class CImageLoaderTGA : public IImageLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tga") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! returns true if the file maybe is able to be loaded by this class + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! creates a surface from the file + virtual IImage* loadImage(io::IReadFile* file) const; + +private: + + //! loads a compressed tga. Was written and sent in by Jon Pry, thank you very much! + u8* loadCompressedImage(io::IReadFile *file, const STGAHeader& header) const; +}; + +#endif // compiled with loader + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.cpp new file mode 100644 index 0000000..f5d2f17 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.cpp @@ -0,0 +1,285 @@ +// Copyright (C) 2004 Murphy McCauley +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageLoaderWAL.h" + +#include "CColorConverter.h" +#include "CImage.h" +#include "os.h" +#include "dimension2d.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "IReadFile.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_LMP_LOADER_ + +// Palette quake2 colormap.h, 768 byte, last is transparent +static const u32 colormap_h[256] = { + 0xFF000000,0xFF0F0F0F,0xFF1F1F1F,0xFF2F2F2F,0xFF3F3F3F,0xFF4B4B4B,0xFF5B5B5B,0xFF6B6B6B, + 0xFF7B7B7B,0xFF8B8B8B,0xFF9B9B9B,0xFFABABAB,0xFFBBBBBB,0xFFCBCBCB,0xFFDBDBDB,0xFFEBEBEB, + 0xFF0F0B07,0xFF170F0B,0xFF1F170B,0xFF271B0F,0xFF2F2313,0xFF372B17,0xFF3F2F17,0xFF4B371B, + 0xFF533B1B,0xFF5B431F,0xFF634B1F,0xFF6B531F,0xFF73571F,0xFF7B5F23,0xFF836723,0xFF8F6F23, + 0xFF0B0B0F,0xFF13131B,0xFF1B1B27,0xFF272733,0xFF2F2F3F,0xFF37374B,0xFF3F3F57,0xFF474767, + 0xFF4F4F73,0xFF5B5B7F,0xFF63638B,0xFF6B6B97,0xFF7373A3,0xFF7B7BAF,0xFF8383BB,0xFF8B8BCB, + 0xFF000000,0xFF070700,0xFF0B0B00,0xFF131300,0xFF1B1B00,0xFF232300,0xFF2B2B07,0xFF2F2F07, + 0xFF373707,0xFF3F3F07,0xFF474707,0xFF4B4B0B,0xFF53530B,0xFF5B5B0B,0xFF63630B,0xFF6B6B0F, + 0xFF070000,0xFF0F0000,0xFF170000,0xFF1F0000,0xFF270000,0xFF2F0000,0xFF370000,0xFF3F0000, + 0xFF470000,0xFF4F0000,0xFF570000,0xFF5F0000,0xFF670000,0xFF6F0000,0xFF770000,0xFF7F0000, + 0xFF131300,0xFF1B1B00,0xFF232300,0xFF2F2B00,0xFF372F00,0xFF433700,0xFF4B3B07,0xFF574307, + 0xFF5F4707,0xFF6B4B0B,0xFF77530F,0xFF835713,0xFF8B5B13,0xFF975F1B,0xFFA3631F,0xFFAF6723, + 0xFF231307,0xFF2F170B,0xFF3B1F0F,0xFF4B2313,0xFF572B17,0xFF632F1F,0xFF733723,0xFF7F3B2B, + 0xFF8F4333,0xFF9F4F33,0xFFAF632F,0xFFBF772F,0xFFCF8F2B,0xFFDFAB27,0xFFEFCB1F,0xFFFFF31B, + 0xFF0B0700,0xFF1B1300,0xFF2B230F,0xFF372B13,0xFF47331B,0xFF533723,0xFF633F2B,0xFF6F4733, + 0xFF7F533F,0xFF8B5F47,0xFF9B6B53,0xFFA77B5F,0xFFB7876B,0xFFC3937B,0xFFD3A38B,0xFFE3B397, + 0xFFAB8BA3,0xFF9F7F97,0xFF937387,0xFF8B677B,0xFF7F5B6F,0xFF775363,0xFF6B4B57,0xFF5F3F4B, + 0xFF573743,0xFF4B2F37,0xFF43272F,0xFF371F23,0xFF2B171B,0xFF231313,0xFF170B0B,0xFF0F0707, + 0xFFBB739F,0xFFAF6B8F,0xFFA35F83,0xFF975777,0xFF8B4F6B,0xFF7F4B5F,0xFF734353,0xFF6B3B4B, + 0xFF5F333F,0xFF532B37,0xFF47232B,0xFF3B1F23,0xFF2F171B,0xFF231313,0xFF170B0B,0xFF0F0707, + 0xFFDBC3BB,0xFFCBB3A7,0xFFBFA39B,0xFFAF978B,0xFFA3877B,0xFF977B6F,0xFF876F5F,0xFF7B6353, + 0xFF6B5747,0xFF5F4B3B,0xFF533F33,0xFF433327,0xFF372B1F,0xFF271F17,0xFF1B130F,0xFF0F0B07, + 0xFF6F837B,0xFF677B6F,0xFF5F7367,0xFF576B5F,0xFF4F6357,0xFF475B4F,0xFF3F5347,0xFF374B3F, + 0xFF2F4337,0xFF2B3B2F,0xFF233327,0xFF1F2B1F,0xFF172317,0xFF0F1B13,0xFF0B130B,0xFF070B07, + 0xFFFFF31B,0xFFEFDF17,0xFFDBCB13,0xFFCBB70F,0xFFBBA70F,0xFFAB970B,0xFF9B8307,0xFF8B7307, + 0xFF7B6307,0xFF6B5300,0xFF5B4700,0xFF4B3700,0xFF3B2B00,0xFF2B1F00,0xFF1B0F00,0xFF0B0700, + 0xFF0000FF,0xFF0B0BEF,0xFF1313DF,0xFF1B1BCF,0xFF2323BF,0xFF2B2BAF,0xFF2F2F9F,0xFF2F2F8F, + 0xFF2F2F7F,0xFF2F2F6F,0xFF2F2F5F,0xFF2B2B4F,0xFF23233F,0xFF1B1B2F,0xFF13131F,0xFF0B0B0F, + 0xFF2B0000,0xFF3B0000,0xFF4B0700,0xFF5F0700,0xFF6F0F00,0xFF7F1707,0xFF931F07,0xFFA3270B, + 0xFFB7330F,0xFFC34B1B,0xFFCF632B,0xFFDB7F3B,0xFFE3974F,0xFFE7AB5F,0xFFEFBF77,0xFFF7D38B, + 0xFFA77B3B,0xFFB79B37,0xFFC7C337,0xFFE7E357,0xFF7FBFFF,0xFFABE7FF,0xFFD7FFFF,0xFF670000, + 0xFF8B0000,0xFFB30000,0xFFD70000,0xFFFF0000,0xFFFFF393,0xFFFFF7C7,0xFFFFFFFF,0x009F5B53 +}; + +bool CImageLoaderLMP::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "lmp" ); +} + + +bool CImageLoaderLMP::isALoadableFileFormat(irr::io::IReadFile* file) const +{ + return false; +} + +/*! + Quake1, Quake2, Hallife lmp texture +*/ +IImage* CImageLoaderLMP::loadImage(irr::io::IReadFile* file) const +{ + SLMPHeader header; + + file->seek(0); + file->read(&header, sizeof(header)); + + // maybe palette file + u32 rawtexsize = header.width * header.height; + if ( rawtexsize + sizeof ( header ) != (u32)file->getSize() ) + return 0; + + u8 *rawtex = new u8 [ rawtexsize ]; + + file->read(rawtex, rawtexsize); + + IImage* image = new CImage(ECF_A8R8G8B8, core::dimension2d(header.width, header.height)); + + CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) colormap_h, 0, false); + image->unlock(); + + delete [] rawtex; + + return image; +} + + +IImageLoader* createImageLoaderLMP() +{ + return new irr::video::CImageLoaderLMP(); +} + +#endif + +#ifdef _IRR_COMPILE_WITH_WAL_LOADER_ + +// Palette quake2 demo pics/colormap.pcx, last is transparent +static const u32 colormap_pcx[256] = { + 0xFF000000,0xFF0F0F0F,0xFF1F1F1F,0xFF2F2F2F,0xFF3F3F3F,0xFF4B4B4B,0xFF5B5B5B,0xFF6B6B6B, + 0xFF7B7B7B,0xFF8B8B8B,0xFF9B9B9B,0xFFABABAB,0xFFBBBBBB,0xFFCBCBCB,0xFFDBDBDB,0xFFEBEBEB, + 0xFF634B23,0xFF5B431F,0xFF533F1F,0xFF4F3B1B,0xFF47371B,0xFF3F2F17,0xFF3B2B17,0xFF332713, + 0xFF2F2313,0xFF2B1F13,0xFF271B0F,0xFF23170F,0xFF1B130B,0xFF170F0B,0xFF130F07,0xFF0F0B07, + 0xFF5F5F6F,0xFF5B5B67,0xFF5B535F,0xFF574F5B,0xFF534B53,0xFF4F474B,0xFF473F43,0xFF3F3B3B, + 0xFF3B3737,0xFF332F2F,0xFF2F2B2B,0xFF272727,0xFF232323,0xFF1B1B1B,0xFF171717,0xFF131313, + 0xFF8F7753,0xFF7B6343,0xFF735B3B,0xFF674F2F,0xFFCF974B,0xFFA77B3B,0xFF8B672F,0xFF6F5327, + 0xFFEB9F27,0xFFCB8B23,0xFFAF771F,0xFF93631B,0xFF774F17,0xFF5B3B0F,0xFF3F270B,0xFF231707, + 0xFFA73B2B,0xFF9F2F23,0xFF972B1B,0xFF8B2713,0xFF7F1F0F,0xFF73170B,0xFF671707,0xFF571300, + 0xFF4B0F00,0xFF430F00,0xFF3B0F00,0xFF330B00,0xFF2B0B00,0xFF230B00,0xFF1B0700,0xFF130700, + 0xFF7B5F4B,0xFF735743,0xFF6B533F,0xFF674F3B,0xFF5F4737,0xFF574333,0xFF533F2F,0xFF4B372B, + 0xFF433327,0xFF3F2F23,0xFF37271B,0xFF2F2317,0xFF271B13,0xFF1F170F,0xFF170F0B,0xFF0F0B07, + 0xFF6F3B17,0xFF5F3717,0xFF532F17,0xFF432B17,0xFF372313,0xFF271B0F,0xFF1B130B,0xFF0F0B07, + 0xFFB35B4F,0xFFBF7B6F,0xFFCB9B93,0xFFD7BBB7,0xFFCBD7DF,0xFFB3C7D3,0xFF9FB7C3,0xFF87A7B7, + 0xFF7397A7,0xFF5B879B,0xFF47778B,0xFF2F677F,0xFF17536F,0xFF134B67,0xFF0F435B,0xFF0B3F53, + 0xFF07374B,0xFF072F3F,0xFF072733,0xFF001F2B,0xFF00171F,0xFF000F13,0xFF00070B,0xFF000000, + 0xFF8B5757,0xFF834F4F,0xFF7B4747,0xFF734343,0xFF6B3B3B,0xFF633333,0xFF5B2F2F,0xFF572B2B, + 0xFF4B2323,0xFF3F1F1F,0xFF331B1B,0xFF2B1313,0xFF1F0F0F,0xFF130B0B,0xFF0B0707,0xFF000000, + 0xFF979F7B,0xFF8F9773,0xFF878B6B,0xFF7F8363,0xFF777B5F,0xFF737357,0xFF6B6B4F,0xFF636347, + 0xFF5B5B43,0xFF4F4F3B,0xFF434333,0xFF37372B,0xFF2F2F23,0xFF23231B,0xFF171713,0xFF0F0F0B, + 0xFF9F4B3F,0xFF934337,0xFF8B3B2F,0xFF7F3727,0xFF772F23,0xFF6B2B1B,0xFF632317,0xFF571F13, + 0xFF4F1B0F,0xFF43170B,0xFF37130B,0xFF2B0F07,0xFF1F0B07,0xFF170700,0xFF0B0000,0xFF000000, + 0xFF777BCF,0xFF6F73C3,0xFF676BB7,0xFF6363A7,0xFF5B5B9B,0xFF53578F,0xFF4B4F7F,0xFF474773, + 0xFF3F3F67,0xFF373757,0xFF2F2F4B,0xFF27273F,0xFF231F2F,0xFF1B1723,0xFF130F17,0xFF0B0707, + 0xFF9BAB7B,0xFF8F9F6F,0xFF879763,0xFF7B8B57,0xFF73834B,0xFF677743,0xFF5F6F3B,0xFF576733, + 0xFF4B5B27,0xFF3F4F1B,0xFF374313,0xFF2F3B0B,0xFF232F07,0xFF1B2300,0xFF131700,0xFF0B0F00, + 0xFF00FF00,0xFF23E70F,0xFF3FD31B,0xFF53BB27,0xFF5FA72F,0xFF5F8F33,0xFF5F7B33,0xFFFFFFFF, + 0xFFFFFFD3,0xFFFFFFA7,0xFFFFFF7F,0xFFFFFF53,0xFFFFFF27,0xFFFFEB1F,0xFFFFD717,0xFFFFBF0F, + 0xFFFFAB07,0xFFFF9300,0xFFEF7F00,0xFFE36B00,0xFFD35700,0xFFC74700,0xFFB73B00,0xFFAB2B00, + 0xFF9B1F00,0xFF8F1700,0xFF7F0F00,0xFF730700,0xFF5F0000,0xFF470000,0xFF2F0000,0xFF1B0000, + 0xFFEF0000,0xFF3737FF,0xFFFF0000,0xFF0000FF,0xFF2B2B23,0xFF1B1B17,0xFF13130F,0xFFEB977F, + 0xFFC37353,0xFF9F5733,0xFF7B3F1B,0xFFEBD3C7,0xFFC7AB9B,0xFFA78B77,0xFF876B57,0x009F5B53 +}; + +/*! + Halflife +*/ +bool CImageLoaderWAL2::isALoadableFileExtension(const io::path& filename) const +{ + // embedded in Wad(WAD3 format). originally it has no extension + return core::hasFileExtension ( filename, "wal2" ); +} + + +bool CImageLoaderWAL2::isALoadableFileFormat(irr::io::IReadFile* file) const +{ + return false; +} + +/* + Halflite Texture WAD +*/ +IImage* CImageLoaderWAL2::loadImage(irr::io::IReadFile* file) const +{ + miptex_halflife header; + + file->seek(0); + file->read(&header, sizeof(header)); + +#ifdef __BIG_ENDIAN__ + header.width = os::Byteswap::byteswap(header.width); + header.height = os::Byteswap::byteswap(header.height); +#endif + + // palette + //u32 paletteofs = header.mipmap[0] + ((rawtexsize * 85) >> 6) + 2; + u32 *pal = new u32 [ 192 + 256 ]; + u8 *s = (u8*) pal; + + file->seek ( file->getSize() - 768 - 2 ); + file->read ( s, 768 ); + u32 i; + + for ( i = 0; i < 256; ++i, s+= 3 ) + { + pal [ 192 + i ] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2]; + } + + ECOLOR_FORMAT format = ECF_R8G8B8; + + // transparency in filename;-) funny. rgb:0x0000FF is colorkey + if ( file->getFileName().findFirst ( '{' ) >= 0 ) + { + format = ECF_A8R8G8B8; + pal [ 192 + 255 ] &= 0x00FFFFFF; + } + + u32 rawtexsize = header.width * header.height; + + + u8 *rawtex = new u8 [ rawtexsize ]; + + file->seek ( header.mipmap[0] ); + file->read(rawtex, rawtexsize); + + IImage* image = new CImage(format, core::dimension2d(header.width, header.height)); + + switch ( format ) + { + case ECF_R8G8B8: + CColorConverter::convert8BitTo24Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) pal + 768, 0, false); + break; + case ECF_A8R8G8B8: + CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) pal + 768, 0, false); + break; + } + + image->unlock(); + + delete [] rawtex; + delete [] pal; + + return image; +} + +bool CImageLoaderWAL::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "wal" ); +} + + +bool CImageLoaderWAL::isALoadableFileFormat(irr::io::IReadFile* file) const +{ + return false; +} + + +/*! + quake2 +*/ +IImage* CImageLoaderWAL::loadImage(irr::io::IReadFile* file) const +{ + miptex_quake2 header; + + file->seek(0); + file->read(&header, sizeof(header)); + +#ifdef __BIG_ENDIAN__ + header.width = os::Byteswap::byteswap(header.width); + header.height = os::Byteswap::byteswap(header.height); +#endif + + u32 rawtexsize = header.width * header.height; + + u8 *rawtex = new u8 [ rawtexsize ]; + + file->seek ( header.mipmap[0] ); + file->read(rawtex, rawtexsize); + + IImage* image = new CImage(ECF_A8R8G8B8, core::dimension2d(header.width, header.height)); + + CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) colormap_pcx, 0, false); + image->unlock(); + + delete [] rawtex; + + return image; +} + +IImageLoader* createImageLoaderWAL() +{ + return new irr::video::CImageLoaderWAL(); +} + +IImageLoader* createImageLoaderHalfLife() +{ + return new irr::video::CImageLoaderWAL2(); +} + +#endif + +} // end namespace video +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.h new file mode 100644 index 0000000..871814a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageLoaderWAL.h @@ -0,0 +1,100 @@ +// Copyright (C) 2004 Murphy McCauley +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +/* + Thanks to: + Max McGuire for his Flipcode article about WAL textures + Nikolaus Gebhardt for the Irrlicht 3D engine +*/ + +#ifndef __C_IMAGE_LOADER_WAL_H_INCLUDED__ +#define __C_IMAGE_LOADER_WAL_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#include "IImageLoader.h" + +namespace irr +{ +namespace video +{ + +#ifdef _IRR_COMPILE_WITH_LMP_LOADER_ + +// byte-align structures +#include "irrpack.h" + + struct SLMPHeader { + u32 width; // width + u32 height; // height + // variably sized + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +//! An Irrlicht image loader for Quake1,2 engine lmp textures/palette +class CImageLoaderLMP : public irr::video::IImageLoader +{ +public: + virtual bool isALoadableFileExtension(const io::path& filename) const; + virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const; + virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const; +}; + +#endif + +#ifdef _IRR_COMPILE_WITH_WAL_LOADER_ + +//! An Irrlicht image loader for quake2 wal engine textures +class CImageLoaderWAL : public irr::video::IImageLoader +{ +public: + virtual bool isALoadableFileExtension(const io::path& filename) const; + virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const; + virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const; +}; + +//! An Irrlicht image loader for Halflife 1 engine textures +class CImageLoaderWAL2 : public irr::video::IImageLoader +{ +public: + virtual bool isALoadableFileExtension(const io::path& filename) const; + virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const; + virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const; +}; + +// byte-align structures +#include "irrpack.h" + + // Halfelife wad3 type 67 file + struct miptex_halflife + { + c8 name[16]; + u32 width, height; + u32 mipmap[4]; // four mip maps stored + } PACK_STRUCT; + + //quake2 texture + struct miptex_quake2 + { + c8 name[32]; + u32 width; + u32 height; + u32 mipmap[4]; // four mip maps stored + c8 animname[32]; // next frame in animation chain + s32 flags; + s32 contents; + s32 value; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +#endif + +} +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.cpp new file mode 100644 index 0000000..8a91c3a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.cpp @@ -0,0 +1,140 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterBMP.h" + +#ifdef _IRR_COMPILE_WITH_BMP_WRITER_ + +#include "CImageLoaderBMP.h" +#include "IWriteFile.h" +#include "CColorConverter.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterBMP() +{ + return new CImageWriterBMP; +} + +CImageWriterBMP::CImageWriterBMP() +{ +#ifdef _DEBUG + setDebugName("CImageWriterBMP"); +#endif +} + +bool CImageWriterBMP::isAWriteableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "bmp" ); +} + +bool CImageWriterBMP::writeImage(io::IWriteFile* file, IImage* image, u32 param) const +{ + // we always write 24-bit color because nothing really reads 32-bit + + SBMPHeader imageHeader; + imageHeader.Id = 0x4d42; + imageHeader.Reserved = 0; + imageHeader.BitmapDataOffset = sizeof(imageHeader); + imageHeader.BitmapHeaderSize = 0x28; + imageHeader.Width = image->getDimension().Width; + imageHeader.Height = image->getDimension().Height; + imageHeader.Planes = 1; + imageHeader.BPP = 24; + imageHeader.Compression = 0; + imageHeader.PixelPerMeterX = 0; + imageHeader.PixelPerMeterY = 0; + imageHeader.Colors = 0; + imageHeader.ImportantColors = 0; + + // data size is rounded up to next larger 4 bytes boundary + imageHeader.BitmapDataSize = imageHeader.Width * imageHeader.BPP / 8; + imageHeader.BitmapDataSize = (imageHeader.BitmapDataSize + 3) & ~3; + imageHeader.BitmapDataSize *= imageHeader.Height; + + // file size is data size plus offset to data + imageHeader.FileSize = imageHeader.BitmapDataOffset + imageHeader.BitmapDataSize; + + // bitmaps are stored upside down and padded so we always do this + void (*CColorConverter_convertFORMATtoFORMAT)(const void*, s32, void*) = 0; + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R8G8B8toR8G8B8; + break; + case ECF_A8R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A8R8G8B8toB8G8R8; + break; + case ECF_A1R5G5B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A1R5G5B5toR8G8B8; + break; + case ECF_R5G6B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R5G6B5toR8G8B8; + break; +#ifndef _DEBUG + default: + break; +#endif + } + + // couldn't find a color converter + if (!CColorConverter_convertFORMATtoFORMAT) + return false; + + // write the bitmap header + if (file->write(&imageHeader, sizeof(imageHeader)) != sizeof(imageHeader)) + return false; + + u8* scan_lines = (u8*)image->lock(); + if (!scan_lines) + return false; + + // size of one pixel in bytes + u32 pixel_size = image->getBytesPerPixel(); + + // length of one row of the source image in bytes + u32 row_stride = (pixel_size * imageHeader.Width); + + // length of one row in bytes, rounded up to nearest 4-byte boundary + s32 row_size = ((3 * imageHeader.Width) + 3) & ~3; + + // allocate and clear memory for our scan line + u8* row_pointer = new u8[row_size]; + memset(row_pointer, 0, row_size); + + // convert the image to 24-bit BGR and flip it over + s32 y; + for (y = imageHeader.Height - 1; 0 <= y; --y) + { + if (image->getColorFormat()==ECF_R8G8B8) + CColorConverter::convert24BitTo24Bit(&scan_lines[y * row_stride], row_pointer, imageHeader.Width, 1, 0, false, true); + else + // source, length [pixels], destination + CColorConverter_convertFORMATtoFORMAT(&scan_lines[y * row_stride], imageHeader.Width, row_pointer); + if (file->write(row_pointer, row_size) < row_size) + break; + } + + // clean up our scratch area + delete [] row_pointer; + + // give back image handle + image->unlock(); + + return y < 0; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.h new file mode 100644 index 0000000..c66a6b4 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterBMP.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_BMP_H_INCLUDED__ +#define _C_IMAGE_WRITER_BMP_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_BMP_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterBMP : public IImageWriter +{ +public: + //! constructor + CImageWriterBMP(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif +#endif // _C_IMAGE_WRITER_BMP_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp new file mode 100644 index 0000000..944db6c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp @@ -0,0 +1,229 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterJPG.h" + +#ifdef _IRR_COMPILE_WITH_JPG_WRITER_ + +#include "CColorConverter.h" +#include "IWriteFile.h" +#include "CImage.h" +#include "irrString.h" + +#ifdef _IRR_COMPILE_WITH_LIBJPEG_ +#include // required for jpeglib.h +extern "C" +{ +#ifndef _IRR_USE_NON_SYSTEM_JPEG_LIB_ + #include + #include +#else + #include "jpeglib/jpeglib.h" + #include "jpeglib/jerror.h" +#endif +} + + +namespace irr +{ +namespace video +{ + +// The writer uses a 4k buffer and flushes to disk each time it's filled +#define OUTPUT_BUF_SIZE 4096 +typedef struct +{ + struct jpeg_destination_mgr pub;/* public fields */ + + io::IWriteFile* file; /* target file */ + JOCTET buffer[OUTPUT_BUF_SIZE]; /* image buffer */ +} mem_destination_mgr; + + +typedef mem_destination_mgr * mem_dest_ptr; + + +// init +static void jpeg_init_destination(j_compress_ptr cinfo) +{ + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + + +// flush to disk and reset buffer +static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo) +{ + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + + // for now just exit upon file error + if (dest->file->write(dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE) + ERREXIT (cinfo, JERR_FILE_WRITE); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + + +static void jpeg_term_destination(j_compress_ptr cinfo) +{ + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + const s32 datacount = (s32)(OUTPUT_BUF_SIZE - dest->pub.free_in_buffer); + // for now just exit upon file error + if (dest->file->write(dest->buffer, datacount) != datacount) + ERREXIT (cinfo, JERR_FILE_WRITE); +} + + +// set up buffer data +static void jpeg_file_dest(j_compress_ptr cinfo, io::IWriteFile* file) +{ + if (cinfo->dest == NULL) + { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, + JPOOL_PERMANENT, + sizeof(mem_destination_mgr)); + } + + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; /* for casting */ + + /* Initialize method pointers */ + dest->pub.init_destination = jpeg_init_destination; + dest->pub.empty_output_buffer = jpeg_empty_output_buffer; + dest->pub.term_destination = jpeg_term_destination; + + /* Initialize private member */ + dest->file = file; +} + + +/* write_JPEG_memory: store JPEG compressed image into memory. +*/ +static bool writeJPEGFile(io::IWriteFile* file, IImage* image, u32 quality) +{ + void (*format)(const void*, s32, void*) = 0; + switch( image->getColorFormat () ) + { + case ECF_R8G8B8: + format = CColorConverter::convert_R8G8B8toR8G8B8; + break; + case ECF_A8R8G8B8: + format = CColorConverter::convert_A8R8G8B8toR8G8B8; + break; + case ECF_A1R5G5B5: + format = CColorConverter::convert_A1R5G5B5toB8G8R8; + break; + case ECF_R5G6B5: + format = CColorConverter::convert_R5G6B5toR8G8B8; + break; +#ifndef _DEBUG + default: + break; +#endif + } + + // couldn't find a color converter + if ( 0 == format ) + return false; + + const core::dimension2du dim = image->getDimension(); + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + + jpeg_create_compress(&cinfo); + jpeg_file_dest(&cinfo, file); + cinfo.image_width = dim.Width; + cinfo.image_height = dim.Height; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + + if ( 0 == quality ) + quality = 75; + + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + + u8 * dest = new u8[dim.Width*3]; + + if (dest) + { + const u32 pitch = image->getPitch(); + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + row_pointer[0] = dest; + + u8* src = (u8*)image->lock(); + + while (cinfo.next_scanline < cinfo.image_height) + { + // convert next line + format( src, dim.Width, dest ); + src += pitch; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + image->unlock(); + + delete [] dest; + + /* Step 6: Finish compression */ + jpeg_finish_compress(&cinfo); + } + + /* Step 7: Destroy */ + jpeg_destroy_compress(&cinfo); + + return (dest != 0); +} + + +} // namespace video +} // namespace irr + +#endif // _IRR_COMPILE_WITH_LIBJPEG_ + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterJPG() +{ + return new CImageWriterJPG; +} + +CImageWriterJPG::CImageWriterJPG() +{ +#ifdef _DEBUG + setDebugName("CImageWriterJPG"); +#endif +} + + +bool CImageWriterJPG::isAWriteableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "jpg", "jpeg" ); +} + + +bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *image, u32 quality) const +{ +#ifndef _IRR_COMPILE_WITH_LIBJPEG_ + return false; +#else + return writeJPEGFile(file, image, quality); +#endif +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.h new file mode 100644 index 0000000..7abe68d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_JPG_H_INCLUDED__ +#define _C_IMAGE_WRITER_JPG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_JPG_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterJPG : public IImageWriter +{ +public: + //! constructor + CImageWriterJPG(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} +} + +#endif // _C_IMAGE_WRITER_JPG_H_INCLUDED__ +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.cpp new file mode 100644 index 0000000..5ace342 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.cpp @@ -0,0 +1,162 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPCX.h" + +#ifdef _IRR_COMPILE_WITH_PCX_WRITER_ + +#include "CImageLoaderPCX.h" +#include "IWriteFile.h" +#include "os.h" // for logging +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterPCX() +{ + return new CImageWriterPCX; +} + +CImageWriterPCX::CImageWriterPCX() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPCX"); +#endif +} + +bool CImageWriterPCX::isAWriteableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "pcx" ); +} + +bool CImageWriterPCX::writeImage(io::IWriteFile *file, IImage *image,u32 param) const +{ + if (!file || !image) + return false; + + u8 d1; + u16 d2; + u32 i; + + d1 = 10; // Manufacturer + file->write(&d1, 1); + d1 = 5; // Version + file->write(&d1, 1); + d1 = 1; // Encoding + file->write(&d1, 1); + d1 = 8; // Bits per Pixel + file->write(&d1, 1); + d2 = 0; // pixel origin + file->write(&d2, 2); + file->write(&d2, 2); + d2 = image->getDimension().Width-1; // width +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + d2 = image->getDimension().Height-1; // height +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + d2 = 300; // dpi +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + file->write(&d2, 2); + d2 = 0; // palette (not used) + for (i=0; i<24; ++i) + { + file->write(&d2, 2); + } + d1 = 0; // reserved + file->write(&d1, 1); + d1 = 3; // planes + file->write(&d1, 1); + d2 = image->getDimension().Width; // pitch + if (d2&0x0001) // must be even + ++d2; +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + d2 = 1; // color mode +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + d2 = 800; // screen width +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + d2 = 600; // screen height +#ifdef __BIG_ENDIAN__ + d2 = os::Byteswap::byteswap(d2); +#endif + file->write(&d2, 2); + d2 = 0; // filler (not used) + for (i=0; i<27; ++i) + { + file->write(&d2, 2); + } + + u8 cnt, value; + for (i=0; igetDimension().Height; ++i) + { + cnt = 0; + value = 0; + for (u32 j=0; j<3; ++j) // color planes + { + for (u32 k=0; kgetDimension().Width; ++k) + { + const SColor pix = image->getPixel(k,i); + if ((cnt!=0) && (cnt<63) && + (((j==0) && (value==pix.getRed())) || + ((j==1) && (value==pix.getGreen())) || + ((j==2) && (value==pix.getBlue())))) + { + ++cnt; + } + else + { + if (cnt!=0) + { + if ((cnt>1) || ((value&0xc0)==0xc0)) + { + cnt |= 0xc0; + file->write(&cnt, 1); + } + file->write(&value, 1); + } + cnt=1; + if (j==0) + value=(u8)pix.getRed(); + else if (j==1) + value=(u8)pix.getGreen(); + else if (j==2) + value=(u8)pix.getBlue(); + } + } + } + if ((cnt>1) || ((value&0xc0)==0xc0)) + { + cnt |= 0xc0; + file->write(&cnt, 1); + } + file->write(&value, 1); + } + + return true; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.h new file mode 100644 index 0000000..a0c6d6d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPCX.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PCX_H_INCLUDED__ +#define _C_IMAGE_WRITER_PCX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PCX_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPCX : public IImageWriter +{ +public: + //! constructor + CImageWriterPCX(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif +#endif // _C_IMAGE_WRITER_PCX_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.cpp new file mode 100644 index 0000000..6c6386e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.cpp @@ -0,0 +1,222 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPNG.h" + +#ifdef _IRR_COMPILE_WITH_PNG_WRITER_ + +#include "CImageLoaderPNG.h" +#include "CColorConverter.h" +#include "IWriteFile.h" +#include "irrString.h" +#include "os.h" // for logging + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ +#ifndef _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include // use system lib png +#else // _IRR_USE_NON_SYSTEM_LIB_PNG_ + #include "libpng/png.h" // use irrlicht included lib png +#endif // _IRR_USE_NON_SYSTEM_LIB_PNG_ +#endif // _IRR_COMPILE_WITH_LIBPNG_ + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterPNG() +{ + return new CImageWriterPNG; +} + +#ifdef _IRR_COMPILE_WITH_LIBPNG_ +// PNG function for error handling +static void png_cpexcept_error(png_structp png_ptr, png_const_charp msg) +{ + os::Printer::log("PNG fatal error", msg, ELL_ERROR); + longjmp(png_jmpbuf(png_ptr), 1); +} + +// PNG function for warning handling +static void png_cpexcept_warning(png_structp png_ptr, png_const_charp msg) +{ + os::Printer::log("PNG warning", msg, ELL_WARNING); +} + +// PNG function for file writing +void PNGAPI user_write_data_fcn(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_size_t check; + + io::IWriteFile* file=(io::IWriteFile*)png_get_io_ptr(png_ptr); + check=(png_size_t) file->write((const void*)data,(u32)length); + + if (check != length) + png_error(png_ptr, "Write Error"); +} +#endif // _IRR_COMPILE_WITH_LIBPNG_ + +CImageWriterPNG::CImageWriterPNG() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPNG"); +#endif +} + +bool CImageWriterPNG::isAWriteableFileExtension(const io::path& filename) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + return core::hasFileExtension ( filename, "png" ); +#else + return false; +#endif +} + +bool CImageWriterPNG::writeImage(io::IWriteFile* file, IImage* image,u32 param) const +{ +#ifdef _IRR_COMPILE_WITH_LIBPNG_ + if (!file || !image) + return false; + + // Allocate the png write struct + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + NULL, (png_error_ptr)png_cpexcept_error, (png_error_ptr)png_cpexcept_warning); + if (!png_ptr) + { + os::Printer::log("PNGWriter: Internal PNG create write struct failure\n", file->getFileName(), ELL_ERROR); + return false; + } + + // Allocate the png info struct + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + os::Printer::log("PNGWriter: Internal PNG create info struct failure\n", file->getFileName(), ELL_ERROR); + png_destroy_write_struct(&png_ptr, NULL); + return false; + } + + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; + } + + png_set_write_fn(png_ptr, file, user_write_data_fcn, NULL); + + // Set info + switch(image->getColorFormat()) + { + case ECF_A8R8G8B8: + case ECF_A1R5G5B5: + png_set_IHDR(png_ptr, info_ptr, + image->getDimension().Width, image->getDimension().Height, + 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + break; + default: + png_set_IHDR(png_ptr, info_ptr, + image->getDimension().Width, image->getDimension().Height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + } + + s32 lineWidth = image->getDimension().Width; + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + case ECF_R5G6B5: + lineWidth*=3; + break; + case ECF_A8R8G8B8: + case ECF_A1R5G5B5: + lineWidth*=4; + break; + // TODO: Error handling in case of unsupported color format + default: + break; + } + u8* tmpImage = new u8[image->getDimension().Height*lineWidth]; + if (!tmpImage) + { + os::Printer::log("PNGWriter: Internal PNG create image failure\n", file->getFileName(), ELL_ERROR); + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; + } + + u8* data = (u8*)image->lock(); + switch(image->getColorFormat()) + { + case ECF_R8G8B8: + CColorConverter::convert_R8G8B8toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + case ECF_A8R8G8B8: + CColorConverter::convert_A8R8G8B8toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + case ECF_R5G6B5: + CColorConverter::convert_R5G6B5toR8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; + case ECF_A1R5G5B5: + CColorConverter::convert_A1R5G5B5toA8R8G8B8(data,image->getDimension().Height*image->getDimension().Width,tmpImage); + break; +#ifndef _DEBUG + // TODO: Error handling in case of unsupported color format + default: + break; +#endif + } + image->unlock(); + + // Create array of pointers to rows in image data + + //Used to point to image rows + u8** RowPointers = new png_bytep[image->getDimension().Height]; + if (!RowPointers) + { + os::Printer::log("PNGWriter: Internal PNG create row pointers failure\n", file->getFileName(), ELL_ERROR); + png_destroy_write_struct(&png_ptr, &info_ptr); + delete [] tmpImage; + return false; + } + + data=tmpImage; + // Fill array of pointers to rows in image data + for (u32 i=0; igetDimension().Height; ++i) + { + RowPointers[i]=data; + data += lineWidth; + } + // for proper error handling + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + delete [] RowPointers; + delete [] tmpImage; + return false; + } + + png_set_rows(png_ptr, info_ptr, RowPointers); + + if (image->getColorFormat()==ECF_A8R8G8B8 || image->getColorFormat()==ECF_A1R5G5B5) + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL); + else + { + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + } + + delete [] RowPointers; + delete [] tmpImage; + png_destroy_write_struct(&png_ptr, &info_ptr); + return true; +#else + return false; +#endif +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.h new file mode 100644 index 0000000..67facc2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPNG.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PNG_H_INCLUDED__ +#define _C_IMAGE_WRITER_PNG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PNG_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPNG : public IImageWriter +{ +public: + //! constructor + CImageWriterPNG(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _C_IMAGE_WRITER_PNG_H_INCLUDED__ +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.cpp new file mode 100644 index 0000000..3bc1737 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPPM.h" + +#ifdef _IRR_COMPILE_WITH_PPM_WRITER_ + +#include "IWriteFile.h" +#include "IImage.h" +#include "dimension2d.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + + +IImageWriter* createImageWriterPPM() +{ + return new CImageWriterPPM; +} + + +CImageWriterPPM::CImageWriterPPM() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPPM"); +#endif +} + + +bool CImageWriterPPM::isAWriteableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "ppm" ); +} + + +bool CImageWriterPPM::writeImage(io::IWriteFile *file, IImage *image, u32 param) const +{ + char cache[70]; + int size; + + const core::dimension2d& imageSize = image->getDimension(); + + const bool binary = false; + + if (binary) + size = snprintf(cache, 70, "P6\n"); + else + size = snprintf(cache, 70, "P3\n"); + + if (file->write(cache, size) != size) + return false; + + size = snprintf(cache, 70, "%d %d\n", imageSize.Width, imageSize.Height); + if (file->write(cache, size) != size) + return false; + + size = snprintf(cache, 70, "255\n"); + if (file->write(cache, size) != size) + return false; + + if (binary) + { + for (u32 h = 0; h < imageSize.Height; ++h) + { + for (u32 c = 0; c < imageSize.Width; ++c) + { + const video::SColor& pixel = image->getPixel(c, h); + const u8 r = (u8)(pixel.getRed() & 0xff); + const u8 g = (u8)(pixel.getGreen() & 0xff); + const u8 b = (u8)(pixel.getBlue() & 0xff); + file->write(&r, 1); + file->write(&g, 1); + file->write(&b, 1); + } + } + } + else + { + s32 n = 0; + + for (u32 h = 0; h < imageSize.Height; ++h) + { + for (u32 c = 0; c < imageSize.Width; ++c, ++n) + { + const video::SColor& pixel = image->getPixel(c, h); + size = snprintf(cache, 70, "%.3u %.3u %.3u%s", pixel.getRed(), pixel.getGreen(), pixel.getBlue(), n % 5 == 4 ? "\n" : " "); + if (file->write(cache, size) != size) + return false; + } + } + } + + return true; +} + + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.h new file mode 100644 index 0000000..853674f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPPM.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PPM_H_INCLUDED__ +#define _C_IMAGE_WRITER_PPM_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PPM_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPPM : public IImageWriter +{ +public: + //! constructor + CImageWriterPPM(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image, u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _C_IMAGE_WRITER_PPM_H_INCLUDED__ +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.cpp new file mode 100644 index 0000000..952eb0b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterPSD.h" + +#ifdef _IRR_COMPILE_WITH_PSD_WRITER_ + +#include "CImageLoaderPSD.h" +#include "IWriteFile.h" +#include "os.h" // for logging +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterPSD() +{ + return new CImageWriterPSD; +} + +CImageWriterPSD::CImageWriterPSD() +{ +#ifdef _DEBUG + setDebugName("CImageWriterPSD"); +#endif +} + +bool CImageWriterPSD::isAWriteableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "psd" ); +} + +bool CImageWriterPSD::writeImage(io::IWriteFile *file, IImage *image,u32 param) const +{ + os::Printer::log("PSD writer not yet implemented. Image not written.", ELL_WARNING); + return false; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.h new file mode 100644 index 0000000..6f1494e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterPSD.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_PSD_H_INCLUDED__ +#define _C_IMAGE_WRITER_PSD_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PSD_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterPSD : public IImageWriter +{ +public: + //! constructor + CImageWriterPSD(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image,u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _I_IMAGE_WRITER_PSD_H_INCLUDED__ +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.cpp new file mode 100644 index 0000000..4a87eeb --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.cpp @@ -0,0 +1,147 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CImageWriterTGA.h" + +#ifdef _IRR_COMPILE_WITH_TGA_WRITER_ + +#include "CImageLoaderTGA.h" +#include "IWriteFile.h" +#include "CColorConverter.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +IImageWriter* createImageWriterTGA() +{ + return new CImageWriterTGA; +} + +CImageWriterTGA::CImageWriterTGA() +{ +#ifdef _DEBUG + setDebugName("CImageWriterTGA"); +#endif +} + +bool CImageWriterTGA::isAWriteableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "tga" ); +} + +bool CImageWriterTGA::writeImage(io::IWriteFile *file, IImage *image,u32 param) const +{ + STGAHeader imageHeader; + imageHeader.IdLength = 0; + imageHeader.ColorMapType = 0; + imageHeader.ImageType = 2; + imageHeader.FirstEntryIndex[0] = 0; + imageHeader.FirstEntryIndex[1] = 0; + imageHeader.ColorMapLength = 0; + imageHeader.ColorMapEntrySize = 0; + imageHeader.XOrigin[0] = 0; + imageHeader.XOrigin[1] = 0; + imageHeader.YOrigin[0] = 0; + imageHeader.YOrigin[1] = 0; + imageHeader.ImageWidth = image->getDimension().Width; + imageHeader.ImageHeight = image->getDimension().Height; + + // top left of image is the top. the image loader needs to + // be fixed to only swap/flip + imageHeader.ImageDescriptor = (1 << 5); + + // chances are good we'll need to swizzle data, so i'm going + // to convert and write one scan line at a time. it's also + // a bit cleaner this way + void (*CColorConverter_convertFORMATtoFORMAT)(const void*, s32, void*) = 0; + switch(image->getColorFormat()) + { + case ECF_A8R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A8R8G8B8toA8R8G8B8; + imageHeader.PixelDepth = 32; + imageHeader.ImageDescriptor |= 8; + break; + case ECF_A1R5G5B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_A1R5G5B5toA1R5G5B5; + imageHeader.PixelDepth = 16; + imageHeader.ImageDescriptor |= 1; + break; + case ECF_R5G6B5: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R5G6B5toA1R5G5B5; + imageHeader.PixelDepth = 16; + imageHeader.ImageDescriptor |= 1; + break; + case ECF_R8G8B8: + CColorConverter_convertFORMATtoFORMAT + = CColorConverter::convert_R8G8B8toR8G8B8; + imageHeader.PixelDepth = 24; + imageHeader.ImageDescriptor |= 0; + break; +#ifndef _DEBUG + default: + break; +#endif + } + + // couldn't find a color converter + if (!CColorConverter_convertFORMATtoFORMAT) + return false; + + if (file->write(&imageHeader, sizeof(imageHeader)) != sizeof(imageHeader)) + return false; + + u8* scan_lines = (u8*)image->lock(); + if (!scan_lines) + return false; + + // size of one pixel in bytes + u32 pixel_size = image->getBytesPerPixel(); + + // length of one row of the source image in bytes + u32 row_stride = (pixel_size * imageHeader.ImageWidth); + + // length of one output row in bytes + s32 row_size = ((imageHeader.PixelDepth / 8) * imageHeader.ImageWidth); + + // allocate a row do translate data into + u8* row_pointer = new u8[row_size]; + + u32 y; + for (y = 0; y < imageHeader.ImageHeight; ++y) + { + // source, length [pixels], destination + if (image->getColorFormat()==ECF_R8G8B8) + CColorConverter::convert24BitTo24Bit(&scan_lines[y * row_stride], row_pointer, imageHeader.ImageWidth, 1, 0, 0, true); + else + CColorConverter_convertFORMATtoFORMAT(&scan_lines[y * row_stride], imageHeader.ImageWidth, row_pointer); + if (file->write(row_pointer, row_size) != row_size) + break; + } + + delete [] row_pointer; + + image->unlock(); + + STGAFooter imageFooter; + imageFooter.ExtensionOffset = 0; + imageFooter.DeveloperOffset = 0; + strncpy(imageFooter.Signature, "TRUEVISION-XFILE.", 18); + + if (file->write(&imageFooter, sizeof(imageFooter)) < (s32)sizeof(imageFooter)) + return false; + + return imageHeader.ImageHeight <= y; +} + +} // namespace video +} // namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.h new file mode 100644 index 0000000..ee8e4cb --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterTGA.h @@ -0,0 +1,37 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef _C_IMAGE_WRITER_TGA_H_INCLUDED__ +#define _C_IMAGE_WRITER_TGA_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_TGA_WRITER_ + +#include "IImageWriter.h" + +namespace irr +{ +namespace video +{ + +class CImageWriterTGA : public IImageWriter +{ +public: + //! constructor + CImageWriterTGA(); + + //! return true if this writer can write a file with the given extension + virtual bool isAWriteableFileExtension(const io::path& filename) const; + + //! write image to file + virtual bool writeImage(io::IWriteFile *file, IImage *image,u32 param) const; +}; + +} // namespace video +} // namespace irr + +#endif // _C_IMAGE_WRITER_TGA_H_INCLUDED__ +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp new file mode 100644 index 0000000..53892ee --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp @@ -0,0 +1,477 @@ +// Copyright (C) 2009-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CIrrDeviceConsole.h" + +#ifdef _IRR_COMPILE_WITH_CONSOLE_DEVICE_ + +#include "os.h" +#include "IGUISkin.h" +#include "IGUIEnvironment.h" + +// to close the device on terminate signal +irr::CIrrDeviceConsole *DeviceToClose; + +#ifdef _IRR_WINDOWS_NT_CONSOLE_ +// Callback for Windows +BOOL WINAPI ConsoleHandler(DWORD CEvent) +{ + switch(CEvent) + { + case CTRL_C_EVENT: + irr::os::Printer::log("Closing console device", "CTRL+C"); + break; + case CTRL_BREAK_EVENT: + irr::os::Printer::log("Closing console device", "CTRL+Break"); + break; + case CTRL_CLOSE_EVENT: + irr::os::Printer::log("Closing console device", "User closed console"); + break; + case CTRL_LOGOFF_EVENT: + irr::os::Printer::log("Closing console device", "User is logging off"); + break; + case CTRL_SHUTDOWN_EVENT: + irr::os::Printer::log("Closing console device", "Computer shutting down"); + break; + } + DeviceToClose->closeDevice(); + return TRUE; +} +#elif defined(_IRR_POSIX_API_) +// sigterm handler +#include + +void sighandler(int sig) +{ + irr::core::stringc code = "Signal "; + code += sig; + code += " received"; + irr::os::Printer::log("Closing console device", code.c_str()); + + DeviceToClose->closeDevice(); +} +#endif + +namespace irr +{ + +const c8 ASCIIArtChars[] = " .,'~:;!+>=icopjtJY56SB8XDQKHNWM"; //MWNHKQDX8BS65YJtjpoci=+>!;:~',. "; +const u16 ASCIIArtCharsCount = 32; + +//const c8 ASCIIArtChars[] = " \xb0\xb1\xf9\xb2\xdb"; +//const u16 ASCIIArtCharsCount = 5; + +//! constructor +CIrrDeviceConsole::CIrrDeviceConsole(const SIrrlichtCreationParameters& params) + : CIrrDeviceStub(params), IsWindowFocused(true), ConsoleFont(0), OutFile(stdout) +{ + DeviceToClose = this; + +#ifdef _IRR_WINDOWS_NT_CONSOLE_ + MouseButtonStates = 0; + + WindowsSTDIn = GetStdHandle(STD_INPUT_HANDLE); + WindowsSTDOut = GetStdHandle(STD_OUTPUT_HANDLE); + PCOORD Dimensions = 0; + + if (CreationParams.Fullscreen) + { +// Some mingw versions lack this define, so avoid it in case it does not exist +#if (_WIN32_WINNT >= 0x0501) && defined(CONSOLE_FULLSCREEN_MODE) + if (SetConsoleDisplayMode(WindowsSTDOut, CONSOLE_FULLSCREEN_MODE, Dimensions)) + { + CreationParams.WindowSize.Width = Dimensions->X; + CreationParams.WindowSize.Width = Dimensions->Y; + } +#endif + } + else + { + COORD ConsoleSize; + ConsoleSize.X = CreationParams.WindowSize.Width; + ConsoleSize.X = CreationParams.WindowSize.Height; + SetConsoleScreenBufferSize(WindowsSTDOut, ConsoleSize); + } + + // catch windows close/break signals + SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE); + +#elif defined(_IRR_POSIX_API_) + // catch other signals + signal(SIGABRT, &sighandler); + signal(SIGTERM, &sighandler); + signal(SIGINT, &sighandler); + + // set output stream + if (params.WindowId) + OutFile = (FILE*)(params.WindowId); +#endif + +#ifdef _IRR_VT100_CONSOLE_ + // reset terminal + fprintf(OutFile, "%cc", 27); + // disable line wrapping + fprintf(OutFile, "%c[7l", 27); +#endif + + switch (params.DriverType) + { + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + #else + os::Printer::log("Software driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + case video::EDT_OPENGL: + os::Printer::log("The console device cannot use hardware drivers yet.", ELL_ERROR); + break; + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + default: + break; + } + + // set up output buffer + for (u32 y=0; ygetSkin(); + if (skin) + { + for (u32 i=0; i < gui::EGDF_COUNT; ++i) + skin->setFont(ConsoleFont, gui::EGUI_DEFAULT_FONT(i)); + } + } +#endif + } +} + +//! destructor +CIrrDeviceConsole::~CIrrDeviceConsole() +{ + // GUI and scene are dropped in the stub + if (CursorControl) + { + CursorControl->drop(); + CursorControl = 0; + } + if (ConsoleFont) + { + ConsoleFont->drop(); + ConsoleFont = 0; + } +#ifdef _IRR_VT100_CONSOLE_ + // reset terminal + fprintf(OutFile, "%cc", 27); +#endif +} + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceConsole::run() +{ + // increment timer + os::Timer::tick(); + + // process Windows console input +#ifdef _IRR_WINDOWS_NT_CONSOLE_ + + INPUT_RECORD in; + DWORD oldMode; + DWORD count, waste; + + // get old input mode + GetConsoleMode(WindowsSTDIn, &oldMode); + SetConsoleMode(WindowsSTDIn, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); + + GetNumberOfConsoleInputEvents(WindowsSTDIn, &count); + + // read keyboard and mouse input + while (count) + { + ReadConsoleInput(WindowsSTDIn, &in, 1, &waste ); + switch(in.EventType) + { + case KEY_EVENT: + { + SEvent e; + e.EventType = EET_KEY_INPUT_EVENT; + e.KeyInput.PressedDown = (in.Event.KeyEvent.bKeyDown == TRUE); + e.KeyInput.Control = (in.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0; + e.KeyInput.Shift = (in.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) != 0; + e.KeyInput.Key = EKEY_CODE(in.Event.KeyEvent.wVirtualKeyCode); + e.KeyInput.Char = in.Event.KeyEvent.uChar.UnicodeChar; + postEventFromUser(e); + break; + } + case MOUSE_EVENT: + { + SEvent e; + e.EventType = EET_MOUSE_INPUT_EVENT; + e.MouseInput.X = in.Event.MouseEvent.dwMousePosition.X; + e.MouseInput.Y = in.Event.MouseEvent.dwMousePosition.Y; + e.MouseInput.Wheel = 0.f; + e.MouseInput.ButtonStates = + ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) ? EMBSM_LEFT : 0 ) | + ( (in.Event.MouseEvent.dwButtonState & RIGHTMOST_BUTTON_PRESSED) ? EMBSM_RIGHT : 0 ) | + ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) ? EMBSM_MIDDLE : 0 ) | + ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_3RD_BUTTON_PRESSED) ? EMBSM_EXTRA1 : 0 ) | + ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_4TH_BUTTON_PRESSED) ? EMBSM_EXTRA2 : 0 ); + + if (in.Event.MouseEvent.dwEventFlags & MOUSE_MOVED) + { + CursorControl->setPosition(core::position2di(e.MouseInput.X, e.MouseInput.Y)); + + // create mouse moved event + e.MouseInput.Event = EMIE_MOUSE_MOVED; + postEventFromUser(e); + } + + if (in.Event.MouseEvent.dwEventFlags & MOUSE_WHEELED) + { + e.MouseInput.Event = EMIE_MOUSE_WHEEL; + e.MouseInput.Wheel = (in.Event.MouseEvent.dwButtonState & 0xFF000000) ? -1.0f : 1.0f; + postEventFromUser(e); + } + + if ( (MouseButtonStates & EMBSM_LEFT) != (e.MouseInput.ButtonStates & EMBSM_LEFT) ) + { + e.MouseInput.Event = (e.MouseInput.ButtonStates & EMBSM_LEFT) ? EMIE_LMOUSE_PRESSED_DOWN : EMIE_LMOUSE_LEFT_UP; + postEventFromUser(e); + } + + if ( (MouseButtonStates & EMBSM_RIGHT) != (e.MouseInput.ButtonStates & EMBSM_RIGHT) ) + { + e.MouseInput.Event = (e.MouseInput.ButtonStates & EMBSM_RIGHT) ? EMIE_RMOUSE_PRESSED_DOWN : EMIE_RMOUSE_LEFT_UP; + postEventFromUser(e); + } + + if ( (MouseButtonStates & EMBSM_MIDDLE) != (e.MouseInput.ButtonStates & EMBSM_MIDDLE) ) + { + e.MouseInput.Event = (e.MouseInput.ButtonStates & EMBSM_MIDDLE) ? EMIE_MMOUSE_PRESSED_DOWN : EMIE_MMOUSE_LEFT_UP; + postEventFromUser(e); + } + + // save current button states + MouseButtonStates = e.MouseInput.ButtonStates; + + break; + } + case WINDOW_BUFFER_SIZE_EVENT: + VideoDriver->OnResize( + core::dimension2d(in.Event.WindowBufferSizeEvent.dwSize.X, + in.Event.WindowBufferSizeEvent.dwSize.Y)); + break; + case FOCUS_EVENT: + IsWindowFocused = (in.Event.FocusEvent.bSetFocus == TRUE); + break; + default: + break; + } + GetNumberOfConsoleInputEvents(WindowsSTDIn, &count); + } + + // set input mode + SetConsoleMode(WindowsSTDIn, oldMode); +#else + // todo: keyboard input from terminal in raw mode +#endif + + return !Close; +} + +//! Cause the device to temporarily pause execution and let other processes to run +// This should bring down processor usage without major performance loss for Irrlicht +void CIrrDeviceConsole::yield() +{ +#ifdef _IRR_WINDOWS_API_ + Sleep(1); +#else + struct timespec ts = {0,0}; + nanosleep(&ts, NULL); +#endif +} + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceConsole::sleep(u32 timeMs, bool pauseTimer) +{ + const bool wasStopped = Timer ? Timer->isStopped() : true; + +#ifdef _IRR_WINDOWS_API_ + Sleep(timeMs); +#else + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); +#endif + + if (pauseTimer && !wasStopped) + Timer->start(); +} + +//! sets the caption of the window +void CIrrDeviceConsole::setWindowCaption(const wchar_t* text) +{ +#ifdef _IRR_WINDOWS_NT_CONSOLE_ + SetConsoleTitleW(text); +#endif +} + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceConsole::isWindowActive() const +{ + // there is no window, but we always assume it is active + return true; +} + +//! returns if window has focus +bool CIrrDeviceConsole::isWindowFocused() const +{ + return IsWindowFocused; +} + +//! returns if window is minimized +bool CIrrDeviceConsole::isWindowMinimized() const +{ + return false; +} + +//! presents a surface in the client area +bool CIrrDeviceConsole::present(video::IImage* surface, void* windowId, core::rect* src) +{ + + if (surface) + { + for (u32 y=0; y < surface->getDimension().Height; ++y) + { + for (u32 x=0; x< surface->getDimension().Width; ++x) + { + // get average pixel + u32 avg = surface->getPixel(x,y).getAverage() * (ASCIIArtCharsCount-1); + avg /= 255; + OutputBuffer[y] [x] = ASCIIArtChars[avg]; + } + } + } +#ifdef _IRR_USE_CONSOLE_FONT_ + for (u32 i=0; i< Text.size(); ++i) + { + s32 y = Text[i].Pos.Y; + + if ( y < (s32)OutputBuffer.size() && y > 0) + for (u32 c=0; c < Text[i].Text.size() && c + Text[i].Pos.X < OutputBuffer[y].size(); ++c) + //if (Text[i].Text[c] != ' ') + OutputBuffer[y] [c+Text[i].Pos.X] = Text[i].Text[c]; + } + Text.clear(); +#endif + + // draw output + for (u32 y=0; y +#endif +#if(_WIN32_WINNT >= 0x0500) +#define _IRR_WINDOWS_NT_CONSOLE_ +#endif +#else +#include +#endif + +// for now we assume all other terminal types are VT100 +#ifndef _IRR_WINDOWS_NT_CONSOLE_ +#define _IRR_VT100_CONSOLE_ +#endif + +namespace irr +{ + + class CIrrDeviceConsole : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceConsole(const SIrrlichtCreationParameters& params); + + //! destructor + virtual ~CIrrDeviceConsole(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! returns if window has focus + virtual bool isWindowFocused() const; + + //! returns if window is minimized + virtual bool isWindowMinimized() const; + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize=false); + + //! Minimizes the window. + virtual void minimizeWindow(); + + //! Maximizes the window. + virtual void maximizeWindow(); + + //! Restores the window size. + virtual void restoreWindow(); + + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_CONSOLE; + } + + void addPostPresentText(s16 X, s16 Y, const wchar_t *text); + + //! Implementation of the win32 console mouse cursor + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(const core::dimension2d& wsize) + : WindowSize(wsize), InvWindowSize(0.0f, 0.0f), IsVisible(true), UseReferenceRect(false) + { + if (WindowSize.Width!=0) + InvWindowSize.Width = 1.0f / WindowSize.Width; + + if (WindowSize.Height!=0) + InvWindowSize.Height = 1.0f / WindowSize.Height; + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + if(visible != IsVisible) + { + IsVisible = visible; + setPosition(CursorPos.X, CursorPos.Y); + } + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + if (!UseReferenceRect) + setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); + else + setPosition((s32)(x*ReferenceRect.getWidth()), (s32)(y*ReferenceRect.getHeight())); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + setInternalCursorPosition(core::position2di(x,y)); + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + + //! Updates the internal cursor position + void setInternalCursorPosition(const core::position2di &pos) + { + CursorPos = pos; + + if (UseReferenceRect) + CursorPos -= ReferenceRect.UpperLeftCorner; + } + + private: + + core::position2d CursorPos; + core::dimension2d WindowSize; + core::dimension2d InvWindowSize; + bool IsVisible, + UseReferenceRect; + core::rect ReferenceRect; + }; + + private: + + //! Set the position of the text caret + void setTextCursorPos(s16 x, s16 y); + + // text to be added after drawing the screen + struct SPostPresentText + { + core::position2d Pos; + core::stringc Text; + }; + + bool IsWindowFocused; + + core::array OutputBuffer; + gui::IGUIFont *ConsoleFont; + core::array Text; + + FILE *OutFile; + +#ifdef _IRR_WINDOWS_NT_CONSOLE_ + HANDLE WindowsSTDIn, WindowsSTDOut; + u32 MouseButtonStates; +#endif + }; + +#ifdef _IRR_USE_CONSOLE_FONT_ + +namespace gui +{ + class CGUIConsoleFont : public IGUIFont + { + public: + + CGUIConsoleFont(CIrrDeviceConsole* device) : Device(device) { } + + //! Draws some text and clips it to the specified rectangle if wanted. + virtual void draw(const wchar_t* text, const core::rect& position, + video::SColor color, bool hcenter=false, bool vcenter=false, + const core::rect* clip=0) + { + core::rect Area = clip ? *clip : position; + + if (Area.UpperLeftCorner.X < 0) + Area.UpperLeftCorner.X = 0; + + if (Area.UpperLeftCorner.Y < 0) + Area.UpperLeftCorner.Y = 0; + + core::position2d pos; + + // centre vertically + pos.Y = vcenter ? (position.UpperLeftCorner.Y + position.LowerRightCorner.Y) / 2 : position.UpperLeftCorner.Y; + + // nothing to display? + if (pos.Y < Area.UpperLeftCorner.Y || pos.Y > Area.LowerRightCorner.Y) + return; + + tempText = text; + + // centre horizontally + pos.X = hcenter ? position.getCenter().X - ( tempText.size() / 2) : position.UpperLeftCorner.X; + + // clip + u32 xlclip = 0, + xrclip = 0; + + // get right clip + if (pos.X + (s32)tempText.size() > Area.LowerRightCorner.X) + xrclip = Area.LowerRightCorner.X - pos.X; + + // get left clip + if (pos.X < Area.UpperLeftCorner.X) + xlclip = Area.UpperLeftCorner.X - pos.X; + + // totally clipped? + if ((s32)tempText.size() - xlclip - xrclip < 0) + return; + + // null terminate the string + if (xrclip > 0) + tempText[xrclip] = L'\0'; + + Device->addPostPresentText(pos.X + xlclip, pos.Y, &(tempText.c_str()[xlclip])); + } + + //! Calculates the dimension of some text. + virtual core::dimension2d getDimension(const wchar_t* text) const + { + return core::dimension2d(wcslen(text),1); + } + + //! Calculates the index of the character in the text which is on a specific position. + virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const { return pixel_x; }; + + //! No kerning + virtual void setKerningWidth (s32 kerning) { } + virtual void setKerningHeight (s32 kerning) { } + virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const {return 0;} + virtual s32 getKerningHeight() const { return 0;} + virtual void setInvisibleCharacters( const wchar_t *s ) { } + // I guess this is an OS specific font + virtual EGUI_FONT_TYPE getType() const { return EGFT_OS; } + private: + CIrrDeviceConsole* Device; + core::stringw tempText; + }; + +} // end namespace gui + +#endif // _IRR_USE_CONSOLE_FONT_ + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_CONSOLE_DEVICE_ +#endif // __C_IRR_DEVICE_CONSOLE_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp new file mode 100644 index 0000000..e3af6c2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp @@ -0,0 +1,405 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CIrrDeviceFB.h" + +#ifdef _IRR_COMPILE_WITH_FB_DEVICE_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "IEventReceiver.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include "COSOperator.h" +#include "CColorConverter.h" +#include "SIrrCreationParameters.h" + +#include + +namespace irr +{ + +//! constructor +CIrrDeviceFB::CIrrDeviceFB(const SIrrlichtCreationParameters& params) + : CIrrDeviceStub(params), Framebuffer(-1), EventDevice(-1), SoftwareImage(0), + Pitch(0), FBColorFormat(video::ECF_A8R8G8B8), Close(false) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceFB"); + #endif + + // print version, distribution etc. + // thx to LynxLuna for pointing me to the uname function + core::stringc linuxversion; + struct utsname FBInfo; + uname(&FBInfo); + + linuxversion += FBInfo.sysname; + linuxversion += " "; + linuxversion += FBInfo.release; + linuxversion += " "; + linuxversion += FBInfo.version; + linuxversion += " "; + linuxversion += FBInfo.machine; + + Operator = new COSOperator(linuxversion); + os::Printer::log(linuxversion.c_str(), ELL_INFORMATION); + + // create window + if (params.DriverType != video::EDT_NULL) + { + // create the window, only if we do not use the null device + if (!createWindow(params.WindowSize, params.Bits)) + return; + } + + // create cursor control + CursorControl = new CCursorControl(this, params.DriverType == video::EDT_NULL); + + // create driver + createDriver(); + + if (!VideoDriver) + return; + + createGUIAndScene(); +} + + + +//! destructor +CIrrDeviceFB::~CIrrDeviceFB() +{ + if (SoftwareImage) + munmap(SoftwareImage, CreationParams.WindowSize.Height*Pitch); + // go back to previous format + if (ioctl(Framebuffer, FBIOPUT_VSCREENINFO, &oldscreeninfo) <0) + perror("Restoring old fb mode"); + + if (KeyboardDevice != -1) + if (ioctl(KeyboardDevice, KDSETMODE, &KeyboardMode) <0) + perror("Restoring keyboard mode"); + if (EventDevice != -1) + close(EventDevice); + if (KeyboardDevice != -1) + close(KeyboardDevice); + if (Framebuffer != -1) + close(Framebuffer); +} + + +bool CIrrDeviceFB::createWindow(const core::dimension2d& windowSize, u32 bits) +{ + char buf[256]; + CreationParams.WindowSize.Width = windowSize.Width; + CreationParams.WindowSize.Height = windowSize.Height; + + KeyboardDevice = open("/dev/tty", O_RDWR); + if (KeyboardDevice == -1) + perror("Open keyboard"); + if (ioctl(KeyboardDevice, KDGETMODE, &KeyboardMode) <0) + perror("Read keyboard mode"); + if (ioctl(KeyboardDevice, KDSETMODE, KD_GRAPHICS) <0) + perror("Set keyboard mode"); + + Framebuffer=open("/dev/fb/0", O_RDWR); + if (Framebuffer == -1) + { + Framebuffer=open("/dev/fb0", O_RDWR); + if (Framebuffer == -1) + { + perror("Open framebuffer"); + return false; + } + } + EventDevice = open("/dev/input/event0", O_RDONLY | O_NONBLOCK); + if (EventDevice == -1) + perror("Open event device"); + + // make format settings + ioctl(Framebuffer, FBIOGET_FSCREENINFO, &fbfixscreeninfo); + ioctl(Framebuffer, FBIOGET_VSCREENINFO, &oldscreeninfo); +snprintf(buf, 256, "Original resolution: %d x %d\nARGB%d%d%d%d\n",oldscreeninfo.xres,oldscreeninfo.yres, + oldscreeninfo.transp.length,oldscreeninfo.red.length,oldscreeninfo.green.length,oldscreeninfo.blue.length); + os::Printer::log(buf); + memcpy(&fbscreeninfo, &oldscreeninfo, sizeof(struct fb_var_screeninfo)); + if (CreationParams.DriverType != video::EDT_NULL) + { + fbscreeninfo.xres = fbscreeninfo.xres_virtual = CreationParams.WindowSize.Width; + fbscreeninfo.yres = fbscreeninfo.yres_virtual = CreationParams.WindowSize.Height; + fbscreeninfo.bits_per_pixel = 16; + fbscreeninfo.red.offset = 10; + fbscreeninfo.red.length = 5; + fbscreeninfo.green.offset = 5; + fbscreeninfo.green.length = 5; + fbscreeninfo.blue.offset = 0; + fbscreeninfo.blue.length = 5; + fbscreeninfo.transp.offset = 15; + fbscreeninfo.transp.length = 1; + ioctl(Framebuffer, FBIOPUT_VSCREENINFO, &fbscreeninfo); + ioctl(Framebuffer, FBIOGET_VSCREENINFO, &fbscreeninfo); + +snprintf(buf, 256, "New resolution: %d x %d (%d x %d)\nARGB%d%d%d%d\n",fbscreeninfo.xres,fbscreeninfo.yres,fbscreeninfo.xres_virtual,fbscreeninfo.yres_virtual, + fbscreeninfo.transp.length,fbscreeninfo.red.length,fbscreeninfo.green.length,fbscreeninfo.blue.length); + os::Printer::log(buf); + + CreationParams.WindowSize.Width = fbscreeninfo.xres; + CreationParams.WindowSize.Height = fbscreeninfo.yres; + CreationParams.Bits = fbscreeninfo.bits_per_pixel; + Pitch = fbfixscreeninfo.line_length; + if (fbscreeninfo.bits_per_pixel == 16) + { + if (fbscreeninfo.transp.length == 0) + FBColorFormat = video::ECF_R5G6B5; + else + FBColorFormat = video::ECF_A1R5G5B5; + } + else + { + if (fbscreeninfo.transp.length == 0) + FBColorFormat = video::ECF_R8G8B8; + else + FBColorFormat = video::ECF_A8R8G8B8; + } + if (MAP_FAILED==(SoftwareImage=(u8*)mmap(0, CreationParams.WindowSize.Height*Pitch, PROT_READ|PROT_WRITE, MAP_SHARED, Framebuffer, 0))) + { + perror("mmap render target"); + return false; + } + } + return true; +} + + +//! create the driver +void CIrrDeviceFB::createDriver() +{ + switch(CreationParams.DriverType) + { + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + #else + os::Printer::log("No Software driver support compiled in.", ELL_WARNING); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_WARNING); + #endif + break; + + case video::EDT_OPENGL: + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in FB. Try Software renderer.", + ELL_WARNING); + break; + + default: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + } +} + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceFB::run() +{ + os::Timer::tick(); + + struct input_event ev; + if (EventDevice>=0) + { + if ((read(EventDevice, &ev, sizeof(input_event)) < 0) && + errno != EAGAIN) + perror("Read input event"); + if (ev.type == EV_KEY) + { + irr::SEvent irrevent; + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.PressedDown = true; + + switch (ev.code) + { + case KEY_RIGHTCTRL: + case KEY_LEFTCTRL: + irrevent.KeyInput.Control = true; + break; + case KEY_RIGHTSHIFT: + case KEY_LEFTSHIFT: + irrevent.KeyInput.Shift = true; + break; + case KEY_ESC: + irrevent.KeyInput.Key = (EKEY_CODE)0x1B; + break; + case KEY_SPACE: + irrevent.KeyInput.Key = (EKEY_CODE)0x20; + break; + case KEY_UP: + irrevent.KeyInput.Key = (EKEY_CODE)0x26; + break; + case KEY_LEFT: + irrevent.KeyInput.Key = (EKEY_CODE)0x25; + break; + case KEY_RIGHT: + irrevent.KeyInput.Key = (EKEY_CODE)0x27; + break; + case KEY_DOWN: + irrevent.KeyInput.Key = (EKEY_CODE)0x28; + break; + default: + irrevent.KeyInput.Key = (EKEY_CODE)0; + break; + } + postEventFromUser(irrevent); + } + } + + return !Close; +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceFB::yield() +{ + struct timespec ts = {0,0}; + nanosleep(&ts, NULL); +} + + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceFB::sleep(u32 timeMs, bool pauseTimer=false) +{ + bool wasStopped = Timer ? Timer->isStopped() : true; + + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +//! presents a surface in the client area +bool CIrrDeviceFB::present(video::IImage* image, void* windowId, core::rect* src ) +{ + // this is only necessary for software drivers. + if (CreationParams.DriverType != video::EDT_SOFTWARE && CreationParams.DriverType != video::EDT_BURNINGSVIDEO) + return false; + + if (!SoftwareImage) + return false; + + u8* destData = SoftwareImage; + u32 srcwidth = (u32)image->getDimension().Width; + u32 srcheight = (u32)image->getDimension().Height; + // clip images + srcheight = core::min_(srcheight, CreationParams.WindowSize.Height); + srcwidth = core::min_(srcwidth, CreationParams.WindowSize.Width); + + u8* srcdata = (u8*)image->lock(); + for (u32 y=0; ygetColorFormat(), srcwidth, destData, FBColorFormat); + srcdata+=image->getPitch(); + destData+=Pitch; + } + image->unlock(); + msync(SoftwareImage,CreationParams.WindowSize.Width*CreationParams.WindowSize.Height,MS_ASYNC); + return true; +} + + +//! notifies the device that it should close itself +void CIrrDeviceFB::closeDevice() +{ + Close = true; +} + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceFB::isWindowActive() const +{ + return true; +} + + +//! returns if window has focus +bool CIrrDeviceFB::isWindowFocused() const +{ + return true; +} + + +//! returns if window is minimized +bool CIrrDeviceFB::isWindowMinimized() const +{ + return false; +} + + +//! sets the caption of the window +void CIrrDeviceFB::setWindowCaption(const wchar_t* text) +{ +} + + +//! Sets if the window should be resizeable in windowed mode. +void CIrrDeviceFB::setResizable(bool resize) +{ +} + + +//! Minimizes window +void CIrrDeviceFB::minimizeWindow() +{ +} + + +//! Maximizes window +void CIrrDeviceFB::maximizeWindow() +{ +} + + +//! Restores original window size +void CIrrDeviceFB::restoreWindow() +{ +} + + +//! Returns the type of this device +E_DEVICE_TYPE CIrrDeviceFB::getType() const +{ + return EIDT_FRAMEBUFFER; +} + + +} // end namespace irr + +#endif // _IRR_USE_FB_DEVICE_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.h new file mode 100644 index 0000000..07a9aca --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.h @@ -0,0 +1,207 @@ +// Copyright (C) 2002-2007 Nikolaus Gebhardt +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_FB_H_INCLUDED__ +#define __C_IRR_DEVICE_FB_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_FB_DEVICE_ + +#include "CIrrDeviceStub.h" +#include "SIrrCreationParameters.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "ICursorControl.h" + +#define KeySym s32 +#include +#include + +namespace irr +{ + class CIrrDeviceFB : public CIrrDeviceStub, public video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceFB(const SIrrlichtCreationParameters& params); + + //! destructor + virtual ~CIrrDeviceFB(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! returns if window has focus + virtual bool isWindowFocused() const; + + //! returns if window is minimized + virtual bool isWindowMinimized() const; + + //! Minimizes window + virtual void minimizeWindow(); + + //! Maximizes window + virtual void maximizeWindow(); + + //! Restores original window size + virtual void restoreWindow(); + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId = 0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! Sets if the window should be resizeable in windowed mode. + virtual void setResizable(bool resize=false); + + //! Returns the type of this device + virtual E_DEVICE_TYPE getType() const; + + private: + + //! create the driver + void createDriver(); + + bool createWindow(const core::dimension2d& windowSize, u32 bits); + + //! Implementation of the cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(CIrrDeviceFB* dev, bool null) + : Device(dev), IsVisible(true), Null(null) + { + Device->grab(); + } + + ~CCursorControl() + { + Device->drop(); + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*Device->CreationParams.WindowSize.Width), (s32)(y*Device->CreationParams.WindowSize.Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + updateCursorPos(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateCursorPos(); + return core::position2d(CursorPos.X / (f32)Device->CreationParams.WindowSize.Width, + CursorPos.Y / (f32)Device->CreationParams.WindowSize.Height); + } + + virtual void setReferenceRect(core::rect* rect=0) + { + } + + private: + + void updateCursorPos() + { + } + + core::position2d CursorPos; + CIrrDeviceFB* Device; + bool IsVisible; + bool Null; + }; + + friend class CCursorControl; + + int Framebuffer; + int EventDevice; + int KeyboardDevice; + struct fb_fix_screeninfo fbfixscreeninfo; + struct fb_var_screeninfo fbscreeninfo; + struct fb_var_screeninfo oldscreeninfo; + long KeyboardMode; + u8* SoftwareImage; + + u32 Pitch; + video::ECOLOR_FORMAT FBColorFormat; + bool Close; + + struct SKeyMap + { + SKeyMap() {} + SKeyMap(s32 x11, s32 win32) + : X11Key(x11), Win32Key(win32) + { + } + + KeySym X11Key; + s32 Win32Key; + + bool operator<(const SKeyMap& o) const + { + return X11Key KeyMap; + }; + + +} // end namespace irr + +#endif // _IRR_USE_FB_DEVICE_ +#endif // __C_IRR_DEVICE_FB_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.cpp new file mode 100644 index 0000000..b94d566 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.cpp @@ -0,0 +1,2303 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CIrrDeviceLinux.h" + +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + +#include +#include +#include +#include +#include "IEventReceiver.h" +#include "ISceneManager.h" +#include "IGUIEnvironment.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include "COSOperator.h" +#include "CColorConverter.h" +#include "SIrrCreationParameters.h" +#include "IGUISpriteBank.h" +#include +#include + +#ifdef _IRR_LINUX_XCURSOR_ +#include +#endif + +#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#include +#include + +#ifdef __FREE_BSD_ +#include +#else + +// linux/joystick.h includes linux/input.h, which #defines values for various KEY_FOO keys. +// These override the irr::KEY_FOO equivalents, which stops key handling from working. +// As a workaround, defining _INPUT_H stops linux/input.h from being included; it +// doesn't actually seem to be necessary except to pull in sys/ioctl.h. +#define _INPUT_H +#include // Would normally be included in linux/input.h +#include +#undef _INPUT_H +#endif + +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + +namespace irr +{ + namespace video + { + IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceLinux* device); + } +} // end namespace irr + +namespace +{ + Atom X_ATOM_CLIPBOARD; + Atom X_ATOM_TARGETS; + Atom X_ATOM_UTF8_STRING; + Atom X_ATOM_TEXT; +}; + +namespace irr +{ + +const char* wmDeleteWindow = "WM_DELETE_WINDOW"; + +//! constructor +CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param) + : CIrrDeviceStub(param), +#ifdef _IRR_COMPILE_WITH_X11_ + display(0), visual(0), screennr(0), window(0), StdHints(0), SoftwareImage(0), +#ifdef _IRR_COMPILE_WITH_OPENGL_ + glxWin(0), + Context(0), +#endif +#endif + Width(param.WindowSize.Width), Height(param.WindowSize.Height), + WindowHasFocus(false), WindowMinimized(false), + UseXVidMode(false), UseXRandR(false), UseGLXWindow(false), + ExternalWindow(false), AutorepeatSupport(0) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceLinux"); + #endif + + // print version, distribution etc. + // thx to LynxLuna for pointing me to the uname function + core::stringc linuxversion; + struct utsname LinuxInfo; + uname(&LinuxInfo); + + linuxversion += LinuxInfo.sysname; + linuxversion += " "; + linuxversion += LinuxInfo.release; + linuxversion += " "; + linuxversion += LinuxInfo.version; + linuxversion += " "; + linuxversion += LinuxInfo.machine; + + Operator = new COSOperator(linuxversion, this); + os::Printer::log(linuxversion.c_str(), ELL_INFORMATION); + + // create keymap + createKeyMap(); + + // create window + if (CreationParams.DriverType != video::EDT_NULL) + { + // create the window, only if we do not use the null device + if (!createWindow()) + return; + } + + // create cursor control + CursorControl = new CCursorControl(this, CreationParams.DriverType == video::EDT_NULL); + + // create driver + createDriver(); + + if (!VideoDriver) + return; + + createGUIAndScene(); +} + + +//! destructor +CIrrDeviceLinux::~CIrrDeviceLinux() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (StdHints) + XFree(StdHints); + // Disable cursor (it is drop'ed in stub) + if (CursorControl) + { + CursorControl->setVisible(false); + static_cast(CursorControl)->clearCursors(); + } + + // Must free OpenGL textures etc before destroying context, so can't wait for stub destructor + if ( GUIEnvironment ) + { + GUIEnvironment->drop(); + GUIEnvironment = NULL; + } + if ( SceneManager ) + { + SceneManager->drop(); + SceneManager = NULL; + } + if ( VideoDriver ) + { + VideoDriver->drop(); + VideoDriver = NULL; + } + + if (display) + { + #ifdef _IRR_COMPILE_WITH_OPENGL_ + if (Context) + { + if (glxWin) + { + if (!glXMakeContextCurrent(display, None, None, NULL)) + os::Printer::log("Could not release glx context.", ELL_WARNING); + } + else + { + if (!glXMakeCurrent(display, None, NULL)) + os::Printer::log("Could not release glx context.", ELL_WARNING); + } + glXDestroyContext(display, Context); + if (glxWin) + glXDestroyWindow(display, glxWin); + } + #endif // #ifdef _IRR_COMPILE_WITH_OPENGL_ + + // Reset fullscreen resolution change + switchToFullscreen(true); + + if (SoftwareImage) + XDestroyImage(SoftwareImage); + + if (!ExternalWindow) + { + XDestroyWindow(display,window); + XCloseDisplay(display); + } + } + if (visual) + XFree(visual); + +#endif // #ifdef _IRR_COMPILE_WITH_X11_ + +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + for (u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + if (ActiveJoysticks[joystick].fd >= 0) + { + close(ActiveJoysticks[joystick].fd); + } + } +#endif +} + + +#if defined(_IRR_COMPILE_WITH_X11_) && defined(_DEBUG) +int IrrPrintXError(Display *display, XErrorEvent *event) +{ + char msg[256]; + char msg2[256]; + + snprintf(msg, 256, "%d", event->request_code); + XGetErrorDatabaseText(display, "XRequest", msg, "unknown", msg2, 256); + XGetErrorText(display, event->error_code, msg, 256); + os::Printer::log("X Error", msg, ELL_WARNING); + os::Printer::log("From call ", msg2, ELL_WARNING); + return 0; +} +#endif + + +bool CIrrDeviceLinux::switchToFullscreen(bool reset) +{ + if (!CreationParams.Fullscreen) + return true; + if (reset) + { +#ifdef _IRR_LINUX_X11_VIDMODE_ + if (UseXVidMode && CreationParams.Fullscreen) + { + XF86VidModeSwitchToMode(display, screennr, &oldVideoMode); + XF86VidModeSetViewPort(display, screennr, 0, 0); + } + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (UseXRandR && CreationParams.Fullscreen) + { + XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); + XRRSetScreenConfig(display,config,DefaultRootWindow(display),oldRandrMode,oldRandrRotation,CurrentTime); + XRRFreeScreenConfigInfo(config); + } + #endif + return true; + } + + getVideoModeList(); + #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) + s32 eventbase, errorbase; + s32 bestMode = -1; + #endif + + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) + { + // enumerate video modes + s32 modeCount; + XF86VidModeModeInfo** modes; + + XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); + + // find fitting mode + for (s32 i = 0; ihdisplay >= Width && modes[i]->vdisplay >= Height) + bestMode = i; + else if (bestMode!=-1 && + modes[i]->hdisplay >= Width && + modes[i]->vdisplay >= Height && + modes[i]->hdisplay <= modes[bestMode]->hdisplay && + modes[i]->vdisplay <= modes[bestMode]->vdisplay) + bestMode = i; + } + if (bestMode != -1) + { + os::Printer::log("Starting vidmode fullscreen mode...", ELL_INFORMATION); + os::Printer::log("hdisplay: ", core::stringc(modes[bestMode]->hdisplay).c_str(), ELL_INFORMATION); + os::Printer::log("vdisplay: ", core::stringc(modes[bestMode]->vdisplay).c_str(), ELL_INFORMATION); + + XF86VidModeSwitchToMode(display, screennr, modes[bestMode]); + XF86VidModeSetViewPort(display, screennr, 0, 0); + UseXVidMode=true; + } + else + { + os::Printer::log("Could not find specified video mode, running windowed.", ELL_WARNING); + CreationParams.Fullscreen = false; + } + + XFree(modes); + } + else + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (XRRQueryExtension(display, &eventbase, &errorbase)) + { + s32 modeCount; + XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); + XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); + for (s32 i = 0; i= Width && (u32)modes[i].height >= Height) + bestMode = i; + else if (bestMode!=-1 && + (u32)modes[i].width >= Width && + (u32)modes[i].height >= Height && + modes[i].width <= modes[bestMode].width && + modes[i].height <= modes[bestMode].height) + bestMode = i; + } + if (bestMode != -1) + { + os::Printer::log("Starting randr fullscreen mode...", ELL_INFORMATION); + os::Printer::log("width: ", core::stringc(modes[bestMode].width).c_str(), ELL_INFORMATION); + os::Printer::log("height: ", core::stringc(modes[bestMode].height).c_str(), ELL_INFORMATION); + + XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime); + UseXRandR=true; + } + XRRFreeScreenConfigInfo(config); + } + else + #endif + { + os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht " + "to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING); + CreationParams.Fullscreen = false; + } + return CreationParams.Fullscreen; +} + + +#if defined(_IRR_COMPILE_WITH_X11_) +void IrrPrintXGrabError(int grabResult, const c8 * grabCommand ) +{ + if ( grabResult == GrabSuccess ) + { +// os::Printer::log(grabCommand, ": GrabSuccess", ELL_INFORMATION); + return; + } + + switch ( grabResult ) + { + case AlreadyGrabbed: + os::Printer::log(grabCommand, ": AlreadyGrabbed", ELL_WARNING); + break; + case GrabNotViewable: + os::Printer::log(grabCommand, ": GrabNotViewable", ELL_WARNING); + break; + case GrabFrozen: + os::Printer::log(grabCommand, ": GrabFrozen", ELL_WARNING); + break; + case GrabInvalidTime: + os::Printer::log(grabCommand, ": GrabInvalidTime", ELL_WARNING); + break; + default: + os::Printer::log(grabCommand, ": grab failed with unknown problem", ELL_WARNING); + break; + } +} +#endif + + +bool CIrrDeviceLinux::createWindow() +{ +#ifdef _IRR_COMPILE_WITH_X11_ +#ifdef _DEBUG + os::Printer::log("Creating X window...", ELL_INFORMATION); + XSetErrorHandler(IrrPrintXError); +#endif + +// onefang changes start + if (CreationParams.VideoData) + display = (Display *) CreationParams.VideoData->OpenGLLinux.X11Display; + if (!display) +// onefang changes end + display = XOpenDisplay(0); + if (!display) + { + os::Printer::log("Error: Need running XServer to start Irrlicht Engine.", ELL_ERROR); + if (XDisplayName(0)[0]) + os::Printer::log("Could not open display", XDisplayName(0), ELL_ERROR); + else + os::Printer::log("Could not open display, set DISPLAY variable", ELL_ERROR); + return false; + } + + screennr = DefaultScreen(display); + + switchToFullscreen(); + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + + GLXFBConfig glxFBConfig; + int major, minor; + bool isAvailableGLX=false; + if (CreationParams.DriverType==video::EDT_OPENGL) + { + isAvailableGLX=glXQueryExtension(display,&major,&minor); + if (isAvailableGLX && glXQueryVersion(display, &major, &minor)) + { +#ifdef GLX_VERSION_1_3 + typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); + +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast("glXChooseFBConfig")); +#else + PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig=glXChooseFBConfig; +#endif + if (major==1 && minor>2 && glxChooseFBConfig) + { + // attribute array for the draw buffer + int visualAttrBuffer[] = + { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_RED_SIZE, 4, + GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, + GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0, + GLX_DEPTH_SIZE, CreationParams.ZBufferBits, //10,11 + GLX_DOUBLEBUFFER, CreationParams.Doublebuffer?True:False, + GLX_STENCIL_SIZE, CreationParams.Stencilbuffer?1:0, +#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string! + GLX_SAMPLE_BUFFERS, 1, + GLX_SAMPLES, CreationParams.AntiAlias, // 18,19 +#elif defined(GLX_ARB_multisample) + GLX_SAMPLE_BUFFERS_ARB, 1, + GLX_SAMPLES_ARB, CreationParams.AntiAlias, // 18,19 +#elif defined(GLX_SGIS_multisample) + GLX_SAMPLE_BUFFERS_SGIS, 1, + GLX_SAMPLES_SGIS, CreationParams.AntiAlias, // 18,19 +#endif +//#ifdef GL_ARB_framebuffer_sRGB +// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, CreationParams.HandleSRGB, +//#elif defined(GL_EXT_framebuffer_sRGB) +// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, CreationParams.HandleSRGB, +//#endif + GLX_STEREO, CreationParams.Stereobuffer?True:False, + None + }; + + GLXFBConfig *configList=0; + int nitems=0; + if (CreationParams.AntiAlias<2) + { + visualAttrBuffer[17] = 0; + visualAttrBuffer[19] = 0; + } + // first round with unchanged values + { + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (!configList && CreationParams.AntiAlias) + { + while (!configList && (visualAttrBuffer[19]>1)) + { + visualAttrBuffer[19] -= 1; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + } + if (!configList) + { + visualAttrBuffer[17] = 0; + visualAttrBuffer[19] = 0; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (configList) + { + os::Printer::log("No FSAA available.", ELL_WARNING); + CreationParams.AntiAlias=0; + } + else + { + //reenable multisampling + visualAttrBuffer[17] = 1; + visualAttrBuffer[19] = CreationParams.AntiAlias; + } + } + } + } + // Next try with flipped stencil buffer value + // If the first round was with stencil flag it's now without + // Other way round also makes sense because some configs + // only have depth buffer combined with stencil buffer + if (!configList) + { + if (CreationParams.Stencilbuffer) + os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING); + CreationParams.Stencilbuffer = !CreationParams.Stencilbuffer; + visualAttrBuffer[15]=CreationParams.Stencilbuffer?1:0; + + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (!configList && CreationParams.AntiAlias) + { + while (!configList && (visualAttrBuffer[19]>1)) + { + visualAttrBuffer[19] -= 1; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + } + if (!configList) + { + visualAttrBuffer[17] = 0; + visualAttrBuffer[19] = 0; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (configList) + { + os::Printer::log("No FSAA available.", ELL_WARNING); + CreationParams.AntiAlias=0; + } + else + { + //reenable multisampling + visualAttrBuffer[17] = 1; + visualAttrBuffer[19] = CreationParams.AntiAlias; + } + } + } + } + // Next try without double buffer + if (!configList && CreationParams.Doublebuffer) + { + os::Printer::log("No doublebuffering available.", ELL_WARNING); + CreationParams.Doublebuffer=false; + visualAttrBuffer[13] = GLX_DONT_CARE; + CreationParams.Stencilbuffer = false; + visualAttrBuffer[15]=0; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (!configList && CreationParams.AntiAlias) + { + while (!configList && (visualAttrBuffer[19]>1)) + { + visualAttrBuffer[19] -= 1; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + } + if (!configList) + { + visualAttrBuffer[17] = 0; + visualAttrBuffer[19] = 0; + configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); + if (configList) + { + os::Printer::log("No FSAA available.", ELL_WARNING); + CreationParams.AntiAlias=0; + } + else + { + //reenable multisampling + visualAttrBuffer[17] = 1; + visualAttrBuffer[19] = CreationParams.AntiAlias; + } + } + } + } + if (configList) + { + glxFBConfig=configList[0]; + XFree(configList); + UseGLXWindow=true; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); + PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig= (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast("glXGetVisualFromFBConfig")); + if (glxGetVisualFromFBConfig) + visual = glxGetVisualFromFBConfig(display,glxFBConfig); +#else + visual = glXGetVisualFromFBConfig(display,glxFBConfig); +#endif + } + } + else +#endif + { + // attribute array for the draw buffer + int visualAttrBuffer[] = + { + GLX_RGBA, GLX_USE_GL, + GLX_RED_SIZE, 4, + GLX_GREEN_SIZE, 4, + GLX_BLUE_SIZE, 4, + GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0, + GLX_DEPTH_SIZE, CreationParams.ZBufferBits, + GLX_STENCIL_SIZE, CreationParams.Stencilbuffer?1:0, // 12,13 + // The following attributes have no flags, but are + // either present or not. As a no-op we use + // GLX_USE_GL, which is silently ignored by glXChooseVisual + CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14 + CreationParams.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15 +//#ifdef GL_ARB_framebuffer_sRGB +// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL, +//#elif defined(GL_EXT_framebuffer_sRGB) +// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL, +//#endif + None + }; + + visual=glXChooseVisual(display, screennr, visualAttrBuffer); + if (!visual) + { + if (CreationParams.Stencilbuffer) + os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING); + CreationParams.Stencilbuffer = !CreationParams.Stencilbuffer; + visualAttrBuffer[13]=CreationParams.Stencilbuffer?1:0; + + visual=glXChooseVisual(display, screennr, visualAttrBuffer); + if (!visual && CreationParams.Doublebuffer) + { + os::Printer::log("No doublebuffering available.", ELL_WARNING); + CreationParams.Doublebuffer=false; + visualAttrBuffer[14] = GLX_USE_GL; + visual=glXChooseVisual(display, screennr, visualAttrBuffer); + } + } + } + } + else + os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING); + } + // don't use the XVisual with OpenGL, because it ignores all requested + // properties of the CreationParams + else if (!visual) +#endif // _IRR_COMPILE_WITH_OPENGL_ + + // create visual with standard X methods + { + os::Printer::log("Using plain X visual"); + XVisualInfo visTempl; //Template to hold requested values + int visNumber; // Return value of available visuals + + visTempl.screen = screennr; + // ARGB visuals should be avoided for usual applications + visTempl.depth = CreationParams.WithAlphaChannel?32:24; + while ((!visual) && (visTempl.depth>=16)) + { + visual = XGetVisualInfo(display, VisualScreenMask|VisualDepthMask, + &visTempl, &visNumber); + visTempl.depth -= 8; + } + } + + if (!visual) + { + os::Printer::log("Fatal error, could not get visual.", ELL_ERROR); + XCloseDisplay(display); + display=0; + return false; + } +#ifdef _DEBUG + else + os::Printer::log("Visual chosen: ", core::stringc(static_cast(visual->visualid)).c_str(), ELL_DEBUG); +#endif + + // create color map + Colormap colormap; + colormap = XCreateColormap(display, + RootWindow(display, visual->screen), + visual->visual, AllocNone); + + attributes.colormap = colormap; + attributes.border_pixel = 0; + attributes.event_mask = StructureNotifyMask | FocusChangeMask | ExposureMask; + if (!CreationParams.IgnoreInput) + attributes.event_mask |= PointerMotionMask | + ButtonPressMask | KeyPressMask | + ButtonReleaseMask | KeyReleaseMask; + + if (!CreationParams.WindowId) + { + // create new Window + // Remove window manager decoration in fullscreen + attributes.override_redirect = CreationParams.Fullscreen; + window = XCreateWindow(display, + RootWindow(display, visual->screen), + 0, 0, Width, Height, 0, visual->depth, + InputOutput, visual->visual, + CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, + &attributes); + XMapRaised(display, window); + CreationParams.WindowId = (void*)window; + Atom wmDelete; + wmDelete = XInternAtom(display, wmDeleteWindow, True); + XSetWMProtocols(display, window, &wmDelete, 1); + if (CreationParams.Fullscreen) + { + XSetInputFocus(display, window, RevertToParent, CurrentTime); + int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + IrrPrintXGrabError(grabKb, "XGrabKeyboard"); + int grabPointer = XGrabPointer(display, window, True, ButtonPressMask, + GrabModeAsync, GrabModeAsync, window, None, CurrentTime); + IrrPrintXGrabError(grabPointer, "XGrabPointer"); + XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0); + } + } + else + { + // attach external window + window = (Window)CreationParams.WindowId; + if (!CreationParams.IgnoreInput) + { + XCreateWindow(display, + window, + 0, 0, Width, Height, 0, visual->depth, + InputOutput, visual->visual, + CWBorderPixel | CWColormap | CWEventMask, + &attributes); + } + XWindowAttributes wa; + XGetWindowAttributes(display, window, &wa); + CreationParams.WindowSize.Width = wa.width; + CreationParams.WindowSize.Height = wa.height; + CreationParams.Fullscreen = false; + ExternalWindow = true; + } + + WindowMinimized=false; + // Currently broken in X, see Bug ID 2795321 + // XkbSetDetectableAutoRepeat(display, True, &AutorepeatSupport); + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + + // connect glx context to window + Context=0; + if (isAvailableGLX && CreationParams.DriverType==video::EDT_OPENGL) + { +// onefang changes start +// if (UseGLXWindow) + if (CreationParams.VideoData) + Context = (GLXContext) CreationParams.VideoData->OpenGLLinux.X11Context; + if (Context) + { + if (!glXMakeCurrent(display, window, Context)) + { + os::Printer::log("Could not make context current.", ELL_WARNING); + glXDestroyContext(display, Context); + } + } + else if (UseGLXWindow) +// onefang changes end + { + glxWin=glXCreateWindow(display,glxFBConfig,window,NULL); + if (glxWin) + { + // create glx context + Context = glXCreateNewContext(display, glxFBConfig, GLX_RGBA_TYPE, NULL, True); + if (Context) + { + if (!glXMakeContextCurrent(display, glxWin, glxWin, Context)) + { + os::Printer::log("Could not make context current.", ELL_WARNING); + glXDestroyContext(display, Context); + } + } + else + { + os::Printer::log("Could not create GLX rendering context.", ELL_WARNING); + } + } + else + { + os::Printer::log("Could not create GLX window.", ELL_WARNING); + } + } + else + { + Context = glXCreateContext(display, visual, NULL, True); + if (Context) + { + if (!glXMakeCurrent(display, window, Context)) + { + os::Printer::log("Could not make context current.", ELL_WARNING); + glXDestroyContext(display, Context); + } + } + else + { + os::Printer::log("Could not create GLX rendering context.", ELL_WARNING); + } + } + } +#endif // _IRR_COMPILE_WITH_OPENGL_ + + Window tmp; + u32 borderWidth; + int x,y; + unsigned int bits; + + XGetGeometry(display, window, &tmp, &x, &y, &Width, &Height, &borderWidth, &bits); + CreationParams.Bits = bits; + CreationParams.WindowSize.Width = Width; + CreationParams.WindowSize.Height = Height; + + StdHints = XAllocSizeHints(); + long num; + XGetWMNormalHints(display, window, StdHints, &num); + + // create an XImage for the software renderer + //(thx to Nadav for some clues on how to do that!) + + if (CreationParams.DriverType == video::EDT_SOFTWARE || CreationParams.DriverType == video::EDT_BURNINGSVIDEO) + { + SoftwareImage = XCreateImage(display, + visual->visual, visual->depth, + ZPixmap, 0, 0, Width, Height, + BitmapPad(display), 0); + + // use malloc because X will free it later on + if (SoftwareImage) + SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char)); + } + + initXAtoms(); + +#endif // #ifdef _IRR_COMPILE_WITH_X11_ + return true; +} + + +//! create the driver +void CIrrDeviceLinux::createDriver() +{ + switch(CreationParams.DriverType) + { +#ifdef _IRR_COMPILE_WITH_X11_ + + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + #else + os::Printer::log("No Software driver support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + if (Context) + VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in Linux. Try OpenGL or Software renderer.", + ELL_ERROR); + break; + + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; +#else + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + default: + os::Printer::log("No X11 support compiled in. Only Null driver available.", ELL_ERROR); + break; +#endif + } +} + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceLinux::run() +{ + os::Timer::tick(); + +#ifdef _IRR_COMPILE_WITH_X11_ + + if ( CursorControl ) + static_cast(CursorControl)->update(); + + if ((CreationParams.DriverType != video::EDT_NULL) && display) + { + SEvent irrevent; + irrevent.MouseInput.ButtonStates = 0xffffffff; + + while (XPending(display) > 0 && !Close) + { + XEvent event; + XNextEvent(display, &event); + + switch (event.type) + { + case ConfigureNotify: + // check for changed window size + if ((event.xconfigure.width != (int) Width) || + (event.xconfigure.height != (int) Height)) + { + Width = event.xconfigure.width; + Height = event.xconfigure.height; + + // resize image data + if (SoftwareImage) + { + XDestroyImage(SoftwareImage); + + SoftwareImage = XCreateImage(display, + visual->visual, visual->depth, + ZPixmap, 0, 0, Width, Height, + BitmapPad(display), 0); + + // use malloc because X will free it later on + if (SoftwareImage) + SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char)); + } + + if (VideoDriver) + VideoDriver->OnResize(core::dimension2d(Width, Height)); + } + break; + + case MapNotify: + WindowMinimized=false; + break; + + case UnmapNotify: + WindowMinimized=true; + break; + + case FocusIn: + WindowHasFocus=true; + break; + + case FocusOut: + WindowHasFocus=false; + break; + + case MotionNotify: + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + irrevent.MouseInput.X = event.xbutton.x; + irrevent.MouseInput.Y = event.xbutton.y; + irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0; + irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0; + + // mouse button states + irrevent.MouseInput.ButtonStates = (event.xbutton.state & Button1Mask) ? irr::EMBSM_LEFT : 0; + irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button3Mask) ? irr::EMBSM_RIGHT : 0; + irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button2Mask) ? irr::EMBSM_MIDDLE : 0; + + postEventFromUser(irrevent); + break; + + case ButtonPress: + case ButtonRelease: + + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.X = event.xbutton.x; + irrevent.MouseInput.Y = event.xbutton.y; + irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0; + irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0; + + // mouse button states + // This sets the state which the buttons had _prior_ to the event. + // So unlike on Windows the button which just got changed has still the old state here. + // We handle that below by flipping the corresponding bit later. + irrevent.MouseInput.ButtonStates = (event.xbutton.state & Button1Mask) ? irr::EMBSM_LEFT : 0; + irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button3Mask) ? irr::EMBSM_RIGHT : 0; + irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button2Mask) ? irr::EMBSM_MIDDLE : 0; + + irrevent.MouseInput.Event = irr::EMIE_COUNT; + + switch(event.xbutton.button) + { + case Button1: + irrevent.MouseInput.Event = + (event.type == ButtonPress) ? irr::EMIE_LMOUSE_PRESSED_DOWN : irr::EMIE_LMOUSE_LEFT_UP; + irrevent.MouseInput.ButtonStates ^= irr::EMBSM_LEFT; + break; + + case Button3: + irrevent.MouseInput.Event = + (event.type == ButtonPress) ? irr::EMIE_RMOUSE_PRESSED_DOWN : irr::EMIE_RMOUSE_LEFT_UP; + irrevent.MouseInput.ButtonStates ^= irr::EMBSM_RIGHT; + break; + + case Button2: + irrevent.MouseInput.Event = + (event.type == ButtonPress) ? irr::EMIE_MMOUSE_PRESSED_DOWN : irr::EMIE_MMOUSE_LEFT_UP; + irrevent.MouseInput.ButtonStates ^= irr::EMBSM_MIDDLE; + break; + + case Button4: + if (event.type == ButtonPress) + { + irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = 1.0f; + } + break; + + case Button5: + if (event.type == ButtonPress) + { + irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = -1.0f; + } + break; + } + + if (irrevent.MouseInput.Event != irr::EMIE_COUNT) + { + postEventFromUser(irrevent); + + if ( irrevent.MouseInput.Event >= EMIE_LMOUSE_PRESSED_DOWN && irrevent.MouseInput.Event <= EMIE_MMOUSE_PRESSED_DOWN ) + { + u32 clicks = checkSuccessiveClicks(irrevent.MouseInput.X, irrevent.MouseInput.Y, irrevent.MouseInput.Event); + if ( clicks == 2 ) + { + irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_DOUBLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); + postEventFromUser(irrevent); + } + else if ( clicks == 3 ) + { + irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_TRIPLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); + postEventFromUser(irrevent); + } + } + } + break; + + case MappingNotify: + XRefreshKeyboardMapping (&event.xmapping) ; + break; + + case KeyRelease: + if (0 == AutorepeatSupport && (XPending( display ) > 0) ) + { + // check for Autorepeat manually + // We'll do the same as Windows does: Only send KeyPressed + // So every KeyRelease is a real release + XEvent next_event; + XPeekEvent (event.xkey.display, &next_event); + if ((next_event.type == KeyPress) && + (next_event.xkey.keycode == event.xkey.keycode) && + (next_event.xkey.time - event.xkey.time) < 2) // usually same time, but on some systems a difference of 1 is possible + { + /* Ignore the key release event */ + break; + } + } + // fall-through in case the release should be handled + case KeyPress: + { + SKeyMap mp; + char buf[8]={0}; + XLookupString(&event.xkey, buf, sizeof(buf), &mp.X11Key, NULL); + + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.PressedDown = (event.type == KeyPress); +// mbtowc(&irrevent.KeyInput.Char, buf, sizeof(buf)); + irrevent.KeyInput.Char = ((wchar_t*)(buf))[0]; + irrevent.KeyInput.Control = (event.xkey.state & ControlMask) != 0; + irrevent.KeyInput.Shift = (event.xkey.state & ShiftMask) != 0; + + event.xkey.state = 0; // ignore shift-ctrl states for figuring out the key + XLookupString(&event.xkey, buf, sizeof(buf), &mp.X11Key, NULL); + const s32 idx = KeyMap.binary_search(mp); + if (idx != -1) + { + irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key; + } + else + { + irrevent.KeyInput.Key = (EKEY_CODE)0; + } + if (irrevent.KeyInput.Key == 0) + { + // 1:1 mapping to windows-keys would require testing for keyboard type (us, ger, ...) + // So unless we do that we will have some unknown keys here. + if (idx == -1) + { + os::Printer::log("Could not find EKEY_CODE, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION); + } + else + { + os::Printer::log("EKEY_CODE is 0, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION); + } + // Any value is better than none, that allows at least using the keys. + // Worst case is that some keys will be identical, still better than _all_ + // unknown keys being identical. + irrevent.KeyInput.Key = (EKEY_CODE)event.xkey.keycode; + } + + postEventFromUser(irrevent); + } + break; + + case ClientMessage: + { + char *atom = XGetAtomName(display, event.xclient.message_type); + if (*atom == *wmDeleteWindow) + { + os::Printer::log("Quit message received.", ELL_INFORMATION); + Close = true; + } + else + { + // we assume it's a user message + irrevent.EventType = irr::EET_USER_EVENT; + irrevent.UserEvent.UserData1 = (s32)event.xclient.data.l[0]; + irrevent.UserEvent.UserData2 = (s32)event.xclient.data.l[1]; + postEventFromUser(irrevent); + } + XFree(atom); + } + break; + + case SelectionRequest: + { + XEvent respond; + XSelectionRequestEvent *req = &(event.xselectionrequest); + if ( req->target == XA_STRING) + { + XChangeProperty (display, + req->requestor, + req->property, req->target, + 8, // format + PropModeReplace, + (unsigned char*) Clipboard.c_str(), + Clipboard.size()); + respond.xselection.property = req->property; + } + else if ( req->target == X_ATOM_TARGETS ) + { + long data[2]; + + data[0] = X_ATOM_TEXT; + data[1] = XA_STRING; + + XChangeProperty (display, req->requestor, + req->property, req->target, + 8, PropModeReplace, + (unsigned char *) &data, + sizeof (data)); + respond.xselection.property = req->property; + } + else + { + respond.xselection.property= None; + } + respond.xselection.type= SelectionNotify; + respond.xselection.display= req->display; + respond.xselection.requestor= req->requestor; + respond.xselection.selection=req->selection; + respond.xselection.target= req->target; + respond.xselection.time = req->time; + XSendEvent (display, req->requestor,0,0,&respond); + XFlush (display); + } + break; + + default: + break; + } // end switch + + } // end while + } +#endif //_IRR_COMPILE_WITH_X11_ + + if (!Close) + pollJoysticks(); + + return !Close; +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceLinux::yield() +{ + struct timespec ts = {0,1}; + nanosleep(&ts, NULL); +} + + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceLinux::sleep(u32 timeMs, bool pauseTimer=false) +{ + const bool wasStopped = Timer ? Timer->isStopped() : true; + + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +//! sets the caption of the window +void CIrrDeviceLinux::setWindowCaption(const wchar_t* text) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (CreationParams.DriverType == video::EDT_NULL) + return; + + XTextProperty txt; + if (Success==XwcTextListToTextProperty(display, const_cast(&text), + 1, XStdICCTextStyle, &txt)) + { + XSetWMName(display, window, &txt); + XSetWMIconName(display, window, &txt); + XFree(txt.value); + } +#endif +} + + +//! presents a surface in the client area +bool CIrrDeviceLinux::present(video::IImage* image, void* windowId, core::rect* srcRect) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + // this is only necessary for software drivers. + if (!SoftwareImage) + return true; + + // thx to Nadav, who send me some clues of how to display the image + // to the X Server. + + const u32 destwidth = SoftwareImage->width; + const u32 minWidth = core::min_(image->getDimension().Width, destwidth); + const u32 destPitch = SoftwareImage->bytes_per_line; + + video::ECOLOR_FORMAT destColor; + switch (SoftwareImage->bits_per_pixel) + { + case 16: + if (SoftwareImage->depth==16) + destColor = video::ECF_R5G6B5; + else + destColor = video::ECF_A1R5G5B5; + break; + case 24: destColor = video::ECF_R8G8B8; break; + case 32: destColor = video::ECF_A8R8G8B8; break; + default: + os::Printer::log("Unsupported screen depth."); + return false; + } + + u8* srcdata = reinterpret_cast(image->lock()); + u8* destData = reinterpret_cast(SoftwareImage->data); + + const u32 destheight = SoftwareImage->height; + const u32 srcheight = core::min_(image->getDimension().Height, destheight); + const u32 srcPitch = image->getPitch(); + for (u32 y=0; y!=srcheight; ++y) + { + video::CColorConverter::convert_viaFormat(srcdata,image->getColorFormat(), minWidth, destData, destColor); + srcdata+=srcPitch; + destData+=destPitch; + } + image->unlock(); + + GC gc = DefaultGC(display, DefaultScreen(display)); + Window myWindow=window; + if (windowId) + myWindow = reinterpret_cast(windowId); + XPutImage(display, myWindow, gc, SoftwareImage, 0, 0, 0, 0, destwidth, destheight); +#endif + return true; +} + + +//! notifies the device that it should close itself +void CIrrDeviceLinux::closeDevice() +{ + Close = true; +} + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceLinux::isWindowActive() const +{ + return (WindowHasFocus && !WindowMinimized); +} + + +//! returns if window has focus. +bool CIrrDeviceLinux::isWindowFocused() const +{ + return WindowHasFocus; +} + + +//! returns if window is minimized. +bool CIrrDeviceLinux::isWindowMinimized() const +{ + return WindowMinimized; +} + + +//! returns color format of the window. +video::ECOLOR_FORMAT CIrrDeviceLinux::getColorFormat() const +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (visual && (visual->depth != 16)) + return video::ECF_R8G8B8; + else +#endif + return video::ECF_R5G6B5; +} + + +//! Sets if the window should be resizable in windowed mode. +void CIrrDeviceLinux::setResizable(bool resize) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen ) + return; + + XUnmapWindow(display, window); + if ( !resize ) + { + // Must be heap memory because data size depends on X Server + XSizeHints *hints = XAllocSizeHints(); + hints->flags=PSize|PMinSize|PMaxSize; + hints->min_width=hints->max_width=hints->base_width=Width; + hints->min_height=hints->max_height=hints->base_height=Height; + XSetWMNormalHints(display, window, hints); + XFree(hints); + } + else + { + XSetWMNormalHints(display, window, StdHints); + } + XMapWindow(display, window); + XFlush(display); +#endif // #ifdef _IRR_COMPILE_WITH_X11_ +} + + +//! Return pointer to a list with all video modes supported by the gfx adapter. +video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (!VideoModeList->getVideoModeCount()) + { + bool temporaryDisplay = false; + + if (!display) + { + display = XOpenDisplay(0); + temporaryDisplay=true; + } + if (display) + { + #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) + s32 eventbase, errorbase; + s32 defaultDepth=DefaultDepth(display,screennr); + #endif + + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) + { + // enumerate video modes + int modeCount; + XF86VidModeModeInfo** modes; + + XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); + + // save current video mode + oldVideoMode = *modes[0]; + + // find fitting mode + + VideoModeList->setDesktop(defaultDepth, core::dimension2d( + modes[0]->hdisplay, modes[0]->vdisplay)); + for (int i = 0; iaddMode(core::dimension2d( + modes[i]->hdisplay, modes[i]->vdisplay), defaultDepth); + } + XFree(modes); + } + else + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (XRRQueryExtension(display, &eventbase, &errorbase)) + { + int modeCount; + XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); + oldRandrMode=XRRConfigCurrentConfiguration(config,&oldRandrRotation); + XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); + VideoModeList->setDesktop(defaultDepth, core::dimension2d( + modes[oldRandrMode].width, modes[oldRandrMode].height)); + for (int i = 0; iaddMode(core::dimension2d( + modes[i].width, modes[i].height), defaultDepth); + } + XRRFreeScreenConfigInfo(config); + } + else + #endif + { + os::Printer::log("VidMode or RandR X11 extension requireed for VideoModeList." , ELL_WARNING); + } + } + if (display && temporaryDisplay) + { + XCloseDisplay(display); + display=0; + } + } +#endif + + return VideoModeList; +} + + +//! Minimize window +void CIrrDeviceLinux::minimizeWindow() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + XIconifyWindow(display, window, screennr); +#endif +} + + +//! Maximize window +void CIrrDeviceLinux::maximizeWindow() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + XMapWindow(display, window); +#endif +} + + +//! Restore original window size +void CIrrDeviceLinux::restoreWindow() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + XMapWindow(display, window); +#endif +} + + +void CIrrDeviceLinux::createKeyMap() +{ + // I don't know if this is the best method to create + // the lookuptable, but I'll leave it like that until + // I find a better version. + +#ifdef _IRR_COMPILE_WITH_X11_ + KeyMap.reallocate(84); + KeyMap.push_back(SKeyMap(XK_BackSpace, KEY_BACK)); + KeyMap.push_back(SKeyMap(XK_Tab, KEY_TAB)); + KeyMap.push_back(SKeyMap(XK_ISO_Left_Tab, KEY_TAB)); + KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ??? + KeyMap.push_back(SKeyMap(XK_Clear, KEY_CLEAR)); + KeyMap.push_back(SKeyMap(XK_Return, KEY_RETURN)); + KeyMap.push_back(SKeyMap(XK_Pause, KEY_PAUSE)); + KeyMap.push_back(SKeyMap(XK_Scroll_Lock, KEY_SCROLL)); + KeyMap.push_back(SKeyMap(XK_Sys_Req, 0)); // ??? + KeyMap.push_back(SKeyMap(XK_Escape, KEY_ESCAPE)); + KeyMap.push_back(SKeyMap(XK_Insert, KEY_INSERT)); + KeyMap.push_back(SKeyMap(XK_Delete, KEY_DELETE)); + KeyMap.push_back(SKeyMap(XK_Home, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_Left, KEY_LEFT)); + KeyMap.push_back(SKeyMap(XK_Up, KEY_UP)); + KeyMap.push_back(SKeyMap(XK_Right, KEY_RIGHT)); + KeyMap.push_back(SKeyMap(XK_Down, KEY_DOWN)); + KeyMap.push_back(SKeyMap(XK_Prior, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_Page_Up, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_Next, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_Page_Down, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_End, KEY_END)); + KeyMap.push_back(SKeyMap(XK_Begin, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_Num_Lock, KEY_NUMLOCK)); + KeyMap.push_back(SKeyMap(XK_KP_Space, KEY_SPACE)); + KeyMap.push_back(SKeyMap(XK_KP_Tab, KEY_TAB)); + KeyMap.push_back(SKeyMap(XK_KP_Enter, KEY_RETURN)); + KeyMap.push_back(SKeyMap(XK_KP_F1, KEY_F1)); + KeyMap.push_back(SKeyMap(XK_KP_F2, KEY_F2)); + KeyMap.push_back(SKeyMap(XK_KP_F3, KEY_F3)); + KeyMap.push_back(SKeyMap(XK_KP_F4, KEY_F4)); + KeyMap.push_back(SKeyMap(XK_KP_Home, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_KP_Left, KEY_LEFT)); + KeyMap.push_back(SKeyMap(XK_KP_Up, KEY_UP)); + KeyMap.push_back(SKeyMap(XK_KP_Right, KEY_RIGHT)); + KeyMap.push_back(SKeyMap(XK_KP_Down, KEY_DOWN)); + KeyMap.push_back(SKeyMap(XK_Print, KEY_PRINT)); + KeyMap.push_back(SKeyMap(XK_KP_Prior, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_KP_Page_Up, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(XK_KP_Next, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_KP_Page_Down, KEY_NEXT)); + KeyMap.push_back(SKeyMap(XK_KP_End, KEY_END)); + KeyMap.push_back(SKeyMap(XK_KP_Begin, KEY_HOME)); + KeyMap.push_back(SKeyMap(XK_KP_Insert, KEY_INSERT)); + KeyMap.push_back(SKeyMap(XK_KP_Delete, KEY_DELETE)); + KeyMap.push_back(SKeyMap(XK_KP_Equal, 0)); // ??? + KeyMap.push_back(SKeyMap(XK_KP_Multiply, KEY_MULTIPLY)); + KeyMap.push_back(SKeyMap(XK_KP_Add, KEY_ADD)); + KeyMap.push_back(SKeyMap(XK_KP_Separator, KEY_SEPARATOR)); + KeyMap.push_back(SKeyMap(XK_KP_Subtract, KEY_SUBTRACT)); + KeyMap.push_back(SKeyMap(XK_KP_Decimal, KEY_DECIMAL)); + KeyMap.push_back(SKeyMap(XK_KP_Divide, KEY_DIVIDE)); + KeyMap.push_back(SKeyMap(XK_KP_0, KEY_KEY_0)); + KeyMap.push_back(SKeyMap(XK_KP_1, KEY_KEY_1)); + KeyMap.push_back(SKeyMap(XK_KP_2, KEY_KEY_2)); + KeyMap.push_back(SKeyMap(XK_KP_3, KEY_KEY_3)); + KeyMap.push_back(SKeyMap(XK_KP_4, KEY_KEY_4)); + KeyMap.push_back(SKeyMap(XK_KP_5, KEY_KEY_5)); + KeyMap.push_back(SKeyMap(XK_KP_6, KEY_KEY_6)); + KeyMap.push_back(SKeyMap(XK_KP_7, KEY_KEY_7)); + KeyMap.push_back(SKeyMap(XK_KP_8, KEY_KEY_8)); + KeyMap.push_back(SKeyMap(XK_KP_9, KEY_KEY_9)); + KeyMap.push_back(SKeyMap(XK_F1, KEY_F1)); + KeyMap.push_back(SKeyMap(XK_F2, KEY_F2)); + KeyMap.push_back(SKeyMap(XK_F3, KEY_F3)); + KeyMap.push_back(SKeyMap(XK_F4, KEY_F4)); + KeyMap.push_back(SKeyMap(XK_F5, KEY_F5)); + KeyMap.push_back(SKeyMap(XK_F6, KEY_F6)); + KeyMap.push_back(SKeyMap(XK_F7, KEY_F7)); + KeyMap.push_back(SKeyMap(XK_F8, KEY_F8)); + KeyMap.push_back(SKeyMap(XK_F9, KEY_F9)); + KeyMap.push_back(SKeyMap(XK_F10, KEY_F10)); + KeyMap.push_back(SKeyMap(XK_F11, KEY_F11)); + KeyMap.push_back(SKeyMap(XK_F12, KEY_F12)); + KeyMap.push_back(SKeyMap(XK_Shift_L, KEY_LSHIFT)); + KeyMap.push_back(SKeyMap(XK_Shift_R, KEY_RSHIFT)); + KeyMap.push_back(SKeyMap(XK_Control_L, KEY_LCONTROL)); + KeyMap.push_back(SKeyMap(XK_Control_R, KEY_RCONTROL)); + KeyMap.push_back(SKeyMap(XK_Caps_Lock, KEY_CAPITAL)); + KeyMap.push_back(SKeyMap(XK_Shift_Lock, KEY_CAPITAL)); + KeyMap.push_back(SKeyMap(XK_Meta_L, KEY_LWIN)); + KeyMap.push_back(SKeyMap(XK_Meta_R, KEY_RWIN)); + KeyMap.push_back(SKeyMap(XK_Alt_L, KEY_LMENU)); + KeyMap.push_back(SKeyMap(XK_Alt_R, KEY_RMENU)); + KeyMap.push_back(SKeyMap(XK_ISO_Level3_Shift, KEY_RMENU)); + KeyMap.push_back(SKeyMap(XK_Menu, KEY_MENU)); + KeyMap.push_back(SKeyMap(XK_space, KEY_SPACE)); + KeyMap.push_back(SKeyMap(XK_exclam, 0)); //? + KeyMap.push_back(SKeyMap(XK_quotedbl, 0)); //? + KeyMap.push_back(SKeyMap(XK_section, 0)); //? + KeyMap.push_back(SKeyMap(XK_numbersign, KEY_OEM_2)); + KeyMap.push_back(SKeyMap(XK_dollar, 0)); //? + KeyMap.push_back(SKeyMap(XK_percent, 0)); //? + KeyMap.push_back(SKeyMap(XK_ampersand, 0)); //? + KeyMap.push_back(SKeyMap(XK_apostrophe, KEY_OEM_7)); + KeyMap.push_back(SKeyMap(XK_parenleft, 0)); //? + KeyMap.push_back(SKeyMap(XK_parenright, 0)); //? + KeyMap.push_back(SKeyMap(XK_asterisk, 0)); //? + KeyMap.push_back(SKeyMap(XK_plus, KEY_PLUS)); //? + KeyMap.push_back(SKeyMap(XK_comma, KEY_COMMA)); //? + KeyMap.push_back(SKeyMap(XK_minus, KEY_MINUS)); //? + KeyMap.push_back(SKeyMap(XK_period, KEY_PERIOD)); //? + KeyMap.push_back(SKeyMap(XK_slash, KEY_OEM_2)); //? + KeyMap.push_back(SKeyMap(XK_0, KEY_KEY_0)); + KeyMap.push_back(SKeyMap(XK_1, KEY_KEY_1)); + KeyMap.push_back(SKeyMap(XK_2, KEY_KEY_2)); + KeyMap.push_back(SKeyMap(XK_3, KEY_KEY_3)); + KeyMap.push_back(SKeyMap(XK_4, KEY_KEY_4)); + KeyMap.push_back(SKeyMap(XK_5, KEY_KEY_5)); + KeyMap.push_back(SKeyMap(XK_6, KEY_KEY_6)); + KeyMap.push_back(SKeyMap(XK_7, KEY_KEY_7)); + KeyMap.push_back(SKeyMap(XK_8, KEY_KEY_8)); + KeyMap.push_back(SKeyMap(XK_9, KEY_KEY_9)); + KeyMap.push_back(SKeyMap(XK_colon, 0)); //? + KeyMap.push_back(SKeyMap(XK_semicolon, KEY_OEM_1)); + KeyMap.push_back(SKeyMap(XK_less, KEY_OEM_102)); + KeyMap.push_back(SKeyMap(XK_equal, KEY_PLUS)); + KeyMap.push_back(SKeyMap(XK_greater, 0)); //? + KeyMap.push_back(SKeyMap(XK_question, 0)); //? + KeyMap.push_back(SKeyMap(XK_at, KEY_KEY_2)); //? + KeyMap.push_back(SKeyMap(XK_mu, 0)); //? + KeyMap.push_back(SKeyMap(XK_EuroSign, 0)); //? + KeyMap.push_back(SKeyMap(XK_A, KEY_KEY_A)); + KeyMap.push_back(SKeyMap(XK_B, KEY_KEY_B)); + KeyMap.push_back(SKeyMap(XK_C, KEY_KEY_C)); + KeyMap.push_back(SKeyMap(XK_D, KEY_KEY_D)); + KeyMap.push_back(SKeyMap(XK_E, KEY_KEY_E)); + KeyMap.push_back(SKeyMap(XK_F, KEY_KEY_F)); + KeyMap.push_back(SKeyMap(XK_G, KEY_KEY_G)); + KeyMap.push_back(SKeyMap(XK_H, KEY_KEY_H)); + KeyMap.push_back(SKeyMap(XK_I, KEY_KEY_I)); + KeyMap.push_back(SKeyMap(XK_J, KEY_KEY_J)); + KeyMap.push_back(SKeyMap(XK_K, KEY_KEY_K)); + KeyMap.push_back(SKeyMap(XK_L, KEY_KEY_L)); + KeyMap.push_back(SKeyMap(XK_M, KEY_KEY_M)); + KeyMap.push_back(SKeyMap(XK_N, KEY_KEY_N)); + KeyMap.push_back(SKeyMap(XK_O, KEY_KEY_O)); + KeyMap.push_back(SKeyMap(XK_P, KEY_KEY_P)); + KeyMap.push_back(SKeyMap(XK_Q, KEY_KEY_Q)); + KeyMap.push_back(SKeyMap(XK_R, KEY_KEY_R)); + KeyMap.push_back(SKeyMap(XK_S, KEY_KEY_S)); + KeyMap.push_back(SKeyMap(XK_T, KEY_KEY_T)); + KeyMap.push_back(SKeyMap(XK_U, KEY_KEY_U)); + KeyMap.push_back(SKeyMap(XK_V, KEY_KEY_V)); + KeyMap.push_back(SKeyMap(XK_W, KEY_KEY_W)); + KeyMap.push_back(SKeyMap(XK_X, KEY_KEY_X)); + KeyMap.push_back(SKeyMap(XK_Y, KEY_KEY_Y)); + KeyMap.push_back(SKeyMap(XK_Z, KEY_KEY_Z)); + KeyMap.push_back(SKeyMap(XK_bracketleft, KEY_OEM_4)); + KeyMap.push_back(SKeyMap(XK_backslash, KEY_OEM_5)); + KeyMap.push_back(SKeyMap(XK_bracketright, KEY_OEM_6)); + KeyMap.push_back(SKeyMap(XK_asciicircum, KEY_OEM_5)); + KeyMap.push_back(SKeyMap(XK_degree, 0)); //? + KeyMap.push_back(SKeyMap(XK_underscore, KEY_MINUS)); //? + KeyMap.push_back(SKeyMap(XK_grave, KEY_OEM_3)); + KeyMap.push_back(SKeyMap(XK_acute, KEY_OEM_6)); + KeyMap.push_back(SKeyMap(XK_a, KEY_KEY_A)); + KeyMap.push_back(SKeyMap(XK_b, KEY_KEY_B)); + KeyMap.push_back(SKeyMap(XK_c, KEY_KEY_C)); + KeyMap.push_back(SKeyMap(XK_d, KEY_KEY_D)); + KeyMap.push_back(SKeyMap(XK_e, KEY_KEY_E)); + KeyMap.push_back(SKeyMap(XK_f, KEY_KEY_F)); + KeyMap.push_back(SKeyMap(XK_g, KEY_KEY_G)); + KeyMap.push_back(SKeyMap(XK_h, KEY_KEY_H)); + KeyMap.push_back(SKeyMap(XK_i, KEY_KEY_I)); + KeyMap.push_back(SKeyMap(XK_j, KEY_KEY_J)); + KeyMap.push_back(SKeyMap(XK_k, KEY_KEY_K)); + KeyMap.push_back(SKeyMap(XK_l, KEY_KEY_L)); + KeyMap.push_back(SKeyMap(XK_m, KEY_KEY_M)); + KeyMap.push_back(SKeyMap(XK_n, KEY_KEY_N)); + KeyMap.push_back(SKeyMap(XK_o, KEY_KEY_O)); + KeyMap.push_back(SKeyMap(XK_p, KEY_KEY_P)); + KeyMap.push_back(SKeyMap(XK_q, KEY_KEY_Q)); + KeyMap.push_back(SKeyMap(XK_r, KEY_KEY_R)); + KeyMap.push_back(SKeyMap(XK_s, KEY_KEY_S)); + KeyMap.push_back(SKeyMap(XK_t, KEY_KEY_T)); + KeyMap.push_back(SKeyMap(XK_u, KEY_KEY_U)); + KeyMap.push_back(SKeyMap(XK_v, KEY_KEY_V)); + KeyMap.push_back(SKeyMap(XK_w, KEY_KEY_W)); + KeyMap.push_back(SKeyMap(XK_x, KEY_KEY_X)); + KeyMap.push_back(SKeyMap(XK_y, KEY_KEY_Y)); + KeyMap.push_back(SKeyMap(XK_z, KEY_KEY_Z)); + KeyMap.push_back(SKeyMap(XK_ssharp, KEY_OEM_4)); + KeyMap.push_back(SKeyMap(XK_adiaeresis, KEY_OEM_7)); + KeyMap.push_back(SKeyMap(XK_odiaeresis, KEY_OEM_3)); + KeyMap.push_back(SKeyMap(XK_udiaeresis, KEY_OEM_1)); + KeyMap.push_back(SKeyMap(XK_Super_L, KEY_LWIN)); + KeyMap.push_back(SKeyMap(XK_Super_R, KEY_RWIN)); + + KeyMap.sort(); +#endif +} + +bool CIrrDeviceLinux::activateJoysticks(core::array & joystickInfo) +{ +#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + + joystickInfo.clear(); + + u32 joystick; + for (joystick = 0; joystick < 32; ++joystick) + { + // The joystick device could be here... + core::stringc devName = "/dev/js"; + devName += joystick; + + SJoystickInfo returnInfo; + JoystickInfo info; + + info.fd = open(devName.c_str(), O_RDONLY); + if (-1 == info.fd) + { + // ...but Ubuntu and possibly other distros + // create the devices in /dev/input + devName = "/dev/input/js"; + devName += joystick; + info.fd = open(devName.c_str(), O_RDONLY); + if (-1 == info.fd) + { + // and BSD here + devName = "/dev/joy"; + devName += joystick; + info.fd = open(devName.c_str(), O_RDONLY); + } + } + + if (-1 == info.fd) + continue; + +#ifdef __FREE_BSD_ + info.axes=2; + info.buttons=2; +#else + ioctl( info.fd, JSIOCGAXES, &(info.axes) ); + ioctl( info.fd, JSIOCGBUTTONS, &(info.buttons) ); + fcntl( info.fd, F_SETFL, O_NONBLOCK ); +#endif + + (void)memset(&info.persistentData, 0, sizeof(info.persistentData)); + info.persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT; + info.persistentData.JoystickEvent.Joystick = ActiveJoysticks.size(); + + // There's no obvious way to determine which (if any) axes represent a POV + // hat, so we'll just set it to "not used" and forget about it. + info.persistentData.JoystickEvent.POV = 65535; + + ActiveJoysticks.push_back(info); + + returnInfo.Joystick = joystick; + returnInfo.PovHat = SJoystickInfo::POV_HAT_UNKNOWN; + returnInfo.Axes = info.axes; + returnInfo.Buttons = info.buttons; + +#ifndef __FREE_BSD_ + char name[80]; + ioctl( info.fd, JSIOCGNAME(80), name); + returnInfo.Name = name; +#endif + + joystickInfo.push_back(returnInfo); + } + + for (joystick = 0; joystick < joystickInfo.size(); ++joystick) + { + char logString[256]; + (void)sprintf(logString, "Found joystick %u, %u axes, %u buttons '%s'", + joystick, joystickInfo[joystick].Axes, + joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); + os::Printer::log(logString, ELL_INFORMATION); + } + + return true; +#else + return false; +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +} + + +void CIrrDeviceLinux::pollJoysticks() +{ +#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + if (0 == ActiveJoysticks.size()) + return; + + for (u32 j= 0; j< ActiveJoysticks.size(); ++j) + { + JoystickInfo & info = ActiveJoysticks[j]; + +#ifdef __FREE_BSD_ + struct joystick js; + if (read(info.fd, &js, JS_RETURN) == JS_RETURN) + { + info.persistentData.JoystickEvent.ButtonStates = js.buttons; /* should be a two-bit field */ + info.persistentData.JoystickEvent.Axis[0] = js.x; /* X axis */ + info.persistentData.JoystickEvent.Axis[1] = js.y; /* Y axis */ +#else + struct js_event event; + while (sizeof(event) == read(info.fd, &event, sizeof(event))) + { + switch(event.type & ~JS_EVENT_INIT) + { + case JS_EVENT_BUTTON: + if (event.value) + info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number); + else + info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number); + break; + + case JS_EVENT_AXIS: + if (event.number < SEvent::SJoystickEvent::NUMBER_OF_AXES) + info.persistentData.JoystickEvent.Axis[event.number] = event.value; + break; + + default: + break; + } + } +#endif + + // Send an irrlicht joystick event once per ::run() even if no new data were received. + (void)postEventFromUser(info.persistentData); + } +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +} + + +//! Set the current Gamma Value for the Display +bool CIrrDeviceLinux::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) +{ + #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) + s32 eventbase, errorbase; + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) + { + XF86VidModeGamma gamma; + gamma.red=red; + gamma.green=green; + gamma.blue=blue; + XF86VidModeSetGamma(display, screennr, &gamma); + return true; + } + #endif + #if defined(_IRR_LINUX_X11_VIDMODE_) && defined(_IRR_LINUX_X11_RANDR_) + else + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (XRRQueryExtension(display, &eventbase, &errorbase)) + { + XRRQueryVersion(display, &eventbase, &errorbase); // major, minor + if (eventbase>=1 && errorbase>1) + { + #if (RANDR_MAJOR>1 || RANDR_MINOR>1) + XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr); + if (gamma) + { + *gamma->red=(u16)red; + *gamma->green=(u16)green; + *gamma->blue=(u16)blue; + XRRSetCrtcGamma(display, screennr, gamma); + XRRFreeGamma(gamma); + return true; + } + #endif + } + } + #endif + #endif + return false; +} + + +//! Get the current Gamma Value for the Display +bool CIrrDeviceLinux::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) +{ + brightness = 0.f; + contrast = 0.f; + #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) + s32 eventbase, errorbase; + #ifdef _IRR_LINUX_X11_VIDMODE_ + if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) + { + XF86VidModeGamma gamma; + XF86VidModeGetGamma(display, screennr, &gamma); + red = gamma.red; + green = gamma.green; + blue = gamma.blue; + return true; + } + #endif + #if defined(_IRR_LINUX_X11_VIDMODE_) && defined(_IRR_LINUX_X11_RANDR_) + else + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + if (XRRQueryExtension(display, &eventbase, &errorbase)) + { + XRRQueryVersion(display, &eventbase, &errorbase); // major, minor + if (eventbase>=1 && errorbase>1) + { + #if (RANDR_MAJOR>1 || RANDR_MINOR>1) + XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr); + if (gamma) + { + red = *gamma->red; + green = *gamma->green; + blue= *gamma->blue; + XRRFreeGamma(gamma); + return true; + } + #endif + } + } + #endif + #endif + return false; +} + + +//! gets text from the clipboard +//! \return Returns 0 if no string is in there. +const c8* CIrrDeviceLinux::getTextFromClipboard() const +{ +#if defined(_IRR_COMPILE_WITH_X11_) + Window ownerWindow = XGetSelectionOwner (display, X_ATOM_CLIPBOARD); + if ( ownerWindow == window ) + { + return Clipboard.c_str(); + } + Clipboard = ""; + if (ownerWindow != None ) + { + XConvertSelection (display, X_ATOM_CLIPBOARD, XA_STRING, None, ownerWindow, CurrentTime); + XFlush (display); + + // check for data + Atom type; + int format; + unsigned long numItems, bytesLeft, dummy; + unsigned char *data; + XGetWindowProperty (display, ownerWindow, + XA_STRING, // property name + 0, // offset + 0, // length (we only check for data, so 0) + 0, // Delete 0==false + AnyPropertyType, // AnyPropertyType or property identifier + &type, // return type + &format, // return format + &numItems, // number items + &bytesLeft, // remaining bytes for partial reads + &data); // data + if ( bytesLeft > 0 ) + { + // there is some data to get + int result = XGetWindowProperty (display, ownerWindow, XA_STRING, 0, + bytesLeft, 0, AnyPropertyType, &type, &format, + &numItems, &dummy, &data); + if (result == Success) + Clipboard = (irr::c8*)data; + XFree (data); + } + } + + return Clipboard.c_str(); + +#else + return 0; +#endif +} + +//! copies text to the clipboard +void CIrrDeviceLinux::copyToClipboard(const c8* text) const +{ +#if defined(_IRR_COMPILE_WITH_X11_) + // Actually there is no clipboard on X but applications just say they own the clipboard and return text when asked. + // Which btw. also means that on X you lose clipboard content when closing applications. + Clipboard = text; + XSetSelectionOwner (display, X_ATOM_CLIPBOARD, window, CurrentTime); + XFlush (display); +#endif +} + +#ifdef _IRR_COMPILE_WITH_X11_ +// return true if the passed event has the type passed in parameter arg +Bool PredicateIsEventType(Display *display, XEvent *event, XPointer arg) +{ + if ( event && event->type == *(int*)arg ) + { +// os::Printer::log("remove event:", core::stringc((int)arg).c_str(), ELL_INFORMATION); + return True; + } + return False; +} +#endif //_IRR_COMPILE_WITH_X11_ + +//! Remove all messages pending in the system message loop +void CIrrDeviceLinux::clearSystemMessages() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (CreationParams.DriverType != video::EDT_NULL) + { + XEvent event; + int usrArg = ButtonPress; + while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} + usrArg = ButtonRelease; + while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} + usrArg = MotionNotify; + while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} + usrArg = KeyRelease; + while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} + usrArg = KeyPress; + while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} + } +#endif //_IRR_COMPILE_WITH_X11_ +} + +void CIrrDeviceLinux::initXAtoms() +{ +#ifdef _IRR_COMPILE_WITH_X11_ + X_ATOM_CLIPBOARD = XInternAtom(display, "CLIPBOARD", False); + X_ATOM_TARGETS = XInternAtom(display, "TARGETS", False); + X_ATOM_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); + X_ATOM_TEXT = XInternAtom (display, "TEXT", False); +#endif +} + + +#ifdef _IRR_COMPILE_WITH_X11_ + +Cursor CIrrDeviceLinux::TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot) +{ + XImage * sourceImage = XCreateImage(display, visual->visual, + 1, // depth, + ZPixmap, // XYBitmap (depth=1), ZPixmap(depth=x) + 0, 0, sourceRect.getWidth(), sourceRect.getHeight(), + 32, // bitmap_pad, + 0// bytes_per_line (0 means continuos in memory) + ); + sourceImage->data = new char[sourceImage->height * sourceImage->bytes_per_line]; + XImage * maskImage = XCreateImage(display, visual->visual, + 1, // depth, + ZPixmap, + 0, 0, sourceRect.getWidth(), sourceRect.getHeight(), + 32, // bitmap_pad, + 0 // bytes_per_line + ); + maskImage->data = new char[maskImage->height * maskImage->bytes_per_line]; + + // write texture into XImage + video::ECOLOR_FORMAT format = tex->getColorFormat(); + u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; + u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; + u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; + const u8* data = (const u8*)tex->lock(video::ETLM_READ_ONLY, 0); + data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); + for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) + { + data += bytesLeftGap; + for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) + { + video::SColor pixelCol; + pixelCol.setData((const void*)data, format); + data += bytesPerPixel; + + if ( pixelCol.getAlpha() == 0 ) // transparent + { + XPutPixel(maskImage, x, y, 0); + XPutPixel(sourceImage, x, y, 0); + } + else // color + { + if ( pixelCol.getAverage() >= 127 ) + XPutPixel(sourceImage, x, y, 1); + else + XPutPixel(sourceImage, x, y, 0); + XPutPixel(maskImage, x, y, 1); + } + } + data += bytesRightGap; + } + tex->unlock(); + + Pixmap sourcePixmap = XCreatePixmap(display, window, sourceImage->width, sourceImage->height, sourceImage->depth); + Pixmap maskPixmap = XCreatePixmap(display, window, maskImage->width, maskImage->height, maskImage->depth); + + XGCValues values; + values.foreground = 1; + values.background = 1; + GC gc = XCreateGC( display, sourcePixmap, GCForeground | GCBackground, &values ); + + XPutImage(display, sourcePixmap, gc, sourceImage, 0, 0, 0, 0, sourceImage->width, sourceImage->height); + XPutImage(display, maskPixmap, gc, maskImage, 0, 0, 0, 0, maskImage->width, maskImage->height); + + XFreeGC(display, gc); + XDestroyImage(sourceImage); + XDestroyImage(maskImage); + + Cursor cursorResult = 0; + XColor foreground, background; + foreground.red = 65535; + foreground.green = 65535; + foreground.blue = 65535; + foreground.flags = DoRed | DoGreen | DoBlue; + background.red = 0; + background.green = 0; + background.blue = 0; + background.flags = DoRed | DoGreen | DoBlue; + + cursorResult = XCreatePixmapCursor(display, sourcePixmap, maskPixmap, &foreground, &background, hotspot.X, hotspot.Y); + + XFreePixmap(display, sourcePixmap); + XFreePixmap(display, maskPixmap); + + return cursorResult; +} + +#ifdef _IRR_LINUX_XCURSOR_ +Cursor CIrrDeviceLinux::TextureToARGBCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot) +{ + XcursorImage * image = XcursorImageCreate (sourceRect.getWidth(), sourceRect.getHeight()); + image->xhot = hotspot.X; + image->yhot = hotspot.Y; + + // write texture into XcursorImage + video::ECOLOR_FORMAT format = tex->getColorFormat(); + u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; + u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; + u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; + XcursorPixel* target = image->pixels; + const u8* data = (const u8*)tex->lock(ETLM_READ_ONLY, 0); + data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); + for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) + { + data += bytesLeftGap; + for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) + { + video::SColor pixelCol; + pixelCol.setData((const void*)data, format); + data += bytesPerPixel; + + *target = (XcursorPixel)pixelCol.color; + ++target; + } + data += bytesRightGap; + } + tex->unlock(); + + Cursor cursorResult=XcursorImageLoadCursor(display, image); + + XcursorImageDestroy(image); + + + return cursorResult; +} +#endif // #ifdef _IRR_LINUX_XCURSOR_ + +Cursor CIrrDeviceLinux::TextureToCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot) +{ +#ifdef _IRR_LINUX_XCURSOR_ + return TextureToARGBCursor( tex, sourceRect, hotspot ); +#else + return TextureToMonochromeCursor( tex, sourceRect, hotspot ); +#endif +} +#endif // _IRR_COMPILE_WITH_X11_ + + +CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null) + : Device(dev) +#ifdef _IRR_COMPILE_WITH_X11_ + , PlatformBehavior(gui::ECPB_NONE), lastQuery(0) +#endif + , IsVisible(true), Null(null), UseReferenceRect(false) + , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if (!Null) + { + XGCValues values; + unsigned long valuemask = 0; + + XColor fg, bg; + + // this code, for making the cursor invisible was sent in by + // Sirshane, thank your very much! + + + Pixmap invisBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1); + Pixmap maskBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1); + Colormap screen_colormap = DefaultColormap( Device->display, DefaultScreen( Device->display ) ); + XAllocNamedColor( Device->display, screen_colormap, "black", &fg, &fg ); + XAllocNamedColor( Device->display, screen_colormap, "white", &bg, &bg ); + + GC gc = XCreateGC( Device->display, invisBitmap, valuemask, &values ); + + XSetForeground( Device->display, gc, BlackPixel( Device->display, DefaultScreen( Device->display ) ) ); + XFillRectangle( Device->display, invisBitmap, gc, 0, 0, 32, 32 ); + XFillRectangle( Device->display, maskBitmap, gc, 0, 0, 32, 32 ); + + invisCursor = XCreatePixmapCursor( Device->display, invisBitmap, maskBitmap, &fg, &bg, 1, 1 ); + XFreeGC(Device->display, gc); + XFreePixmap(Device->display, invisBitmap); + XFreePixmap(Device->display, maskBitmap); + + initCursors(); + } +#endif +} + +CIrrDeviceLinux::CCursorControl::~CCursorControl() +{ + // Do not clearCursors here as the display is already closed + // TODO (cutealien): droping cursorcontrol earlier might work, not sure about reason why that's done in stub currently. +} + +#ifdef _IRR_COMPILE_WITH_X11_ +void CIrrDeviceLinux::CCursorControl::clearCursors() +{ + if (!Null) + XFreeCursor(Device->display, invisCursor); + for ( u32 i=0; i < Cursors.size(); ++i ) + { + for ( u32 f=0; f < Cursors[i].Frames.size(); ++f ) + { + XFreeCursor(Device->display, Cursors[i].Frames[f].IconHW); + } + } +} + +void CIrrDeviceLinux::CCursorControl::initCursors() +{ + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_arrow)) ); // (or XC_arrow?) + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_crosshair)) ); + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_hand2)) ); // (or XC_hand1? ) + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_question_arrow)) ); + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_xterm)) ); + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_X_cursor)) ); // (or XC_pirate?) + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_watch)) ); // (or XC_clock?) + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_fleur)) ); + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_right_corner)) ); // NESW not available in X11 + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_corner)) ); // NWSE not available in X11 + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_v_double_arrow)) ); + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_h_double_arrow)) ); + Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_up_arrow)) ); // (or XC_center_ptr?) +} + +void CIrrDeviceLinux::CCursorControl::update() +{ + if ( (u32)ActiveIcon < Cursors.size() && !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime ) + { + // update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement) + u32 now = Device->getTimer()->getRealTime(); + u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size(); + XDefineCursor(Device->display, Device->window, Cursors[ActiveIcon].Frames[frame].IconHW); + } +} +#endif + +//! Sets the active cursor icon +void CIrrDeviceLinux::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if ( iconId >= (s32)Cursors.size() ) + return; + + if ( Cursors[iconId].Frames.size() ) + XDefineCursor(Device->display, Device->window, Cursors[iconId].Frames[0].IconHW); + + ActiveIconStartTime = Device->getTimer()->getRealTime(); + ActiveIcon = iconId; +#endif +} + + +//! Add a custom sprite as cursor icon. +gui::ECURSOR_ICON CIrrDeviceLinux::CCursorControl::addIcon(const gui::SCursorSprite& icon) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if ( icon.SpriteId >= 0 ) + { + CursorX11 cX11; + cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; + for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) + { + irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; + irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; + irr::core::rect rectIcon = icon.SpriteBank->getPositions()[rectId]; + Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); + cX11.Frames.push_back( CursorFrameX11(cursor) ); + } + + Cursors.push_back( cX11 ); + + return (gui::ECURSOR_ICON)(Cursors.size() - 1); + } +#endif + return gui::ECI_NORMAL; +} + +//! replace the given cursor icon. +void CIrrDeviceLinux::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) +{ +#ifdef _IRR_COMPILE_WITH_X11_ + if ( iconId >= (s32)Cursors.size() ) + return; + + for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i ) + XFreeCursor(Device->display, Cursors[iconId].Frames[i].IconHW); + + if ( icon.SpriteId >= 0 ) + { + CursorX11 cX11; + cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; + for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) + { + irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; + irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; + irr::core::rect rectIcon = icon.SpriteBank->getPositions()[rectId]; + Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); + cX11.Frames.push_back( CursorFrameX11(cursor) ); + } + + Cursors[iconId] = cX11; + } +#endif +} + +irr::core::dimension2di CIrrDeviceLinux::CCursorControl::getSupportedIconSize() const +{ + // this returns the closest match that is smaller or same size, so we just pass a value which should be large enough for cursors + unsigned int width=0, height=0; +#ifdef _IRR_COMPILE_WITH_X11_ + XQueryBestCursor(Device->display, Device->window, 64, 64, &width, &height); +#endif + return core::dimension2di(width, height); +} + +} // end namespace + +#endif // _IRR_COMPILE_WITH_X11_DEVICE_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.h new file mode 100644 index 0000000..4d2a2c6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceLinux.h @@ -0,0 +1,452 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_LINUX_H_INCLUDED__ +#define __C_IRR_DEVICE_LINUX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "ICursorControl.h" +#include "os.h" + +#ifdef _IRR_COMPILE_WITH_X11_ + +#ifdef _IRR_COMPILE_WITH_OPENGL_ +#include +#define GLX_GLXEXT_LEGACY 1 +#include +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ +#include "glxext.h" +#endif +#endif + +#include +#include +#include +#ifdef _IRR_LINUX_X11_VIDMODE_ +#include +#endif +#ifdef _IRR_LINUX_X11_RANDR_ +#include +#endif +#include + +#else +#define KeySym s32 +#endif + +namespace irr +{ + + class CIrrDeviceLinux : public CIrrDeviceStub, public video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceLinux(const SIrrlichtCreationParameters& param); + + //! destructor + virtual ~CIrrDeviceLinux(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! returns if window has focus. + virtual bool isWindowFocused() const; + + //! returns if window is minimized. + virtual bool isWindowMinimized() const; + + //! returns color format of the window. + virtual video::ECOLOR_FORMAT getColorFormat() const; + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + video::IVideoModeList* getVideoModeList(); + + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize=false); + + //! Minimizes the window. + virtual void minimizeWindow(); + + //! Maximizes the window. + virtual void maximizeWindow(); + + //! Restores the window size. + virtual void restoreWindow(); + + //! Activate any joysticks, and generate events for them. + virtual bool activateJoysticks(core::array & joystickInfo); + + //! Set the current Gamma Value for the Display + virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ); + + //! Get the current Gamma Value for the Display + virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ); + + //! gets text from the clipboard + //! \return Returns 0 if no string is in there. + virtual const c8* getTextFromClipboard() const; + + //! copies text to the clipboard + //! This sets the clipboard selection and _not_ the primary selection which you have on X on the middle mouse button. + virtual void copyToClipboard(const c8* text) const; + + //! Remove all messages pending in the system message loop + virtual void clearSystemMessages(); + + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_X11; + } + +#ifdef _IRR_COMPILE_WITH_X11_ + // convert an Irrlicht texture to a X11 cursor + Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot); + Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot); +#ifdef _IRR_LINUX_XCURSOR_ + Cursor TextureToARGBCursor(irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot); +#endif +#endif + + private: + + //! create the driver + void createDriver(); + + bool createWindow(); + + void createKeyMap(); + + void pollJoysticks(); + + void initXAtoms(); + + bool switchToFullscreen(bool reset=false); + + //! Implementation of the linux cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(CIrrDeviceLinux* dev, bool null); + + ~CCursorControl(); + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + if (visible==IsVisible) + return; + IsVisible = visible; +#ifdef _IRR_COMPILE_WITH_X11_ + if (!Null) + { + if ( !IsVisible ) + XDefineCursor( Device->display, Device->window, invisCursor ); + else + XUndefineCursor( Device->display, Device->window ); + } +#endif + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*Device->Width), (s32)(y*Device->Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { +#ifdef _IRR_COMPILE_WITH_X11_ + + if (!Null) + { + if (UseReferenceRect) + { + XWarpPointer(Device->display, + None, + Device->window, 0, 0, + Device->Width, + Device->Height, + ReferenceRect.UpperLeftCorner.X + x, + ReferenceRect.UpperLeftCorner.Y + y); + + } + else + { + XWarpPointer(Device->display, + None, + Device->window, 0, 0, + Device->Width, + Device->Height, x, y); + } + XFlush(Device->display); + } +#endif + CursorPos.X = x; + CursorPos.Y = y; + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + updateCursorPos(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateCursorPos(); + + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X / (f32)Device->Width, + CursorPos.Y / (f32)Device->Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + //! Sets the active cursor icon + virtual void setActiveIcon(gui::ECURSOR_ICON iconId); + + //! Gets the currently active icon + virtual gui::ECURSOR_ICON getActiveIcon() const + { + return ActiveIcon; + } + + //! Add a custom sprite as cursor icon. + virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon); + + //! replace the given cursor icon. + virtual void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon); + + //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. + virtual core::dimension2di getSupportedIconSize() const; + +#ifdef _IRR_COMPILE_WITH_X11_ + //! Set platform specific behavior flags. + virtual void setPlatformBehavior(gui::ECURSOR_PLATFORM_BEHAVIOR behavior) {PlatformBehavior = behavior; } + + //! Return platform specific behavior. + virtual gui::ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const { return PlatformBehavior; } + + void update(); + void clearCursors(); +#endif + private: + + void updateCursorPos() + { +#ifdef _IRR_COMPILE_WITH_X11_ + if (Null) + return; + + if ( PlatformBehavior&gui::ECPB_X11_CACHE_UPDATES && !os::Timer::isStopped() ) + { + u32 now = os::Timer::getTime(); + if (now <= lastQuery) + return; + lastQuery = now; + } + + Window tmp; + int itmp1, itmp2; + unsigned int maskreturn; + XQueryPointer(Device->display, Device->window, + &tmp, &tmp, + &itmp1, &itmp2, + &CursorPos.X, &CursorPos.Y, &maskreturn); + + if (CursorPos.X < 0) + CursorPos.X = 0; + if (CursorPos.X > (s32) Device->Width) + CursorPos.X = Device->Width; + if (CursorPos.Y < 0) + CursorPos.Y = 0; + if (CursorPos.Y > (s32) Device->Height) + CursorPos.Y = Device->Height; +#endif + } + + CIrrDeviceLinux* Device; + core::position2d CursorPos; + core::rect ReferenceRect; +#ifdef _IRR_COMPILE_WITH_X11_ + gui::ECURSOR_PLATFORM_BEHAVIOR PlatformBehavior; + u32 lastQuery; + Cursor invisCursor; + + struct CursorFrameX11 + { + CursorFrameX11() : IconHW(0) {} + CursorFrameX11(Cursor icon) : IconHW(icon) {} + + Cursor IconHW; // hardware cursor + }; + + struct CursorX11 + { + CursorX11() {} + explicit CursorX11(Cursor iconHw, u32 frameTime=0) : FrameTime(frameTime) + { + Frames.push_back( CursorFrameX11(iconHw) ); + } + core::array Frames; + u32 FrameTime; + }; + + core::array Cursors; + + void initCursors(); +#endif + bool IsVisible; + bool Null; + bool UseReferenceRect; + gui::ECURSOR_ICON ActiveIcon; + u32 ActiveIconStartTime; + }; + + friend class CCursorControl; + +#ifdef _IRR_COMPILE_WITH_X11_ + friend class COpenGLDriver; + + Display *display; + XVisualInfo* visual; + int screennr; + Window window; + XSetWindowAttributes attributes; + XSizeHints* StdHints; + XImage* SoftwareImage; + mutable core::stringc Clipboard; + #ifdef _IRR_LINUX_X11_VIDMODE_ + XF86VidModeModeInfo oldVideoMode; + #endif + #ifdef _IRR_LINUX_X11_RANDR_ + SizeID oldRandrMode; + Rotation oldRandrRotation; + #endif + #ifdef _IRR_COMPILE_WITH_OPENGL_ + GLXWindow glxWin; + GLXContext Context; + #endif +#endif + u32 Width, Height; + bool WindowHasFocus; + bool WindowMinimized; + bool UseXVidMode; + bool UseXRandR; + bool UseGLXWindow; + bool ExternalWindow; + int AutorepeatSupport; + + struct SKeyMap + { + SKeyMap() {} + SKeyMap(s32 x11, s32 win32) + : X11Key(x11), Win32Key(win32) + { + } + + KeySym X11Key; + s32 Win32Key; + + bool operator<(const SKeyMap& o) const + { + return X11Key KeyMap; + +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + struct JoystickInfo + { + int fd; + int axes; + int buttons; + + SEvent persistentData; + + JoystickInfo() : fd(-1), axes(0), buttons(0) { } + }; + core::array ActiveJoysticks; +#endif + }; + + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_X11_DEVICE_ +#endif // __C_IRR_DEVICE_LINUX_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.cpp new file mode 100644 index 0000000..809b9d7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.cpp @@ -0,0 +1,973 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + +#include "CIrrDeviceSDL.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include "COSOperator.h" +#include +#include +#include "SIrrCreationParameters.h" +#include +#include + +#ifdef _MSC_VER +#pragma comment(lib, "SDL.lib") +#endif // _MSC_VER + +namespace irr +{ + namespace video + { + + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + IVideoDriver* createDirectX8Driver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window); + #endif + + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window); + #endif + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceSDL* device); + #endif + } // end namespace video + +} // end namespace irr + + +namespace irr +{ + +//! constructor +CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param) + : CIrrDeviceStub(param), + Screen((SDL_Surface*)param.WindowId), SDL_Flags(SDL_ANYFORMAT), + MouseX(0), MouseY(0), MouseButtonStates(0), + Width(param.WindowSize.Width), Height(param.WindowSize.Height), + Resizable(false), WindowHasFocus(false), WindowMinimized(false) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceSDL"); + #endif + + // Initialize SDL... Timer for sleep, video for the obvious, and + // noparachute prevents SDL from catching fatal errors. + if (SDL_Init( SDL_INIT_TIMER|SDL_INIT_VIDEO| +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + SDL_INIT_JOYSTICK| +#endif + SDL_INIT_NOPARACHUTE ) < 0) + { + os::Printer::log( "Unable to initialize SDL!", SDL_GetError()); + Close = true; + } + +#if defined(_IRR_WINDOWS_) + SDL_putenv("SDL_VIDEODRIVER=directx"); +#elif defined(_IRR_OSX_PLATFORM_) + SDL_putenv("SDL_VIDEODRIVER=Quartz"); +#else + SDL_putenv("SDL_VIDEODRIVER=x11"); +#endif +// SDL_putenv("SDL_WINDOWID="); + + SDL_VERSION(&Info.version); + + SDL_GetWMInfo(&Info); + core::stringc sdlversion = "SDL Version "; + sdlversion += Info.version.major; + sdlversion += "."; + sdlversion += Info.version.minor; + sdlversion += "."; + sdlversion += Info.version.patch; + + Operator = new COSOperator(sdlversion); + os::Printer::log(sdlversion.c_str(), ELL_INFORMATION); + + // create keymap + createKeyMap(); + // enable key to character translation + SDL_EnableUNICODE(1); + + (void)SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + + if ( CreationParams.Fullscreen ) + SDL_Flags |= SDL_FULLSCREEN; + if (CreationParams.DriverType == video::EDT_OPENGL) + SDL_Flags |= SDL_OPENGL; + else if (CreationParams.Doublebuffer) + SDL_Flags |= SDL_DOUBLEBUF; + // create window + if (CreationParams.DriverType != video::EDT_NULL) + { + // create the window, only if we do not use the null device + createWindow(); + } + + // create cursor control + CursorControl = new CCursorControl(this); + + // create driver + createDriver(); + + if (VideoDriver) + createGUIAndScene(); +} + + +//! destructor +CIrrDeviceSDL::~CIrrDeviceSDL() +{ +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + const u32 numJoysticks = Joysticks.size(); + for (u32 i=0; i1) + { + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias ); + } + if ( !Screen ) + Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + if ( !Screen && CreationParams.AntiAlias>1) + { + while (--CreationParams.AntiAlias>1) + { + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias ); + Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + if (Screen) + break; + } + if ( !Screen ) + { + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 ); + Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + if (Screen) + os::Printer::log("AntiAliasing disabled due to lack of support!" ); + } + } + } + else if ( !Screen ) + Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + + if ( !Screen && CreationParams.Doublebuffer) + { + // Try single buffer + if (CreationParams.DriverType == video::EDT_OPENGL) + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + SDL_Flags &= ~SDL_DOUBLEBUF; + Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags ); + } + if ( !Screen ) + { + os::Printer::log( "Could not initialize display!" ); + return false; + } + + return true; +} + + +//! create the driver +void CIrrDeviceSDL::createDriver() +{ + switch(CreationParams.DriverType) + { + case video::EDT_DIRECT3D8: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + + VideoDriver = video::createDirectX8Driver(CreationParams, FileSystem, HWnd); + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + + break; + + case video::EDT_DIRECT3D9: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + + VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, HWnd); + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + + break; + + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + #else + os::Printer::log("No Software driver support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceSDL::run() +{ + os::Timer::tick(); + + SEvent irrevent; + SDL_Event SDL_event; + + while ( !Close && SDL_PollEvent( &SDL_event ) ) + { + switch ( SDL_event.type ) + { + case SDL_MOUSEMOTION: + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + MouseX = irrevent.MouseInput.X = SDL_event.motion.x; + MouseY = irrevent.MouseInput.Y = SDL_event.motion.y; + irrevent.MouseInput.ButtonStates = MouseButtonStates; + + postEventFromUser(irrevent); + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + + irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; + irrevent.MouseInput.X = SDL_event.button.x; + irrevent.MouseInput.Y = SDL_event.button.y; + + irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + + switch(SDL_event.button.button) + { + case SDL_BUTTON_LEFT: + if (SDL_event.type == SDL_MOUSEBUTTONDOWN) + { + irrevent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; + MouseButtonStates |= irr::EMBSM_LEFT; + } + else + { + irrevent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; + MouseButtonStates &= !irr::EMBSM_LEFT; + } + break; + + case SDL_BUTTON_RIGHT: + if (SDL_event.type == SDL_MOUSEBUTTONDOWN) + { + irrevent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; + MouseButtonStates |= irr::EMBSM_RIGHT; + } + else + { + irrevent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; + MouseButtonStates &= !irr::EMBSM_RIGHT; + } + break; + + case SDL_BUTTON_MIDDLE: + if (SDL_event.type == SDL_MOUSEBUTTONDOWN) + { + irrevent.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; + MouseButtonStates |= irr::EMBSM_MIDDLE; + } + else + { + irrevent.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; + MouseButtonStates &= !irr::EMBSM_MIDDLE; + } + break; + + case SDL_BUTTON_WHEELUP: + irrevent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = 1.0f; + break; + + case SDL_BUTTON_WHEELDOWN: + irrevent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + irrevent.MouseInput.Wheel = -1.0f; + break; + } + + irrevent.MouseInput.ButtonStates = MouseButtonStates; + + if (irrevent.MouseInput.Event != irr::EMIE_MOUSE_MOVED) + { + postEventFromUser(irrevent); + + if ( irrevent.MouseInput.Event >= EMIE_LMOUSE_PRESSED_DOWN && irrevent.MouseInput.Event <= EMIE_MMOUSE_PRESSED_DOWN ) + { + u32 clicks = checkSuccessiveClicks(irrevent.MouseInput.X, irrevent.MouseInput.Y, irrevent.MouseInput.Event); + if ( clicks == 2 ) + { + irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_DOUBLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); + postEventFromUser(irrevent); + } + else if ( clicks == 3 ) + { + irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_TRIPLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); + postEventFromUser(irrevent); + } + } + } + break; + + case SDL_KEYDOWN: + case SDL_KEYUP: + { + SKeyMap mp; + mp.SDLKey = SDL_event.key.keysym.sym; + s32 idx = KeyMap.binary_search(mp); + + EKEY_CODE key; + if (idx == -1) + key = (EKEY_CODE)0; + else + key = (EKEY_CODE)KeyMap[idx].Win32Key; + +#ifdef _IRR_WINDOWS_API_ + // handle alt+f4 in Windows, because SDL seems not to + if ( (SDL_event.key.keysym.mod & KMOD_LALT) && key == KEY_F4) + { + Close = true; + break; + } +#endif + irrevent.EventType = irr::EET_KEY_INPUT_EVENT; + irrevent.KeyInput.Char = SDL_event.key.keysym.unicode; + irrevent.KeyInput.Key = key; + irrevent.KeyInput.PressedDown = (SDL_event.type == SDL_KEYDOWN); + irrevent.KeyInput.Shift = (SDL_event.key.keysym.mod & KMOD_SHIFT) != 0; + irrevent.KeyInput.Control = (SDL_event.key.keysym.mod & KMOD_CTRL ) != 0; + postEventFromUser(irrevent); + } + break; + + case SDL_QUIT: + Close = true; + break; + + case SDL_ACTIVEEVENT: + if ((SDL_event.active.state == SDL_APPMOUSEFOCUS) || + (SDL_event.active.state == SDL_APPINPUTFOCUS)) + WindowHasFocus = (SDL_event.active.gain==1); + else + if (SDL_event.active.state == SDL_APPACTIVE) + WindowMinimized = (SDL_event.active.gain!=1); + break; + + case SDL_VIDEORESIZE: + if ((SDL_event.resize.w != (int)Width) || (SDL_event.resize.h != (int)Height)) + { + Width = SDL_event.resize.w; + Height = SDL_event.resize.h; + Screen = SDL_SetVideoMode( Width, Height, 0, SDL_Flags ); + if (VideoDriver) + VideoDriver->OnResize(core::dimension2d(Width, Height)); + } + break; + + case SDL_USEREVENT: + irrevent.EventType = irr::EET_USER_EVENT; + irrevent.UserEvent.UserData1 = *(reinterpret_cast(&SDL_event.user.data1)); + irrevent.UserEvent.UserData2 = *(reinterpret_cast(&SDL_event.user.data2)); + + postEventFromUser(irrevent); + break; + + default: + break; + } // end switch + + } // end while + +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + // TODO: Check if the multiple open/close calls are too expensive, then + // open/close in the constructor/destructor instead + + // update joystick states manually + SDL_JoystickUpdate(); + // we'll always send joystick input events... + SEvent joyevent; + joyevent.EventType = EET_JOYSTICK_INPUT_EVENT; + for (u32 i=0; i0) + { + switch (SDL_JoystickGetHat(joystick, 0)) + { + case SDL_HAT_UP: + joyevent.JoystickEvent.POV=0; + break; + case SDL_HAT_RIGHTUP: + joyevent.JoystickEvent.POV=4500; + break; + case SDL_HAT_RIGHT: + joyevent.JoystickEvent.POV=9000; + break; + case SDL_HAT_RIGHTDOWN: + joyevent.JoystickEvent.POV=13500; + break; + case SDL_HAT_DOWN: + joyevent.JoystickEvent.POV=18000; + break; + case SDL_HAT_LEFTDOWN: + joyevent.JoystickEvent.POV=22500; + break; + case SDL_HAT_LEFT: + joyevent.JoystickEvent.POV=27000; + break; + case SDL_HAT_LEFTUP: + joyevent.JoystickEvent.POV=31500; + break; + case SDL_HAT_CENTERED: + default: + joyevent.JoystickEvent.POV=65535; + break; + } + } + else + { + joyevent.JoystickEvent.POV=65535; + } + + // we map the number directly + joyevent.JoystickEvent.Joystick=static_cast(i); + // now post the event + postEventFromUser(joyevent); + // and close the joystick + } + } +#endif + return !Close; +} + +//! Activate any joysticks, and generate events for them. +bool CIrrDeviceSDL::activateJoysticks(core::array & joystickInfo) +{ +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + joystickInfo.clear(); + + // we can name up to 256 different joysticks + const int numJoysticks = core::min_(SDL_NumJoysticks(), 256); + Joysticks.reallocate(numJoysticks); + joystickInfo.reallocate(numJoysticks); + + int joystick = 0; + for (; joystick 0) + ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; + + joystickInfo.push_back(info); + } + + for(joystick = 0; joystick < (int)joystickInfo.size(); ++joystick) + { + char logString[256]; + (void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'", + joystick, joystickInfo[joystick].Axes, + joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); + os::Printer::log(logString, ELL_INFORMATION); + } + + return true; + +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + + return false; +} + + + +//! pause execution temporarily +void CIrrDeviceSDL::yield() +{ + SDL_Delay(0); +} + + +//! pause execution for a specified time +void CIrrDeviceSDL::sleep(u32 timeMs, bool pauseTimer) +{ + const bool wasStopped = Timer ? Timer->isStopped() : true; + if (pauseTimer && !wasStopped) + Timer->stop(); + + SDL_Delay(timeMs); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +//! sets the caption of the window +void CIrrDeviceSDL::setWindowCaption(const wchar_t* text) +{ + core::stringc textc = text; + SDL_WM_SetCaption( textc.c_str( ), textc.c_str( ) ); +} + + +//! presents a surface in the client area +bool CIrrDeviceSDL::present(video::IImage* surface, void* windowId, core::rect* srcClip) +{ + SDL_Surface *sdlSurface = SDL_CreateRGBSurfaceFrom( + surface->lock(), surface->getDimension().Width, surface->getDimension().Height, + surface->getBitsPerPixel(), surface->getPitch(), + surface->getRedMask(), surface->getGreenMask(), surface->getBlueMask(), surface->getAlphaMask()); + if (!sdlSurface) + return false; + SDL_SetAlpha(sdlSurface, 0, 0); + SDL_SetColorKey(sdlSurface, 0, 0); + sdlSurface->format->BitsPerPixel=surface->getBitsPerPixel(); + sdlSurface->format->BytesPerPixel=surface->getBytesPerPixel(); + if ((surface->getColorFormat()==video::ECF_R8G8B8) || + (surface->getColorFormat()==video::ECF_A8R8G8B8)) + { + sdlSurface->format->Rloss=0; + sdlSurface->format->Gloss=0; + sdlSurface->format->Bloss=0; + sdlSurface->format->Rshift=16; + sdlSurface->format->Gshift=8; + sdlSurface->format->Bshift=0; + if (surface->getColorFormat()==video::ECF_R8G8B8) + { + sdlSurface->format->Aloss=8; + sdlSurface->format->Ashift=32; + } + else + { + sdlSurface->format->Aloss=0; + sdlSurface->format->Ashift=24; + } + } + else if (surface->getColorFormat()==video::ECF_R5G6B5) + { + sdlSurface->format->Rloss=3; + sdlSurface->format->Gloss=2; + sdlSurface->format->Bloss=3; + sdlSurface->format->Aloss=8; + sdlSurface->format->Rshift=11; + sdlSurface->format->Gshift=5; + sdlSurface->format->Bshift=0; + sdlSurface->format->Ashift=16; + } + else if (surface->getColorFormat()==video::ECF_A1R5G5B5) + { + sdlSurface->format->Rloss=3; + sdlSurface->format->Gloss=3; + sdlSurface->format->Bloss=3; + sdlSurface->format->Aloss=7; + sdlSurface->format->Rshift=10; + sdlSurface->format->Gshift=5; + sdlSurface->format->Bshift=0; + sdlSurface->format->Ashift=15; + } + + SDL_Surface* scr = (SDL_Surface* )windowId; + if (!scr) + scr = Screen; + if (scr) + { + if (srcClip) + { + SDL_Rect sdlsrcClip; + sdlsrcClip.x = srcClip->UpperLeftCorner.X; + sdlsrcClip.y = srcClip->UpperLeftCorner.Y; + sdlsrcClip.w = srcClip->getWidth(); + sdlsrcClip.h = srcClip->getHeight(); + SDL_BlitSurface(sdlSurface, &sdlsrcClip, scr, NULL); + } + else + SDL_BlitSurface(sdlSurface, NULL, scr, NULL); + SDL_Flip(scr); + } + + SDL_FreeSurface(sdlSurface); + surface->unlock(); + return (scr != 0); +} + + +//! notifies the device that it should close itself +void CIrrDeviceSDL::closeDevice() +{ + Close = true; +} + + +//! \return Pointer to a list with all video modes supported +video::IVideoModeList* CIrrDeviceSDL::getVideoModeList() +{ + if (!VideoModeList->getVideoModeCount()) + { + // enumerate video modes. + const SDL_VideoInfo *vi = SDL_GetVideoInfo(); + SDL_Rect **modes = SDL_ListModes(vi->vfmt, SDL_Flags); + if (modes != 0) + { + if (modes == (SDL_Rect **)-1) + os::Printer::log("All modes available.\n"); + else + { + for (u32 i=0; modes[i]; ++i) + VideoModeList->addMode(core::dimension2d(modes[i]->w, modes[i]->h), vi->vfmt->BitsPerPixel); + } + } + } + + return VideoModeList; +} + + +//! Sets if the window should be resizable in windowed mode. +void CIrrDeviceSDL::setResizable(bool resize) +{ + if (resize != Resizable) + { + if (resize) + SDL_Flags |= SDL_RESIZABLE; + else + SDL_Flags &= ~SDL_RESIZABLE; + Screen = SDL_SetVideoMode( 0, 0, 0, SDL_Flags ); + Resizable = resize; + } +} + + +//! Minimizes window if possible +void CIrrDeviceSDL::minimizeWindow() +{ + SDL_WM_IconifyWindow(); +} + + +//! Maximize window +void CIrrDeviceSDL::maximizeWindow() +{ + // do nothing +} + + +//! Restore original window size +void CIrrDeviceSDL::restoreWindow() +{ + // do nothing +} + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceSDL::isWindowActive() const +{ + return (WindowHasFocus && !WindowMinimized); +} + + +//! returns if window has focus. +bool CIrrDeviceSDL::isWindowFocused() const +{ + return WindowHasFocus; +} + + +//! returns if window is minimized. +bool CIrrDeviceSDL::isWindowMinimized() const +{ + return WindowMinimized; +} + + +//! Set the current Gamma Value for the Display +bool CIrrDeviceSDL::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) +{ + /* + // todo: Gamma in SDL takes ints, what does Irrlicht use? + return (SDL_SetGamma(red, green, blue) != -1); + */ + return false; +} + +//! Get the current Gamma Value for the Display +bool CIrrDeviceSDL::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) +{ +/* brightness = 0.f; + contrast = 0.f; + return (SDL_GetGamma(&red, &green, &blue) != -1);*/ + return false; +} + +//! returns color format of the window. +video::ECOLOR_FORMAT CIrrDeviceSDL::getColorFormat() const +{ + if (Screen) + { + if (Screen->format->BitsPerPixel==16) + { + if (Screen->format->Amask != 0) + return video::ECF_A1R5G5B5; + else + return video::ECF_R5G6B5; + } + else + { + if (Screen->format->Amask != 0) + return video::ECF_A8R8G8B8; + else + return video::ECF_R8G8B8; + } + } + else + return CIrrDeviceStub::getColorFormat(); +} + + +void CIrrDeviceSDL::createKeyMap() +{ + // I don't know if this is the best method to create + // the lookuptable, but I'll leave it like that until + // I find a better version. + + KeyMap.reallocate(105); + + // buttons missing + + KeyMap.push_back(SKeyMap(SDLK_BACKSPACE, KEY_BACK)); + KeyMap.push_back(SKeyMap(SDLK_TAB, KEY_TAB)); + KeyMap.push_back(SKeyMap(SDLK_CLEAR, KEY_CLEAR)); + KeyMap.push_back(SKeyMap(SDLK_RETURN, KEY_RETURN)); + + // combined modifiers missing + + KeyMap.push_back(SKeyMap(SDLK_PAUSE, KEY_PAUSE)); + KeyMap.push_back(SKeyMap(SDLK_CAPSLOCK, KEY_CAPITAL)); + + // asian letter keys missing + + KeyMap.push_back(SKeyMap(SDLK_ESCAPE, KEY_ESCAPE)); + + // asian letter keys missing + + KeyMap.push_back(SKeyMap(SDLK_SPACE, KEY_SPACE)); + KeyMap.push_back(SKeyMap(SDLK_PAGEUP, KEY_PRIOR)); + KeyMap.push_back(SKeyMap(SDLK_PAGEDOWN, KEY_NEXT)); + KeyMap.push_back(SKeyMap(SDLK_END, KEY_END)); + KeyMap.push_back(SKeyMap(SDLK_HOME, KEY_HOME)); + KeyMap.push_back(SKeyMap(SDLK_LEFT, KEY_LEFT)); + KeyMap.push_back(SKeyMap(SDLK_UP, KEY_UP)); + KeyMap.push_back(SKeyMap(SDLK_RIGHT, KEY_RIGHT)); + KeyMap.push_back(SKeyMap(SDLK_DOWN, KEY_DOWN)); + + // select missing + KeyMap.push_back(SKeyMap(SDLK_PRINT, KEY_PRINT)); + // execute missing + KeyMap.push_back(SKeyMap(SDLK_PRINT, KEY_SNAPSHOT)); + + KeyMap.push_back(SKeyMap(SDLK_INSERT, KEY_INSERT)); + KeyMap.push_back(SKeyMap(SDLK_DELETE, KEY_DELETE)); + KeyMap.push_back(SKeyMap(SDLK_HELP, KEY_HELP)); + + KeyMap.push_back(SKeyMap(SDLK_0, KEY_KEY_0)); + KeyMap.push_back(SKeyMap(SDLK_1, KEY_KEY_1)); + KeyMap.push_back(SKeyMap(SDLK_2, KEY_KEY_2)); + KeyMap.push_back(SKeyMap(SDLK_3, KEY_KEY_3)); + KeyMap.push_back(SKeyMap(SDLK_4, KEY_KEY_4)); + KeyMap.push_back(SKeyMap(SDLK_5, KEY_KEY_5)); + KeyMap.push_back(SKeyMap(SDLK_6, KEY_KEY_6)); + KeyMap.push_back(SKeyMap(SDLK_7, KEY_KEY_7)); + KeyMap.push_back(SKeyMap(SDLK_8, KEY_KEY_8)); + KeyMap.push_back(SKeyMap(SDLK_9, KEY_KEY_9)); + + KeyMap.push_back(SKeyMap(SDLK_a, KEY_KEY_A)); + KeyMap.push_back(SKeyMap(SDLK_b, KEY_KEY_B)); + KeyMap.push_back(SKeyMap(SDLK_c, KEY_KEY_C)); + KeyMap.push_back(SKeyMap(SDLK_d, KEY_KEY_D)); + KeyMap.push_back(SKeyMap(SDLK_e, KEY_KEY_E)); + KeyMap.push_back(SKeyMap(SDLK_f, KEY_KEY_F)); + KeyMap.push_back(SKeyMap(SDLK_g, KEY_KEY_G)); + KeyMap.push_back(SKeyMap(SDLK_h, KEY_KEY_H)); + KeyMap.push_back(SKeyMap(SDLK_i, KEY_KEY_I)); + KeyMap.push_back(SKeyMap(SDLK_j, KEY_KEY_J)); + KeyMap.push_back(SKeyMap(SDLK_k, KEY_KEY_K)); + KeyMap.push_back(SKeyMap(SDLK_l, KEY_KEY_L)); + KeyMap.push_back(SKeyMap(SDLK_m, KEY_KEY_M)); + KeyMap.push_back(SKeyMap(SDLK_n, KEY_KEY_N)); + KeyMap.push_back(SKeyMap(SDLK_o, KEY_KEY_O)); + KeyMap.push_back(SKeyMap(SDLK_p, KEY_KEY_P)); + KeyMap.push_back(SKeyMap(SDLK_q, KEY_KEY_Q)); + KeyMap.push_back(SKeyMap(SDLK_r, KEY_KEY_R)); + KeyMap.push_back(SKeyMap(SDLK_s, KEY_KEY_S)); + KeyMap.push_back(SKeyMap(SDLK_t, KEY_KEY_T)); + KeyMap.push_back(SKeyMap(SDLK_u, KEY_KEY_U)); + KeyMap.push_back(SKeyMap(SDLK_v, KEY_KEY_V)); + KeyMap.push_back(SKeyMap(SDLK_w, KEY_KEY_W)); + KeyMap.push_back(SKeyMap(SDLK_x, KEY_KEY_X)); + KeyMap.push_back(SKeyMap(SDLK_y, KEY_KEY_Y)); + KeyMap.push_back(SKeyMap(SDLK_z, KEY_KEY_Z)); + + KeyMap.push_back(SKeyMap(SDLK_LSUPER, KEY_LWIN)); + KeyMap.push_back(SKeyMap(SDLK_RSUPER, KEY_RWIN)); + // apps missing + KeyMap.push_back(SKeyMap(SDLK_POWER, KEY_SLEEP)); //?? + + KeyMap.push_back(SKeyMap(SDLK_KP0, KEY_NUMPAD0)); + KeyMap.push_back(SKeyMap(SDLK_KP1, KEY_NUMPAD1)); + KeyMap.push_back(SKeyMap(SDLK_KP2, KEY_NUMPAD2)); + KeyMap.push_back(SKeyMap(SDLK_KP3, KEY_NUMPAD3)); + KeyMap.push_back(SKeyMap(SDLK_KP4, KEY_NUMPAD4)); + KeyMap.push_back(SKeyMap(SDLK_KP5, KEY_NUMPAD5)); + KeyMap.push_back(SKeyMap(SDLK_KP6, KEY_NUMPAD6)); + KeyMap.push_back(SKeyMap(SDLK_KP7, KEY_NUMPAD7)); + KeyMap.push_back(SKeyMap(SDLK_KP8, KEY_NUMPAD8)); + KeyMap.push_back(SKeyMap(SDLK_KP9, KEY_NUMPAD9)); + KeyMap.push_back(SKeyMap(SDLK_KP_MULTIPLY, KEY_MULTIPLY)); + KeyMap.push_back(SKeyMap(SDLK_KP_PLUS, KEY_ADD)); +// KeyMap.push_back(SKeyMap(SDLK_KP_, KEY_SEPARATOR)); + KeyMap.push_back(SKeyMap(SDLK_KP_MINUS, KEY_SUBTRACT)); + KeyMap.push_back(SKeyMap(SDLK_KP_PERIOD, KEY_DECIMAL)); + KeyMap.push_back(SKeyMap(SDLK_KP_DIVIDE, KEY_DIVIDE)); + + KeyMap.push_back(SKeyMap(SDLK_F1, KEY_F1)); + KeyMap.push_back(SKeyMap(SDLK_F2, KEY_F2)); + KeyMap.push_back(SKeyMap(SDLK_F3, KEY_F3)); + KeyMap.push_back(SKeyMap(SDLK_F4, KEY_F4)); + KeyMap.push_back(SKeyMap(SDLK_F5, KEY_F5)); + KeyMap.push_back(SKeyMap(SDLK_F6, KEY_F6)); + KeyMap.push_back(SKeyMap(SDLK_F7, KEY_F7)); + KeyMap.push_back(SKeyMap(SDLK_F8, KEY_F8)); + KeyMap.push_back(SKeyMap(SDLK_F9, KEY_F9)); + KeyMap.push_back(SKeyMap(SDLK_F10, KEY_F10)); + KeyMap.push_back(SKeyMap(SDLK_F11, KEY_F11)); + KeyMap.push_back(SKeyMap(SDLK_F12, KEY_F12)); + KeyMap.push_back(SKeyMap(SDLK_F13, KEY_F13)); + KeyMap.push_back(SKeyMap(SDLK_F14, KEY_F14)); + KeyMap.push_back(SKeyMap(SDLK_F15, KEY_F15)); + // no higher F-keys + + KeyMap.push_back(SKeyMap(SDLK_NUMLOCK, KEY_NUMLOCK)); + KeyMap.push_back(SKeyMap(SDLK_SCROLLOCK, KEY_SCROLL)); + KeyMap.push_back(SKeyMap(SDLK_LSHIFT, KEY_LSHIFT)); + KeyMap.push_back(SKeyMap(SDLK_RSHIFT, KEY_RSHIFT)); + KeyMap.push_back(SKeyMap(SDLK_LCTRL, KEY_LCONTROL)); + KeyMap.push_back(SKeyMap(SDLK_RCTRL, KEY_RCONTROL)); + KeyMap.push_back(SKeyMap(SDLK_LALT, KEY_LMENU)); + KeyMap.push_back(SKeyMap(SDLK_RALT, KEY_RMENU)); + + KeyMap.push_back(SKeyMap(SDLK_PLUS, KEY_PLUS)); + KeyMap.push_back(SKeyMap(SDLK_COMMA, KEY_COMMA)); + KeyMap.push_back(SKeyMap(SDLK_MINUS, KEY_MINUS)); + KeyMap.push_back(SKeyMap(SDLK_PERIOD, KEY_PERIOD)); + + // some special keys missing + + KeyMap.sort(); +} + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.h new file mode 100644 index 0000000..c151f1d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceSDL.h @@ -0,0 +1,235 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// This device code is based on the original SDL device implementation +// contributed by Shane Parker (sirshane). + +#ifndef __C_IRR_DEVICE_SDL_H_INCLUDED__ +#define __C_IRR_DEVICE_SDL_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + +#include "IrrlichtDevice.h" +#include "CIrrDeviceStub.h" +#include "IImagePresenter.h" +#include "ICursorControl.h" + +#include +#include + +namespace irr +{ + + class CIrrDeviceSDL : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceSDL(const SIrrlichtCreationParameters& param); + + //! destructor + virtual ~CIrrDeviceSDL(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! pause execution temporarily + virtual void yield(); + + //! pause execution for a specified time + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! returns if window has focus. + bool isWindowFocused() const; + + //! returns if window is minimized. + bool isWindowMinimized() const; + + //! returns color format of the window. + video::ECOLOR_FORMAT getColorFormat() const; + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes supported + video::IVideoModeList* getVideoModeList(); + + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize=false); + + //! Minimizes the window. + virtual void minimizeWindow(); + + //! Maximizes the window. + virtual void maximizeWindow(); + + //! Restores the window size. + virtual void restoreWindow(); + + //! Activate any joysticks, and generate events for them. + virtual bool activateJoysticks(core::array & joystickInfo); + + //! Set the current Gamma Value for the Display + virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ); + + //! Get the current Gamma Value for the Display + virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ); + + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_SDL; + } + + //! Implementation of the linux cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(CIrrDeviceSDL* dev) + : Device(dev), IsVisible(true) + { + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + if ( visible ) + SDL_ShowCursor( SDL_ENABLE ); + else + SDL_ShowCursor( SDL_DISABLE ); + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*Device->Width), (s32)(y*Device->Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + SDL_WarpMouse( x, y ); + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + updateCursorPos(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateCursorPos(); + return core::position2d(CursorPos.X / (f32)Device->Width, + CursorPos.Y / (f32)Device->Height); + } + + virtual void setReferenceRect(core::rect* rect=0) + { + } + + private: + + void updateCursorPos() + { + CursorPos.X = Device->MouseX; + CursorPos.Y = Device->MouseY; + + if (CursorPos.X < 0) + CursorPos.X = 0; + if (CursorPos.X > (s32)Device->Width) + CursorPos.X = Device->Width; + if (CursorPos.Y < 0) + CursorPos.Y = 0; + if (CursorPos.Y > (s32)Device->Height) + CursorPos.Y = Device->Height; + } + + CIrrDeviceSDL* Device; + core::position2d CursorPos; + bool IsVisible; + }; + + private: + + //! create the driver + void createDriver(); + + bool createWindow(); + + void createKeyMap(); + + SDL_Surface* Screen; + int SDL_Flags; +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + core::array Joysticks; +#endif + + s32 MouseX, MouseY; + u32 MouseButtonStates; + + u32 Width, Height; + + bool Resizable; + bool WindowHasFocus; + bool WindowMinimized; + + struct SKeyMap + { + SKeyMap() {} + SKeyMap(s32 x11, s32 win32) + : SDLKey(x11), Win32Key(win32) + { + } + + s32 SDLKey; + s32 Win32Key; + + bool operator<(const SKeyMap& o) const + { + return SDLKey KeyMap; + SDL_SysWMinfo Info; + }; + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ +#endif // __C_IRR_DEVICE_SDL_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.cpp new file mode 100644 index 0000000..d74c929 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.cpp @@ -0,0 +1,429 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CIrrDeviceStub.h" +#include "ISceneManager.h" +#include "IEventReceiver.h" +#include "IFileSystem.h" +#include "IGUIEnvironment.h" +#include "os.h" +#include "IrrCompileConfig.h" +#include "CTimer.h" +#include "CLogger.h" +#include "irrString.h" +#include "IRandomizer.h" + +namespace irr +{ +//! constructor +CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params) +: IrrlichtDevice(), VideoDriver(0), GUIEnvironment(0), SceneManager(0), + Timer(0), CursorControl(0), UserReceiver(params.EventReceiver), + Logger(0), Operator(0), Randomizer(0), FileSystem(0), + InputReceivingSceneManager(0), VideoModeList(0), + CreationParams(params), Close(false) +{ + Timer = new CTimer(params.UsePerformanceTimer); + if (os::Printer::Logger) + { + os::Printer::Logger->grab(); + Logger = (CLogger*)os::Printer::Logger; + Logger->setReceiver(UserReceiver); + } + else + { + Logger = new CLogger(UserReceiver); + os::Printer::Logger = Logger; + } + Logger->setLogLevel(CreationParams.LoggingLevel); + + os::Printer::Logger = Logger; + Randomizer = createDefaultRandomizer(); + + FileSystem = io::createFileSystem(); + VideoModeList = new video::CVideoModeList(); + + core::stringc s = "Irrlicht Engine version "; + s.append(getVersion()); + os::Printer::log(s.c_str(), ELL_INFORMATION); + + checkVersion(params.SDK_version_do_not_use); +} + + +CIrrDeviceStub::~CIrrDeviceStub() +{ + VideoModeList->drop(); + FileSystem->drop(); + + if (GUIEnvironment) + GUIEnvironment->drop(); + + if (VideoDriver) + VideoDriver->drop(); + + if (SceneManager) + SceneManager->drop(); + + if (InputReceivingSceneManager) + InputReceivingSceneManager->drop(); + + if (CursorControl) + CursorControl->drop(); + + if (Operator) + Operator->drop(); + + if (Randomizer) + Randomizer->drop(); + + CursorControl = 0; + + if (Timer) + Timer->drop(); + + if (Logger->drop()) + os::Printer::Logger = 0; +} + + +void CIrrDeviceStub::createGUIAndScene() +{ + #ifdef _IRR_COMPILE_WITH_GUI_ + // create gui environment + GUIEnvironment = gui::createGUIEnvironment(FileSystem, VideoDriver, Operator); + #endif + + // create Scene manager + SceneManager = scene::createSceneManager(VideoDriver, FileSystem, CursorControl, GUIEnvironment); + + setEventReceiver(UserReceiver); +} + + +//! returns the video driver +video::IVideoDriver* CIrrDeviceStub::getVideoDriver() +{ + return VideoDriver; +} + + + +//! return file system +io::IFileSystem* CIrrDeviceStub::getFileSystem() +{ + return FileSystem; +} + + + +//! returns the gui environment +gui::IGUIEnvironment* CIrrDeviceStub::getGUIEnvironment() +{ + return GUIEnvironment; +} + + + +//! returns the scene manager +scene::ISceneManager* CIrrDeviceStub::getSceneManager() +{ + return SceneManager; +} + + +//! \return Returns a pointer to the ITimer object. With it the +//! current Time can be received. +ITimer* CIrrDeviceStub::getTimer() +{ + return Timer; +} + + +//! Returns the version of the engine. +const char* CIrrDeviceStub::getVersion() const +{ + return IRRLICHT_SDK_VERSION; +} + +//! \return Returns a pointer to the mouse cursor control interface. +gui::ICursorControl* CIrrDeviceStub::getCursorControl() +{ + return CursorControl; +} + + +//! \return Returns a pointer to a list with all video modes supported +//! by the gfx adapter. +video::IVideoModeList* CIrrDeviceStub::getVideoModeList() +{ + return VideoModeList; +} + + +//! checks version of sdk and prints warning if there might be a problem +bool CIrrDeviceStub::checkVersion(const char* version) +{ + if (strcmp(getVersion(), version)) + { + core::stringc w; + w = "Warning: The library version of the Irrlicht Engine ("; + w += getVersion(); + w += ") does not match the version the application was compiled with ("; + w += version; + w += "). This may cause problems."; + os::Printer::log(w.c_str(), ELL_WARNING); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + return true; +} + + +//! Compares to the last call of this function to return double and triple clicks. +u32 CIrrDeviceStub::checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent ) +{ + const s32 MAX_MOUSEMOVE = 3; + + irr::u32 clickTime = getTimer()->getRealTime(); + + if ( (clickTime-MouseMultiClicks.LastClickTime) < MouseMultiClicks.DoubleClickTime + && core::abs_(MouseMultiClicks.LastClick.X - mouseX ) <= MAX_MOUSEMOVE + && core::abs_(MouseMultiClicks.LastClick.Y - mouseY ) <= MAX_MOUSEMOVE + && MouseMultiClicks.CountSuccessiveClicks < 3 + && MouseMultiClicks.LastMouseInputEvent == inputEvent + ) + { + ++MouseMultiClicks.CountSuccessiveClicks; + } + else + { + MouseMultiClicks.CountSuccessiveClicks = 1; + } + + MouseMultiClicks.LastMouseInputEvent = inputEvent; + MouseMultiClicks.LastClickTime = clickTime; + MouseMultiClicks.LastClick.X = mouseX; + MouseMultiClicks.LastClick.Y = mouseY; + + return MouseMultiClicks.CountSuccessiveClicks; +} + + +//! send the event to the right receiver +bool CIrrDeviceStub::postEventFromUser(const SEvent& event) +{ + bool absorbed = false; + + if (UserReceiver) + absorbed = UserReceiver->OnEvent(event); + + if (!absorbed && GUIEnvironment) + absorbed = GUIEnvironment->postEventFromUser(event); + + scene::ISceneManager* inputReceiver = InputReceivingSceneManager; + if (!inputReceiver) + inputReceiver = SceneManager; + + if (!absorbed && inputReceiver) + absorbed = inputReceiver->postEventFromUser(event); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return absorbed; +} + + +//! Sets a new event receiver to receive events +void CIrrDeviceStub::setEventReceiver(IEventReceiver* receiver) +{ + UserReceiver = receiver; + Logger->setReceiver(receiver); + if (GUIEnvironment) + GUIEnvironment->setUserEventReceiver(receiver); +} + + +//! Returns poinhter to the current event receiver. Returns 0 if there is none. +IEventReceiver* CIrrDeviceStub::getEventReceiver() +{ + return UserReceiver; +} + + +//! \return Returns a pointer to the logger. +ILogger* CIrrDeviceStub::getLogger() +{ + return Logger; +} + + +//! Returns the operation system opertator object. +IOSOperator* CIrrDeviceStub::getOSOperator() +{ + return Operator; +} + + +//! Provides access to the engine's currently set randomizer. +IRandomizer* CIrrDeviceStub::getRandomizer() const +{ + return Randomizer; +} + +//! Sets a new randomizer. +void CIrrDeviceStub::setRandomizer(IRandomizer* r) +{ + if (r!=Randomizer) + { + if (Randomizer) + Randomizer->drop(); + Randomizer=r; + if (Randomizer) + Randomizer->grab(); + } +} + +namespace +{ + struct SDefaultRandomizer : public IRandomizer + { + virtual void reset(s32 value=0x0f0f0f0f) + { + os::Randomizer::reset(value); + } + + virtual s32 rand() const + { + return os::Randomizer::rand(); + } + + virtual f32 frand() const + { + return os::Randomizer::frand(); + } + + virtual s32 randMax() const + { + return os::Randomizer::randMax(); + } + }; +} + +//! Creates a new default randomizer. +IRandomizer* CIrrDeviceStub::createDefaultRandomizer() const +{ + IRandomizer* r = new SDefaultRandomizer(); + if (r) + r->reset(); + return r; +} + + +//! Sets the input receiving scene manager. +void CIrrDeviceStub::setInputReceivingSceneManager(scene::ISceneManager* sceneManager) +{ + if (sceneManager) + sceneManager->grab(); + if (InputReceivingSceneManager) + InputReceivingSceneManager->drop(); + + InputReceivingSceneManager = sceneManager; +} + + +//! Checks if the window is running in fullscreen mode +bool CIrrDeviceStub::isFullscreen() const +{ + return CreationParams.Fullscreen; +} + + +//! returns color format +video::ECOLOR_FORMAT CIrrDeviceStub::getColorFormat() const +{ + return video::ECF_R5G6B5; +} + +//! No-op in this implementation +bool CIrrDeviceStub::activateJoysticks(core::array & joystickInfo) +{ + return false; +} + +/*! +*/ +void CIrrDeviceStub::calculateGammaRamp ( u16 *ramp, f32 gamma, f32 relativebrightness, f32 relativecontrast ) +{ + s32 i; + s32 value; + s32 rbright = (s32) ( relativebrightness * (65535.f / 4 ) ); + f32 rcontrast = 1.f / (255.f - ( relativecontrast * 127.5f ) ); + + gamma = gamma > 0.f ? 1.0f / gamma : 0.f; + + for ( i = 0; i < 256; ++i ) + { + value = (s32)(pow( rcontrast * i, gamma)*65535.f + 0.5f ); + ramp[i] = (u16) core::s32_clamp ( value + rbright, 0, 65535 ); + } + +} + +void CIrrDeviceStub::calculateGammaFromRamp ( f32 &gamma, const u16 *ramp ) +{ + /* The following is adapted from a post by Garrett Bass on OpenGL + Gamedev list, March 4, 2000. + */ + f32 sum = 0.0; + s32 i, count = 0; + + gamma = 1.0; + for ( i = 1; i < 256; ++i ) { + if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { + f32 B = (f32)i / 256.f; + f32 A = ramp[i] / 65535.f; + sum += (f32) ( logf(A) / logf(B) ); + count++; + } + } + if ( count && sum ) { + gamma = 1.0f / (sum / count); + } + +} + +//! Set the current Gamma Value for the Display +bool CIrrDeviceStub::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) +{ + return false; +} + +//! Get the current Gamma Value for the Display +bool CIrrDeviceStub::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) +{ + return false; +} + +//! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior. +void CIrrDeviceStub::setDoubleClickTime( u32 timeMs ) +{ + MouseMultiClicks.DoubleClickTime = timeMs; +} + +//! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse. +u32 CIrrDeviceStub::getDoubleClickTime() const +{ + return MouseMultiClicks.DoubleClickTime; +} + +//! Remove all messages pending in the system message loop +void CIrrDeviceStub::clearSystemMessages() +{ +} + + + +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.h new file mode 100644 index 0000000..c6334fe --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceStub.h @@ -0,0 +1,186 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_STUB_H_INCLUDED__ +#define __C_IRR_DEVICE_STUB_H_INCLUDED__ + +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "SIrrCreationParameters.h" +#include "CVideoModeList.h" + +namespace irr +{ + // lots of prototypes: + class ILogger; + class CLogger; + class IRandomizer; + + namespace gui + { + class IGUIEnvironment; + IGUIEnvironment* createGUIEnvironment(io::IFileSystem* fs, + video::IVideoDriver* Driver, IOSOperator* op); + } + + namespace scene + { + ISceneManager* createSceneManager(video::IVideoDriver* driver, + io::IFileSystem* fs, gui::ICursorControl* cc, gui::IGUIEnvironment *gui); + } + + namespace io + { + IFileSystem* createFileSystem(); + } + + namespace video + { + IVideoDriver* createSoftwareDriver(const core::dimension2d& windowSize, + bool fullscreen, io::IFileSystem* io, + video::IImagePresenter* presenter); + IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, video::IImagePresenter* presenter); + IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize); + } + + + + //! Stub for an Irrlicht Device implementation + class CIrrDeviceStub : public IrrlichtDevice + { + public: + + //! constructor + CIrrDeviceStub(const SIrrlichtCreationParameters& param); + + //! destructor + virtual ~CIrrDeviceStub(); + + //! returns the video driver + virtual video::IVideoDriver* getVideoDriver(); + + //! return file system + virtual io::IFileSystem* getFileSystem(); + + //! returns the gui environment + virtual gui::IGUIEnvironment* getGUIEnvironment(); + + //! returns the scene manager + virtual scene::ISceneManager* getSceneManager(); + + //! \return Returns a pointer to the mouse cursor control interface. + virtual gui::ICursorControl* getCursorControl(); + + //! Returns a pointer to a list with all video modes supported by the gfx adapter. + virtual video::IVideoModeList* getVideoModeList(); + + //! Returns a pointer to the ITimer object. With it the current Time can be received. + virtual ITimer* getTimer(); + + //! Returns the version of the engine. + virtual const char* getVersion() const; + + //! send the event to the right receiver + virtual bool postEventFromUser(const SEvent& event); + + //! Sets a new event receiver to receive events + virtual void setEventReceiver(IEventReceiver* receiver); + + //! Returns pointer to the current event receiver. Returns 0 if there is none. + virtual IEventReceiver* getEventReceiver(); + + //! Sets the input receiving scene manager. + /** If set to null, the main scene manager (returned by GetSceneManager()) will receive the input */ + virtual void setInputReceivingSceneManager(scene::ISceneManager* sceneManager); + + //! Returns a pointer to the logger. + virtual ILogger* getLogger(); + + //! Provides access to the engine's currently set randomizer. + virtual IRandomizer* getRandomizer() const; + + //! Sets a new randomizer. + virtual void setRandomizer(IRandomizer* r); + + //! Creates a new default randomizer. + virtual IRandomizer* createDefaultRandomizer() const; + + //! Returns the operation system opertator object. + virtual IOSOperator* getOSOperator(); + + //! Checks if the window is running in fullscreen mode. + virtual bool isFullscreen() const; + + //! get color format of the current window + virtual video::ECOLOR_FORMAT getColorFormat() const; + + //! Activate any joysticks, and generate events for them. + virtual bool activateJoysticks(core::array & joystickInfo); + + //! Set the current Gamma Value for the Display + virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ); + + //! Get the current Gamma Value for the Display + virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ); + + //! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior. + //! When set to 0 no double- and tripleclicks will be generated. + virtual void setDoubleClickTime( u32 timeMs ); + + //! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse. + virtual u32 getDoubleClickTime() const; + + //! Remove all messages pending in the system message loop + virtual void clearSystemMessages(); + + + protected: + + void createGUIAndScene(); + + //! checks version of SDK and prints warning if there might be a problem + bool checkVersion(const char* version); + + //! Compares to the last call of this function to return double and triple clicks. + //! \return Returns only 1,2 or 3. A 4th click will start with 1 again. + virtual u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent ); + + void calculateGammaRamp ( u16 *ramp, f32 gamma, f32 relativebrightness, f32 relativecontrast ); + void calculateGammaFromRamp ( f32 &gamma, const u16 *ramp ); + + video::IVideoDriver* VideoDriver; + gui::IGUIEnvironment* GUIEnvironment; + scene::ISceneManager* SceneManager; + ITimer* Timer; + gui::ICursorControl* CursorControl; + IEventReceiver* UserReceiver; + CLogger* Logger; + IOSOperator* Operator; + IRandomizer* Randomizer; + io::IFileSystem* FileSystem; + scene::ISceneManager* InputReceivingSceneManager; + + struct SMouseMultiClicks + { + SMouseMultiClicks() + : DoubleClickTime(500), CountSuccessiveClicks(0), LastClickTime(0), LastMouseInputEvent(EMIE_COUNT) + {} + + u32 DoubleClickTime; + u32 CountSuccessiveClicks; + u32 LastClickTime; + core::position2di LastClick; + EMOUSE_INPUT_EVENT LastMouseInputEvent; + }; + SMouseMultiClicks MouseMultiClicks; + video::CVideoModeList* VideoModeList; + SIrrlichtCreationParameters CreationParams; + bool Close; + }; + +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.cpp new file mode 100644 index 0000000..93af802 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.cpp @@ -0,0 +1,2068 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + +#include "CIrrDeviceWin32.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" + +#include "CTimer.h" +#include "irrString.h" +#include "COSOperator.h" +#include "dimension2d.h" +#include "IGUISpriteBank.h" +#include +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) +#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ +#define DIRECTINPUT_VERSION 0x0800 +#include +#ifdef _MSC_VER +#pragma comment(lib, "dinput8.lib") +#pragma comment(lib, "dxguid.lib") +#endif +#else +#ifdef _MSC_VER +#pragma comment(lib, "winmm.lib") +#endif +#endif +#endif + +namespace irr +{ + namespace video + { + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + IVideoDriver* createDirectX8Driver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window); + #endif + + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window); + #endif + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceWin32* device); + #endif + } +} // end namespace irr + +namespace irr +{ +struct SJoystickWin32Control +{ + CIrrDeviceWin32* Device; + +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) + IDirectInput8* DirectInputDevice; +#endif +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + struct JoystickInfo + { + u32 Index; +#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ + core::stringc Name; + GUID guid; + LPDIRECTINPUTDEVICE8 lpdijoy; + DIDEVCAPS devcaps; + u8 axisValid[8]; +#else + JOYCAPS Caps; +#endif + }; + core::array ActiveJoysticks; +#endif + + SJoystickWin32Control(CIrrDeviceWin32* dev) : Device(dev) + { +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) + DirectInputDevice=0; + if (DI_OK != (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&DirectInputDevice, NULL))) + { + os::Printer::log("Could not create DirectInput8 Object", ELL_WARNING); + return; + } +#endif + } + ~SJoystickWin32Control() + { +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) + for(u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + LPDIRECTINPUTDEVICE8 dev = ActiveJoysticks[joystick].lpdijoy; + if (dev) + { + dev->Unacquire(); + } + dev->Release(); + } + + if (DirectInputDevice) + DirectInputDevice->Release(); +#endif + } + +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) + static BOOL CALLBACK EnumJoysticks(LPCDIDEVICEINSTANCE lpddi, LPVOID cp) + { + SJoystickWin32Control* p=(SJoystickWin32Control*)cp; + p->directInputAddJoystick(lpddi); + return DIENUM_CONTINUE; + } + void directInputAddJoystick(LPCDIDEVICEINSTANCE lpddi) + { + //Get the GUID of the joystuck + const GUID guid = lpddi->guidInstance; + + JoystickInfo activeJoystick; + activeJoystick.Index=ActiveJoysticks.size(); + activeJoystick.guid=guid; + activeJoystick.Name=lpddi->tszProductName; + if (FAILED(DirectInputDevice->CreateDevice(guid, &activeJoystick.lpdijoy, NULL))) + { + os::Printer::log("Could not create DirectInput device", ELL_WARNING); + return; + } + + activeJoystick.devcaps.dwSize=sizeof(activeJoystick.devcaps); + if (FAILED(activeJoystick.lpdijoy->GetCapabilities(&activeJoystick.devcaps))) + { + os::Printer::log("Could not create DirectInput device", ELL_WARNING); + return; + } + + if (FAILED(activeJoystick.lpdijoy->SetCooperativeLevel(Device->HWnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE))) + { + os::Printer::log("Could not set DirectInput device cooperative level", ELL_WARNING); + return; + } + + if (FAILED(activeJoystick.lpdijoy->SetDataFormat(&c_dfDIJoystick2))) + { + os::Printer::log("Could not set DirectInput device data format", ELL_WARNING); + return; + } + + if (FAILED(activeJoystick.lpdijoy->Acquire())) + { + os::Printer::log("Could not set DirectInput cooperative level", ELL_WARNING); + return; + } + + DIJOYSTATE2 info; + if (FAILED(activeJoystick.lpdijoy->GetDeviceState(sizeof(info),&info))) + { + os::Printer::log("Could not read DirectInput device state", ELL_WARNING); + return; + } + + ZeroMemory(activeJoystick.axisValid,sizeof(activeJoystick.axisValid)); + activeJoystick.axisValid[0]= (info.lX!=0) ? 1 : 0; + activeJoystick.axisValid[1]= (info.lY!=0) ? 1 : 0; + activeJoystick.axisValid[2]= (info.lZ!=0) ? 1 : 0; + activeJoystick.axisValid[3]= (info.lRx!=0) ? 1 : 0; + activeJoystick.axisValid[4]= (info.lRy!=0) ? 1 : 0; + activeJoystick.axisValid[5]= (info.lRz!=0) ? 1 : 0; + + int caxis=0; + for (u8 i=0; i<6; i++) + { + if (activeJoystick.axisValid[i]) + caxis++; + } + + for (u8 i=0; i<(activeJoystick.devcaps.dwAxes)-caxis; i++) + { + if (i+caxis < 8) + activeJoystick.axisValid[i+caxis]=1; + } + + ActiveJoysticks.push_back(activeJoystick); + } +#endif + +void pollJoysticks() +{ +#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ + if(0 == ActiveJoysticks.size()) + return; + + u32 joystick; + DIJOYSTATE2 info; + + for(joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + // needs to be reset for each joystick + // request ALL values and POV as continuous if possible + + const DIDEVCAPS & caps = ActiveJoysticks[joystick].devcaps; + // if no POV is available don't ask for POV values + + if (!FAILED(ActiveJoysticks[joystick].lpdijoy->GetDeviceState(sizeof(info),&info))) + { + SEvent event; + + event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; + event.JoystickEvent.Joystick = (u8)joystick; + + event.JoystickEvent.POV = (u16)info.rgdwPOV[0]; + // set to undefined if no POV value was returned or the value + // is out of range + if ((caps.dwPOVs==0) || (event.JoystickEvent.POV > 35900)) + event.JoystickEvent.POV = 65535; + + for(int axis = 0; axis < SEvent::SJoystickEvent::NUMBER_OF_AXES; ++axis) + event.JoystickEvent.Axis[axis] = 0; + + u16 dxAxis=0; + u16 irrAxis=0; + + while (dxAxis < 6 && irrAxis 0) + axisFound=1; + + if (axisFound) + { + s32 val=axisValue - 32768; + + if (val <-32767) val=-32767; + if (val > 32767) val=32767; + event.JoystickEvent.Axis[irrAxis]=(s16)(val); + irrAxis++; + } + + dxAxis++; + } + + u32 buttons=0; + BYTE* bytebuttons=info.rgbButtons; + for (u16 i=0; i<32; i++) + { + if (bytebuttons[i] >0) + { + buttons |= (1 << i); + } + } + event.JoystickEvent.ButtonStates = buttons; + + (void)Device->postEventFromUser(event); + } + } +#else + if (0 == ActiveJoysticks.size()) + return; + + u32 joystick; + JOYINFOEX info; + + for(joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + // needs to be reset for each joystick + // request ALL values and POV as continuous if possible + info.dwSize = sizeof(info); + info.dwFlags = JOY_RETURNALL|JOY_RETURNPOVCTS; + const JOYCAPS & caps = ActiveJoysticks[joystick].Caps; + // if no POV is available don't ask for POV values + if (!(caps.wCaps & JOYCAPS_HASPOV)) + info.dwFlags &= ~(JOY_RETURNPOV|JOY_RETURNPOVCTS); + if(JOYERR_NOERROR == joyGetPosEx(ActiveJoysticks[joystick].Index, &info)) + { + SEvent event; + + event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; + event.JoystickEvent.Joystick = (u8)joystick; + + event.JoystickEvent.POV = (u16)info.dwPOV; + // set to undefined if no POV value was returned or the value + // is out of range + if (!(info.dwFlags & JOY_RETURNPOV) || (event.JoystickEvent.POV > 35900)) + event.JoystickEvent.POV = 65535; + + for(int axis = 0; axis < SEvent::SJoystickEvent::NUMBER_OF_AXES; ++axis) + event.JoystickEvent.Axis[axis] = 0; + + event.JoystickEvent.ButtonStates = info.dwButtons; + + switch(caps.wNumAxes) + { + default: + case 6: + event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_V] = + (s16)((65535 * (info.dwVpos - caps.wVmin)) / (caps.wVmax - caps.wVmin) - 32768); + + case 5: + event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_U] = + (s16)((65535 * (info.dwUpos - caps.wUmin)) / (caps.wUmax - caps.wUmin) - 32768); + + case 4: + event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_R] = + (s16)((65535 * (info.dwRpos - caps.wRmin)) / (caps.wRmax - caps.wRmin) - 32768); + + case 3: + event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Z] = + (s16)((65535 * (info.dwZpos - caps.wZmin)) / (caps.wZmax - caps.wZmin) - 32768); + + case 2: + event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Y] = + (s16)((65535 * (info.dwYpos - caps.wYmin)) / (caps.wYmax - caps.wYmin) - 32768); + + case 1: + event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_X] = + (s16)((65535 * (info.dwXpos - caps.wXmin)) / (caps.wXmax - caps.wXmin) - 32768); + } + + (void)Device->postEventFromUser(event); + } + } +#endif +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +} + +bool activateJoysticks(core::array & joystickInfo) +{ +#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ + if (!DirectInputDevice || (DirectInputDevice->EnumDevices(DI8DEVCLASS_GAMECTRL, SJoystickWin32Control::EnumJoysticks, this, DIEDFL_ATTACHEDONLY ))) + { + os::Printer::log("Could not enum DirectInput8 controllers", ELL_WARNING); + return false; + } + + for(u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + JoystickInfo& activeJoystick = ActiveJoysticks[joystick]; + SJoystickInfo info; + info.Axes=activeJoystick.devcaps.dwAxes; + info.Buttons=activeJoystick.devcaps.dwButtons; + info.Name=activeJoystick.Name; + info.PovHat = (activeJoystick.devcaps.dwPOVs != 0) + ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; + joystickInfo.push_back(info); + } + return true; +#else + joystickInfo.clear(); + ActiveJoysticks.clear(); + + const u32 numberOfJoysticks = ::joyGetNumDevs(); + JOYINFOEX info; + info.dwSize = sizeof(info); + info.dwFlags = JOY_RETURNALL; + + JoystickInfo activeJoystick; + SJoystickInfo returnInfo; + + joystickInfo.reallocate(numberOfJoysticks); + ActiveJoysticks.reallocate(numberOfJoysticks); + + u32 joystick = 0; + for(; joystick < numberOfJoysticks; ++joystick) + { + if(JOYERR_NOERROR == joyGetPosEx(joystick, &info) + && + JOYERR_NOERROR == joyGetDevCaps(joystick, + &activeJoystick.Caps, + sizeof(activeJoystick.Caps))) + { + activeJoystick.Index = joystick; + ActiveJoysticks.push_back(activeJoystick); + + returnInfo.Joystick = (u8)joystick; + returnInfo.Axes = activeJoystick.Caps.wNumAxes; + returnInfo.Buttons = activeJoystick.Caps.wNumButtons; + returnInfo.Name = activeJoystick.Caps.szPname; + returnInfo.PovHat = ((activeJoystick.Caps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV) + ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; + + joystickInfo.push_back(returnInfo); + } + } + + for(joystick = 0; joystick < joystickInfo.size(); ++joystick) + { + char logString[256]; + (void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'", + joystick, joystickInfo[joystick].Axes, + joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); + os::Printer::log(logString, ELL_INFORMATION); + } + + return true; +#endif +#else + return false; +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +} +}; +} // end namespace irr + +// Get the codepage from the locale language id +// Based on the table from http://www.science.co.il/Language/Locale-Codes.asp?s=decimal +static unsigned int LocaleIdToCodepage(unsigned int lcid) +{ + switch ( lcid ) + { + case 1098: // Telugu + case 1095: // Gujarati + case 1094: // Punjabi + case 1103: // Sanskrit + case 1111: // Konkani + case 1114: // Syriac + case 1099: // Kannada + case 1102: // Marathi + case 1125: // Divehi + case 1067: // Armenian + case 1081: // Hindi + case 1079: // Georgian + case 1097: // Tamil + return 0; + case 1054: // Thai + return 874; + case 1041: // Japanese + return 932; + case 2052: // Chinese (PRC) + case 4100: // Chinese (Singapore) + return 936; + case 1042: // Korean + return 949; + case 5124: // Chinese (Macau S.A.R.) + case 3076: // Chinese (Hong Kong S.A.R.) + case 1028: // Chinese (Taiwan) + return 950; + case 1048: // Romanian + case 1060: // Slovenian + case 1038: // Hungarian + case 1051: // Slovak + case 1045: // Polish + case 1052: // Albanian + case 2074: // Serbian (Latin) + case 1050: // Croatian + case 1029: // Czech + return 1250; + case 1104: // Mongolian (Cyrillic) + case 1071: // FYRO Macedonian + case 2115: // Uzbek (Cyrillic) + case 1058: // Ukrainian + case 2092: // Azeri (Cyrillic) + case 1092: // Tatar + case 1087: // Kazakh + case 1059: // Belarusian + case 1088: // Kyrgyz (Cyrillic) + case 1026: // Bulgarian + case 3098: // Serbian (Cyrillic) + case 1049: // Russian + return 1251; + case 8201: // English (Jamaica) + case 3084: // French (Canada) + case 1036: // French (France) + case 5132: // French (Luxembourg) + case 5129: // English (New Zealand) + case 6153: // English (Ireland) + case 1043: // Dutch (Netherlands) + case 9225: // English (Caribbean) + case 4108: // French (Switzerland) + case 4105: // English (Canada) + case 1110: // Galician + case 10249: // English (Belize) + case 3079: // German (Austria) + case 6156: // French (Monaco) + case 12297: // English (Zimbabwe) + case 1069: // Basque + case 2067: // Dutch (Belgium) + case 2060: // French (Belgium) + case 1035: // Finnish + case 1080: // Faroese + case 1031: // German (Germany) + case 3081: // English (Australia) + case 1033: // English (United States) + case 2057: // English (United Kingdom) + case 1027: // Catalan + case 11273: // English (Trinidad) + case 7177: // English (South Africa) + case 1030: // Danish + case 13321: // English (Philippines) + case 15370: // Spanish (Paraguay) + case 9226: // Spanish (Colombia) + case 5130: // Spanish (Costa Rica) + case 7178: // Spanish (Dominican Republic) + case 12298: // Spanish (Ecuador) + case 17418: // Spanish (El Salvador) + case 4106: // Spanish (Guatemala) + case 18442: // Spanish (Honduras) + case 3082: // Spanish (International Sort) + case 13322: // Spanish (Chile) + case 19466: // Spanish (Nicaragua) + case 2058: // Spanish (Mexico) + case 10250: // Spanish (Peru) + case 20490: // Spanish (Puerto Rico) + case 1034: // Spanish (Traditional Sort) + case 14346: // Spanish (Uruguay) + case 8202: // Spanish (Venezuela) + case 1089: // Swahili + case 1053: // Swedish + case 2077: // Swedish (Finland) + case 5127: // German (Liechtenstein) + case 1078: // Afrikaans + case 6154: // Spanish (Panama) + case 4103: // German (Luxembourg) + case 16394: // Spanish (Bolivia) + case 2055: // German (Switzerland) + case 1039: // Icelandic + case 1057: // Indonesian + case 1040: // Italian (Italy) + case 2064: // Italian (Switzerland) + case 2068: // Norwegian (Nynorsk) + case 11274: // Spanish (Argentina) + case 1046: // Portuguese (Brazil) + case 1044: // Norwegian (Bokmal) + case 1086: // Malay (Malaysia) + case 2110: // Malay (Brunei Darussalam) + case 2070: // Portuguese (Portugal) + return 1252; + case 1032: // Greek + return 1253; + case 1091: // Uzbek (Latin) + case 1068: // Azeri (Latin) + case 1055: // Turkish + return 1254; + case 1037: // Hebrew + return 1255; + case 5121: // Arabic (Algeria) + case 15361: // Arabic (Bahrain) + case 9217: // Arabic (Yemen) + case 3073: // Arabic (Egypt) + case 2049: // Arabic (Iraq) + case 11265: // Arabic (Jordan) + case 13313: // Arabic (Kuwait) + case 12289: // Arabic (Lebanon) + case 4097: // Arabic (Libya) + case 6145: // Arabic (Morocco) + case 8193: // Arabic (Oman) + case 16385: // Arabic (Qatar) + case 1025: // Arabic (Saudi Arabia) + case 10241: // Arabic (Syria) + case 14337: // Arabic (U.A.E.) + case 1065: // Farsi + case 1056: // Urdu + case 7169: // Arabic (Tunisia) + return 1256; + case 1061: // Estonian + case 1062: // Latvian + case 1063: // Lithuanian + return 1257; + case 1066: // Vietnamese + return 1258; + } + return 65001; // utf-8 +} + +namespace +{ + struct SEnvMapper + { + HWND hWnd; + irr::CIrrDeviceWin32* irrDev; + }; + irr::core::list EnvMap; + + HKL KEYBOARD_INPUT_HKL=0; + unsigned int KEYBOARD_INPUT_CODEPAGE = 1252; +} + +SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) +{ + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == hWnd) + return &(*it); + + return 0; +} + + +irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd) +{ + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == hWnd) + return (*it).irrDev; + + return 0; +} + + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef WM_MOUSEWHEEL + #define WM_MOUSEWHEEL 0x020A + #endif + #ifndef WHEEL_DELTA + #define WHEEL_DELTA 120 + #endif + + irr::CIrrDeviceWin32* dev = 0; + irr::SEvent event; + + static irr::s32 ClickCount=0; + if (GetCapture() != hWnd && ClickCount > 0) + ClickCount = 0; + + + struct messageMap + { + irr::s32 group; + UINT winMessage; + irr::s32 irrMessage; + }; + + static messageMap mouseMap[] = + { + {0, WM_LBUTTONDOWN, irr::EMIE_LMOUSE_PRESSED_DOWN}, + {1, WM_LBUTTONUP, irr::EMIE_LMOUSE_LEFT_UP}, + {0, WM_RBUTTONDOWN, irr::EMIE_RMOUSE_PRESSED_DOWN}, + {1, WM_RBUTTONUP, irr::EMIE_RMOUSE_LEFT_UP}, + {0, WM_MBUTTONDOWN, irr::EMIE_MMOUSE_PRESSED_DOWN}, + {1, WM_MBUTTONUP, irr::EMIE_MMOUSE_LEFT_UP}, + {2, WM_MOUSEMOVE, irr::EMIE_MOUSE_MOVED}, + {3, WM_MOUSEWHEEL, irr::EMIE_MOUSE_WHEEL}, + {-1, 0, 0} + }; + + // handle grouped events + messageMap * m = mouseMap; + while ( m->group >=0 && m->winMessage != message ) + m += 1; + + if ( m->group >= 0 ) + { + if ( m->group == 0 ) // down + { + ClickCount++; + SetCapture(hWnd); + } + else + if ( m->group == 1 ) // up + { + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + } + + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT) m->irrMessage; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; +#if(_WIN32_WINNT >= 0x0500) + if (wParam & MK_XBUTTON1) + event.MouseInput.ButtonStates |= irr::EMBSM_EXTRA1; + if (wParam & MK_XBUTTON2) + event.MouseInput.ButtonStates |= irr::EMBSM_EXTRA2; +#endif + event.MouseInput.Wheel = 0.f; + + // wheel + if ( m->group == 3 ) + { + POINT p; // fixed by jox + p.x = 0; p.y = 0; + ClientToScreen(hWnd, &p); + event.MouseInput.X -= p.x; + event.MouseInput.Y -= p.y; + event.MouseInput.Wheel = ((irr::f32)((short)HIWORD(wParam))) / (irr::f32)WHEEL_DELTA; + } + + dev = getDeviceFromHWnd(hWnd); + if (dev) + { + dev->postEventFromUser(event); + + if ( event.MouseInput.Event >= irr::EMIE_LMOUSE_PRESSED_DOWN && event.MouseInput.Event <= irr::EMIE_MMOUSE_PRESSED_DOWN ) + { + irr::u32 clicks = dev->checkSuccessiveClicks(event.MouseInput.X, event.MouseInput.Y, event.MouseInput.Event); + if ( clicks == 2 ) + { + event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_LMOUSE_DOUBLE_CLICK + event.MouseInput.Event-irr::EMIE_LMOUSE_PRESSED_DOWN); + dev->postEventFromUser(event); + } + else if ( clicks == 3 ) + { + event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_LMOUSE_TRIPLE_CLICK + event.MouseInput.Event-irr::EMIE_LMOUSE_PRESSED_DOWN); + dev->postEventFromUser(event); + } + } + } + return 0; + } + + switch (message) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + } + return 0; + + case WM_ERASEBKGND: + return 0; + + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + case WM_KEYDOWN: + case WM_KEYUP: + { + BYTE allKeys[256]; + + event.EventType = irr::EET_KEY_INPUT_EVENT; + event.KeyInput.Key = (irr::EKEY_CODE)wParam; + event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN); + + const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine. + if ( event.KeyInput.Key == irr::KEY_SHIFT ) + { + // this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead. + event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); + } + if ( event.KeyInput.Key == irr::KEY_CONTROL ) + { + event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); + // some keyboards will just return LEFT for both - left and right keys. So also check extend bit. + if (lParam & 0x1000000) + event.KeyInput.Key = irr::KEY_RCONTROL; + } + if ( event.KeyInput.Key == irr::KEY_MENU ) + { + event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); + if (lParam & 0x1000000) + event.KeyInput.Key = irr::KEY_RMENU; + } + + GetKeyboardState(allKeys); + + event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0); + event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0); + + // Handle unicode and deadkeys in a way that works since Windows 95 and nt4.0 + // Using ToUnicode instead would be shorter, but would to my knowledge not run on 95 and 98. + WORD keyChars[2]; + UINT scanCode = HIWORD(lParam); + int conversionResult = ToAsciiEx(wParam,scanCode,allKeys,keyChars,0,KEYBOARD_INPUT_HKL); + if (conversionResult == 1) + { + WORD unicodeChar; + MultiByteToWideChar( + KEYBOARD_INPUT_CODEPAGE, + MB_PRECOMPOSED, // default + (LPCSTR)keyChars, + sizeof(keyChars), + (WCHAR*)&unicodeChar, + 1 ); + event.KeyInput.Char = unicodeChar; + } + else + event.KeyInput.Char = 0; + + // allow composing characters like '@' with Alt Gr on non-US keyboards + if ((allKeys[VK_MENU] & 0x80) != 0) + event.KeyInput.Control = 0; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + + if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP) + return DefWindowProc(hWnd, message, wParam, lParam); + else + return 0; + } + + case WM_SIZE: + { + // resize + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->OnResized(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + case WM_SYSCOMMAND: + // prevent screensaver or monitor powersave mode from starting + if ((wParam & 0xFFF0) == SC_SCREENSAVE || + (wParam & 0xFFF0) == SC_MONITORPOWER || + (wParam & 0xFFF0) == SC_KEYMENU + ) + return 0; + + break; + + case WM_ACTIVATE: + // we need to take care for screen changes, e.g. Alt-Tab + dev = getDeviceFromHWnd(hWnd); + if (dev && dev->isFullscreen()) + { + if ((wParam&0xFF)==WA_INACTIVE) + { + // If losing focus we minimize the app to show other one + ShowWindow(hWnd,SW_MINIMIZE); + // and switch back to default resolution + dev->switchToFullScreen(true); + } + else + { + // Otherwise we retore the fullscreen Irrlicht app + SetForegroundWindow(hWnd); + ShowWindow(hWnd, SW_RESTORE); + // and set the fullscreen resolution again + dev->switchToFullScreen(); + } + } + break; + + case WM_USER: + event.EventType = irr::EET_USER_EVENT; + event.UserEvent.UserData1 = (irr::s32)wParam; + event.UserEvent.UserData2 = (irr::s32)lParam; + dev = getDeviceFromHWnd(hWnd); + + if (dev) + dev->postEventFromUser(event); + + return 0; + + case WM_SETCURSOR: + // because Windows forgot about that in the meantime + dev = getDeviceFromHWnd(hWnd); + if (dev) + { + dev->getCursorControl()->setActiveIcon( dev->getCursorControl()->getActiveIcon() ); + dev->getCursorControl()->setVisible( dev->getCursorControl()->isVisible() ); + } + break; + + case WM_INPUTLANGCHANGE: + // get the new codepage used for keyboard input + KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); + KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); + return 0; + } + return DefWindowProc(hWnd, message, wParam, lParam); +} + + +namespace irr +{ + +//! constructor +CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) +: CIrrDeviceStub(params), HWnd(0), ChangedToFullScreen(false), Resized(false), + ExternalWindow(false), Win32CursorControl(0), JoyControl(0) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceWin32"); + #endif + + // get windows version and create OS operator + core::stringc winversion; + getWindowsVersion(winversion); + Operator = new COSOperator(winversion); + os::Printer::log(winversion.c_str(), ELL_INFORMATION); + + // get handle to exe file + HINSTANCE hInstance = GetModuleHandle(0); + + // Store original desktop mode. + + memset(&DesktopMode, 0, sizeof(DesktopMode)); + DesktopMode.dmSize = sizeof(DesktopMode); + + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DesktopMode); + + // create the window if we need to and we do not use the null device + if (!CreationParams.WindowId && CreationParams.DriverType != video::EDT_NULL) + { + const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); + + // Register Class + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = NULL; + wcex.hCursor = 0; // LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = 0; + wcex.lpszClassName = ClassName; + wcex.hIconSm = 0; + + // if there is an icon, load it + wcex.hIcon = (HICON)LoadImage(hInstance, __TEXT("irrlicht.ico"), IMAGE_ICON, 0,0, LR_LOADFROMFILE); + + RegisterClassEx(&wcex); + + // calculate client size + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = CreationParams.WindowSize.Width; + clientSize.bottom = CreationParams.WindowSize.Height; + + DWORD style = WS_POPUP; + + if (!CreationParams.Fullscreen) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + AdjustWindowRect(&clientSize, style, FALSE); + + const s32 realWidth = clientSize.right - clientSize.left; + const s32 realHeight = clientSize.bottom - clientSize.top; + + s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; + s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + + if ( windowLeft < 0 ) + windowLeft = 0; + if ( windowTop < 0 ) + windowTop = 0; // make sure window menus are in screen on creation + + if (CreationParams.Fullscreen) + { + windowLeft = 0; + windowTop = 0; + } + + // create window + + HWnd = CreateWindow( ClassName, __TEXT(""), style, windowLeft, windowTop, + realWidth, realHeight, NULL, NULL, hInstance, NULL); + CreationParams.WindowId = HWnd; +// CreationParams.WindowSize.Width = realWidth; +// CreationParams.WindowSize.Height = realHeight; + + ShowWindow(HWnd, SW_SHOWNORMAL); + UpdateWindow(HWnd); + + // fix ugly ATI driver bugs. Thanks to ariaci + MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE); + + // make sure everything gets updated to the real sizes + Resized = true; + } + else if (CreationParams.WindowId) + { + // attach external window + HWnd = static_cast(CreationParams.WindowId); + RECT r; + GetWindowRect(HWnd, &r); + CreationParams.WindowSize.Width = r.right - r.left; + CreationParams.WindowSize.Height = r.bottom - r.top; + CreationParams.Fullscreen = false; + ExternalWindow = true; + } + + // create cursor control + + Win32CursorControl = new CCursorControl(this, CreationParams.WindowSize, HWnd, CreationParams.Fullscreen); + CursorControl = Win32CursorControl; + JoyControl = new SJoystickWin32Control(this); + + // initialize doubleclicks with system values + MouseMultiClicks.DoubleClickTime = GetDoubleClickTime(); + + // create driver + + createDriver(); + + if (VideoDriver) + createGUIAndScene(); + + // register environment + + SEnvMapper em; + em.irrDev = this; + em.hWnd = HWnd; + EnvMap.push_back(em); + + // set this as active window + if (!ExternalWindow) + { + SetActiveWindow(HWnd); + SetForegroundWindow(HWnd); + } + + // get the codepage used for keyboard input + KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); + KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); + + // inform driver about the window size etc. + resizeIfNecessary(); +} + + +//! destructor +CIrrDeviceWin32::~CIrrDeviceWin32() +{ + delete JoyControl; + + // unregister environment + + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + { + if ((*it).hWnd == HWnd) + { + EnvMap.erase(it); + break; + } + } + + switchToFullScreen(true); +} + + +//! create the driver +void CIrrDeviceWin32::createDriver() +{ + switch(CreationParams.DriverType) + { + case video::EDT_DIRECT3D8: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + + VideoDriver = video::createDirectX8Driver(CreationParams, FileSystem, HWnd); + + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + + break; + + case video::EDT_DIRECT3D9: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + + VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, HWnd); + + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + + break; + + case video::EDT_OPENGL: + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + switchToFullScreen(); + + VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); + if (!VideoDriver) + { + os::Printer::log("Could not create OpenGL driver.", ELL_ERROR); + } + #else + os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_SOFTWARE: + + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + switchToFullScreen(); + + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + #else + os::Printer::log("Software driver was not compiled in.", ELL_ERROR); + #endif + + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + switchToFullScreen(); + + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_NULL: + // create null driver + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceWin32::run() +{ + os::Timer::tick(); + + static_cast(CursorControl)->update(); + + handleSystemMessages(); + + if (!Close) + resizeIfNecessary(); + + if(!Close && JoyControl) + JoyControl->pollJoysticks(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return !Close; +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceWin32::yield() +{ + Sleep(1); +} + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceWin32::sleep(u32 timeMs, bool pauseTimer) +{ + const bool wasStopped = Timer ? Timer->isStopped() : true; + if (pauseTimer && !wasStopped) + Timer->stop(); + + Sleep(timeMs); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +void CIrrDeviceWin32::resizeIfNecessary() +{ + if (!Resized || !getVideoDriver()) + return; + + RECT r; + GetClientRect(HWnd, &r); + + char tmp[255]; + + if (r.right < 2 || r.bottom < 2) + { + sprintf(tmp, "Ignoring resize operation to (%ld %ld)", r.right, r.bottom); + os::Printer::log(tmp); + } + else + { + sprintf(tmp, "Resizing window (%ld %ld)", r.right, r.bottom); + os::Printer::log(tmp); + + getVideoDriver()->OnResize(irr::core::dimension2du((u32)r.right, (u32)r.bottom)); + getWin32CursorControl()->OnResize(getVideoDriver()->getScreenSize()); + } + + Resized = false; +} + + +//! sets the caption of the window +void CIrrDeviceWin32::setWindowCaption(const wchar_t* text) +{ + // We use SendMessage instead of SetText to ensure proper + // function even in cases where the HWND was created in a different thread + DWORD_PTR dwResult; + SendMessageTimeoutW(HWnd, WM_SETTEXT, 0, + reinterpret_cast(text), + SMTO_ABORTIFHUNG, 2000, &dwResult); +} + + +//! presents a surface in the client area +bool CIrrDeviceWin32::present(video::IImage* image, void* windowId, core::rect* src) +{ + HWND hwnd = HWnd; + if ( windowId ) + hwnd = reinterpret_cast(windowId); + + HDC dc = GetDC(hwnd); + + if ( dc ) + { + RECT rect; + GetClientRect(hwnd, &rect); + const void* memory = (const void *)image->lock(); + + BITMAPV4HEADER bi; + ZeroMemory (&bi, sizeof(bi)); + bi.bV4Size = sizeof(BITMAPINFOHEADER); + bi.bV4BitCount = (WORD)image->getBitsPerPixel(); + bi.bV4Planes = 1; + bi.bV4Width = image->getDimension().Width; + bi.bV4Height = -((s32)image->getDimension().Height); + bi.bV4V4Compression = BI_BITFIELDS; + bi.bV4AlphaMask = image->getAlphaMask(); + bi.bV4RedMask = image->getRedMask(); + bi.bV4GreenMask = image->getGreenMask(); + bi.bV4BlueMask = image->getBlueMask(); + + if ( src ) + { + StretchDIBits(dc, 0,0, rect.right, rect.bottom, + src->UpperLeftCorner.X, src->UpperLeftCorner.Y, + src->getWidth(), src->getHeight(), + memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); + } + else + { + StretchDIBits(dc, 0,0, rect.right, rect.bottom, + 0, 0, image->getDimension().Width, image->getDimension().Height, + memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); + } + + image->unlock(); + + ReleaseDC(hwnd, dc); + } + return true; +} + + +//! notifies the device that it should close itself +void CIrrDeviceWin32::closeDevice() +{ + MSG msg; + PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); + PostQuitMessage(0); + PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); + if (!ExternalWindow) + { + DestroyWindow(HWnd); + const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); + HINSTANCE hInstance = GetModuleHandle(0); + UnregisterClass(ClassName, hInstance); + } + Close=true; +} + + +//! returns if window is active. if not, nothing needs to be drawn +bool CIrrDeviceWin32::isWindowActive() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return (GetActiveWindow() == HWnd); +} + + +//! returns if window has focus +bool CIrrDeviceWin32::isWindowFocused() const +{ + bool ret = (GetFocus() == HWnd); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! returns if window is minimized +bool CIrrDeviceWin32::isWindowMinimized() const +{ + WINDOWPLACEMENT plc; + plc.length=sizeof(WINDOWPLACEMENT); + bool ret=false; + if (GetWindowPlacement(HWnd,&plc)) + ret=(plc.showCmd & SW_SHOWMINIMIZED)!=0; + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! switches to fullscreen +bool CIrrDeviceWin32::switchToFullScreen(bool reset) +{ + if (!CreationParams.Fullscreen) + return true; + + if (reset) + { + if (ChangedToFullScreen) + { + return (ChangeDisplaySettings(&DesktopMode,0)==DISP_CHANGE_SUCCESSFUL); + } + else + return true; + } + + // use default values from current setting + + DEVMODE dm; + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); + dm.dmPelsWidth = CreationParams.WindowSize.Width; + dm.dmPelsHeight = CreationParams.WindowSize.Height; + dm.dmBitsPerPel = CreationParams.Bits; + dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + + LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); + if (res != DISP_CHANGE_SUCCESSFUL) + { // try again without forcing display frequency + dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); + } + + bool ret = false; + switch(res) + { + case DISP_CHANGE_SUCCESSFUL: + ChangedToFullScreen = true; + ret = true; + break; + case DISP_CHANGE_RESTART: + os::Printer::log("Switch to fullscreen: The computer must be restarted in order for the graphics mode to work.", ELL_ERROR); + break; + case DISP_CHANGE_BADFLAGS: + os::Printer::log("Switch to fullscreen: An invalid set of flags was passed in.", ELL_ERROR); + break; + case DISP_CHANGE_BADPARAM: + os::Printer::log("Switch to fullscreen: An invalid parameter was passed in. This can include an invalid flag or combination of flags.", ELL_ERROR); + break; + case DISP_CHANGE_FAILED: + os::Printer::log("Switch to fullscreen: The display driver failed the specified graphics mode.", ELL_ERROR); + break; + case DISP_CHANGE_BADMODE: + os::Printer::log("Switch to fullscreen: The graphics mode is not supported.", ELL_ERROR); + break; + default: + os::Printer::log("An unknown error occured while changing to fullscreen.", ELL_ERROR); + break; + } + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! returns the win32 cursor control +CIrrDeviceWin32::CCursorControl* CIrrDeviceWin32::getWin32CursorControl() +{ + return Win32CursorControl; +} + + +//! \return Returns a pointer to a list with all video modes supported +//! by the gfx adapter. +video::IVideoModeList* CIrrDeviceWin32::getVideoModeList() +{ + if (!VideoModeList->getVideoModeCount()) + { + // enumerate video modes. + DWORD i=0; + DEVMODE mode; + memset(&mode, 0, sizeof(mode)); + mode.dmSize = sizeof(mode); + + while (EnumDisplaySettings(NULL, i, &mode)) + { + VideoModeList->addMode(core::dimension2d(mode.dmPelsWidth, mode.dmPelsHeight), + mode.dmBitsPerPel); + + ++i; + } + + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode)) + VideoModeList->setDesktop(mode.dmBitsPerPel, core::dimension2d(mode.dmPelsWidth, mode.dmPelsHeight)); + } + + return VideoModeList; +} + +typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); +// Needed for old windows apis +// depending on the SDK version and compilers some defines might be available +// or not +#ifndef PRODUCT_ULTIMATE +#define PRODUCT_ULTIMATE 0x00000001 +#define PRODUCT_HOME_BASIC 0x00000002 +#define PRODUCT_HOME_PREMIUM 0x00000003 +#define PRODUCT_ENTERPRISE 0x00000004 +#define PRODUCT_HOME_BASIC_N 0x00000005 +#define PRODUCT_BUSINESS 0x00000006 +#define PRODUCT_STARTER 0x0000000B +#endif +#ifndef PRODUCT_ULTIMATE_N +#define PRODUCT_BUSINESS_N 0x00000010 +#define PRODUCT_HOME_PREMIUM_N 0x0000001A +#define PRODUCT_ENTERPRISE_N 0x0000001B +#define PRODUCT_ULTIMATE_N 0x0000001C +#endif +#ifndef PRODUCT_STARTER_N +#define PRODUCT_STARTER_N 0x0000002F +#endif +#ifndef PRODUCT_PROFESSIONAL +#define PRODUCT_PROFESSIONAL 0x00000030 +#define PRODUCT_PROFESSIONAL_N 0x00000031 +#endif +#ifndef PRODUCT_ULTIMATE_E +#define PRODUCT_STARTER_E 0x00000042 +#define PRODUCT_HOME_BASIC_E 0x00000043 +#define PRODUCT_HOME_PREMIUM_E 0x00000044 +#define PRODUCT_PROFESSIONAL_E 0x00000045 +#define PRODUCT_ENTERPRISE_E 0x00000046 +#define PRODUCT_ULTIMATE_E 0x00000047 +#endif + +void CIrrDeviceWin32::getWindowsVersion(core::stringc& out) +{ + OSVERSIONINFOEX osvi; + PGPI pGPI; + BOOL bOsVersionInfoEx; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi); + if (!bOsVersionInfoEx) + { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (! GetVersionEx((OSVERSIONINFO *) &osvi)) + return; + } + + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_NT: + if (osvi.dwMajorVersion <= 4) + out.append("Microsoft Windows NT "); + else + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + out.append("Microsoft Windows 2000 "); + else + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + out.append("Microsoft Windows XP "); + else + if (osvi.dwMajorVersion == 6 ) + { + if (osvi.dwMinorVersion == 0) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + out.append("Microsoft Windows Vista "); + else + out.append("Microsoft Windows Server 2008 "); + } + else if (osvi.dwMinorVersion == 1) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + out.append("Microsoft Windows 7 "); + else + out.append("Microsoft Windows Server 2008 R2 "); + } + } + + if (bOsVersionInfoEx) + { + if (osvi.dwMajorVersion == 6) + { + DWORD dwType; + pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); + pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); + + switch (dwType) + { + case PRODUCT_ULTIMATE: + case PRODUCT_ULTIMATE_E: + case PRODUCT_ULTIMATE_N: + out.append("Ultimate Edition "); + break; + case PRODUCT_PROFESSIONAL: + case PRODUCT_PROFESSIONAL_E: + case PRODUCT_PROFESSIONAL_N: + out.append("Professional Edition "); + break; + case PRODUCT_HOME_BASIC: + case PRODUCT_HOME_BASIC_E: + case PRODUCT_HOME_BASIC_N: + out.append("Home Basic Edition "); + break; + case PRODUCT_HOME_PREMIUM: + case PRODUCT_HOME_PREMIUM_E: + case PRODUCT_HOME_PREMIUM_N: + out.append("Home Premium Edition "); + break; + case PRODUCT_ENTERPRISE: + case PRODUCT_ENTERPRISE_E: + case PRODUCT_ENTERPRISE_N: + out.append("Enterprise Edition "); + break; + case PRODUCT_BUSINESS: + case PRODUCT_BUSINESS_N: + out.append("Business Edition "); + break; + case PRODUCT_STARTER: + case PRODUCT_STARTER_E: + case PRODUCT_STARTER_N: + out.append("Starter Edition "); + break; + } + } +#ifdef VER_SUITE_ENTERPRISE + else + if (osvi.wProductType == VER_NT_WORKSTATION) + { +#ifndef __BORLANDC__ + if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) + out.append("Personal "); + else + out.append("Professional "); +#endif + } + else if (osvi.wProductType == VER_NT_SERVER) + { + if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) + out.append("DataCenter Server "); + else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) + out.append("Advanced Server "); + else + out.append("Server "); + } +#endif + } + else + { + HKEY hKey; + char szProductType[80]; + DWORD dwBufLen; + + RegOpenKeyEx( HKEY_LOCAL_MACHINE, + __TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), + 0, KEY_QUERY_VALUE, &hKey ); + RegQueryValueEx( hKey, __TEXT("ProductType"), NULL, NULL, + (LPBYTE) szProductType, &dwBufLen); + RegCloseKey( hKey ); + + if (_strcmpi( "WINNT", szProductType) == 0 ) + out.append("Professional "); + if (_strcmpi( "LANMANNT", szProductType) == 0) + out.append("Server "); + if (_strcmpi( "SERVERNT", szProductType) == 0) + out.append("Advanced Server "); + } + + // Display version, service pack (if any), and build number. + + char tmp[255]; + + if (osvi.dwMajorVersion <= 4 ) + { + sprintf(tmp, "version %ld.%ld %s (Build %ld)", + osvi.dwMajorVersion, + osvi.dwMinorVersion, + irr::core::stringc(osvi.szCSDVersion).c_str(), + osvi.dwBuildNumber & 0xFFFF); + } + else + { + sprintf(tmp, "%s (Build %ld)", irr::core::stringc(osvi.szCSDVersion).c_str(), + osvi.dwBuildNumber & 0xFFFF); + } + + out.append(tmp); + break; + + case VER_PLATFORM_WIN32_WINDOWS: + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) + { + out.append("Microsoft Windows 95 "); + if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) + out.append("OSR2 " ); + } + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) + { + out.append("Microsoft Windows 98 "); + if ( osvi.szCSDVersion[1] == 'A' ) + out.append( "SE " ); + } + + if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) + out.append("Microsoft Windows Me "); + + break; + + case VER_PLATFORM_WIN32s: + out.append("Microsoft Win32s "); + break; + } +} + +//! Notifies the device, that it has been resized +void CIrrDeviceWin32::OnResized() +{ + Resized = true; +} + +//! Sets if the window should be resizable in windowed mode. +void CIrrDeviceWin32::setResizable(bool resize) +{ + if (ExternalWindow || !getVideoDriver() || CreationParams.Fullscreen) + return; + + LONG_PTR style = WS_POPUP; + + if (!resize) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + else + style = WS_THICKFRAME | WS_SYSMENU | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; + + if (!SetWindowLongPtr(HWnd, GWL_STYLE, style)) + os::Printer::log("Could not change window style."); + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = getVideoDriver()->getScreenSize().Width; + clientSize.bottom = getVideoDriver()->getScreenSize().Height; + + AdjustWindowRect(&clientSize, style, FALSE); + + const s32 realWidth = clientSize.right - clientSize.left; + const s32 realHeight = clientSize.bottom - clientSize.top; + + const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; + const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + + SetWindowPos(HWnd, HWND_TOP, windowLeft, windowTop, realWidth, realHeight, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_SHOWWINDOW); + + static_cast(CursorControl)->updateBorderSize(CreationParams.Fullscreen, resize); +} + + +//! Minimizes the window. +void CIrrDeviceWin32::minimizeWindow() +{ + WINDOWPLACEMENT wndpl; + wndpl.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(HWnd, &wndpl); + wndpl.showCmd = SW_SHOWMINNOACTIVE; + SetWindowPlacement(HWnd, &wndpl); +} + + +//! Maximizes the window. +void CIrrDeviceWin32::maximizeWindow() +{ + WINDOWPLACEMENT wndpl; + wndpl.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(HWnd, &wndpl); + wndpl.showCmd = SW_SHOWMAXIMIZED; + SetWindowPlacement(HWnd, &wndpl); +} + + +//! Restores the window to its original size. +void CIrrDeviceWin32::restoreWindow() +{ + WINDOWPLACEMENT wndpl; + wndpl.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(HWnd, &wndpl); + wndpl.showCmd = SW_SHOWNORMAL; + SetWindowPlacement(HWnd, &wndpl); +} + + +bool CIrrDeviceWin32::activateJoysticks(core::array & joystickInfo) +{ + if (JoyControl) + return JoyControl->activateJoysticks(joystickInfo); + else + return false; +} + + +//! Set the current Gamma Value for the Display +bool CIrrDeviceWin32::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) +{ + bool r; + u16 ramp[3][256]; + + calculateGammaRamp( ramp[0], red, brightness, contrast ); + calculateGammaRamp( ramp[1], green, brightness, contrast ); + calculateGammaRamp( ramp[2], blue, brightness, contrast ); + + HDC dc = GetDC(0); + r = SetDeviceGammaRamp ( dc, ramp ) == TRUE; + ReleaseDC(HWnd, dc); + return r; +} + +//! Get the current Gamma Value for the Display +bool CIrrDeviceWin32::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) +{ + bool r; + u16 ramp[3][256]; + + HDC dc = GetDC(0); + r = GetDeviceGammaRamp ( dc, ramp ) == TRUE; + ReleaseDC(HWnd, dc); + + if ( r ) + { + calculateGammaFromRamp(red, ramp[0]); + calculateGammaFromRamp(green, ramp[1]); + calculateGammaFromRamp(blue, ramp[2]); + } + + brightness = 0.f; + contrast = 0.f; + + return r; + +} + + +//! Process system events +void CIrrDeviceWin32::handleSystemMessages() +{ + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + // No message translation because we don't use WM_CHAR and it would conflict with our + // deadkey handling. + + if (ExternalWindow && msg.hwnd == HWnd) + WndProc(HWnd, msg.message, msg.wParam, msg.lParam); + else + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + Close = true; + } +} + + +//! Remove all messages pending in the system message loop +void CIrrDeviceWin32::clearSystemMessages() +{ + MSG msg; + while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) + {} + while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) + {} +} + +// shows last error in a messagebox to help internal debugging. +void CIrrDeviceWin32::ReportLastWinApiError() +{ + // (based on code from ovidiucucu from http://www.codeguru.com/forum/showthread.php?t=318721) + LPCTSTR pszCaption = __TEXT("Windows SDK Error Report"); + DWORD dwError = GetLastError(); + + if(NOERROR == dwError) + { + MessageBox(NULL, __TEXT("No error"), pszCaption, MB_OK); + } + else + { + const DWORD dwFormatControl = FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM; + + LPVOID pTextBuffer = NULL; + DWORD dwCount = FormatMessage(dwFormatControl, + NULL, + dwError, + 0, + (LPTSTR) &pTextBuffer, + 0, + NULL); + if(0 != dwCount) + { + MessageBox(NULL, (LPCTSTR)pTextBuffer, pszCaption, MB_OK|MB_ICONERROR); + LocalFree(pTextBuffer); + } + else + { + MessageBox(NULL, __TEXT("Unknown error"), pszCaption, MB_OK|MB_ICONERROR); + } + } +} + +// Convert an Irrlicht texture to a Windows cursor +// Based on http://www.codeguru.com/cpp/w-p/win32/cursors/article.php/c4529/ +HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot) +{ + // + // create the bitmaps needed for cursors from the texture + + HDC dc = GetDC(hwnd); + HDC andDc = CreateCompatibleDC(dc); + HDC xorDc = CreateCompatibleDC(dc); + HBITMAP andBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight()); + HBITMAP xorBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight()); + + HBITMAP oldAndBitmap = (HBITMAP)SelectObject(andDc, andBitmap); + HBITMAP oldXorBitmap = (HBITMAP)SelectObject(xorDc, xorBitmap); + + + video::ECOLOR_FORMAT format = tex->getColorFormat(); + u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; + u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; + u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; + const u8* data = (const u8*)tex->lock(video::ETLM_READ_ONLY, 0); + data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); + for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) + { + data += bytesLeftGap; + for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) + { + video::SColor pixelCol; + pixelCol.setData((const void*)data, format); + data += bytesPerPixel; + + if ( pixelCol.getAlpha() == 0 ) // transparent + { + SetPixel(andDc, x, y, RGB(255,255,255)); + SetPixel(xorDc, x, y, RGB(0,0,0)); + } + else // color + { + SetPixel(andDc, x, y, RGB(0,0,0)); + SetPixel(xorDc, x, y, RGB(pixelCol.getRed(), pixelCol.getGreen(), pixelCol.getBlue())); + } + } + data += bytesRightGap; + } + tex->unlock(); + + SelectObject(andDc, oldAndBitmap); + SelectObject(xorDc, oldXorBitmap); + + DeleteDC(xorDc); + DeleteDC(andDc); + + ReleaseDC(hwnd, dc); + + // create the cursor + + ICONINFO iconinfo; + iconinfo.fIcon = false; // type is cursor not icon + iconinfo.xHotspot = hotspot.X; + iconinfo.yHotspot = hotspot.Y; + iconinfo.hbmMask = andBitmap; + iconinfo.hbmColor = xorBitmap; + + HCURSOR cursor = CreateIconIndirect(&iconinfo); + + DeleteObject(andBitmap); + DeleteObject(xorBitmap); + + return cursor; +} + + +CIrrDeviceWin32::CCursorControl::CCursorControl(CIrrDeviceWin32* device, const core::dimension2d& wsize, HWND hwnd, bool fullscreen) + : Device(device), WindowSize(wsize), InvWindowSize(0.0f, 0.0f), + HWnd(hwnd), BorderX(0), BorderY(0), + UseReferenceRect(false), IsVisible(true) + , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) +{ + if (WindowSize.Width!=0) + InvWindowSize.Width = 1.0f / WindowSize.Width; + + if (WindowSize.Height!=0) + InvWindowSize.Height = 1.0f / WindowSize.Height; + + updateBorderSize(fullscreen, false); + initCursors(); +} + +CIrrDeviceWin32::CCursorControl::~CCursorControl() +{ + for ( u32 i=0; i < Cursors.size(); ++i ) + { + for ( u32 f=0; f < Cursors[i].Frames.size(); ++f ) + { + DestroyCursor(Cursors[i].Frames[f].IconHW); + } + } +} + + +void CIrrDeviceWin32::CCursorControl::initCursors() +{ + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_ARROW)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_CROSS)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HAND)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HELP)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_IBEAM)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_NO)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_WAIT)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEALL)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENESW)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENWSE)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENS)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEWE)) ); + Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_UPARROW)) ); +} + + +void CIrrDeviceWin32::CCursorControl::update() +{ + if ( !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime ) + { + // update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement) + u32 now = Device->getTimer()->getRealTime(); + u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size(); + SetCursor( Cursors[ActiveIcon].Frames[frame].IconHW ); + } +} + +//! Sets the active cursor icon +void CIrrDeviceWin32::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId) +{ + if ( iconId >= (s32)Cursors.size() ) + return; + + ActiveIcon = iconId; + ActiveIconStartTime = Device->getTimer()->getRealTime(); + if ( Cursors[ActiveIcon].Frames.size() ) + SetCursor( Cursors[ActiveIcon].Frames[0].IconHW ); +} + + +//! Add a custom sprite as cursor icon. +gui::ECURSOR_ICON CIrrDeviceWin32::CCursorControl::addIcon(const gui::SCursorSprite& icon) +{ + if ( icon.SpriteId >= 0 ) + { + CursorW32 cW32; + cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; + + for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) + { + irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; + irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; + irr::core::rect rectIcon = icon.SpriteBank->getPositions()[rectId]; + + HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); + cW32.Frames.push_back( CursorFrameW32(hc) ); + } + + Cursors.push_back( cW32 ); + return (gui::ECURSOR_ICON)(Cursors.size() - 1); + } + return gui::ECI_NORMAL; +} + + +//! replace the given cursor icon. +void CIrrDeviceWin32::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) +{ + if ( iconId >= (s32)Cursors.size() ) + return; + + for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i ) + DestroyCursor(Cursors[iconId].Frames[i].IconHW); + + if ( icon.SpriteId >= 0 ) + { + CursorW32 cW32; + cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; + for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) + { + irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; + irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; + irr::core::rect rectIcon = icon.SpriteBank->getPositions()[rectId]; + + HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); + cW32.Frames.push_back( CursorFrameW32(hc) ); + } + + Cursors[iconId] = cW32; + } +} + + +//! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. +core::dimension2di CIrrDeviceWin32::CCursorControl::getSupportedIconSize() const +{ + core::dimension2di result; + + result.Width = GetSystemMetrics(SM_CXCURSOR); + result.Height = GetSystemMetrics(SM_CYCURSOR); + + return result; +} + + + +} // end namespace + +#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.h new file mode 100644 index 0000000..c11a3fd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWin32.h @@ -0,0 +1,420 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_WIN32_H_INCLUDED__ +#define __C_IRR_DEVICE_WIN32_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" + +#define WIN32_LEAN_AND_MEAN +#if !defined(_IRR_XBOX_PLATFORM_) + #include + #include // For JOYCAPS + #include +#endif +#if !defined(GET_X_LPARAM) +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) +#endif + +namespace irr +{ + struct SJoystickWin32Control; + + class CIrrDeviceWin32 : public CIrrDeviceStub, video::IImagePresenter + { + friend struct SJoystickWin32Control; + public: + + //! constructor + CIrrDeviceWin32(const SIrrlichtCreationParameters& params); + + //! destructor + virtual ~CIrrDeviceWin32(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! returns if window has focus + virtual bool isWindowFocused() const; + + //! returns if window is minimized + virtual bool isWindowMinimized() const; + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + video::IVideoModeList* getVideoModeList(); + + //! Notifies the device, that it has been resized + void OnResized(); + + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize=false); + + //! Minimizes the window. + virtual void minimizeWindow(); + + //! Maximizes the window. + virtual void maximizeWindow(); + + //! Restores the window size. + virtual void restoreWindow(); + + //! Activate any joysticks, and generate events for them. + virtual bool activateJoysticks(core::array & joystickInfo); + + //! Set the current Gamma Value for the Display + virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ); + + //! Get the current Gamma Value for the Display + virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ); + + //! Remove all messages pending in the system message loop + virtual void clearSystemMessages(); + + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_WIN32; + } + + //! Compares to the last call of this function to return double and triple clicks. + //! \return Returns only 1,2 or 3. A 4th click will start with 1 again. + virtual u32 checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent ) + { + // we just have to make it public + return CIrrDeviceStub::checkSuccessiveClicks(mouseX, mouseY, inputEvent ); + } + + //! switchs to fullscreen + bool switchToFullScreen(bool reset=false); + + //! Check for and show last Windows API error to help internal debugging. + //! Does call GetLastError and on errors formats the errortext and displays it in a messagebox. + static void ReportLastWinApiError(); + + // convert an Irrlicht texture to a windows cursor + HCURSOR TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect& sourceRect, const core::position2d &hotspot); + + //! Implementation of the win32 cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(CIrrDeviceWin32* device, const core::dimension2d& wsize, HWND hwnd, bool fullscreen); + ~CCursorControl(); + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + CURSORINFO info; + info.cbSize = sizeof(CURSORINFO); + BOOL gotCursorInfo = GetCursorInfo(&info); + while ( gotCursorInfo ) + { +#ifdef CURSOR_SUPPRESSED + // new flag for Windows 8, where cursor + // might be suppressed for touch interface + if (info.flags == CURSOR_SUPPRESSED) + { + visible=false; + break; + } +#endif + if ( (visible && info.flags == CURSOR_SHOWING) || // visible + (!visible && info.flags == 0 ) ) // hidden + { + break; + } + // this only increases an internal + // display counter in windows, so it + // might have to be called some more + const int showResult = ShowCursor(visible); + // if result has correct sign we can + // stop here as well + if (( !visible && showResult < 0 ) || + (visible && showResult >= 0)) + break; + // yes, it really must be set each time + info.cbSize = sizeof(CURSORINFO); + gotCursorInfo = GetCursorInfo(&info); + } + IsVisible = visible; + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + if (!UseReferenceRect) + setPosition(core::round32(x*WindowSize.Width), core::round32(y*WindowSize.Height)); + else + setPosition(core::round32(x*ReferenceRect.getWidth()), core::round32(y*ReferenceRect.getHeight())); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + if (UseReferenceRect) + { + SetCursorPos(ReferenceRect.UpperLeftCorner.X + x, + ReferenceRect.UpperLeftCorner.Y + y); + } + else + { + RECT rect; + if (GetWindowRect(HWnd, &rect)) + SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY); + } + + CursorPos.X = x; + CursorPos.Y = y; + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + updateInternalCursorPosition(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateInternalCursorPosition(); + + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + /** Used to notify the cursor that the window was resized. */ + virtual void OnResize(const core::dimension2d& size) + { + WindowSize = size; + if (size.Width!=0) + InvWindowSize.Width = 1.0f / size.Width; + else + InvWindowSize.Width = 0.f; + + if (size.Height!=0) + InvWindowSize.Height = 1.0f / size.Height; + else + InvWindowSize.Height = 0.f; + } + + /** Used to notify the cursor that the window resizable settings changed. */ + void updateBorderSize(bool fullscreen, bool resizable) + { + if (!fullscreen) + { + if (resizable) + { + BorderX = GetSystemMetrics(SM_CXSIZEFRAME); + BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME); + } + else + { + BorderX = GetSystemMetrics(SM_CXDLGFRAME); + BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME); + } + } + else + { + BorderX = BorderY = 0; + } + } + + + //! Sets the active cursor icon + virtual void setActiveIcon(gui::ECURSOR_ICON iconId); + + //! Gets the currently active icon + virtual gui::ECURSOR_ICON getActiveIcon() const + { + return ActiveIcon; + } + + //! Add a custom sprite as cursor icon. + virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon); + + //! replace the given cursor icon. + virtual void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon); + + //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. + virtual core::dimension2di getSupportedIconSize() const; + + void update(); + + private: + + //! Updates the internal cursor position + void updateInternalCursorPosition() + { + POINT p; + if (!GetCursorPos(&p)) + { + DWORD xy = GetMessagePos(); + p.x = GET_X_LPARAM(xy); + p.y = GET_Y_LPARAM(xy); + } + + if (UseReferenceRect) + { + CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X; + CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y; + } + else + { + RECT rect; + if (GetWindowRect(HWnd, &rect)) + { + CursorPos.X = p.x-rect.left-BorderX; + CursorPos.Y = p.y-rect.top-BorderY; + } + else + { + // window seems not to be existent, so set cursor to + // a negative value + CursorPos.X = -1; + CursorPos.Y = -1; + } + } + } + + CIrrDeviceWin32* Device; + core::position2d CursorPos; + core::dimension2d WindowSize; + core::dimension2d InvWindowSize; + HWND HWnd; + + s32 BorderX, BorderY; + core::rect ReferenceRect; + bool UseReferenceRect; + bool IsVisible; + + + struct CursorFrameW32 + { + CursorFrameW32() : IconHW(0) {} + CursorFrameW32(HCURSOR icon) : IconHW(icon) {} + + HCURSOR IconHW; // hardware cursor + }; + + struct CursorW32 + { + CursorW32() {} + explicit CursorW32(HCURSOR iconHw, u32 frameTime=0) : FrameTime(frameTime) + { + Frames.push_back( CursorFrameW32(iconHw) ); + } + core::array Frames; + u32 FrameTime; + }; + + core::array Cursors; + gui::ECURSOR_ICON ActiveIcon; + u32 ActiveIconStartTime; + + void initCursors(); + }; + + //! returns the win32 cursor control + CCursorControl* getWin32CursorControl(); + + private: + + //! create the driver + void createDriver(); + + //! Process system events + void handleSystemMessages(); + + void getWindowsVersion(core::stringc& version); + + void resizeIfNecessary(); + + HWND HWnd; + + bool ChangedToFullScreen; + bool Resized; + bool ExternalWindow; + CCursorControl* Win32CursorControl; + DEVMODE DesktopMode; + + SJoystickWin32Control* JoyControl; + }; + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ +#endif // __C_IRR_DEVICE_WIN32_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.cpp new file mode 100644 index 0000000..e6eb27d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.cpp @@ -0,0 +1,868 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ + +#include "CIrrDeviceWinCE.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" + +#include "CTimer.h" +#include "irrString.h" +#include "COSOperator.h" +#include "dimension2d.h" +#include +#include "irrlicht.h" + +#ifdef _MSC_VER + #pragma comment (lib, "aygshell.lib") +#endif + + +namespace irr +{ + namespace video + { + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + IVideoDriver* createDirectX8Driver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window); + #endif + + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, HWND window); + #endif + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, this); + #endif + } +} // end namespace irr + + + +struct SEnvMapper +{ + HWND hWnd; + irr::CIrrDeviceWinCE* irrDev; +}; + +irr::core::list EnvMap; + +SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) +{ + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == hWnd) + return &(*it); + + return 0; +} + +irr::CIrrDeviceWinCE* getDeviceFromHWnd(HWND hWnd) +{ + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == hWnd) + return (*it).irrDev; + + return 0; +} + + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef WM_MOUSEWHEEL + #define WM_MOUSEWHEEL 0x020A + #endif + #ifndef WHEEL_DELTA + #define WHEEL_DELTA 120 + #endif + + irr::CIrrDeviceWinCE* dev = 0; + irr::SEvent event; + SEnvMapper* envm = 0; + + //BYTE allKeys[256]; + + static irr::s32 ClickCount=0; + if (GetCapture() != hWnd && ClickCount > 0) + ClickCount = 0; + + switch (message) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + } + return 0; + + case WM_ERASEBKGND: + return 0; + + case WM_SETCURSOR: + envm = getEnvMapperFromHWnd(hWnd); + if (envm && !envm->irrDev->getWin32CursorControl()->isVisible()) + { + SetCursor(NULL); + return 0; + } + break; + + case WM_MOUSEWHEEL: + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Wheel = ((irr::f32)((short)HIWORD(wParam))) / (irr::f32)WHEEL_DELTA; + event.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + + POINT p; // fixed by jox + p.x = 0; p.y = 0; + ClientToScreen(hWnd, &p); + event.MouseInput.X = LOWORD(lParam) - p.x; + event.MouseInput.Y = HIWORD(lParam) - p.y; + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + break; + + case WM_LBUTTONDOWN: + ClickCount++; + SetCapture(hWnd); + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_LBUTTONUP: + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_RBUTTONDOWN: + ClickCount++; + SetCapture(hWnd); + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_RBUTTONUP: + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_MBUTTONDOWN: + ClickCount++; + SetCapture(hWnd); + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_MBUTTONUP: + ClickCount--; + if (ClickCount<1) + { + ClickCount=0; + ReleaseCapture(); + } + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + return 0; + + case WM_MOUSEMOVE: + event.EventType = irr::EET_MOUSE_INPUT_EVENT; + event.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + event.MouseInput.X = (short)LOWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); + event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); + // left and right mouse buttons + event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); + // middle and extra buttons + if (wParam & MK_MBUTTON) + event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; + + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->postEventFromUser(event); + + return 0; + + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + case WM_KEYDOWN: + case WM_KEYUP: + { + event.EventType = irr::EET_KEY_INPUT_EVENT; + event.KeyInput.Key = (irr::EKEY_CODE)wParam; + event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN); + dev = getDeviceFromHWnd(hWnd); +/* + WORD KeyAsc=0; + GetKeyboardState(allKeys); + ToAscii(wParam,lParam,allKeys,&KeyAsc,0); +*/ +// event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0); +// event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0); +// event.KeyInput.Char = (KeyAsc & 0x00ff); //KeyAsc >= 0 ? KeyAsc : 0; + + if (dev) + dev->postEventFromUser(event); + + return 0; + } + + case WM_SIZE: + { + // resize + dev = getDeviceFromHWnd(hWnd); + if (dev) + dev->OnResized(); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + +namespace irr +{ + +//! constructor +CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params) +: CIrrDeviceStub(params), HWnd(0), + Win32CursorControl(0), ChangedToFullScreen(false), Resized(false), + ExternalWindow(false) +{ + #ifdef _DEBUG + setDebugName("CIrrDeviceWinCE"); + #endif + + core::stringc winversion; + getWindowsVersion(winversion); + Operator = new COSOperator(winversion); + os::Printer::log(winversion.c_str(), ELL_INFORMATION); + + HINSTANCE hInstance = GetModuleHandle(0); + + // create the window only if we do not use the null device + if (!CreationParams.WindowId && (CreationParams.DriverType != video::EDT_NULL)) + { + const wchar_t* ClassName = L"CIrrDeviceWinCE"; + + // Register Class + WNDCLASS wc; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = 0; + wc.lpszClassName = ClassName; + + // if there is an icon, load it + wc.hIcon = (HICON)LoadImageW(hInstance, L"irrlicht.ico", IMAGE_ICON, 0,0, 0); + + RegisterClass(&wc); + + // calculate client size + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = CreationParams.WindowSize.Width; + clientSize.bottom = CreationParams.WindowSize.Height; + + DWORD style = WS_POPUP; + + if (!CreationParams.Fullscreen) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + AdjustWindowRectEx(&clientSize, style, FALSE, 0); + + const s32 realWidth = clientSize.right - clientSize.left; + const s32 realHeight = clientSize.bottom - clientSize.top; + + const s32 windowLeft = core::s32_max ( 0, (GetSystemMetrics(SM_CXSCREEN) - realWidth) >> 1 ); + const s32 windowTop = core::s32_max ( 0, (GetSystemMetrics(SM_CYSCREEN) - realHeight) >> 1 ); + + // create window + + HWnd = CreateWindowW( ClassName, L"", style, windowLeft, windowTop, + realWidth, realHeight, NULL, NULL, hInstance, NULL); + + ShowWindow(HWnd , SW_SHOW); + UpdateWindow(HWnd); + + // fix ugly ATI driver bugs. Thanks to ariaci + MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE); + } + else if (CreationParams.WindowId) + { + // attach external window + HWnd = static_cast(CreationParams.WindowId); + RECT r; + GetWindowRect(HWnd, &r); + CreationParams.WindowSize.Width = r.right - r.left; + CreationParams.WindowSize.Height = r.bottom - r.top; + CreationParams.Fullscreen = false; + ExternalWindow = true; + } + + // create cursor control + + Win32CursorControl = new CCursorControl(CreationParams.WindowSize, HWnd, CreationParams.Fullscreen); + CursorControl = Win32CursorControl; + + // create driver + + createDriver(); + + if (VideoDriver) + createGUIAndScene(); + + // register environment + + SEnvMapper em; + em.irrDev = this; + em.hWnd = HWnd; + EnvMap.push_back(em); + + // set this as active window + SetActiveWindow(HWnd); + SetForegroundWindow(HWnd); +} + + +//! destructor +CIrrDeviceWinCE::~CIrrDeviceWinCE() +{ + // unregister environment + + if (ChangedToFullScreen) + SHFullScreen(HWnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON); + + irr::core::list::Iterator it = EnvMap.begin(); + for (; it!= EnvMap.end(); ++it) + if ((*it).hWnd == HWnd) + { + EnvMap.erase(it); + break; + } +} + + +//! create the driver +void CIrrDeviceWinCE::createDriver() +{ + switch(CreationParams.DriverType) + { + case video::EDT_DIRECT3D8: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ + VideoDriver = video::createDirectX8Driver(CreationParams, FileSystem, HWnd); + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ + + break; + + case video::EDT_DIRECT3D9: + #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ + VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, HWnd); + if (!VideoDriver) + { + os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR); + } + #else + os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR); + #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ + + break; + + case video::EDT_OPENGL: + + #ifdef _IRR_COMPILE_WITH_OPENGL_ + if (CreationParams.Fullscreen) + switchToFullScreen(); + VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem); + if (!VideoDriver) + { + os::Printer::log("Could not create OpenGL driver.", ELL_ERROR); + } + #else + os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_SOFTWARE: + + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + if (CreationParams.Fullscreen) + switchToFullScreen(); + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + #else + os::Printer::log("Software driver was not compiled in.", ELL_ERROR); + #endif + + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + if (CreationParams.Fullscreen) + switchToFullScreen(); + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_NULL: + // create null driver + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + + +//! runs the device. Returns false if device wants to be deleted +bool CIrrDeviceWinCE::run() +{ + os::Timer::tick(); + + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + + if (ExternalWindow && msg.hwnd == HWnd) + WndProc(HWnd, msg.message, msg.wParam, msg.lParam); + else + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + Close = true; + } + + if (!Close) + resizeIfNecessary(); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return !Close; +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceWinCE::yield() +{ + Sleep(1); +} + + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceWinCE::sleep(u32 timeMs, bool pauseTimer) +{ + const bool wasStopped = Timer ? Timer->isStopped() : true; + if (pauseTimer && !wasStopped) + Timer->stop(); + + Sleep(timeMs); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +void CIrrDeviceWinCE::resizeIfNecessary() +{ + if (!Resized) + return; + + RECT r; + GetClientRect(HWnd, &r); + + char tmp[255]; + + if (r.right < 2 || r.bottom < 2) + { + sprintf(tmp, "Ignoring resize operation to (%ld %ld)", r.right, r.bottom); + os::Printer::log(tmp); + } + else + { + sprintf(tmp, "Resizing window (%ld %ld)", r.right, r.bottom); + os::Printer::log(tmp); + + getVideoDriver()->OnResize(irr::core::dimension2d(r.right, r.bottom)); + getWin32CursorControl()->OnResize(getVideoDriver()->getScreenSize()); + } + + Resized = false; +} + + +//! sets the caption of the window +void CIrrDeviceWinCE::setWindowCaption(const wchar_t* text) +{ + SetWindowTextW(HWnd, text); +} + + +#if !defined(BITMAPV4HEADER) +typedef struct { + DWORD bV4Size; + LONG bV4Width; + LONG bV4Height; + WORD bV4Planes; + WORD bV4BitCount; + DWORD bV4V4Compression; + DWORD bV4SizeImage; + LONG bV4XPelsPerMeter; + LONG bV4YPelsPerMeter; + DWORD bV4ClrUsed; + DWORD bV4ClrImportant; + DWORD bV4RedMask; + DWORD bV4GreenMask; + DWORD bV4BlueMask; + DWORD bV4AlphaMask; + DWORD bV4CSType; + DWORD un[9]; +} BITMAPV4HEADER, *PBITMAPV4HEADER; +#endif + + +//! presents a surface in the client area +bool CIrrDeviceWinCE::present(video::IImage* image, void* windowId, core::rect* src) +{ + HWND hwnd = HWnd; + if ( windowId ) + hwnd = (HWND)windowId; + + HDC dc = GetDC(hwnd); + + if ( dc ) + { + RECT rect; + GetClientRect(hwnd, &rect); + const void* memory = (const void *)image->lock(); + + BITMAPV4HEADER bi; + memset (&bi, 0, sizeof(bi)); + bi.bV4Size = sizeof(BITMAPINFOHEADER); + bi.bV4BitCount = image->getBitsPerPixel(); + bi.bV4Planes = 1; + bi.bV4Width = image->getDimension().Width; + bi.bV4Height = 0 - image->getDimension().Height; + bi.bV4V4Compression = BI_BITFIELDS; + bi.bV4AlphaMask = image->getAlphaMask (); + bi.bV4RedMask = image->getRedMask (); + bi.bV4GreenMask = image->getGreenMask(); + bi.bV4BlueMask = image->getBlueMask(); + + int r = 0; + if ( src ) + { + r = StretchDIBits(dc, 0,0, rect.right, rect.bottom, + src->UpperLeftCorner.X, src->UpperLeftCorner.Y, + src->getWidth(), src->getHeight(), + memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); + } + else + { + r = StretchDIBits(dc, 0,0, rect.right, rect.bottom, + 0, 0, image->getDimension().Width, image->getDimension().Height, + memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); + } + + image->unlock(); + + ReleaseDC(hwnd, dc); + } + return true; +} + + +//! notifies the device that it should close itself +void CIrrDeviceWinCE::closeDevice() +{ + MSG msg; + PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); + PostQuitMessage(0); + PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); + if (!ExternalWindow) + { + DestroyWindow(HWnd); + const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); + HINSTANCE hInstance = GetModuleHandle(0); + UnregisterClass(ClassName, hInstance); + } + Close=true; +} + + +//! returns if window is active. if not, nothing need to be drawn +bool CIrrDeviceWinCE::isWindowActive() const +{ + bool ret = (GetActiveWindow() == HWnd); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! returns if window has focus +bool CIrrDeviceWinCE::isWindowFocused() const +{ + bool ret = (GetFocus() == HWnd); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! returns if window is minimized +bool CIrrDeviceWinCE::isWindowMinimized() const +{ +#if 0 + WINDOWPLACEMENT plc; + plc.length=sizeof(WINDOWPLACEMENT); + bool ret=false; + if (GetWindowPlacement(HWnd,&plc)) + ret=(plc.showCmd & SW_SHOWMINIMIZED); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +#endif + return false; +} + + +//! switches to fullscreen +bool CIrrDeviceWinCE::switchToFullScreen() +{ + ChangedToFullScreen = SHFullScreen(HWnd, SHFS_HIDESIPBUTTON | SHFS_HIDETASKBAR) != 0; + return ChangedToFullScreen; +} + + +//! returns the win32 cursor control +CIrrDeviceWinCE::CCursorControl* CIrrDeviceWinCE::getWin32CursorControl() +{ + return Win32CursorControl; +} + + +//! Return pointer to a list with all video modes supported by the gfx adapter. +/** \return Pointer to video modes list */ +video::IVideoModeList* CIrrDeviceWinCE::getVideoModeList() +{ + if (!VideoModeList->getVideoModeCount()) + { + // enumerate video modes. + DWORD i=0; + DEVMODE mode; + memset(&mode, 0, sizeof(mode)); + mode.dmSize = sizeof(mode); + + while (EnumDisplaySettings(NULL, i, &mode)) + { + VideoModeList->addMode(core::dimension2d(mode.dmPelsWidth, mode.dmPelsHeight), + mode.dmBitsPerPel); + + ++i; + } + + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode)) + VideoModeList->setDesktop(mode.dmBitsPerPel, core::dimension2d(mode.dmPelsWidth, mode.dmPelsHeight)); + } + + return VideoModeList; +} + + +void CIrrDeviceWinCE::getWindowsVersion(core::stringc& out) +{ + out = "WinCE"; +} + + +//! Notifies the device, that it has been resized +void CIrrDeviceWinCE::OnResized() +{ + Resized = true; +} + + +//! Sets if the window should be resizable in windowed mode. +void CIrrDeviceWinCE::setResizable(bool resize) +{ + if (ExternalWindow || !getVideoDriver() || CreationParams.Fullscreen) + return; + + LONG style = WS_POPUP; + + if (!resize) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + else + style = WS_THICKFRAME | WS_SYSMENU | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX; + + if (!SetWindowLong(HWnd, GWL_STYLE, style)) + os::Printer::log("Could not change window style."); + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = getVideoDriver()->getScreenSize().Width; + clientSize.bottom = getVideoDriver()->getScreenSize().Height; + + AdjustWindowRectEx(&clientSize, style, FALSE, 0); + + const s32 realWidth = clientSize.right - clientSize.left; + const s32 realHeight = clientSize.bottom - clientSize.top; + + const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; + const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + + SetWindowPos(HWnd, HWND_TOP, windowLeft, windowTop, realWidth, realHeight, + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_SHOWWINDOW); +} + + +//! Minimizes the window. +void CIrrDeviceWinCE::minimizeWindow() +{ + // do nothing +} + +//! Maximize window +void CIrrDeviceWinCE::maximizeWindow() +{ + // do nothing +} + + +//! Restore original window size +void CIrrDeviceWinCE::restoreWindow() +{ + // do nothing +} + + +} // end namespace + +#endif // _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.h new file mode 100644 index 0000000..7fe1063 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceWinCE.h @@ -0,0 +1,296 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_DEVICE_WINCE_H_INCLUDED__ +#define __C_IRR_DEVICE_WINCE_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" + +#include +#include +#include +#include +#include +#include + +namespace irr +{ + class CIrrDeviceWinCE : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceWinCE( const SIrrlichtCreationParameters& params); + + //! destructor + virtual ~CIrrDeviceWinCE(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! returns if window has focus + virtual bool isWindowFocused() const; + + //! returns if window is minimized + virtual bool isWindowMinimized() const; + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId = 0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + video::IVideoModeList* getVideoModeList(); + + //! Notifies the device, that it has been resized + void OnResized(); + + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize=false); + + //! Minimizes the window. + virtual void minimizeWindow(); + + //! Maximizes the window. + virtual void maximizeWindow(); + + //! Restores the window size. + virtual void restoreWindow(); + + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_WINCE; + } + + //! Implementation of the win32 cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(const core::dimension2d& wsize, HWND hwnd, bool fullscreen) + : WindowSize(wsize), InvWindowSize(0.0f, 0.0f), + HWnd(hwnd), BorderX(0), BorderY(0), + UseReferenceRect(false), IsVisible(true) + { + if (WindowSize.Width!=0) + InvWindowSize.Width = 1.0f / WindowSize.Width; + + if (WindowSize.Height!=0) + InvWindowSize.Height = 1.0f / WindowSize.Height; + + if (!fullscreen) + { + BorderX = GetSystemMetrics(SM_CXDLGFRAME); + BorderY = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME); + } + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + if (!UseReferenceRect) + setPosition(core::round32(x*WindowSize.Width), core::round32(y*WindowSize.Height)); + else + setPosition(core::round32(x*ReferenceRect.getWidth()), core::round32(y*ReferenceRect.getHeight())); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + RECT rect; + + if (UseReferenceRect) + { + SetCursorPos(ReferenceRect.UpperLeftCorner.X + x, + ReferenceRect.UpperLeftCorner.Y + y); + } + else + { + if (GetWindowRect(HWnd, &rect)) + SetCursorPos(x + rect.left + BorderX, y + rect.top + BorderY); + } + + CursorPos.X = x; + CursorPos.Y = y; + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + updateInternalCursorPosition(); + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + updateInternalCursorPosition(); + + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + /** Used to notify the cursor that the window was resized. */ + virtual void OnResize(const core::dimension2d& size) + { + WindowSize = size; + if (size.Width!=0) + InvWindowSize.Width = 1.0f / size.Width; + else + InvWindowSize.Width = 0.f; + + if (size.Height!=0) + InvWindowSize.Height = 1.0f / size.Height; + else + InvWindowSize.Height = 0.f; + } + + private: + + //! Updates the internal cursor position + void updateInternalCursorPosition() + { + POINT p; + if (!GetCursorPos(&p)) + { + DWORD xy = GetMessagePos(); + p.x = GET_X_LPARAM(xy); + p.y = GET_Y_LPARAM(xy); + } + + if (UseReferenceRect) + { + CursorPos.X = p.x - ReferenceRect.UpperLeftCorner.X; + CursorPos.Y = p.y - ReferenceRect.UpperLeftCorner.Y; + } + else + { + RECT rect; + if (GetWindowRect(HWnd, &rect)) + { + CursorPos.X = p.x-rect.left-BorderX; + CursorPos.Y = p.y-rect.top-BorderY; + } + else + { + // window seems not to be existent, so set cursor to + // a negative value + CursorPos.X = -1; + CursorPos.Y = -1; + } + } + } + + core::position2d CursorPos; + core::dimension2d WindowSize; + core::dimension2d InvWindowSize; + HWND HWnd; + + s32 BorderX, BorderY; + core::rect ReferenceRect; + bool UseReferenceRect; + bool IsVisible; + }; + + + //! returns the win32 cursor control + CCursorControl* getWin32CursorControl(); + + private: + + //! create the driver + void createDriver(); + + //! switchs to fullscreen + bool switchToFullScreen(); + + void getWindowsVersion(core::stringc& version); + + void resizeIfNecessary(); + + HWND HWnd; + CCursorControl* Win32CursorControl; + + bool ChangedToFullScreen; + bool Resized; + bool ExternalWindow; + }; + + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ +#endif // __C_IRR_DEVICE_WINCE_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.cpp new file mode 100644 index 0000000..6478aaf --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.cpp @@ -0,0 +1,554 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ + +#include "CIrrMeshFileLoader.h" +#include "os.h" +#include "IXMLReader.h" +#include "SAnimatedMesh.h" +#include "fast_atof.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "IMeshSceneNode.h" +#include "CDynamicMeshBuffer.h" +#include "SMeshBufferLightMap.h" + +namespace irr +{ +namespace scene +{ + + +//! Constructor +CIrrMeshFileLoader::CIrrMeshFileLoader(scene::ISceneManager* smgr, + io::IFileSystem* fs) + : SceneManager(smgr), FileSystem(fs) +{ + + #ifdef _DEBUG + setDebugName("CIrrMeshFileLoader"); + #endif + +} + + +//! Returns true if the file maybe is able to be loaded by this class. +/** This decision should be based only on the file extension (e.g. ".cob") */ +bool CIrrMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "xml", "irrmesh" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CIrrMeshFileLoader::createMesh(io::IReadFile* file) +{ + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + return 0; + + // read until mesh section, skip other parts + + const core::stringc meshTagName = "mesh"; + IAnimatedMesh* mesh = 0; + + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + if (meshTagName == reader->getNodeName()) + { + mesh = readMesh(reader); + break; + } + else + skipSection(reader, true); // unknown section + } + } + + reader->drop(); + + return mesh; +} + + +//! reads a mesh sections and creates a mesh from it +IAnimatedMesh* CIrrMeshFileLoader::readMesh(io::IXMLReader* reader) +{ + SAnimatedMesh* animatedmesh = new SAnimatedMesh(); + SMesh* mesh = new SMesh(); + + animatedmesh->addMesh(mesh); + mesh->drop(); + + core::stringc bbSectionName = "boundingBox"; + core::stringc bufferSectionName = "buffer"; + core::stringc meshSectionName = "mesh"; + + if (!reader->isEmptyElement()) + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const wchar_t* nodeName = reader->getNodeName(); + if (bbSectionName == nodeName) + { + // inside a bounding box, ignore it for now because + // we are calculating this anyway ourselves later. + } + else + if (bufferSectionName == nodeName) + { + // we've got a mesh buffer + + IMeshBuffer* buffer = readMeshBuffer(reader); + if (buffer) + { + mesh->addMeshBuffer(buffer); + buffer->drop(); + } + } + else + skipSection(reader, true); // unknown section + + } // end if node type is element + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (meshSectionName == reader->getNodeName()) + { + // end of mesh section reached, cancel out + break; + } + } + } // end while reader->read(); + + mesh->recalculateBoundingBox(); + animatedmesh->recalculateBoundingBox(); + + return animatedmesh; +} + + +//! reads a mesh sections and creates a mesh buffer from it +IMeshBuffer* CIrrMeshFileLoader::readMeshBuffer(io::IXMLReader* reader) +{ + CDynamicMeshBuffer* buffer = 0; + + core::stringc verticesSectionName = "vertices"; + core::stringc bbSectionName = "boundingBox"; + core::stringc materialSectionName = "material"; + core::stringc indicesSectionName = "indices"; + core::stringc bufferSectionName = "buffer"; + + bool insideVertexSection = false; + bool insideIndexSection = false; + + int vertexCount = 0; + int indexCount = 0; + + video::SMaterial material; + + if (!reader->isEmptyElement()) + while(reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT) + { + const wchar_t* nodeName = reader->getNodeName(); + if (bbSectionName == nodeName) + { + // inside a bounding box, ignore it for now because + // we are calculating this anyway ourselves later. + } + else + if (materialSectionName == nodeName) + { + //we've got a material + + io::IAttributes* attributes = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); + attributes->read(reader, true, L"material"); + + SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes(material, attributes); + attributes->drop(); + } + else + if (verticesSectionName == nodeName) + { + // vertices section + + const core::stringc vertexTypeName1 = "standard"; + const core::stringc vertexTypeName2 = "2tcoords"; + const core::stringc vertexTypeName3 = "tangents"; + + const wchar_t* vertexType = reader->getAttributeValue(L"type"); + vertexCount = reader->getAttributeValueAsInt(L"vertexCount"); + + insideVertexSection = true; + + video::E_INDEX_TYPE itype = (vertexCount > 65536)?irr::video::EIT_32BIT:irr::video::EIT_16BIT; + if (vertexTypeName1 == vertexType) + { + buffer = new CDynamicMeshBuffer(irr::video::EVT_STANDARD, itype); + + } + else + if (vertexTypeName2 == vertexType) + { + buffer = new CDynamicMeshBuffer(irr::video::EVT_2TCOORDS, itype); + } + else + if (vertexTypeName3 == vertexType) + { + buffer = new CDynamicMeshBuffer(irr::video::EVT_TANGENTS, itype); + } + buffer->getVertexBuffer().reallocate(vertexCount); + buffer->Material = material; + } + else + if (indicesSectionName == nodeName) + { + // indices section + + indexCount = reader->getAttributeValueAsInt(L"indexCount"); + insideIndexSection = true; + } + + } // end if node type is element + else + if (reader->getNodeType() == io::EXN_TEXT) + { + // read vertex data + if (insideVertexSection) + { + readMeshBuffer(reader, vertexCount, buffer); + insideVertexSection = false; + + } // end reading vertex array + else + if (insideIndexSection) + { + readIndices(reader, indexCount, buffer->getIndexBuffer()); + insideIndexSection = false; + } + + } // end if node type is text + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + { + if (bufferSectionName == reader->getNodeName()) + { + // end of buffer section reached, cancel out + break; + } + } + } // end while reader->read(); + + if (buffer) + buffer->recalculateBoundingBox(); + + return buffer; +} + + +//! read indices +void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices) +{ + indices.reallocate(indexCount); + + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + for (int i=0; igetNodeData(); + const c8* p = &data[0]; + scene::IVertexBuffer& Vertices = sbuffer->getVertexBuffer(); + video::E_VERTEX_TYPE vType = Vertices.getType(); + + if (sbuffer) + { + for (int i=0; igetNodeName()).c_str()); +#endif + + // skip if this element is empty anyway. + if (reader->isEmptyElement()) + return; + + // read until we've reached the last element in this section + u32 tagCounter = 1; + + while(tagCounter && reader->read()) + { + if (reader->getNodeType() == io::EXN_ELEMENT && + !reader->isEmptyElement()) + { + #ifdef _DEBUG + if (reportSkipping) + os::Printer::log("irrMesh unknown element:", core::stringc(reader->getNodeName()).c_str()); + #endif + + ++tagCounter; + } + else + if (reader->getNodeType() == io::EXN_ELEMENT_END) + --tagCounter; + } +} + + +//! parses a float from a char pointer and moves the pointer +//! to the end of the parsed float +inline f32 CIrrMeshFileLoader::readFloat(const c8** p) +{ + f32 ftmp; + *p = core::fast_atof_move(*p, ftmp); + return ftmp; +} + + +//! parses an int from a char pointer and moves the pointer to +//! the end of the parsed float +inline s32 CIrrMeshFileLoader::readInt(const c8** p) +{ + return (s32)readFloat(p); +} + + +//! places pointer to next begin of a token +void CIrrMeshFileLoader::skipCurrentNoneWhiteSpace(const c8** start) +{ + const c8* p = *start; + + while(*p && !(*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) + ++p; + + // TODO: skip comments + + *start = p; +} + +//! places pointer to next begin of a token +void CIrrMeshFileLoader::findNextNoneWhiteSpace(const c8** start) +{ + const c8* p = *start; + + while(*p && (*p==' ' || *p=='\n' || *p=='\r' || *p=='\t')) + ++p; + + // TODO: skip comments + + *start = p; +} + + +//! reads floats from inside of xml element until end of xml element +void CIrrMeshFileLoader::readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count) +{ + if (reader->isEmptyElement()) + return; + + while(reader->read()) + { + // TODO: check for comments inside the element + // and ignore them. + + if (reader->getNodeType() == io::EXN_TEXT) + { + // parse float data + core::stringc data = reader->getNodeData(); + const c8* p = &data[0]; + + for (u32 i=0; igetNodeType() == io::EXN_ELEMENT_END) + break; // end parsing text + } +} + + + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_IRR_MESH_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.h new file mode 100644 index 0000000..39b2332 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshFileLoader.h @@ -0,0 +1,90 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_IRR_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "CDynamicMeshBuffer.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + + +//! Meshloader capable of loading .irrmesh meshes, the Irrlicht Engine mesh format for static meshes +class CIrrMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CIrrMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + //! reads a mesh sections and creates a mesh from it + IAnimatedMesh* readMesh(io::IXMLReader* reader); + + //! reads a mesh sections and creates a mesh buffer from it + IMeshBuffer* readMeshBuffer(io::IXMLReader* reader); + + //! skips an (unknown) section in the irrmesh file + void skipSection(io::IXMLReader* reader, bool reportSkipping); + + //! reads a element and stores it in the material section + void readMaterial(io::IXMLReader* reader); + + //! parses a float from a char pointer and moves the pointer to + //! the end of the parsed float + inline f32 readFloat(const c8** p); + + //! parses an int from a char pointer and moves the pointer to + //! the end of the parsed float + inline s32 readInt(const c8** p); + + //! places pointer to next begin of a token + void findNextNoneWhiteSpace(const c8** p); + + //! places pointer to next begin of a token + void skipCurrentNoneWhiteSpace(const c8** p); + + //! reads floats from inside of xml element until end of xml element + void readFloatsInsideElement(io::IXMLReader* reader, f32* floats, u32 count); + + //! read the mesh buffers + void readMeshBuffer(io::IXMLReader* reader, int vertexCount, CDynamicMeshBuffer* sbuffer); + + //! read indices + void readIndices(io::IXMLReader* reader, int indexCount, IIndexBuffer& indices); + + + // member variables + + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.cpp new file mode 100644 index 0000000..2f7f9bd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.cpp @@ -0,0 +1,315 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_IRR_WRITER_ + +#include "CIrrMeshWriter.h" +#include "os.h" +#include "IWriteFile.h" +#include "IXMLWriter.h" +#include "IMesh.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + + +CIrrMeshWriter::CIrrMeshWriter(video::IVideoDriver* driver, + io::IFileSystem* fs) + : FileSystem(fs), VideoDriver(driver), Writer(0) +{ + #ifdef _DEBUG + setDebugName("CIrrMeshWriter"); + #endif + + if (VideoDriver) + VideoDriver->grab(); + + if (FileSystem) + FileSystem->grab(); +} + + +CIrrMeshWriter::~CIrrMeshWriter() +{ + if (VideoDriver) + VideoDriver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CIrrMeshWriter::getType() const +{ + return EMWT_IRR_MESH; +} + + +//! writes a mesh +bool CIrrMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + Writer = FileSystem->createXMLWriter(file); + + if (!Writer) + { + os::Printer::log("Could not write file", file->getFileName()); + return false; + } + + os::Printer::log("Writing mesh", file->getFileName()); + + // write IRR MESH header + + Writer->writeXMLHeader(); + + Writer->writeElement(L"mesh", false, + L"xmlns", L"http://irrlicht.sourceforge.net/IRRMESH_09_2007", + L"version", L"1.0"); + Writer->writeLineBreak(); + + // add some informational comment. Add a space after and before the comment + // tags so that some braindead xml parsers (AS anyone?) are able to parse this too. + + core::stringw infoComment = L" This file contains a static mesh in the Irrlicht Engine format with "; + infoComment += core::stringw(mesh->getMeshBufferCount()); + infoComment += L" materials."; + + Writer->writeComment(infoComment.c_str()); + Writer->writeLineBreak(); + + // write mesh bounding box + + writeBoundingBox(mesh->getBoundingBox()); + Writer->writeLineBreak(); + + // write mesh buffers + + for (int i=0; i<(int)mesh->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer) + { + writeMeshBuffer(buffer); + Writer->writeLineBreak(); + } + } + + Writer->writeClosingTag(L"mesh"); + + Writer->drop(); + return true; +} + + +void CIrrMeshWriter::writeBoundingBox(const core::aabbox3df& box) +{ + Writer->writeElement(L"boundingBox", true, + L"minEdge", getVectorAsStringLine(box.MinEdge).c_str(), + L"maxEdge", getVectorAsStringLine(box.MaxEdge).c_str()); +} + + +core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector3df& v) const +{ + core::stringw str; + + str = core::stringw(v.X); + str += L" "; + str += core::stringw(v.Y); + str += L" "; + str += core::stringw(v.Z); + + return str; +} + + +core::stringw CIrrMeshWriter::getVectorAsStringLine(const core::vector2df& v) const +{ + core::stringw str; + + str = core::stringw(v.X); + str += L" "; + str += core::stringw(v.Y); + + return str; +} + + +void CIrrMeshWriter::writeMeshBuffer(const scene::IMeshBuffer* buffer) +{ + Writer->writeElement(L"buffer", false); + Writer->writeLineBreak(); + + // write bounding box + + writeBoundingBox(buffer->getBoundingBox()); + Writer->writeLineBreak(); + + // write material + + writeMaterial(buffer->getMaterial()); + + // write vertices + + const core::stringw vertexTypeStr = video::sBuiltInVertexTypeNames[buffer->getVertexType()]; + + Writer->writeElement(L"vertices", false, + L"type", vertexTypeStr.c_str(), + L"vertexCount", core::stringw(buffer->getVertexCount()).c_str()); + + Writer->writeLineBreak(); + + u32 vertexCount = buffer->getVertexCount(); + + switch(buffer->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* vtx = (video::S3DVertex*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* vtx = (video::S3DVertex2TCoords*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* vtx = (video::S3DVertexTangents*)buffer->getVertices(); + for (u32 j=0; jwriteText(str.c_str()); + Writer->writeLineBreak(); + } + } + break; + } + + Writer->writeClosingTag(L"vertices"); + Writer->writeLineBreak(); + + // write indices + + Writer->writeElement(L"indices", false, + L"indexCount", core::stringw(buffer->getIndexCount()).c_str()); + + Writer->writeLineBreak(); + + int indexCount = (int)buffer->getIndexCount(); + + video::E_INDEX_TYPE iType = buffer->getIndexType(); + + const u16* idx16 = buffer->getIndices(); + const u32* idx32 = (u32*) buffer->getIndices(); + const int maxIndicesPerLine = 25; + + for (int i=0; iwriteText(str.c_str()); + } + else + { + core::stringw str((int)idx32[i]); + Writer->writeText(str.c_str()); + } + + if (i % maxIndicesPerLine != maxIndicesPerLine) + { + if (i % maxIndicesPerLine == maxIndicesPerLine-1) + Writer->writeLineBreak(); + else + Writer->writeText(L" "); + } + } + + if ((indexCount-1) % maxIndicesPerLine != maxIndicesPerLine-1) + Writer->writeLineBreak(); + + Writer->writeClosingTag(L"indices"); + Writer->writeLineBreak(); + + // close buffer tag + + Writer->writeClosingTag(L"buffer"); +} + + +void CIrrMeshWriter::writeMaterial(const video::SMaterial& material) +{ + // simply use irrlichts built-in attribute serialization capabilities here: + + io::IAttributes* attributes = + VideoDriver->createAttributesFromMaterial(material); + + if (attributes) + { + attributes->write(Writer, false, L"material"); + attributes->drop(); + } +} + + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.h new file mode 100644 index 0000000..4b62633 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrMeshWriter.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_IRR_MESH_WRITER_H_INCLUDED__ +#define __IRR_IRR_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "S3DVertex.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; +} +namespace scene +{ + class IMeshBuffer; + + + //! class to write meshes, implementing a IrrMesh (.irrmesh, .xml) writer + /** This writer implementation has been originally developed for irrEdit and then + merged out to the Irrlicht Engine */ + class CIrrMeshWriter : public IMeshWriter + { + public: + + CIrrMeshWriter(video::IVideoDriver* driver, io::IFileSystem* fs); + virtual ~CIrrMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + protected: + + void writeBoundingBox(const core::aabbox3df& box); + + void writeMeshBuffer(const scene::IMeshBuffer* buffer); + + void writeMaterial(const video::SMaterial& material); + + core::stringw getVectorAsStringLine(const core::vector3df& v) const; + + core::stringw getVectorAsStringLine(const core::vector2df& v) const; + + // member variables: + + io::IFileSystem* FileSystem; + video::IVideoDriver* VideoDriver; + io::IXMLWriter* Writer; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp new file mode 100644 index 0000000..6969731 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.cpp @@ -0,0 +1,373 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// This file was written by Jonas Petersen and modified by Nikolaus Gebhardt. +// See CLMTSMeshFileLoder.h for details. +/* + +CLMTSMeshFileLoader.cpp + +LMTSMeshFileLoader +Written by Jonas Petersen (a.k.a. jox) + +Version 1.5 - 15 March 2005 + +Get the latest version here: http://development.mindfloaters.de/ + +This class allows loading meshes with lightmaps (*.lmts + *.tga files) that were created +using Pulsar LMTools by Lord Trancos (http://www.geocities.com/dxlab/index_en.html) + +Notes: +- This version does not support user data in the *.lmts files, but still loads those files (by skipping the extra data). + +License: +-------- + +It's free. You are encouraged to give me credit if you use it in your software. + +Version History: +---------------- + +Version 1.5 - 15 March 2005 +- Did a better cleanup. No memory leaks in case of an loading error. +- Added "#include " for sprintf. + +Version 1.4 - 12 March 2005 +- Fixed bug in texture and subset loading code that would possibly cause crash. +- Fixed memory cleanup to avoid leak when loading more then one mesh +- Used the irrlicht Logger instead of cerr to output warnings and errors. + For this I had to change the constructor + from: + CLMTSMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) + to: + CLMTSMeshFileLoader(IrrlichtDevice* device) + +Version 1.3 - 15 February 2005 +- Fixed bug that prevented loading more than one different lmts files. +- Removed unnecessary "#include ". +- Added "std::" in front of "cerr". This was necessary for Visual Studio .NET, + I hope it's not disturbing other compilers. +- Added warning message when a texture can not be loaded. +- Changed the documentation a bit (minor). + +Version 1.2 +- To avoid confusion I skipped version 1.2 because the website was offering +version 1.2 even though it was only version 1.1. Sorry about that. + +Version 1.1 - 29 July 2004 +- Added setTexturePath() function +- Minor improvements + +Version 1.0 - 29 July 2004 +- Initial release + + +*/ +////////////////////////////////////////////////////////////////////// + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_ + +#include "SMeshBufferLightMap.h" +#include "SAnimatedMesh.h" +#include "SMeshBuffer.h" +#include "irrString.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "ISceneManager.h" +#include "CLMTSMeshFileLoader.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +CLMTSMeshFileLoader::CLMTSMeshFileLoader(io::IFileSystem* fs, + video::IVideoDriver* driver, io::IAttributes* parameters) + : Textures(0), Subsets(0), Triangles(0), + Parameters(parameters), Driver(driver), FileSystem(fs), FlipEndianess(false) +{ + #ifdef _DEBUG + setDebugName("CLMTSMeshFileLoader"); + #endif + + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); +} + + +CLMTSMeshFileLoader::~CLMTSMeshFileLoader() +{ + cleanup(); + + if (Driver) + Driver->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + +void CLMTSMeshFileLoader::cleanup() +{ + delete [] Textures; + Textures = 0; + delete [] Subsets; + Subsets = 0; + delete [] Triangles; + Triangles = 0; +} + + +bool CLMTSMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "lmts" ); +} + + +IAnimatedMesh* CLMTSMeshFileLoader::createMesh(io::IReadFile* file) +{ + u32 i; + u32 id; + + // HEADER + + file->read(&Header, sizeof(SLMTSHeader)); + if (Header.MagicID == 0x4C4D5354) + { + FlipEndianess = true; + Header.MagicID = os::Byteswap::byteswap(Header.MagicID); + Header.Version = os::Byteswap::byteswap(Header.Version); + Header.HeaderSize = os::Byteswap::byteswap(Header.HeaderSize); + Header.TextureCount = os::Byteswap::byteswap(Header.TextureCount); + Header.SubsetCount = os::Byteswap::byteswap(Header.SubsetCount); + Header.TriangleCount = os::Byteswap::byteswap(Header.TriangleCount); + Header.SubsetSize = os::Byteswap::byteswap(Header.SubsetSize); + Header.VertexSize = os::Byteswap::byteswap(Header.VertexSize); + } + if (Header.MagicID != 0x53544D4C) { // "LMTS" + os::Printer::log("LMTS ERROR: wrong header magic id!", ELL_ERROR); + return 0; + } + + //Skip any User Data (arbitrary app specific data) + + const s32 userSize = Header.HeaderSize - sizeof(SLMTSHeader); + if (userSize>0) + file->seek(userSize,true); + + // TEXTURES + + file->read(&id, sizeof(u32)); + if (FlipEndianess) + id = os::Byteswap::byteswap(id); + if (id != 0x54584554) { // "TEXT" + os::Printer::log("LMTS ERROR: wrong texture magic id!", ELL_ERROR); + return 0; + } + + Textures = new SLMTSTextureInfoEntry[Header.TextureCount]; + + file->read(Textures, sizeof(SLMTSTextureInfoEntry)*Header.TextureCount); + if (FlipEndianess) + { + for (i=0; iread(&id, sizeof(u32)); + if (FlipEndianess) + id = os::Byteswap::byteswap(id); + if (id != 0x53425553) // "SUBS" + { + os::Printer::log("LMTS ERROR: wrong subset magic id!", ELL_ERROR); + cleanup(); + return 0; + } + + Subsets = new SLMTSSubsetInfoEntry[Header.SubsetCount]; + const s32 subsetUserSize = Header.SubsetSize - sizeof(SLMTSSubsetInfoEntry); + + for (i=0; iread(&Subsets[i], sizeof(SLMTSSubsetInfoEntry)); + if (FlipEndianess) + { + Subsets[i].Offset = os::Byteswap::byteswap(Subsets[i].Offset); + Subsets[i].Count = os::Byteswap::byteswap(Subsets[i].Count); + Subsets[i].TextID1 = os::Byteswap::byteswap(Subsets[i].TextID1); + Subsets[i].TextID2 = os::Byteswap::byteswap(Subsets[i].TextID2); + } + if (subsetUserSize>0) + file->seek(subsetUserSize,true); + } + + // TRIANGLES + + file->read(&id, sizeof(u32)); + if (FlipEndianess) + id = os::Byteswap::byteswap(id); + if (id != 0x53495254) // "TRIS" + { + os::Printer::log("LMTS ERROR: wrong triangle magic id!", ELL_ERROR); + cleanup(); + return 0; + } + + Triangles = new SLMTSTriangleDataEntry[(Header.TriangleCount*3)]; + const s32 triUserSize = Header.VertexSize - sizeof(SLMTSTriangleDataEntry); + + for (i=0; i<(Header.TriangleCount*3); ++i) + { + file->read(&Triangles[i], sizeof(SLMTSTriangleDataEntry)); + if (FlipEndianess) + { + Triangles[i].X = os::Byteswap::byteswap(Triangles[i].X); + Triangles[i].Y = os::Byteswap::byteswap(Triangles[i].Y); + Triangles[i].Z = os::Byteswap::byteswap(Triangles[i].Z); + Triangles[i].U1 = os::Byteswap::byteswap(Triangles[i].U1); + Triangles[i].V1 = os::Byteswap::byteswap(Triangles[i].U2); + Triangles[i].U2 = os::Byteswap::byteswap(Triangles[i].V1); + Triangles[i].V2 = os::Byteswap::byteswap(Triangles[i].V2); + } + if (triUserSize>0) + file->seek(triUserSize,true); + } + + ///////////////////////////////////////////////////////////////// + + SMesh* mesh = new SMesh(); + + constructMesh(mesh); + + loadTextures(mesh); + + cleanup(); + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_LMTS; // not unknown to irrlicht anymore + + am->addMesh(mesh); + am->recalculateBoundingBox(); + mesh->drop(); + return am; +} + + +void CLMTSMeshFileLoader::constructMesh(SMesh* mesh) +{ + for (s32 i=0; iMaterial.MaterialType = video::EMT_LIGHTMAP; + meshBuffer->Material.Wireframe = false; + meshBuffer->Material.Lighting = false; + + mesh->addMeshBuffer(meshBuffer); + + const u32 offs = Subsets[i].Offset * 3; + + for (u32 sc=0; scgetVertexCount(); + + for (u32 vu=0; vu<3; ++vu) + { + const SLMTSTriangleDataEntry& v = Triangles[offs+(3*sc)+vu]; + meshBuffer->Vertices.push_back( + video::S3DVertex2TCoords( + v.X, v.Y, v.Z, + video::SColor(255,255,255,255), + v.U1, v.V1, v.U2, v.V2)); + } + const core::vector3df normal = core::plane3df( + meshBuffer->Vertices[idx].Pos, + meshBuffer->Vertices[idx+1].Pos, + meshBuffer->Vertices[idx+2].Pos).Normal; + + meshBuffer->Vertices[idx].Normal = normal; + meshBuffer->Vertices[idx+1].Normal = normal; + meshBuffer->Vertices[idx+2].Normal = normal; + + meshBuffer->Indices.push_back(idx); + meshBuffer->Indices.push_back(idx+1); + meshBuffer->Indices.push_back(idx+2); + } + meshBuffer->drop(); + } + + for (u32 j=0; jMeshBuffers.size(); ++j) + mesh->MeshBuffers[j]->recalculateBoundingBox(); + + mesh->recalculateBoundingBox(); +} + + +void CLMTSMeshFileLoader::loadTextures(SMesh* mesh) +{ + if (!Driver || !FileSystem) + return; + + // load textures + + // a little too much space, but won't matter here + core::array tex; + tex.reallocate(Header.TextureCount); + core::array lig; + lig.reallocate(Header.TextureCount); + core::array id2id; + id2id.reallocate(Header.TextureCount); + + const core::stringc Path = Parameters->getAttributeAsString(LMTS_TEXTURE_PATH); + + core::stringc s; + for (u32 t=0; texistFile(s)) + tmptex = Driver->getTexture(s); + else + os::Printer::log("LMTS WARNING: Texture does not exist", s.c_str(), ELL_WARNING); + + if (Textures[t].Flags & 0x01) + { + id2id.push_back(lig.size()); + lig.push_back(tmptex); + } + else + { + id2id.push_back(tex.size()); + tex.push_back(tmptex); + } + } + + // attach textures to materials. + + for (u32 i=0; igetMeshBuffer(i)->getMaterial().setTexture(0, tex[id2id[Subsets[i].TextID1]]); + if (Subsets[i].TextID2 < Header.TextureCount && id2id[Subsets[i].TextID2] < lig.size()) + mesh->getMeshBuffer(i)->getMaterial().setTexture(1, lig[id2id[Subsets[i].TextID2]]); + + if (!mesh->getMeshBuffer(i)->getMaterial().getTexture(1)) + mesh->getMeshBuffer(i)->getMaterial().MaterialType = video::EMT_SOLID; + } +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_LMTS_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.h new file mode 100644 index 0000000..4e3bb09 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLMTSMeshFileLoader.h @@ -0,0 +1,109 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// I (Nikolaus Gebhardt) did some few changes to Jonas Petersen's original loader: +// - removed setTexturePath() and replaced with the ISceneManager::getStringParameter()-stuff. +// - added EAMT_LMTS enumeration value +// Thanks a lot to Jonas Petersen for his work +// on this and that he gave me his permission to add it into Irrlicht. +/* + +CLMTSMeshFileLoader.h + +LMTSMeshFileLoader +Written by Jonas Petersen (a.k.a. jox) + +Version 1.5 - 15 March 2005 + +*/ + +#if !defined(__C_LMTS_MESH_FILE_LOADER_H_INCLUDED__) +#define __C_LMTS_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "SMesh.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + +class CLMTSMeshFileLoader : public IMeshLoader +{ +public: + + CLMTSMeshFileLoader(io::IFileSystem* fs, + video::IVideoDriver* driver, io::IAttributes* parameters); + + virtual ~CLMTSMeshFileLoader(); + + virtual bool isALoadableFileExtension(const io::path& filename) const; + + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + void constructMesh(SMesh* mesh); + void loadTextures(SMesh* mesh); + void cleanup(); + +// byte-align structures +#include "irrpack.h" + + struct SLMTSHeader + { + u32 MagicID; + u32 Version; + u32 HeaderSize; + u16 TextureCount; + u16 SubsetCount; + u32 TriangleCount; + u16 SubsetSize; + u16 VertexSize; + } PACK_STRUCT; + + struct SLMTSTextureInfoEntry + { + c8 Filename[256]; + u16 Flags; + } PACK_STRUCT; + + struct SLMTSSubsetInfoEntry + { + u32 Offset; + u32 Count; + u16 TextID1; + u16 TextID2; + } PACK_STRUCT; + + struct SLMTSTriangleDataEntry + { + f32 X; + f32 Y; + f32 Z; + f32 U1; + f32 V1; + f32 U2; + f32 V2; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + SLMTSHeader Header; + SLMTSTextureInfoEntry* Textures; + SLMTSSubsetInfoEntry* Subsets; + SLMTSTriangleDataEntry* Triangles; + + io::IAttributes* Parameters; + video::IVideoDriver* Driver; + io::IFileSystem* FileSystem; + bool FlipEndianess; +}; + +} // end namespace scene +} // end namespace irr + +#endif // !defined(__C_LMTS_MESH_FILE_LOADER_H_INCLUDED__) diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.cpp new file mode 100644 index 0000000..6534727 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.cpp @@ -0,0 +1,2114 @@ +// Copyright (C) 2007-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLWOMeshFileLoader.h" +#include "os.h" +#include "SAnimatedMesh.h" +#include "SMesh.h" +#include "IReadFile.h" +#include "ISceneManager.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "IMeshManipulator.h" + +namespace irr +{ +namespace scene +{ + +#ifdef _DEBUG +#define LWO_READER_DEBUG +#endif + +#define charsToUIntD(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d) +inline unsigned int charsToUInt(const char *str) +{ + return (str[0] << 24) | (str[1] << 16) | (str[2] << 8) | str[3]; +} + + +struct tLWOTextureInfo +{ + tLWOTextureInfo() : UVTag(0), DUVTag(0), Flags(0), WidthWrap(2), + HeightWrap(2), OpacType(0), Color(0xffffffff), + Value(0.0f), AntiAliasing(1.0f), Opacity(1.0f), + Axis(255), Projection(0), Active(false) {} + core::stringc Type; + core::stringc Map; + core::stringc AlphaMap; + core::stringc UVname; + u16 UVTag; + u16 DUVTag; + u16 Flags; + u16 WidthWrap; + u16 HeightWrap; + u16 OpacType; + u16 IParam[3]; + core::vector3df Size; + core::vector3df Center; + core::vector3df Falloff; + core::vector3df Velocity; + video::SColor Color; + f32 Value; + f32 AntiAliasing; + f32 Opacity; + f32 FParam[3]; + u8 Axis; + u8 Projection; + bool Active; +}; + +struct CLWOMeshFileLoader::tLWOMaterial +{ + tLWOMaterial() : Meshbuffer(0), TagType(0), Flags(0), ReflMode(3), TranspMode(3), + Glow(0), AlphaMode(2), Luminance(0.0f), Diffuse(1.0f), Specular(0.0f), + Reflection(0.0f), Transparency(0.0f), Translucency(0.0f), + Sharpness(0.0f), ReflSeamAngle(0.0f), ReflBlur(0.0f), + RefrIndex(1.0f), TranspBlur(0.0f), SmoothingAngle(0.0f), + EdgeTransparency(0.0f), HighlightColor(0.0f), ColorFilter(0.0f), + AdditiveTransparency(0.0f), GlowIntensity(0.0f), GlowSize(0.0f), + AlphaValue(0.0f), VertexColorIntensity(0.0f), VertexColor() {} + + core::stringc Name; + scene::SMeshBuffer *Meshbuffer; + core::stringc ReflMap; + u16 TagType; + u16 Flags; + u16 ReflMode; + u16 TranspMode; + u16 Glow; + u16 AlphaMode; + f32 Luminance; + f32 Diffuse; + f32 Specular; + f32 Reflection; + f32 Transparency; + f32 Translucency; + f32 Sharpness; + f32 ReflSeamAngle; + f32 ReflBlur; + f32 RefrIndex; + f32 TranspBlur; + f32 SmoothingAngle; + f32 EdgeTransparency; + f32 HighlightColor; + f32 ColorFilter; + f32 AdditiveTransparency; + f32 GlowIntensity; + f32 GlowSize; + f32 AlphaValue; + f32 VertexColorIntensity; + video::SColorf VertexColor; + u32 Envelope[23]; + tLWOTextureInfo Texture[7]; +}; + +struct tLWOLayerInfo +{ + u16 Number; + u16 Parent; + u16 Flags; + bool Active; + core::stringc Name; + core::vector3df Pivot; +}; + + +//! Constructor +CLWOMeshFileLoader::CLWOMeshFileLoader(scene::ISceneManager* smgr, + io::IFileSystem* fs) +: SceneManager(smgr), FileSystem(fs), File(0), Mesh(0) +{ + #ifdef _DEBUG + setDebugName("CLWOMeshFileLoader"); + #endif +} + + +//! destructor +CLWOMeshFileLoader::~CLWOMeshFileLoader() +{ + if (Mesh) + Mesh->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CLWOMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension(filename, "lwo"); +} + + +//! creates/loads an animated mesh from the file. +IAnimatedMesh* CLWOMeshFileLoader::createMesh(io::IReadFile* file) +{ + File = file; + + if (Mesh) + Mesh->drop(); + + Mesh = new SMesh(); + + if (!readFileHeader()) + return 0; + + if (!readChunks()) + return 0; + +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Creating geometry."); + os::Printer::log("LWO loader: Assigning UV maps."); +#endif + u32 i; + for (i=0; iTexture[j].UVname.size()) + { + for (uvTag=0; uvTagTexture[j].UVname == UvName[uvTag]) + { + Materials[i]->Texture[j].UVTag=uvTag; + break; + } + } + for (uvTag=0; uvTagTexture[j].UVname == DUvName[uvTag]) + { + Materials[i]->Texture[j].DUVTag=uvTag; + break; + } + } + } + } + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Creating polys."); +#endif + // create actual geometry for lwo2 + if (FormatVersion==2) + { + core::array vertexCount; + vertexCount.reallocate(Materials.size()); + for (i=0; iMeshbuffer->Vertices.reallocate(vertexCount[i]); + Materials[i]->Meshbuffer->Indices.reallocate(vertexCount[i]); + } + } + // create actual geometry for lwo2 + for (u32 polyIndex=0; polyIndexMeshbuffer; + const core::array& poly = Indices[polyIndex]; + const u32 polySize=poly.size(); + const u16 uvTag = Materials[tag]->Texture[0].UVTag; + const u16 duvTag = Materials[tag]->Texture[0].DUVTag; + video::S3DVertex vertex; + vertex.Color=0xffffffff; + const u32 vertCount=mb->Vertices.size(); + for (u32 i=0; iVertices.push_back(vertex); + } + // triangulate as trifan + if (polySize>2) + { + for (u32 i=1; iIndices.push_back(vertCount); + mb->Indices.push_back(vertCount+i); + mb->Indices.push_back(vertCount+i+1); + } + } + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Fixing meshbuffers."); +#endif + for (u32 i=0; iName); + os::Printer::log("LWO loader: Vertex count", core::stringc(Materials[i]->Meshbuffer->Vertices.size())); +#endif + if (!Materials[i]->Meshbuffer->Vertices.size()) + { + Materials[i]->Meshbuffer->drop(); + delete Materials[i]; + continue; + } + for (u32 j=0; jMeshbuffer->Vertices.size(); ++j) + Materials[i]->Meshbuffer->Vertices[j].Color=Materials[i]->Meshbuffer->Material.DiffuseColor; + Materials[i]->Meshbuffer->recalculateBoundingBox(); + + // load textures + video::SMaterial& irrMat=Materials[i]->Meshbuffer->Material; + if (Materials[i]->Texture[0].Map != "") // diffuse + irrMat.setTexture(0,loadTexture(Materials[i]->Texture[0].Map)); + if (Materials[i]->Texture[3].Map != "") // reflection + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection texture."); +#endif + video::ITexture* reflTexture = loadTexture(Materials[i]->Texture[3].Map); + if (reflTexture && irrMat.getTexture(0)) + irrMat.setTexture(1, irrMat.getTexture(0)); + irrMat.setTexture(0, reflTexture); + irrMat.MaterialType=video::EMT_REFLECTION_2_LAYER; + } + if (Materials[i]->Texture[4].Map != "") // transparency + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency texture."); +#endif + video::ITexture* transTexture = loadTexture(Materials[i]->Texture[4].Map); + if (transTexture && irrMat.getTexture(0)) + irrMat.setTexture(1, irrMat.getTexture(0)); + irrMat.setTexture(0, transTexture); + irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } + if (Materials[i]->Texture[6].Map != "") // bump + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading bump texture."); +#endif + const u8 pos = irrMat.getTexture(0)?1:0; + irrMat.setTexture(pos, loadTexture(Materials[i]->Texture[6].Map)); + if (irrMat.getTexture(pos)) + { + // SceneManager->getVideoDriver()->makeNormalMapTexture(irrMat.getTexture(1)); + // irrMat.MaterialType=video::EMT_NORMAL_MAP_SOLID; + } + } + + // cope with planar mapping texture coords + if (Materials[i]->Texture[0].Projection != 5) + { + if (FormatVersion!=2) + { + if (Materials[i]->Texture[0].Flags&1) + Materials[i]->Texture[0].Axis=0; + else if (Materials[i]->Texture[0].Flags&2) + Materials[i]->Texture[0].Axis=1; + else if (Materials[i]->Texture[0].Flags&4) + Materials[i]->Texture[0].Axis=2; + } + // if no axis given choose the dominant one + else if (Materials[i]->Texture[0].Axis>2) + { + if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().YMeshbuffer->getBoundingBox().getExtent().X) + { + if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().YMeshbuffer->getBoundingBox().getExtent().Z) + Materials[i]->Texture[0].Axis=1; + else + Materials[i]->Texture[0].Axis=2; + } + else + { + if (Materials[i]->Meshbuffer->getBoundingBox().getExtent().XMeshbuffer->getBoundingBox().getExtent().Z) + Materials[i]->Texture[0].Axis=0; + else + Materials[i]->Texture[0].Axis=2; + } + } + // get the resolution for this axis + f32 resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.Z); + f32 resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); + if (Materials[i]->Texture[0].Axis==1) + { + resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); + resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Z); + } + else if (Materials[i]->Texture[0].Axis==2) + { + resolutionS = core::reciprocal(Materials[i]->Texture[0].Size.X); + resolutionT = core::reciprocal(Materials[i]->Texture[0].Size.Y); + } + // use the two-way planar mapping + SceneManager->getMeshManipulator()->makePlanarTextureMapping(Materials[i]->Meshbuffer, resolutionS, resolutionT, Materials[i]->Texture[0].Axis, Materials[i]->Texture[0].Center); + } + + // add bump maps + if (Materials[i]->Meshbuffer->Material.MaterialType==video::EMT_NORMAL_MAP_SOLID) + { + SMesh* tmpmesh = new SMesh(); + tmpmesh->addMeshBuffer(Materials[i]->Meshbuffer); + SceneManager->getMeshManipulator()->createMeshWithTangents(tmpmesh, true, true); + Mesh->addMeshBuffer(tmpmesh->getMeshBuffer(0)); + tmpmesh->getMeshBuffer(0)->drop(); + tmpmesh->drop(); + } + else + { + SceneManager->getMeshManipulator()->recalculateNormals(Materials[i]->Meshbuffer); + Mesh->addMeshBuffer(Materials[i]->Meshbuffer); + } + Materials[i]->Meshbuffer->drop(); + // clear the material array elements + delete Materials[i]; + } + Mesh->recalculateBoundingBox(); + + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + + Points.clear(); + Indices.clear(); + MaterialMapping.clear(); + TCoords.clear(); + Materials.clear(); + Images.clear(); + VmPolyPointsIndex.clear(); + VmCoordsIndex.clear(); + UvIndex.clear(); + UvName.clear(); + + return am; +} + + +bool CLWOMeshFileLoader::readChunks() +{ + s32 lastPos; + u32 size; + unsigned int uiType; + char type[5]; + type[4]=0; + tLWOLayerInfo layer; + + while(File->getPos()getSize()) + { + File->read(&type, 4); + //Convert 4-char string to 4-byte integer + //Makes it possible to do a switch statement + uiType = charsToUInt(type); + File->read(&size, 4); +#ifndef __BIG_ENDIAN__ + size=os::Byteswap::byteswap(size); +#endif + lastPos=File->getPos(); + + switch(uiType) + { + case charsToUIntD('L','A','Y','R'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading layer."); +#endif + u16 tmp16; + File->read(&tmp16, 2); // number + File->read(&tmp16, 2); // flags + size -= 4; +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + if (((FormatVersion==1)&&(tmp16!=1)) || + ((FormatVersion==2)&&(tmp16&1))) + layer.Active=false; + else + layer.Active=true; + if (FormatVersion==2) + size -= readVec(layer.Pivot); + size -= readString(layer.Name); + if (size) + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + layer.Parent = tmp16; + } + } + break; + case charsToUIntD('P','N','T','S'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading points."); +#endif + core::vector3df vec; + Points.clear(); + const u32 tmpsize = size/12; + Points.reallocate(tmpsize); + for (u32 i=0; iName=""; + mat->Meshbuffer=new scene::SMeshBuffer(); + size -= readString(mat->Name); + if (FormatVersion!=2) + mat->TagType = 1; // format 2 has more types + Materials.push_back(mat); + } + } + break; + case charsToUIntD('P','T','A','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading tag mapping."); +#endif + readTagMapping(size); + break; + case charsToUIntD('V','M','A','D'): // discontinuous vertex mapping, i.e. additional texcoords +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Vertex mapping VMAD."); +#endif + readDiscVertexMapping(size); +// case charsToUIntD('V','M','P','A'): +// case charsToUIntD('E','N','V','L'): + break; + case charsToUIntD('C','L','I','P'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading clips."); +#endif + u32 index; + u16 subsize; + File->read(&index, 4); +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); +#endif + size -= 4; + while (size != 0) + { + File->read(&type, 4); + File->read(&subsize, 2); +#ifndef __BIG_ENDIAN__ + subsize=os::Byteswap::byteswap(subsize); +#endif + size -= 6; + if (strncmp(type, "STIL", 4)) + { + File->seek(subsize, true); + size -= subsize; + continue; + } + core::stringc path; + size -= readString(path, subsize); + #ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loaded clip", path.c_str()); + #endif + Images.push_back(path); + } + } + break; + case charsToUIntD('S','U','R','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading material."); +#endif + readMat(size); + break; + case charsToUIntD('B','B','O','X'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading bbox."); +#endif + // not stored + core::vector3df vec; + for (u32 i=0; i<2; ++i) + readVec(vec); + size -= 24; + } + break; + case charsToUIntD('D','E','S','C'): + case charsToUIntD('T','E','X','T'): + { + core::stringc text; + size -= readString(text, size); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader text", text); +#endif + } + break; + // not needed + case charsToUIntD('I','C','O','N'): + // not yet supported + case charsToUIntD('P','C','H','S'): + case charsToUIntD('C','R','V','S'): + default: +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: skipping ", type); +#endif + //Go to next chunk + File->seek(lastPos + size, false); + break; + } + } + return true; +} + + +void CLWOMeshFileLoader::readObj1(u32 size) +{ + u32 pos; + u16 numVerts, vertIndex; + s16 material; + video::S3DVertex vertex; + vertex.Color=0xffffffff; + + while (size!=0) + { + File->read(&numVerts, 2); +#ifndef __BIG_ENDIAN__ + numVerts=os::Byteswap::byteswap(numVerts); +#endif + pos=File->getPos(); + // skip forward to material number + File->seek(2*numVerts, true); + File->read(&material, 2); +#ifndef __BIG_ENDIAN__ + material=os::Byteswap::byteswap(material); +#endif + size -=2*numVerts+4; + // detail meshes ? + scene::SMeshBuffer *mb; + if (material<0) + mb=Materials[-material-1]->Meshbuffer; + else + mb=Materials[material-1]->Meshbuffer; + // back to vertex list start + File->seek(pos, false); + + const u16 vertCount=mb->Vertices.size(); + for (u16 i=0; iread(&vertIndex, 2); +#ifndef __BIG_ENDIAN__ + vertIndex=os::Byteswap::byteswap(vertIndex); +#endif + vertex.Pos=Points[vertIndex]; + mb->Vertices.push_back(vertex); + } + for (u16 i=1; iIndices.push_back(vertCount); + mb->Indices.push_back(vertCount+i); + mb->Indices.push_back(vertCount+i+1); + } + // skip material number and detail surface count + // detail surface can be read just as a normal one now + if (material<0) + File->read(&material, 2); + File->read(&material, 2); + } +} + + +void CLWOMeshFileLoader::readVertexMapping(u32 size) +{ + char type[5]={0}; + u16 dimension; + core::stringc name; + File->read(&type, 4); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Vertex map type", type); +#endif + File->read(&dimension,2); +#ifndef __BIG_ENDIAN__ + dimension=os::Byteswap::byteswap(dimension); +#endif + size -= 6; + size -= readString(name); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Vertex map", name.c_str()); +#endif + if (strncmp(type, "TXUV", 4)) // also support RGB, RGBA, WGHT, ... + { + File->seek(size, true); + return; + } + UvName.push_back(name); + + TCoords.push_back(core::array()); + core::array& UvCoords=TCoords.getLast(); + UvCoords.reallocate(Points.size()); + UvIndex.push_back(core::array()); + core::array& UvPointsArray=UvIndex.getLast(); + UvPointsArray.reallocate(Points.size()); + + u32 index; + core::vector2df tcoord; + while (size) + { + size -= readVX(index); + File->read(&tcoord.X, 4); + File->read(&tcoord.Y, 4); + size -= 8; +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); + tcoord.X=os::Byteswap::byteswap(tcoord.X); + tcoord.Y=os::Byteswap::byteswap(tcoord.Y); +#endif + UvCoords.push_back(tcoord); + UvPointsArray.push_back(index); + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: UvCoords", core::stringc(UvCoords.size())); +#endif +} + + +void CLWOMeshFileLoader::readDiscVertexMapping(u32 size) +{ + char type[5]={0}; + u16 dimension; + core::stringc name; + File->read(&type, 4); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Discontinuous vertex map type", type); +#endif + File->read(&dimension,2); +#ifndef __BIG_ENDIAN__ + dimension=os::Byteswap::byteswap(dimension); +#endif + size -= 6; + size -= readString(name); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: Discontinuous vertex map", name.c_str()); +#endif + if (strncmp(type, "TXUV", 4)) + { + File->seek(size, true); + return; + } + DUvName.push_back(name); + VmPolyPointsIndex.push_back(core::array()); + core::array& VmPolyPoints=VmPolyPointsIndex.getLast(); + + VmCoordsIndex.push_back(core::array()); + core::array& VmCoords=VmCoordsIndex.getLast(); + + u32 vmpolys; + u32 vmpoints; + core::vector2df vmcoords; + while (size) + { + size-=readVX(vmpoints); + size-=readVX(vmpolys); + File->read(&vmcoords.X, 4); + File->read(&vmcoords.Y, 4); + size -= 8; +#ifndef __BIG_ENDIAN__ + vmpoints=os::Byteswap::byteswap(vmpoints); + vmpolys=os::Byteswap::byteswap(vmpolys); + vmcoords.X=os::Byteswap::byteswap(vmcoords.X); + vmcoords.Y=os::Byteswap::byteswap(vmcoords.Y); +#endif + VmCoords.push_back(vmcoords); + VmPolyPoints.push_back(vmpolys); + VmPolyPoints.push_back(vmpoints); + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: VmCoords", core::stringc(VmCoords.size())); +#endif +} + + +void CLWOMeshFileLoader::readTagMapping(u32 size) +{ + char type[5]; + type[4]=0; + File->read(&type, 4); + size -= 4; + if ((strncmp(type, "SURF", 4))||(Indices.size()==0)) + { + File->seek(size, true); + return; + } + + while (size!=0) + { + u16 tag; + u32 polyIndex; + size-=readVX(polyIndex); + File->read(&tag, 2); +#ifndef __BIG_ENDIAN__ + tag=os::Byteswap::byteswap(tag); +#endif + size -= 2; + MaterialMapping[polyIndex]=tag; + Materials[tag]->TagType=1; + } +} + + +void CLWOMeshFileLoader::readObj2(u32 size) +{ + char type[5]; + type[4]=0; + File->read(&type, 4); + size -= 4; + Indices.clear(); + if (strncmp(type, "FACE", 4)) // also possible are splines, subdivision patches, metaballs, and bones + { + File->seek(size, true); + return; + } + u16 numVerts=0; + while (size!=0) + { + File->read(&numVerts, 2); +#ifndef __BIG_ENDIAN__ + numVerts=os::Byteswap::byteswap(numVerts); +#endif + // mask out flags + numVerts &= 0x03FF; + + size -= 2; + Indices.push_back(core::array()); + u32 vertIndex; + core::array& polyArray = Indices.getLast(); + polyArray.reallocate(numVerts); + for (u16 i=0; iTagType==1) && (Materials[i]->Name==name)) + { + mat=Materials[i]; + break; + } + } + if (!mat) + { + File->seek(size, true); + return; + } + if (FormatVersion==2) + size -= readString(name); + + video::SMaterial& irrMat=mat->Meshbuffer->Material; + + u8 currTexture=0; + while (size!=0) + { + char type[5]; + type[4]=0; + u32 uiType; + u32 tmp32; + u16 subsize, tmp16; + f32 tmpf32; + File->read(&type, 4); + //Convert 4-char string to 4-byte integer + //Makes it possible to do a switch statement + uiType = charsToUInt(type); + File->read(&subsize, 2); +#ifndef __BIG_ENDIAN__ + subsize=os::Byteswap::byteswap(subsize); +#endif + size -= 6; + switch (uiType) + { + case charsToUIntD('C','O','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Ambient color."); +#endif + { + s32 colSize = readColor(irrMat.DiffuseColor); + irrMat.AmbientColor=irrMat.DiffuseColor; + size -= colSize; + subsize -= colSize; + if (FormatVersion==2) + size -= readVX(mat->Envelope[0]); + } + break; + case charsToUIntD('D','I','F','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Diffuse color."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Diffuse, 4); +#ifndef __BIG_ENDIAN__ + mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[1]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Diffuse=tmp16/256.0f; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('V','D','I','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading Diffuse color."); +#endif + { + File->read(&mat->Diffuse, 4); +#ifndef __BIG_ENDIAN__ + mat->Diffuse=os::Byteswap::byteswap(mat->Diffuse); +#endif + size -= 4; + } + break; + case charsToUIntD('L','U','M','I'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading luminance."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Luminance, 4); +#ifndef __BIG_ENDIAN__ + mat->Luminance=os::Byteswap::byteswap(mat->Luminance); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[2]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Luminance=tmp16/256.0f; + size -= 2; + subsize -= 2; + } } + break; + case charsToUIntD('V','L','U','M'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading luminance."); +#endif + { + File->read(&mat->Luminance, 4); +#ifndef __BIG_ENDIAN__ + mat->Luminance=os::Byteswap::byteswap(mat->Luminance); +#endif + size -= 4; + } + break; + case charsToUIntD('S','P','E','C'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading specular."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Specular, 4); +#ifndef __BIG_ENDIAN__ + mat->Specular=os::Byteswap::byteswap(mat->Specular); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[3]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Specular=tmp16/256.0f;; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('V','S','P','C'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading specular."); +#endif + { + File->read(&mat->Specular, 4); +#ifndef __BIG_ENDIAN__ + mat->Specular=os::Byteswap::byteswap(mat->Specular); +#endif + size -= 4; + } + break; + case charsToUIntD('R','E','F','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection."); +#endif + { + if (FormatVersion==2) + { + File->read(&mat->Reflection, 4); +#ifndef __BIG_ENDIAN__ + mat->Reflection=os::Byteswap::byteswap(mat->Reflection); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[4]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Reflection=tmp16/256.0f; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('V','R','F','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection."); +#endif + { + File->read(&mat->Reflection, 4); +#ifndef __BIG_ENDIAN__ + mat->Reflection=os::Byteswap::byteswap(mat->Reflection); +#endif + size -= 4; + } + break; + case charsToUIntD('T','R','A','N'): + { + if (FormatVersion==2) + { + File->read(&mat->Transparency, 4); +#ifndef __BIG_ENDIAN__ + mat->Transparency=os::Byteswap::byteswap(mat->Transparency); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[5]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Transparency=tmp16/256.0f; + size -= 2; + subsize -= 2; + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); +#endif + } + break; + case charsToUIntD('V','T','R','N'): + { + File->read(&mat->Transparency, 4); +#ifndef __BIG_ENDIAN__ + mat->Transparency=os::Byteswap::byteswap(mat->Transparency); +#endif + size -= 4; + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency", core::stringc(mat->Transparency).c_str()); +#endif + break; + case charsToUIntD('T','R','N','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading translucency."); +#endif + { + File->read(&mat->Translucency, 4); +#ifndef __BIG_ENDIAN__ + mat->Translucency=os::Byteswap::byteswap(mat->Translucency); +#endif + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[6]); + } + break; + case charsToUIntD('G','L','O','S'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading glossy."); +#endif + { + if (FormatVersion == 2) + { + File->read(&irrMat.Shininess, 4); +#ifndef __BIG_ENDIAN__ + irrMat.Shininess=os::Byteswap::byteswap(irrMat.Shininess); +#endif + size -= 4; + subsize -= 4; + size -= readVX(mat->Envelope[7]); + } + else + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + irrMat.Shininess=tmp16/16.f; + size -= 2; + subsize -= 2; + } + } + break; + case charsToUIntD('S','H','R','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading sharpness."); +#endif + { + File->read(&mat->Sharpness, 4); +#ifndef __BIG_ENDIAN__ + mat->Sharpness=os::Byteswap::byteswap(mat->Sharpness); +#endif + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[8]); + } + break; + case charsToUIntD('B','U','M','P'): + case charsToUIntD('T','A','M','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading bumpiness."); +#endif + { + File->read(&tmpf32, 4); +#ifndef __BIG_ENDIAN__ + tmpf32=os::Byteswap::byteswap(tmpf32); +#endif + if (currTexture==6) + irrMat.MaterialTypeParam=tmpf32; + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[9]); + } + break; + case charsToUIntD('S','I','D','E'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading backface culled."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + if (tmp16==1) + irrMat.BackfaceCulling=true; + else if (tmp16==3) + irrMat.BackfaceCulling=false; + size -= 2; + } + break; + case charsToUIntD('S','M','A','N'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading smoothing angle."); +#endif + { + File->read(&mat->SmoothingAngle, 4); +#ifndef __BIG_ENDIAN__ + mat->SmoothingAngle=os::Byteswap::byteswap(mat->SmoothingAngle); +#endif + size -= 4; + } + break; + case charsToUIntD('R','F','O','P'): + case charsToUIntD('R','F','L','T'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection mode."); +#endif + { + File->read(&mat->ReflMode, 2); +#ifndef __BIG_ENDIAN__ + mat->ReflMode=os::Byteswap::byteswap(mat->ReflMode); +#endif + size -= 2; + } + break; + case charsToUIntD('R','I','M','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection map."); +#endif + { + if (FormatVersion==2) + { + size -= readVX(tmp32); + if (tmp32) + mat->ReflMap=Images[tmp32-1]; + } + else + size -= readString(mat->ReflMap, size); + } + break; + case charsToUIntD('R','S','A','N'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection seam angle."); +#endif + { + File->read(&mat->ReflSeamAngle, 4); +#ifndef __BIG_ENDIAN__ + mat->ReflSeamAngle=os::Byteswap::byteswap(mat->ReflSeamAngle); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[10]); + } + break; + case charsToUIntD('R','B','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading reflection blur."); +#endif + { + File->read(&mat->ReflBlur, 4); +#ifndef __BIG_ENDIAN__ + mat->ReflBlur=os::Byteswap::byteswap(mat->ReflBlur); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[11]); + } + break; + case charsToUIntD('R','I','N','D'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading refraction index."); +#endif + { + File->read(&mat->RefrIndex, 4); +#ifndef __BIG_ENDIAN__ + mat->RefrIndex=os::Byteswap::byteswap(mat->RefrIndex); +#endif + size -= 4; + subsize -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[12]); + } + break; + case charsToUIntD('T','R','O','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading refraction options."); +#endif + { + File->read(&mat->TranspMode, 2); +#ifndef __BIG_ENDIAN__ + mat->TranspMode=os::Byteswap::byteswap(mat->TranspMode); +#endif + size -= 2; + } + break; + case charsToUIntD('T','I','M','G'): + { + if (FormatVersion==2) + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading refraction map."); +#endif + size -= readVX(tmp32); +#ifndef __BIG_ENDIAN__ + tmp32=os::Byteswap::byteswap(tmp32); +#endif + if (tmp32) + mat->Texture[currTexture].Map=Images[tmp32-1]; + } + else + { + size -= readString(mat->Texture[currTexture].Map, size); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading image", mat->Texture[currTexture].Map.c_str()); +#endif + } + } + break; + case charsToUIntD('T','B','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading transparency blur."); +#endif + { + File->read(&mat->TranspBlur, 4); +#ifndef __BIG_ENDIAN__ + mat->TranspBlur=os::Byteswap::byteswap(mat->TranspBlur); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[13]); + } + break; + case charsToUIntD('C','L','R','H'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading highlight color."); +#endif + { + File->read(&mat->HighlightColor, 4); +#ifndef __BIG_ENDIAN__ + mat->HighlightColor=os::Byteswap::byteswap(mat->HighlightColor); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[14]); + } + break; + case charsToUIntD('C','L','R','F'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading color filter."); +#endif + { + File->read(&mat->ColorFilter, 4); +#ifndef __BIG_ENDIAN__ + mat->ColorFilter=os::Byteswap::byteswap(mat->ColorFilter); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[15]); + } + break; + case charsToUIntD('A','D','T','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading additive transparency."); +#endif + { + File->read(&mat->AdditiveTransparency, 4); +#ifndef __BIG_ENDIAN__ + mat->AdditiveTransparency=os::Byteswap::byteswap(mat->AdditiveTransparency); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[16]); + } + break; + case charsToUIntD('G','L','O','W'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading glow."); +#endif + { + if (FormatVersion==0) + { + File->read(&mat->GlowIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); +#endif + size -= 4; + } + else + { + File->read(&mat->Glow, 2); +#ifndef __BIG_ENDIAN__ + mat->Glow=os::Byteswap::byteswap(mat->Glow); +#endif + size -= 2; + File->read(&mat->GlowIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[17]); + File->read(&mat->GlowSize, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowSize=os::Byteswap::byteswap(mat->GlowSize); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[18]); + } + } + break; + case charsToUIntD('G','V','A','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading glow intensity."); +#endif + { + File->read(&mat->GlowIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->GlowIntensity=os::Byteswap::byteswap(mat->GlowIntensity); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[17]); + } + break; + case charsToUIntD('L','I','N','E'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading isWireframe."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + if (tmp16&1) + irrMat.Wireframe=true; + size -= 2; + if (size!=0) + { + File->read(&irrMat.Thickness, 4); +#ifndef __BIG_ENDIAN__ + irrMat.Thickness=os::Byteswap::byteswap(irrMat.Thickness); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[19]); + } + if (size!=0) + { + video::SColor lineColor; + size -= readColor(lineColor); + if (FormatVersion==2) + size -= readVX(mat->Envelope[20]); + } + } + break; + case charsToUIntD('A','L','P','H'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading alpha mode."); +#endif + { + File->read(&mat->AlphaMode, 2); +#ifndef __BIG_ENDIAN__ + mat->AlphaMode=os::Byteswap::byteswap(mat->AlphaMode); +#endif + size -= 2; + File->read(&mat->AlphaValue, 4); +#ifndef __BIG_ENDIAN__ + mat->AlphaValue=os::Byteswap::byteswap(mat->AlphaValue); +#endif + size -= 4; + } + break; + case charsToUIntD('V','C','O','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading vertex color."); +#endif + { + File->read(&mat->VertexColorIntensity, 4); +#ifndef __BIG_ENDIAN__ + mat->VertexColorIntensity=os::Byteswap::byteswap(mat->VertexColorIntensity); +#endif + size -= 4; + if (FormatVersion==2) + size -= readVX(mat->Envelope[21]); + File->read(&tmp32, 4); // skip type + size -= 4; + core::stringc tmpname; + size -= readString(tmpname, size); +// mat->VertexColor = getColorVMAP(tmpname); + } + break; + case charsToUIntD('F','L','A','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading flag."); +#endif + { + File->read(&mat->Flags, 2); +#ifndef __BIG_ENDIAN__ + mat->Flags=os::Byteswap::byteswap(mat->Flags); +#endif + if (mat->Flags&1) + mat->Luminance=1.0f; + if (mat->Flags&256) + irrMat.BackfaceCulling=false; + size -= 2; + } + break; + case charsToUIntD('E','D','G','E'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading edge."); +#endif + { + File->read(&mat->EdgeTransparency, 4); +#ifndef __BIG_ENDIAN__ + mat->EdgeTransparency=os::Byteswap::byteswap(mat->EdgeTransparency); +#endif + size -= 4; + } + break; + case charsToUIntD('C','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading ctex."); +#endif + currTexture=0; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('D','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading dtex."); +#endif + currTexture=1; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('S','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading stex."); +#endif + currTexture=2; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('R','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading rtex."); +#endif + currTexture=3; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('T','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading ttex."); +#endif + currTexture=4; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('L','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading ltex."); +#endif + currTexture=5; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('B','T','E','X'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading btex."); +#endif + currTexture=6; + size -= readString(mat->Texture[currTexture].Type, size); + break; + case charsToUIntD('T','A','L','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading alpha map."); +#endif + size -= readString(mat->Texture[currTexture].AlphaMap, size); + break; + case charsToUIntD('T','F','L','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture flag."); +#endif + { + File->read(&mat->Texture[currTexture].Flags, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].Flags=os::Byteswap::byteswap(mat->Texture[currTexture].Flags); +#endif + size -= 2; + } + break; + case charsToUIntD('E','N','A','B'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading isEnabled."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Texture[currTexture].Active=(tmp16!=0); + size -= 2; + } + break; + case charsToUIntD('W','R','A','P'): + case charsToUIntD('T','W','R','P'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture wrap."); +#endif + { + File->read(&mat->Texture[currTexture].WidthWrap, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].WidthWrap=os::Byteswap::byteswap(mat->Texture[currTexture].WidthWrap); +#endif + File->read(&mat->Texture[currTexture].HeightWrap, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].HeightWrap=os::Byteswap::byteswap(mat->Texture[currTexture].HeightWrap); +#endif + size -= 4; + } + break; + case charsToUIntD('T','V','E','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture velocity."); +#endif + size -= readVec(mat->Texture[currTexture].Velocity); + break; + case charsToUIntD('T','C','L','R'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture color."); +#endif + size -= readColor(mat->Texture[currTexture].Color); + break; + case charsToUIntD('A','A','S','T'): + case charsToUIntD('T','A','A','S'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture antialias."); +#endif + { + tmp16=0; + if (FormatVersion==2) + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + size -= 2; + } + File->read(&mat->Texture[currTexture].AntiAliasing, 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].AntiAliasing=os::Byteswap::byteswap(mat->Texture[currTexture].AntiAliasing); +#endif + if (tmp16 & ~0x01) + mat->Texture[currTexture].AntiAliasing=0.0f; // disabled + size -= 4; + } + break; + case charsToUIntD('T','O','P','C'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture opacity."); +#endif + { + File->read(&mat->Texture[currTexture].Opacity, 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); +#endif + size -= 4; + } + break; + case charsToUIntD('O','P','A','C'): + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture opacity and type."); +#endif + File->read(&mat->Texture[currTexture].OpacType, 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].OpacType=os::Byteswap::byteswap(mat->Texture[currTexture].OpacType); +#endif + File->read(&mat->Texture[currTexture].Opacity, 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].Opacity=os::Byteswap::byteswap(mat->Texture[currTexture].Opacity); +#endif + size -= 6; + subsize -= 6; + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); + } + break; + case charsToUIntD('A','X','I','S'): + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Texture[currTexture].Axis=(u8)tmp16; + size -= 2; +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading axis value", core::stringc(tmp16).c_str()); +#endif + } + break; + case charsToUIntD('T','M','A','P'): // empty separation chunk + break; + case charsToUIntD('T','C','T','R'): + case charsToUIntD('C','N','T','R'): + { + core::vector3df& center=mat->Texture[currTexture].Center; + size -= readVec(center); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture center", (core::stringc(center.X)+" "+core::stringc(center.Y)+" "+core::stringc(center.Z)).c_str()); +#endif + } + break; + case charsToUIntD('T','S','I','Z'): + case charsToUIntD('S','I','Z','E'): + { + core::vector3df& tsize=mat->Texture[currTexture].Size; + size -= readVec(tsize); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture size", (core::stringc(tsize.X)+" "+core::stringc(tsize.Y)+" "+core::stringc(tsize.Z)).c_str()); +#endif + } + break; + case charsToUIntD('R','O','T','A'): + { + core::vector3df rotation; + size -= readVec(rotation); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture rotation", (core::stringc(rotation.X)+" "+core::stringc(rotation.Y)+" "+core::stringc(rotation.Z)).c_str()); +#endif + } + break; + case charsToUIntD('O','R','E','F'): + { + core::stringc tmpname; + size -= readString(tmpname); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: texture reference object", tmpname.c_str()); +#endif + } + break; + case charsToUIntD('T','F','A','L'): + case charsToUIntD('F','A','L','L'): + { + if (FormatVersion==2) + { + u16 tmp16; + File->read(&tmp16, 2); + size -= 2; +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + } + + core::vector3df& falloff=mat->Texture[currTexture].Falloff; + size -= readVec(falloff); + if (FormatVersion==2) + size -= readVX(mat->Envelope[22]); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture falloff"); +#endif + } + break; + case charsToUIntD('C','S','Y','S'): + { + u16 tmp16; + File->read(&tmp16, 2); + size -= 2; +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: texture coordinate system", tmp16==0?"object coords":"world coords"); +#endif + } + break; + case charsToUIntD('T','V','A','L'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture value."); +#endif + { + File->read(&tmp16, 2); +#ifndef __BIG_ENDIAN__ + tmp16=os::Byteswap::byteswap(tmp16); +#endif + mat->Texture[currTexture].Value=tmp16/256.0f; + size -= 2; + } + break; + case charsToUIntD('T','F','P','0'): + case charsToUIntD('T','S','P','0'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 0."); +#endif + { + File->read(&mat->Texture[currTexture].FParam[0], 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].FParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[0]); +#endif + size -= 4; + } + break; + case charsToUIntD('T','F','P','1'): + case charsToUIntD('T','S','P','1'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 1."); +#endif + { + File->read(&mat->Texture[currTexture].FParam[1], 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].FParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[1]); +#endif + size -= 4; + } + break; + case charsToUIntD('T','F','P','2'): + case charsToUIntD('T','S','P','2'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 2."); +#endif + { + File->read(&mat->Texture[currTexture].FParam[2], 4); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].FParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].FParam[2]); +#endif + size -= 4; + } + break; + case charsToUIntD('T','F','R','Q'): + case charsToUIntD('T','I','P','0'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture iparam 0."); +#endif + { + File->read(&mat->Texture[currTexture].IParam[0], 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].IParam[0]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[0]); +#endif + size -= 2; + } + break; + case charsToUIntD('T','I','P','1'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 1."); +#endif + { + File->read(&mat->Texture[currTexture].IParam[1], 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].IParam[1]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[1]); +#endif + size -= 2; + } + break; + case charsToUIntD('T','I','P','2'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading texture param 2."); +#endif + { + File->read(&mat->Texture[currTexture].IParam[2], 2); +#ifndef __BIG_ENDIAN__ + mat->Texture[currTexture].IParam[2]=os::Byteswap::byteswap(mat->Texture[currTexture].IParam[2]); +#endif + size -= 2; + } + break; + case charsToUIntD('V','M','A','P'): + { + size -= readString(mat->Texture[currTexture].UVname); +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading material vmap binding",mat->Texture[currTexture].UVname.c_str()); +#endif + } + break; + case charsToUIntD('B','L','O','K'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading blok."); +#endif + { + core::stringc ordinal; + File->read(&type, 4); + File->read(&subsize, 2); +#ifndef __BIG_ENDIAN__ + subsize=os::Byteswap::byteswap(subsize); +#endif + size -= 6; + size -= readString(ordinal, size); + } + break; + case charsToUIntD('C','H','A','N'): + { + File->read(&type, 4); + size -= 4; + if (!strncmp(type, "COLR", 4)) + currTexture=0; + else if (!strncmp(type, "DIFF", 4)) + currTexture=1; + else if (!strncmp(type, "LUMI", 4)) + currTexture=5; + else if (!strncmp(type, "SPEC", 4)) + currTexture=2; + else if (!strncmp(type, "REFL", 4)) + currTexture=3; + else if (!strncmp(type, "TRAN", 4)) + currTexture=4; + else if (!strncmp(type, "BUMP", 4)) + currTexture=6; + } +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading channel ", type); +#endif + break; + case charsToUIntD('I','M','A','G'): +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading channel map."); +#endif + { + u16 index; + File->read(&index, 2); +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); +#endif + size -= 2; + if (index) + mat->Texture[currTexture].Map=Images[index-1]; + } + break; + case charsToUIntD('P','R','O','J'): // define the projection type +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: loading channel projection type."); +#endif + { + u16 index; + File->read(&index, 2); +#ifndef __BIG_ENDIAN__ + index=os::Byteswap::byteswap(index); +#endif + size -= 2; +#ifdef LWO_READER_DEBUG + if (index != 5) + os::Printer::log("LWO loader: wrong channel projection type", core::stringc(index).c_str()); +#endif + mat->Texture[currTexture].Projection=(u8)index; + } + break; + case charsToUIntD('W','R','P','W'): // for cylindrical and spherical projections + case charsToUIntD('W','R','P','H'): // for cylindrical and spherical projections + default: + { +#ifdef LWO_READER_DEBUG + os::Printer::log("LWO loader: skipping ", core::stringc((char*)&uiType, 4)); +#endif + File->seek(subsize, true); + size -= subsize; + } + } + } + + if (mat->Transparency != 0.f) + { + irrMat.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } +} + + +u32 CLWOMeshFileLoader::readColor(video::SColor& color) +{ + if (FormatVersion!=2) + { + u8 colorComponent; + File->read(&colorComponent, 1); + color.setRed(colorComponent); + File->read(&colorComponent, 1); + color.setGreen(colorComponent); + File->read(&colorComponent, 1); + color.setBlue(colorComponent); + // unknown value + File->read(&colorComponent, 1); + return 4; + } + else + { + video::SColorf col; + File->read(&col.r, 4); +#ifndef __BIG_ENDIAN__ + col.r=os::Byteswap::byteswap(col.r); +#endif + File->read(&col.g, 4); +#ifndef __BIG_ENDIAN__ + col.g=os::Byteswap::byteswap(col.g); +#endif + File->read(&col.b, 4); +#ifndef __BIG_ENDIAN__ + col.b=os::Byteswap::byteswap(col.b); +#endif + color=col.toSColor(); + return 12; + } +} + +u32 CLWOMeshFileLoader::readString(core::stringc& name, u32 size) +{ + c8 c; + + name=""; + if (size) + name.reserve(size); + File->read(&c, 1); + while (c) + { + name.append(c); + File->read(&c, 1); + } + // read extra 0 upon odd file position + if (File->getPos() & 0x1) + { + File->read(&c, 1); + return (name.size()+2); + } + return (name.size()+1); +} + + +u32 CLWOMeshFileLoader::readVec(core::vector3df& vec) +{ + File->read(&vec.X, 4); +#ifndef __BIG_ENDIAN__ + vec.X=os::Byteswap::byteswap(vec.X); +#endif + File->read(&vec.Y, 4); +#ifndef __BIG_ENDIAN__ + vec.Y=os::Byteswap::byteswap(vec.Y); +#endif + File->read(&vec.Z, 4); +#ifndef __BIG_ENDIAN__ + vec.Z=os::Byteswap::byteswap(vec.Z); +#endif + return 12; +} + + +u32 CLWOMeshFileLoader::readVX(u32& num) +{ + u16 tmpIndex; + + File->read(&tmpIndex, 2); +#ifndef __BIG_ENDIAN__ + tmpIndex=os::Byteswap::byteswap(tmpIndex); +#endif + num=tmpIndex; + if (num >= 0xFF00) + { + File->read(&tmpIndex, 2); +#ifndef __BIG_ENDIAN__ + tmpIndex=os::Byteswap::byteswap(tmpIndex); +#endif + num=((num << 16)|tmpIndex) & ~0xFF000000; + return 4; + } + return 2; +} + + +bool CLWOMeshFileLoader::readFileHeader() +{ + u32 Id; + + File->read(&Id, 4); +#ifndef __BIG_ENDIAN__ + Id=os::Byteswap::byteswap(Id); +#endif + if (Id != 0x464f524d) // FORM + return false; + + //skip the file length + File->read(&Id, 4); + + File->read(&Id, 4); +#ifndef __BIG_ENDIAN__ + Id=os::Byteswap::byteswap(Id); +#endif + // Currently supported: LWOB, LWLO, LWO2 + switch (Id) + { + case 0x4c574f42: + FormatVersion = 0; // LWOB + break; + case 0x4c574c4f: + FormatVersion = 1; // LWLO + break; + case 0x4c574f32: + FormatVersion = 2; // LWO2 + break; + default: + return false; // unsupported + } + + return true; +} + + +video::ITexture* CLWOMeshFileLoader::loadTexture(const core::stringc& file) +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (FileSystem->existFile(file)) + return driver->getTexture(file); + + core::stringc strippedName=FileSystem->getFileBasename(file); + if (FileSystem->existFile(strippedName)) + return driver->getTexture(strippedName); + core::stringc newpath = FileSystem->getFileDir(File->getFileName()); + newpath.append("/"); + newpath.append(strippedName); + if (FileSystem->existFile(newpath)) + return driver->getTexture(newpath); + os::Printer::log("Could not load texture", file.c_str(), ELL_WARNING); + + return 0; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.h new file mode 100644 index 0000000..c72d666 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLWOMeshFileLoader.h @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LWO_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_LWO_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "SMeshBuffer.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + class IReadFile; + class IFileSystem; +} // end namespace io +namespace scene +{ + + struct SMesh; + class ISceneManager; + +//! Meshloader capable of loading Lightwave 3D meshes. +class CLWOMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CLWOMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~CLWOMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IUnknown::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + struct tLWOMaterial; + + bool readFileHeader(); + bool readChunks(); + void readObj1(u32 size); + void readTagMapping(u32 size); + void readVertexMapping(u32 size); + void readDiscVertexMapping (u32 size); + void readObj2(u32 size); + void readMat(u32 size); + u32 readString(core::stringc& name, u32 size=0); + u32 readVec(core::vector3df& vec); + u32 readVX(u32& num); + u32 readColor(video::SColor& color); + video::ITexture* loadTexture(const core::stringc& file); + + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + io::IReadFile* File; + SMesh* Mesh; + + core::array Points; + core::array > Indices; + core::array UvName; + core::array > UvIndex; + core::array DUvName; + core::array > VmPolyPointsIndex; + core::array > VmCoordsIndex; + + core::array MaterialMapping; + core::array > TCoords; + core::array Materials; + core::array Images; + u8 FormatVersion; +}; + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp new file mode 100644 index 0000000..55b6337 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.cpp @@ -0,0 +1,275 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLightSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" + +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CLightSceneNode::CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, video::SColorf color, f32 radius) +: ILightSceneNode(parent, mgr, id, position), DriverLightIndex(-1), LightIsOn(true) +{ + #ifdef _DEBUG + setDebugName("CLightSceneNode"); + #endif + + LightData.DiffuseColor = color; + // set some useful specular color + LightData.SpecularColor = color.getInterpolated(video::SColor(255,255,255,255),0.7f); + + setRadius(radius); +} + + +//! pre render event +void CLightSceneNode::OnRegisterSceneNode() +{ + doLightRecalc(); + + if (IsVisible) + SceneManager->registerNodeForRendering(this, ESNRP_LIGHT); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! render +void CLightSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if (!driver) + return; + + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + + switch ( LightData.Type ) + { + case video::ELT_POINT: + case video::ELT_SPOT: + driver->draw3DBox(BBox, LightData.DiffuseColor.toSColor()); + break; + + case video::ELT_DIRECTIONAL: + driver->draw3DLine(core::vector3df(0.f, 0.f, 0.f), + LightData.Direction * LightData.Radius, + LightData.DiffuseColor.toSColor()); + break; + default: + break; + } + } + + DriverLightIndex = driver->addDynamicLight(LightData); + setVisible(LightIsOn); +} + + +//! sets the light data +void CLightSceneNode::setLightData(const video::SLight& light) +{ + LightData = light; +} + + +//! \return Returns the light data. +const video::SLight& CLightSceneNode::getLightData() const +{ + return LightData; +} + + +//! \return Returns the light data. +video::SLight& CLightSceneNode::getLightData() +{ + return LightData; +} + +void CLightSceneNode::setVisible(bool isVisible) +{ + ISceneNode::setVisible(isVisible); + + if(DriverLightIndex < 0) + return; + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + if (!driver) + return; + + LightIsOn = isVisible; + driver->turnLightOn((u32)DriverLightIndex, LightIsOn); +} + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CLightSceneNode::getBoundingBox() const +{ + return BBox; +} + + +//! Sets the light's radius of influence. +/** Outside this radius the light won't lighten geometry and cast no +shadows. Setting the radius will also influence the attenuation, setting +it to (0,1/radius,0). If you want to override this behavior, set the +attenuation after the radius. +\param radius The new radius. */ +void CLightSceneNode::setRadius(f32 radius) +{ + LightData.Radius=radius; + LightData.Attenuation.set(0.f, 1.f/radius, 0.f); + doLightRecalc(); +} + + +//! Gets the light's radius of influence. +/** \return The current radius. */ +f32 CLightSceneNode::getRadius() const +{ + return LightData.Radius; +} + + +//! Sets the light type. +/** \param type The new type. */ +void CLightSceneNode::setLightType(video::E_LIGHT_TYPE type) +{ + LightData.Type=type; +} + + +//! Gets the light type. +/** \return The current light type. */ +video::E_LIGHT_TYPE CLightSceneNode::getLightType() const +{ + return LightData.Type; +} + + +//! Sets whether this light casts shadows. +/** Enabling this flag won't automatically cast shadows, the meshes +will still need shadow scene nodes attached. But one can enable or +disable distinct lights for shadow casting for performance reasons. +\param shadow True if this light shall cast shadows. */ +void CLightSceneNode::enableCastShadow(bool shadow) +{ + LightData.CastShadows=shadow; +} + + +//! Check whether this light casts shadows. +/** \return True if light would cast shadows, else false. */ +bool CLightSceneNode::getCastShadow() const +{ + return LightData.CastShadows; +} + + +void CLightSceneNode::doLightRecalc() +{ + if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL)) + { + LightData.Direction = core::vector3df(.0f,.0f,1.0f); + getAbsoluteTransformation().rotateVect(LightData.Direction); + LightData.Direction.normalize(); + } + if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_POINT)) + { + const f32 r = LightData.Radius * LightData.Radius * 0.5f; + BBox.MaxEdge.set( r, r, r ); + BBox.MinEdge.set( -r, -r, -r ); + //setAutomaticCulling( scene::EAC_BOX ); + setAutomaticCulling( scene::EAC_OFF ); + LightData.Position = getAbsolutePosition(); + } + if (LightData.Type == video::ELT_DIRECTIONAL) + { + BBox.reset( 0, 0, 0 ); + setAutomaticCulling( scene::EAC_OFF ); + } +} + + +//! Writes attributes of the scene node. +void CLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ILightSceneNode::serializeAttributes(out, options); + + out->addColorf ("AmbientColor", LightData.AmbientColor); + out->addColorf ("DiffuseColor", LightData.DiffuseColor); + out->addColorf ("SpecularColor", LightData.SpecularColor); + out->addVector3d("Attenuation", LightData.Attenuation); + out->addFloat ("Radius", LightData.Radius); + out->addFloat ("OuterCone", LightData.OuterCone); + out->addFloat ("InnerCone", LightData.InnerCone); + out->addFloat ("Falloff", LightData.Falloff); + out->addBool ("CastShadows", LightData.CastShadows); + out->addEnum ("LightType", LightData.Type, video::LightTypeNames); +} + +//! Reads attributes of the scene node. +void CLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + LightData.AmbientColor = in->getAttributeAsColorf("AmbientColor"); + LightData.DiffuseColor = in->getAttributeAsColorf("DiffuseColor"); + LightData.SpecularColor = in->getAttributeAsColorf("SpecularColor"); + + //TODO: clearify Radius and Linear Attenuation +#if 0 + setRadius ( in->getAttributeAsFloat("Radius") ); +#else + LightData.Radius = in->getAttributeAsFloat("Radius"); +#endif + + if (in->existsAttribute("Attenuation")) // might not exist in older files + LightData.Attenuation = in->getAttributeAsVector3d("Attenuation"); + + if (in->existsAttribute("OuterCone")) // might not exist in older files + LightData.OuterCone = in->getAttributeAsFloat("OuterCone"); + if (in->existsAttribute("InnerCone")) // might not exist in older files + LightData.InnerCone = in->getAttributeAsFloat("InnerCone"); + if (in->existsAttribute("Falloff")) // might not exist in older files + LightData.Falloff = in->getAttributeAsFloat("Falloff"); + LightData.CastShadows = in->getAttributeAsBool("CastShadows"); + LightData.Type = (video::E_LIGHT_TYPE)in->getAttributeAsEnumeration("LightType", video::LightTypeNames); + + doLightRecalc (); + + ILightSceneNode::deserializeAttributes(in, options); +} + +//! Creates a clone of this scene node and its children. +ISceneNode* CLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CLightSceneNode* nb = new CLightSceneNode(newParent, + newManager, ID, RelativeTranslation, LightData.DiffuseColor, LightData.Radius); + + nb->cloneMembers(this, newManager); + nb->LightData = LightData; + nb->BBox = BBox; + + if ( newParent ) + nb->drop(); + return nb; +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.h new file mode 100644 index 0000000..b2940ea --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLightSceneNode.h @@ -0,0 +1,108 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LIGHT_SCENE_NODE_H_INCLUDED__ +#define __C_LIGHT_SCENE_NODE_H_INCLUDED__ + +#include "ILightSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a dynamic light. You can switch the light on and off by +//! making it visible or not, and let it be animated by ordinary scene node animators. +class CLightSceneNode : public ILightSceneNode +{ +public: + + //! constructor + CLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, video::SColorf color, f32 range); + + virtual ~CLightSceneNode() { } + + //! pre render event + virtual void OnRegisterSceneNode(); + + //! render + virtual void render(); + + //! set node light data from light info + virtual void setLightData(const video::SLight& light); + + //! \return Returns the light data. + virtual const video::SLight& getLightData() const; + + //! \return Returns the light data. + virtual video::SLight& getLightData(); + + //! Sets if the node should be visible or not. + /** All children of this node won't be visible either, when set + to true. + \param isVisible If the node shall be visible. */ + virtual void setVisible(bool isVisible); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_LIGHT; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + + //! Sets the light's radius of influence. + /** Outside this radius the light won't lighten geometry and cast no + shadows. Setting the radius will also influence the attenuation, setting + it to (0,1/radius,0). If you want to override this behavior, set the + attenuation after the radius. + \param radius The new radius. */ + virtual void setRadius(f32 radius); + + //! Gets the light's radius of influence. + /** \return The current radius. */ + virtual f32 getRadius() const; + + //! Sets the light type. + /** \param type The new type. */ + virtual void setLightType(video::E_LIGHT_TYPE type); + + //! Gets the light type. + /** \return The current light type. */ + virtual video::E_LIGHT_TYPE getLightType() const; + + //! Sets whether this light casts shadows. + /** Enabling this flag won't automatically cast shadows, the meshes + will still need shadow scene nodes attached. But one can enable or + disable distinct lights for shadow casting for performance reasons. + \param shadow True if this light shall cast shadows. */ + virtual void enableCastShadow(bool shadow=true); + + //! Check whether this light casts shadows. + /** \return True if light would cast shadows, else false. */ + virtual bool getCastShadow() const; +private: + + video::SLight LightData; + core::aabbox3d BBox; + s32 DriverLightIndex; + bool LightIsOn; + void doLightRecalc(); +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.cpp new file mode 100644 index 0000000..51afaad --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.cpp @@ -0,0 +1,127 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLimitReadFile.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + + +CLimitReadFile::CLimitReadFile(IReadFile* alreadyOpenedFile, long pos, + long areaSize, const io::path& name) + : Filename(name), AreaStart(0), AreaEnd(0), Pos(0), + File(alreadyOpenedFile) +{ + #ifdef _DEBUG + setDebugName("CLimitReadFile"); + #endif + + if (File) + { + File->grab(); + AreaStart = pos; + AreaEnd = AreaStart + areaSize; + } +} + + +CLimitReadFile::~CLimitReadFile() +{ + if (File) + File->drop(); +} + + +//! returns how much was read +s32 CLimitReadFile::read(void* buffer, u32 sizeToRead) +{ +#if 1 + if (0 == File) + return 0; + + s32 r = AreaStart + Pos; + s32 toRead = core::s32_min(AreaEnd, r + sizeToRead) - core::s32_max(AreaStart, r); + if (toRead < 0) + return 0; + File->seek(r); + r = File->read(buffer, toRead); + Pos += r; + return r; +#else + const long pos = File->getPos(); + + if (pos >= AreaEnd) + return 0; + + if (pos + (long)sizeToRead >= AreaEnd) + sizeToRead = AreaEnd - pos; + + return File->read(buffer, sizeToRead); +#endif +} + + +//! changes position in file, returns true if successful +bool CLimitReadFile::seek(long finalPos, bool relativeMovement) +{ +#if 1 + Pos = core::s32_clamp(finalPos + (relativeMovement ? Pos : 0 ), 0, AreaEnd - AreaStart); + return true; +#else + const long pos = File->getPos(); + + if (relativeMovement) + { + if (pos + finalPos > AreaEnd) + finalPos = AreaEnd - pos; + } + else + { + finalPos += AreaStart; + if (finalPos > AreaEnd) + return false; + } + + return File->seek(finalPos, relativeMovement); +#endif +} + + +//! returns size of file +long CLimitReadFile::getSize() const +{ + return AreaEnd - AreaStart; +} + + +//! returns where in the file we are. +long CLimitReadFile::getPos() const +{ +#if 1 + return Pos; +#else + return File->getPos() - AreaStart; +#endif +} + + +//! returns name of file +const io::path& CLimitReadFile::getFileName() const +{ + return Filename; +} + + +IReadFile* createLimitReadFile(const io::path& fileName, IReadFile* alreadyOpenedFile, long pos, long areaSize) +{ + return new CLimitReadFile(alreadyOpenedFile, pos, areaSize, fileName); +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.h new file mode 100644 index 0000000..00348b1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLimitReadFile.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LIMIT_READ_FILE_H_INCLUDED__ +#define __C_LIMIT_READ_FILE_H_INCLUDED__ + +#include "IReadFile.h" +#include "irrString.h" + +namespace irr +{ + class CUnicodeConverter; + +namespace io +{ + + /*! this is a read file, which is limited to some boundaries, + so that it may only start from a certain file position + and may only read until a certain file position. + This can be useful, for example for reading uncompressed files + in an archive (zip, tar). + !*/ + class CLimitReadFile : public IReadFile + { + public: + + CLimitReadFile(IReadFile* alreadyOpenedFile, long pos, long areaSize, const io::path& name); + + virtual ~CLimitReadFile(); + + //! returns how much was read + virtual s32 read(void* buffer, u32 sizeToRead); + + //! changes position in file, returns true if successful + //! if relativeMovement==true, the pos is changed relative to current pos, + //! otherwise from begin of file + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const io::path& getFileName() const; + + private: + + io::path Filename; + long AreaStart; + long AreaEnd; + long Pos; + IReadFile* File; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.cpp new file mode 100644 index 0000000..5b3feec --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.cpp @@ -0,0 +1,102 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CLogger.h" + +namespace irr +{ + + CLogger::CLogger(IEventReceiver* r) + : LogLevel(ELL_INFORMATION), Receiver(r) + { + #ifdef _DEBUG + setDebugName("CLogger"); + #endif + } + + //! Returns the current set log level. + ELOG_LEVEL CLogger::getLogLevel() const + { + return LogLevel; + } + + //! Sets a new log level. + void CLogger::setLogLevel(ELOG_LEVEL ll) + { + LogLevel = ll; + } + + //! Prints out a text into the log + void CLogger::log(const c8* text, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + if (Receiver) + { + SEvent event; + event.EventType = EET_LOG_TEXT_EVENT; + event.LogEvent.Text = text; + event.LogEvent.Level = ll; + if (Receiver->OnEvent(event)) + return; + } + + os::Printer::print(text); + } + + + //! Prints out a text into the log + void CLogger::log(const c8* text, const c8* hint, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s = text; + s += ": "; + s += hint; + log (s.c_str(), ll); + } + + //! Prints out a text into the log + void CLogger::log(const wchar_t* text, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s = text; + log(s.c_str(), ll); + } + + + //! Prints out a text into the log + void CLogger::log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s1 = text; + core::stringc s2 = hint; + log(s1.c_str(), s2.c_str(), ll); + } + + //! Prints out a text into the log + void CLogger::log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll) + { + if (ll < LogLevel) + return; + + core::stringc s2 = hint; + log( text, s2.c_str(), ll); + } + + //! Sets a new event receiver + void CLogger::setReceiver(IEventReceiver* r) + { + Receiver = r; + } + + +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.h new file mode 100644 index 0000000..314cb13 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CLogger.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_LOGGER_H_INCLUDED__ +#define __C_LOGGER_H_INCLUDED__ + +#include "ILogger.h" +#include "os.h" +#include "irrString.h" +#include "IEventReceiver.h" + +namespace irr +{ + +//! Class for logging messages, warnings and errors to stdout +class CLogger : public ILogger +{ +public: + + CLogger(IEventReceiver* r); + + //! Returns the current set log level. + virtual ELOG_LEVEL getLogLevel() const; + + //! Sets a new log level. virtual void setLogLevel(ELOG_LEVEL ll); + virtual void setLogLevel(ELOG_LEVEL ll); + + //! Prints out a text into the log + virtual void log(const c8* text, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const wchar_t* text, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const c8* text, const c8* hint, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const c8* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Prints out a text into the log + virtual void log(const wchar_t* text, const wchar_t* hint, ELOG_LEVEL ll=ELL_INFORMATION); + + //! Sets a new event receiver + void setReceiver(IEventReceiver* r); + +private: + + ELOG_LEVEL LogLevel; + IEventReceiver* Receiver; +}; + +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.cpp new file mode 100644 index 0000000..4fa26d5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.cpp @@ -0,0 +1,364 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ + +#include "CMD2MeshFileLoader.h" +#include "CAnimatedMeshMD2.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + + // structs needed to load the md2-format + + const s32 MD2_MAGIC_NUMBER = 844121161; + const s32 MD2_VERSION = 8; + const s32 MD2_MAX_VERTS = 2048; + +// byte-align structures +#include "irrpack.h" + + struct SMD2Header + { + s32 magic; // four character code "IDP2" + s32 version; // must be 8 + s32 skinWidth; // width of the texture + s32 skinHeight; // height of the texture + s32 frameSize; // size in bytes of an animation frame + s32 numSkins; // number of textures + s32 numVertices; // total number of vertices + s32 numTexcoords; // number of vertices with texture coords + s32 numTriangles; // number of triangles + s32 numGlCommands; // number of opengl commands (triangle strip or triangle fan) + s32 numFrames; // animation keyframe count + s32 offsetSkins; // offset in bytes to 64 character skin names + s32 offsetTexcoords; // offset in bytes to texture coordinate list + s32 offsetTriangles; // offset in bytes to triangle list + s32 offsetFrames; // offset in bytes to frame list + s32 offsetGlCommands;// offset in bytes to opengl commands + s32 offsetEnd; // offset in bytes to end of file + } PACK_STRUCT; + + struct SMD2Vertex + { + u8 vertex[3]; // [0] = X, [1] = Z, [2] = Y + u8 lightNormalIndex; // index in the normal table + } PACK_STRUCT; + + struct SMD2Frame + { + f32 scale[3]; // first scale the vertex position + f32 translate[3]; // then translate the position + c8 name[16]; // the name of the animation that this key belongs to + SMD2Vertex vertices[1]; // vertex 1 of SMD2Header.numVertices + } PACK_STRUCT; + + struct SMD2Triangle + { + u16 vertexIndices[3]; + u16 textureIndices[3]; + } PACK_STRUCT; + + struct SMD2TextureCoordinate + { + s16 s; + s16 t; + } PACK_STRUCT; + + struct SMD2GLCommand + { + f32 s, t; + s32 vertexIndex; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +//! Constructor +CMD2MeshFileLoader::CMD2MeshFileLoader() +{ + #ifdef _DEBUG + setDebugName("CMD2MeshFileLoader"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CMD2MeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "md2" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CMD2MeshFileLoader::createMesh(io::IReadFile* file) +{ + IAnimatedMesh* msh = new CAnimatedMeshMD2(); + if (msh) + { + if (loadFile(file, (CAnimatedMeshMD2*)msh) ) + return msh; + + msh->drop(); + } + + return 0; +} + +//! loads an md2 file +bool CMD2MeshFileLoader::loadFile(io::IReadFile* file, CAnimatedMeshMD2* mesh) +{ + if (!file) + return false; + + SMD2Header header; + + file->read(&header, sizeof(SMD2Header)); + +#ifdef __BIG_ENDIAN__ + header.magic = os::Byteswap::byteswap(header.magic); + header.version = os::Byteswap::byteswap(header.version); + header.skinWidth = os::Byteswap::byteswap(header.skinWidth); + header.skinHeight = os::Byteswap::byteswap(header.skinHeight); + header.frameSize = os::Byteswap::byteswap(header.frameSize); + header.numSkins = os::Byteswap::byteswap(header.numSkins); + header.numVertices = os::Byteswap::byteswap(header.numVertices); + header.numTexcoords = os::Byteswap::byteswap(header.numTexcoords); + header.numTriangles = os::Byteswap::byteswap(header.numTriangles); + header.numGlCommands = os::Byteswap::byteswap(header.numGlCommands); + header.numFrames = os::Byteswap::byteswap(header.numFrames); + header.offsetSkins = os::Byteswap::byteswap(header.offsetSkins); + header.offsetTexcoords = os::Byteswap::byteswap(header.offsetTexcoords); + header.offsetTriangles = os::Byteswap::byteswap(header.offsetTriangles); + header.offsetFrames = os::Byteswap::byteswap(header.offsetFrames); + header.offsetGlCommands = os::Byteswap::byteswap(header.offsetGlCommands); + header.offsetEnd = os::Byteswap::byteswap(header.offsetEnd); +#endif + + if (header.magic != MD2_MAGIC_NUMBER || header.version != MD2_VERSION) + { + os::Printer::log("MD2 Loader: Wrong file header", file->getFileName(), ELL_WARNING); + return false; + } + + // + // prepare mesh and allocate memory + // + + mesh->FrameCount = header.numFrames; + + // create keyframes + mesh->FrameTransforms.set_used(header.numFrames); + + // create vertex arrays for each keyframe + if (mesh->FrameList) + delete [] mesh->FrameList; + mesh->FrameList = new core::array[header.numFrames]; + + // allocate space in vertex arrays + s32 i; + for (i=0; iFrameList[i].reallocate(header.numVertices); + + // allocate interpolation buffer vertices + mesh->InterpolationBuffer->Vertices.set_used(header.numTriangles*3); + + // populate triangles + mesh->InterpolationBuffer->Indices.reallocate(header.numTriangles*3); + const s32 count = header.numTriangles*3; + for (i=0; iInterpolationBuffer->Indices.push_back(i); + mesh->InterpolationBuffer->Indices.push_back(i+1); + mesh->InterpolationBuffer->Indices.push_back(i+2); + } + + // + // read texture coordinates + // + + file->seek(header.offsetTexcoords); + SMD2TextureCoordinate* textureCoords = new SMD2TextureCoordinate[header.numTexcoords]; + + if (!file->read(textureCoords, sizeof(SMD2TextureCoordinate)*header.numTexcoords)) + { + delete[] textureCoords; + os::Printer::log("MD2 Loader: Error reading TextureCoords.", file->getFileName(), ELL_ERROR); + return false; + } + +#ifdef __BIG_ENDIAN__ + for (i=0; iseek(header.offsetTriangles); + + SMD2Triangle *triangles = new SMD2Triangle[header.numTriangles]; + if (!file->read(triangles, header.numTriangles *sizeof(SMD2Triangle))) + { + delete[] triangles; + delete[] textureCoords; + + os::Printer::log("MD2 Loader: Error reading triangles.", file->getFileName(), ELL_ERROR); + return false; + } + +#ifdef __BIG_ENDIAN__ + for (i=0; iseek(header.offsetFrames); + + for (i = 0; iread(frame, header.frameSize); + +#ifdef __BIG_ENDIAN__ + frame->scale[0] = os::Byteswap::byteswap(frame->scale[0]); + frame->scale[1] = os::Byteswap::byteswap(frame->scale[1]); + frame->scale[2] = os::Byteswap::byteswap(frame->scale[2]); + frame->translate[0] = os::Byteswap::byteswap(frame->translate[0]); + frame->translate[1] = os::Byteswap::byteswap(frame->translate[1]); + frame->translate[2] = os::Byteswap::byteswap(frame->translate[2]); +#endif + // + // store frame data + // + + CAnimatedMeshMD2::SAnimationData adata; + adata.begin = i; + adata.end = i; + adata.fps = 7; + + // Add new named animation if necessary + if (frame->name[0]) + { + // get animation name + for (s32 s = 0; s < 16 && frame->name[s]!=0 && (frame->name[s] < '0' || frame->name[s] > '9'); ++s) + { + adata.name += frame->name[s]; + } + + // Does this keyframe have the same animation name as the current animation? + if (!mesh->AnimationData.empty() && mesh->AnimationData[mesh->AnimationData.size()-1].name == adata.name) + { + // Increase the length of the animation + ++mesh->AnimationData[mesh->AnimationData.size() - 1].end; + } + else + { + // Add the new animation + mesh->AnimationData.push_back(adata); + } + } + + // save keyframe scale and translation + + mesh->FrameTransforms[i].scale.X = frame->scale[0]; + mesh->FrameTransforms[i].scale.Z = frame->scale[1]; + mesh->FrameTransforms[i].scale.Y = frame->scale[2]; + mesh->FrameTransforms[i].translate.X = frame->translate[0]; + mesh->FrameTransforms[i].translate.Z = frame->translate[1]; + mesh->FrameTransforms[i].translate.Y = frame->translate[2]; + + // add vertices + for (s32 j=0; jvertices[num].vertex[0]; + v.Pos.Z = frame->vertices[num].vertex[1]; + v.Pos.Y = frame->vertices[num].vertex[2]; + v.NormalIdx = frame->vertices[num].lightNormalIndex; + + mesh->FrameList[i].push_back(v); + } + } + + // calculate bounding boxes + if (header.numVertices) + { + core::aabbox3d box; + core::vector3df pos; + pos.X = f32(mesh->FrameList[i] [0].Pos.X) * mesh->FrameTransforms[i].scale.X + mesh->FrameTransforms[i].translate.X; + pos.Y = f32(mesh->FrameList[i] [0].Pos.Y) * mesh->FrameTransforms[i].scale.Y + mesh->FrameTransforms[i].translate.Y; + pos.Z = f32(mesh->FrameList[i] [0].Pos.Z) * mesh->FrameTransforms[i].scale.Z + mesh->FrameTransforms[i].translate.Z; + + box.reset(pos); + + for (s32 j=1; jFrameList[i] [j].Pos.X) * mesh->FrameTransforms[i].scale.X + mesh->FrameTransforms[i].translate.X; + pos.Y = f32(mesh->FrameList[i] [j].Pos.Y) * mesh->FrameTransforms[i].scale.Y + mesh->FrameTransforms[i].translate.Y; + pos.Z = f32(mesh->FrameList[i] [j].Pos.Z) * mesh->FrameTransforms[i].scale.Z + mesh->FrameTransforms[i].translate.Z; + + box.addInternalPoint(pos); + } + mesh->BoxList.push_back(box); + } + } + + // populate interpolation buffer with texture coordinates and colors + if (header.numFrames) + { + f32 dmaxs = 1.0f/(header.skinWidth); + f32 dmaxt = 1.0f/(header.skinHeight); + + for (s32 t=0; tInterpolationBuffer->Vertices[t*3 + n].TCoords.X = (textureCoords[triangles[t].textureIndices[n]].s + 0.5f) * dmaxs; + mesh->InterpolationBuffer->Vertices[t*3 + n].TCoords.Y = (textureCoords[triangles[t].textureIndices[n]].t + 0.5f) * dmaxt; + mesh->InterpolationBuffer->Vertices[t*3 + n].Color = video::SColor(255,255,255,255); + } + } + } + + // clean up + delete [] triangles; + delete [] textureCoords; + + // init buffer with start frame. + mesh->getMesh(0); + return true; +} + +} // end namespace scene +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_MD2_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.h new file mode 100644 index 0000000..cc9f3af --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD2MeshFileLoader.h @@ -0,0 +1,45 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MD2_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_MD2_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" + +namespace irr +{ +namespace scene +{ + +class CAnimatedMeshMD2; + +//! Meshloader capable of loading MD2 files +class CMD2MeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CMD2MeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + //! Loads the file data into the mesh + bool loadFile(io::IReadFile* file, CAnimatedMeshMD2* mesh); + +}; + +} // end namespace scene +} // end namespace irr + +#endif // __C_MD2_MESH_LOADER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.cpp new file mode 100644 index 0000000..68f8d80 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ + +#include "CMD3MeshFileLoader.h" +#include "CAnimatedMeshMD3.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CMD3MeshFileLoader::CMD3MeshFileLoader( scene::ISceneManager* smgr) +: SceneManager(smgr) +{ +} + + +//! destructor +CMD3MeshFileLoader::~CMD3MeshFileLoader() +{ +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CMD3MeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "md3" ); +} + + +IAnimatedMesh* CMD3MeshFileLoader::createMesh(io::IReadFile* file) +{ + CAnimatedMeshMD3 * mesh = new CAnimatedMeshMD3(); + + if ( mesh->loadModelFile ( 0, file, SceneManager->getFileSystem(), SceneManager->getVideoDriver() ) ) + return mesh; + + mesh->drop (); + return 0; +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MD3_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.h new file mode 100644 index 0000000..eb7cb90 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMD3MeshFileLoader.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MD3_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_MD3_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "IQ3Shader.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading md3 files. +class CMD3MeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CMD3MeshFileLoader( scene::ISceneManager* smgr ); + + //! destructor + virtual ~CMD3MeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + scene::ISceneManager* SceneManager; + +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.cpp new file mode 100644 index 0000000..9a88d49 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.cpp @@ -0,0 +1,818 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ + +#include "IReadFile.h" +#include "os.h" +#include "CMS3DMeshFileLoader.h" +#include "CSkinnedMesh.h" + + +namespace irr +{ +namespace scene +{ + +#ifdef _DEBUG +#define _IRR_DEBUG_MS3D_LOADER_ +#endif + +// byte-align structures +#include "irrpack.h" + +namespace { +// File header +struct MS3DHeader +{ + char ID[10]; + int Version; +} PACK_STRUCT; + +// Vertex information +struct MS3DVertex +{ + u8 Flags; + float Vertex[3]; + char BoneID; + u8 RefCount; +} PACK_STRUCT; + +// Triangle information +struct MS3DTriangle +{ + u16 Flags; + u16 VertexIndices[3]; + float VertexNormals[3][3]; + float S[3], T[3]; + u8 SmoothingGroup; + u8 GroupIndex; +} PACK_STRUCT; + +// Material information +struct MS3DMaterial +{ + char Name[32]; + float Ambient[4]; + float Diffuse[4]; + float Specular[4]; + float Emissive[4]; + float Shininess; // 0.0f - 128.0f + float Transparency; // 0.0f - 1.0f + u8 Mode; // 0, 1, 2 is unused now + char Texture[128]; + char Alphamap[128]; +} PACK_STRUCT; + +// Joint information +struct MS3DJoint +{ + u8 Flags; + char Name[32]; + char ParentName[32]; + float Rotation[3]; + float Translation[3]; + u16 NumRotationKeyframes; + u16 NumTranslationKeyframes; +} PACK_STRUCT; + +// Keyframe data +struct MS3DKeyframe +{ + float Time; + float Parameter[3]; +} PACK_STRUCT; + +// vertex weights in 1.8.x +struct MS3DVertexWeights +{ + char boneIds[3]; + u8 weights[3]; +} PACK_STRUCT; + +} // end namespace + +// Default alignment +#include "irrunpack.h" + +struct SGroup +{ + core::stringc Name; + core::array VertexIds; + u16 MaterialIdx; +}; + +//! Constructor +CMS3DMeshFileLoader::CMS3DMeshFileLoader(video::IVideoDriver *driver) +: Driver(driver), AnimatedMesh(0) +{ + #ifdef _DEBUG + setDebugName("CMS3DMeshFileLoader"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CMS3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "ms3d" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CMS3DMeshFileLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + AnimatedMesh = new CSkinnedMesh(); + + if ( load(file) ) + { + AnimatedMesh->finalize(); + } + else + { + AnimatedMesh->drop(); + AnimatedMesh = 0; + } + + return AnimatedMesh; +} + + +//! loads a milkshape file +bool CMS3DMeshFileLoader::load(io::IReadFile* file) +{ + if (!file) + return false; + + // find file size + const long fileSize = file->getSize(); + + // read whole file + + u8* buffer = new u8[fileSize]; + s32 read = file->read(buffer, fileSize); + if (read != fileSize) + { + delete [] buffer; + os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR); + return false; + } + + // read header + + const u8 *pPtr = (u8*)((void*)buffer); + MS3DHeader *pHeader = (MS3DHeader*)pPtr; + pPtr += sizeof(MS3DHeader); + + if ( strncmp( pHeader->ID, "MS3D000000", 10 ) != 0 ) + { + delete [] buffer; + os::Printer::log("Not a valid Milkshape3D Model File. Loading failed", file->getFileName(), ELL_ERROR); + return false; + } + +#ifdef __BIG_ENDIAN__ + pHeader->Version = os::Byteswap::byteswap(pHeader->Version); +#endif + if ( pHeader->Version < 3 || pHeader->Version > 4 ) + { + delete [] buffer; + os::Printer::log("Only Milkshape3D version 3 and 4 (1.3 to 1.8) is supported. Loading failed", file->getFileName(), ELL_ERROR); + return false; + } +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Loaded header version", core::stringc(pHeader->Version).c_str()); +#endif + + // get pointers to data + + // vertices + u16 numVertices = *(u16*)pPtr; +#ifdef __BIG_ENDIAN__ + numVertices = os::Byteswap::byteswap(numVertices); +#endif +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Load vertices", core::stringc(numVertices).c_str()); +#endif + pPtr += sizeof(u16); + MS3DVertex *vertices = (MS3DVertex*)pPtr; + pPtr += sizeof(MS3DVertex) * numVertices; + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + for (u16 tmp=0; tmp buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + for (u16 tmp=0; tmp groups; + groups.reallocate(numGroups); + + //store groups + u32 i; + for (i=0; i buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + } + + // load materials + u16 numMaterials = *(u16*)pPtr; +#ifdef __BIG_ENDIAN__ + numMaterials = os::Byteswap::byteswap(numMaterials); +#endif +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Load Materials", core::stringc(numMaterials).c_str()); +#endif + pPtr += sizeof(u16); + + if(numMaterials == 0) + { + // if there are no materials, add at least one buffer + AnimatedMesh->addMeshBuffer(); + } + + for (i=0; iAmbient[j] = os::Byteswap::byteswap(material->Ambient[j]); + for (u16 j=0; j<4; ++j) + material->Diffuse[j] = os::Byteswap::byteswap(material->Diffuse[j]); + for (u16 j=0; j<4; ++j) + material->Specular[j] = os::Byteswap::byteswap(material->Specular[j]); + for (u16 j=0; j<4; ++j) + material->Emissive[j] = os::Byteswap::byteswap(material->Emissive[j]); + material->Shininess = os::Byteswap::byteswap(material->Shininess); + material->Transparency = os::Byteswap::byteswap(material->Transparency); +#endif + pPtr += sizeof(MS3DMaterial); + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + + scene::SSkinMeshBuffer *tmpBuffer = AnimatedMesh->addMeshBuffer(); + + tmpBuffer->Material.MaterialType = video::EMT_SOLID; + + tmpBuffer->Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor (); + tmpBuffer->Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor (); + tmpBuffer->Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor (); + tmpBuffer->Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor (); + tmpBuffer->Material.Shininess = material->Shininess; + + core::stringc TexturePath(material->Texture); + if (TexturePath.trim()!="") + { + TexturePath=stripPathFromString(file->getFileName(),true) + stripPathFromString(TexturePath,false); + tmpBuffer->Material.setTexture(0, Driver->getTexture(TexturePath)); + } + + core::stringc AlphamapPath=(const c8*)material->Alphamap; + if (AlphamapPath.trim()!="") + { + AlphamapPath=stripPathFromString(file->getFileName(),true) + stripPathFromString(AlphamapPath,false); + tmpBuffer->Material.setTexture(2, Driver->getTexture(AlphamapPath)); + } + } + + // animation time + f32 framesPerSecond = *(float*)pPtr; +#ifdef __BIG_ENDIAN__ + framesPerSecond = os::Byteswap::byteswap(framesPerSecond); +#endif +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("FPS", core::stringc(framesPerSecond).c_str()); +#endif + pPtr += sizeof(float) * 2; // fps and current time + + if (framesPerSecond<1.f) + framesPerSecond=1.f; + AnimatedMesh->setAnimationSpeed(framesPerSecond); + +// ignore, calculated inside SkinnedMesh +// s32 frameCount = *(int*)pPtr; +#ifdef __BIG_ENDIAN__ +// frameCount = os::Byteswap::byteswap(frameCount); +#endif + pPtr += sizeof(int); + + u16 jointCount = *(u16*)pPtr; +#ifdef __BIG_ENDIAN__ + jointCount = os::Byteswap::byteswap(jointCount); +#endif +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Joints", core::stringc(jointCount).c_str()); +#endif + pPtr += sizeof(u16); + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + + core::array parentNames; + parentNames.reallocate(jointCount); + + // load joints + for (i=0; iRotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]); + for (j=0; j<3; ++j) + pJoint->Translation[j] = os::Byteswap::byteswap(pJoint->Translation[j]); + pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes); + pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes); +#endif + pPtr += sizeof(MS3DJoint); + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + + ISkinnedMesh::SJoint *jnt = AnimatedMesh->addJoint(); + + jnt->Name = pJoint->Name; +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Joint", jnt->Name.c_str()); + os::Printer::log("Rotation keyframes", core::stringc(pJoint->NumRotationKeyframes).c_str()); + os::Printer::log("Translation keyframes", core::stringc(pJoint->NumTranslationKeyframes).c_str()); +#endif + jnt->LocalMatrix.makeIdentity(); + jnt->LocalMatrix.setRotationRadians( + core::vector3df(pJoint->Rotation[0], pJoint->Rotation[1], pJoint->Rotation[2]) ); + // convert right-handed to left-handed + jnt->LocalMatrix[2]=-jnt->LocalMatrix[2]; + jnt->LocalMatrix[6]=-jnt->LocalMatrix[6]; + jnt->LocalMatrix[8]=-jnt->LocalMatrix[8]; + jnt->LocalMatrix[9]=-jnt->LocalMatrix[9]; + + jnt->LocalMatrix.setTranslation( + core::vector3df(pJoint->Translation[0], pJoint->Translation[1], -pJoint->Translation[2]) ); + jnt->Animatedposition.set(jnt->LocalMatrix.getTranslation()); + jnt->Animatedrotation.set(jnt->LocalMatrix.getRotationDegrees()); + + parentNames.push_back( (c8*)pJoint->ParentName ); + + /*if (pJoint->NumRotationKeyframes || + pJoint->NumTranslationKeyframes) + HasAnimation = true; + */ + + // get rotation keyframes + const u16 numRotationKeyframes = pJoint->NumRotationKeyframes; + for (j=0; j < numRotationKeyframes; ++j) + { + MS3DKeyframe* kf = (MS3DKeyframe*)pPtr; +#ifdef __BIG_ENDIAN__ + kf->Time = os::Byteswap::byteswap(kf->Time); + for (u32 l=0; l<3; ++l) + kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]); +#endif + pPtr += sizeof(MS3DKeyframe); + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + + ISkinnedMesh::SRotationKey *k=AnimatedMesh->addRotationKey(jnt); + k->frame = kf->Time * framesPerSecond-1; + + core::matrix4 tmpMatrix; + + tmpMatrix.setRotationRadians( + core::vector3df(kf->Parameter[0], kf->Parameter[1], kf->Parameter[2]) ); + // convert right-handed to left-handed + tmpMatrix[2]=-tmpMatrix[2]; + tmpMatrix[6]=-tmpMatrix[6]; + tmpMatrix[8]=-tmpMatrix[8]; + tmpMatrix[9]=-tmpMatrix[9]; + + tmpMatrix=jnt->LocalMatrix*tmpMatrix; + + // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from tmpMatrix to tmpMatrix.getTransposed() for downward compatibility. + // Not tested so far if this was correct or wrong before quaternion fix! + k->rotation = core::quaternion(tmpMatrix.getTransposed()); + } + + // get translation keyframes + const u16 numTranslationKeyframes = pJoint->NumTranslationKeyframes; + for (j=0; jTime = os::Byteswap::byteswap(kf->Time); + for (u32 l=0; l<3; ++l) + kf->Parameter[l] = os::Byteswap::byteswap(kf->Parameter[l]); +#endif + pPtr += sizeof(MS3DKeyframe); + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + + ISkinnedMesh::SPositionKey *k=AnimatedMesh->addPositionKey(jnt); + k->frame = kf->Time * framesPerSecond-1; + + k->position = core::vector3df + (kf->Parameter[0]+pJoint->Translation[0], + kf->Parameter[1]+pJoint->Translation[1], + -kf->Parameter[2]-pJoint->Translation[2]); + } + } + + core::array vertexWeights; + f32 weightFactor=0; + + if (jointCount && (pHeader->Version == 4) && (pPtr < buffer+fileSize)) + { + s32 subVersion = *(s32*)pPtr; // comment subVersion, always 1 +#ifdef __BIG_ENDIAN__ + subVersion = os::Byteswap::byteswap(subVersion); +#endif + pPtr += sizeof(s32); + + for (u32 j=0; j<4; ++j) // four comment groups + { +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Skipping comment group", core::stringc(j+1).c_str()); +#endif + u32 numComments = *(u32*)pPtr; +#ifdef __BIG_ENDIAN__ + numComments = os::Byteswap::byteswap(numComments); +#endif + pPtr += sizeof(u32); + for (i=0; i buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + } + + if (pPtr < buffer+fileSize) + { + subVersion = *(s32*)pPtr; // vertex subVersion, 1 or 2 +#ifdef __BIG_ENDIAN__ + subVersion = os::Byteswap::byteswap(subVersion); +#endif + if (subVersion==1) + weightFactor=1.f/255.f; + else + weightFactor=1.f/100.f; + pPtr += sizeof(s32); + +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Reading vertex weights"); +#endif + // read vertex weights, ignoring data 'extra' from 1.8.2 + vertexWeights.reallocate(numVertices); + const char offset = (subVersion==1)?6:10; + for (i=0; i buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); + return false; + } + } + + if (pPtr < buffer+fileSize) + { + subVersion = *(s32*)pPtr; // joint subVersion, 1 or 2 +#ifdef __BIG_ENDIAN__ + subVersion = os::Byteswap::byteswap(subVersion); +#endif + pPtr += sizeof(s32); + // skip joint colors +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Skip joint color"); +#endif + pPtr += 3*sizeof(float)*jointCount; + + if (pPtr > buffer+fileSize) + { + delete [] buffer; + os::Printer::log("Loading failed. Corrupted data found", file->getFileName(), ELL_ERROR); + return false; + } + } + + if (pPtr < buffer+fileSize) + { + subVersion = *(s32*)pPtr; // model subVersion, 1 or 2 +#ifdef __BIG_ENDIAN__ + subVersion = os::Byteswap::byteswap(subVersion); +#endif + pPtr += sizeof(s32); +#ifdef _IRR_DEBUG_MS3D_LOADER_ + os::Printer::log("Skip model extra information"); +#endif + // now the model extra information would follow + // we also skip this for now + } + } + + //find parent of every joint + for (u32 jointnum=0; jointnumgetAllJoints().size(); ++jointnum) + { + for (u32 j2=0; j2getAllJoints().size(); ++j2) + { + if (jointnum != j2 && parentNames[jointnum] == AnimatedMesh->getAllJoints()[j2]->Name ) + { + AnimatedMesh->getAllJoints()[j2]->Children.push_back(AnimatedMesh->getAllJoints()[jointnum]); + break; + } + } + } + + // create vertices and indices, attach them to the joints. + video::S3DVertex v; + core::array *Vertices; + core::array Indices; + + for (i=0; igetMeshBuffers()[tmp]->Vertices_Standard; + + for (s32 j = 2; j!=-1; --j) + { + const u32 vertidx = triangles[i].VertexIndices[j]; + + v.TCoords.X = triangles[i].S[j]; + v.TCoords.Y = triangles[i].T[j]; + + v.Normal.X = triangles[i].VertexNormals[j][0]; + v.Normal.Y = triangles[i].VertexNormals[j][1]; + v.Normal.Z = triangles[i].VertexNormals[j][2]; + + if(triangles[i].GroupIndex < groups.size() && + groups[triangles[i].GroupIndex].MaterialIdx < AnimatedMesh->getMeshBuffers().size()) + v.Color = AnimatedMesh->getMeshBuffers()[groups[triangles[i].GroupIndex].MaterialIdx]->Material.DiffuseColor; + else + v.Color.set(255,255,255,255); + + v.Pos.X = vertices[vertidx].Vertex[0]; + v.Pos.Y = vertices[vertidx].Vertex[1]; + v.Pos.Z = vertices[vertidx].Vertex[2]; + + // check if we already have this vertex in our vertex array + s32 index = -1; + for (u32 iV = 0; iV < Vertices->size(); ++iV) + { + if (v == (*Vertices)[iV]) + { + index = (s32)iV; + break; + } + } + + if (index == -1) + { + index = Vertices->size(); + const u32 matidx = groups[triangles[i].GroupIndex].MaterialIdx; + if (vertexWeights.size()==0) + { + const s32 boneid = vertices[vertidx].BoneID; + if ((u32)boneid < AnimatedMesh->getAllJoints().size()) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = matidx; + w->strength = 1.0f; + w->vertex_id = index; + } + } + else if (jointCount) // new weights from 1.8.x + { + f32 sum = 1.0f; + s32 boneid = vertices[vertidx].BoneID; + if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[0] != 0)) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = matidx; + sum -= (w->strength = vertexWeights[vertidx].weights[0]*weightFactor); + w->vertex_id = index; + } + boneid = vertexWeights[vertidx].boneIds[0]; + if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[1] != 0)) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = matidx; + sum -= (w->strength = vertexWeights[vertidx].weights[1]*weightFactor); + w->vertex_id = index; + } + boneid = vertexWeights[vertidx].boneIds[1]; + if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (vertexWeights[vertidx].weights[2] != 0)) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = matidx; + sum -= (w->strength = vertexWeights[vertidx].weights[2]*weightFactor); + w->vertex_id = index; + } + boneid = vertexWeights[vertidx].boneIds[2]; + if (((u32)boneid < AnimatedMesh->getAllJoints().size()) && (sum > 0.f)) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = matidx; + w->strength = sum; + w->vertex_id = index; + } + // fallback, if no bone chosen. Seems to be an error in the specs + boneid = vertices[vertidx].BoneID; + if ((sum == 1.f) && ((u32)boneid < AnimatedMesh->getAllJoints().size())) + { + ISkinnedMesh::SWeight *w=AnimatedMesh->addWeight(AnimatedMesh->getAllJoints()[boneid]); + w->buffer_id = matidx; + w->strength = 1.f; + w->vertex_id = index; + } + } + + Vertices->push_back(v); + } + Indices.push_back(index); + } + } + + //create groups + s32 iIndex = -1; + for (i=0; i= AnimatedMesh->getMeshBuffers().size()) + grp.MaterialIdx = 0; + + core::array& indices = AnimatedMesh->getMeshBuffers()[grp.MaterialIdx]->Indices; + + for (u32 k=0; k < grp.VertexIds.size(); ++k) + for (u32 l=0; l<3; ++l) + indices.push_back(Indices[++iIndex]); + } + + delete [] buffer; + + return true; +} + + +core::stringc CMS3DMeshFileLoader::stripPathFromString(const core::stringc& inString, bool returnPath) const +{ + s32 slashIndex=inString.findLast('/'); // forward slash + s32 backSlash=inString.findLast('\\'); // back slash + + if (backSlash>slashIndex) slashIndex=backSlash; + + if (slashIndex==-1)//no slashes found + { + if (returnPath) + return core::stringc(); //no path to return + else + return inString; + } + + if (returnPath) + return inString.subString(0, slashIndex + 1); + else + return inString.subString(slashIndex+1, inString.size() - (slashIndex+1)); +} + + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.h new file mode 100644 index 0000000..ad5d657 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMS3DMeshFileLoader.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MS3D_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_MS3D_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IVideoDriver.h" +#include "CSkinnedMesh.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading Milkshape 3D files +class CMS3DMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CMS3DMeshFileLoader(video::IVideoDriver* driver); + + //! returns true if the file might be loadable by this class + //! based on the file extension (e.g. ".bsp") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + core::stringc stripPathFromString(const core::stringc& inString, bool returnPath) const; + + bool load(io::IReadFile* file); + video::IVideoDriver* Driver; + CSkinnedMesh* AnimatedMesh; +}; + +} // end namespace scene +} // end namespace irr + +#endif + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DHelper.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DHelper.h new file mode 100644 index 0000000..e045444 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DHelper.h @@ -0,0 +1,447 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by ZDimitor. + +//---------------------------------------------------------------------- +// somefuncs.h - part of the My3D Tools +// +// This tool was created by Zhuck Dmitry (ZDimitor). +// Everyone can use it as wants ( i'll be happy if it helps to someone :) ). +//---------------------------------------------------------------------- + +//********************************************************************** +// some useful functions +//********************************************************************** + +#ifndef __C_MY3D_HELPER_H_INCLUDED__ +#define __C_MY3D_HELPER_H_INCLUDED__ + +#include + +namespace irr +{ +namespace scene +{ + +//********************************************************************** +// MY3D stuff +//********************************************************************** + +// byte-align structures +#include "irrpack.h" + +struct SMyVector3 +{ SMyVector3 () {;} + SMyVector3 (f32 __X, f32 __Y, f32 __Z) + : X(__X), Y(__Y), Z(__Z) {} + f32 X, Y, Z; +} PACK_STRUCT; + +struct SMyVector2 +{ SMyVector2 () {;} + SMyVector2(f32 __X, f32 __Y) + : X(__X), Y(__Y) {} + f32 X, Y; +} PACK_STRUCT; + +struct SMyVertex +{ SMyVertex () {;} + SMyVertex (SMyVector3 _Coord, SMyColor _Color, SMyVector3 _Normal) + :Coord(_Coord), Color(_Color), Normal(_Normal) {;} + SMyVector3 Coord; + SMyColor Color; + SMyVector3 Normal; +} PACK_STRUCT; + +struct SMyTVertex +{ SMyTVertex () {;} + SMyTVertex (SMyVector2 _TCoord) + : TCoord(_TCoord) {;} + SMyVector2 TCoord; +} PACK_STRUCT; + +struct SMyFace +{ SMyFace() {;} + SMyFace(u32 __A, u32 __B, u32 __C) + : A(__A), B(__B), C(__C) {} + u32 A, B, C; +} PACK_STRUCT; + +// file header (6 bytes) +struct SMyFileHeader +{ u32 MyId; // MY3D + u16 Ver; // Version +} PACK_STRUCT; + +// scene header +struct SMySceneHeader +{ SMyColor BackgrColor; // background color + SMyColor AmbientColor; // ambient color + s32 MaterialCount; // material count + s32 MeshCount; // mesh count +} PACK_STRUCT; + +// mesh header +struct SMyMeshHeader +{ c8 Name[256]; // material name + u32 MatIndex; // index of the mesh material + u32 TChannelCnt; // mesh mapping channels count +} PACK_STRUCT; + +// texture data header +struct SMyTexDataHeader +{ c8 Name[256]; // texture name + u32 ComprMode; //compression mode + u32 PixelFormat; + u32 Width; // image width + u32 Height; // image height +} PACK_STRUCT; + +// pixel color 24bit (R8G8B8) +struct SMyPixelColor24 +{ SMyPixelColor24() {;} + SMyPixelColor24(u8 __r, u8 __g, u8 __b) + : r(__r), g(__g), b(__b) {} + u8 r, g, b; +} PACK_STRUCT; + +// pixel color 16bit (A1R5G5B5) +struct SMyPixelColor16 +{ SMyPixelColor16() {;} + SMyPixelColor16(s16 _argb): argb(_argb) {;} + SMyPixelColor16(u8 r, u8 g, u8 b) + { argb = ((r&0x1F)<<10) | ((g&0x1F)<<5) | (b&0x1F); + } + s16 argb; +} PACK_STRUCT; + +// RLE Header +struct SMyRLEHeader +{ SMyRLEHeader() {} + u32 nEncodedBytes; + u32 nDecodedBytes; +} PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +} // end namespace +} // end namespace + +//----------------------------------------------------------------------------- +namespace irr +{ +namespace core +{ + +//-----------------RLE stuff----------------------------------------- + +int rle_encode ( + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ); +unsigned long process_comp( + unsigned char *buf, int buf_size, + unsigned char *out_buf, int out_buf_size + ); +void process_uncomp( + unsigned char, unsigned char *out_buf, int out_buf_size + ); +void flush_outbuf( + unsigned char *out_buf, int out_buf_size + ); +unsigned long get_byte ( + unsigned char *ch, + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ); +void put_byte( + unsigned char ch, unsigned char *out_buf, int out_buf_size + ); +//----------------------------------------------------------- +const unsigned long LIMIT = 1; // was #define LIMIT 1 +const unsigned long NON_MATCH = 2; // was: #define NON_MATCH 2 +const unsigned long EOD_FOUND = 3; // was: #define EOD_FOUND 3 +const unsigned long EOD = 0x00454f44; // was: #define EOD 'EOD' +//----------------------------------------------------------- +// number of decoded bytes +static int nDecodedBytes=0; +// number of coded bytes +static int nCodedBytes=0; +// number of read bytes +static int nReadedBytes=0; +// table used to look for sequences of repeating bytes +static unsigned char tmpbuf[4]; // we use subscripts 1 - 3 +static int tmpbuf_cnt; +// output buffer for non-compressed output data +static unsigned char outbuf[128]; +static int outbuf_cnt; + + +//----------------------------------------------------------- +int rle_encode ( + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ) +{ + unsigned long ret_code; + + unsigned char ch; + + nCodedBytes=0; + nReadedBytes=0; + + tmpbuf_cnt = 0; // no. of char's in tmpbuf + outbuf_cnt = 0; // no. of char's in outbuf + while (1) + { + if (get_byte(&ch, in_buf, in_buf_size, + out_buf, out_buf_size) == (int)EOD) // read next byte into ch + break; + + tmpbuf[++tmpbuf_cnt] = (unsigned char) ch; + if (tmpbuf_cnt == 3) + { + // see if all 3 match each other + if ((tmpbuf[1] == tmpbuf[2]) && (tmpbuf[2] == tmpbuf[3])) + { + // they do - add compression + // this will process all bytes in input file until + // a non-match occurs, or 128 bytes are processed, + // or we find eod */ + ret_code = process_comp(in_buf, in_buf_size, out_buf, out_buf_size); + if (ret_code == (int)EOD_FOUND) + break; // stop compressing + if (ret_code == (int)NON_MATCH) + tmpbuf_cnt=1; /* save the char that didn't match */ + else + // we just compressed the max. of 128 bytes + tmpbuf_cnt=0; /* start over for next chunk */ + } + else + { + // we know the first byte doesn't match 2 or more + // others, so just send it out as uncompressed. */ + process_uncomp(tmpbuf[1], out_buf, out_buf_size); + + // see if the last 2 bytes in the buffer match + if (tmpbuf[2] == tmpbuf[3]) + { + // move byte 3 to position 1 and pretend we just + // have 2 bytes -- note that the first byte was + // already sent to output */ + tmpbuf[1]=tmpbuf[3]; + tmpbuf_cnt=2; + } + else + { + // send byte 2 and keep byte 3 - it may match the + // next byte. Move byte 3 to position 1 and set + // count to 1. Note that the first byte was + // already sent to output + process_uncomp(tmpbuf[2], out_buf, out_buf_size); + tmpbuf[1]=tmpbuf[3]; + tmpbuf_cnt=1; + } + } + } + } // end while + flush_outbuf(out_buf, out_buf_size); + + return nCodedBytes; +} + + +//------------------------------------------------------------------ +// This flushes any non-compressed data not yet sent, then it processes +// repeating bytes until > 128, or EOD, or non-match. +// return values: LIMIT, EOD_FOUND, NON_MATCH +// Prior to ANY return, it writes out the 2 byte compressed code. +// If a NON_MATCH was found, this returns with the non-matching char +// residing in tmpbuf[0]. +// Inputs: tmpbuf[0], input file +// Outputs: tmpbuf[0] (sometimes), output file, and return code +//------------------------------------------------------------------ +unsigned long process_comp( + unsigned char *buf, int buf_size, + unsigned char *out_buf, int out_buf_size) +{ + // we start out with 3 repeating bytes + register int len = 3; + + unsigned char ch; + + // we're starting a repeating chunk - end the non-repeaters + flush_outbuf(out_buf, out_buf_size); + + while (get_byte(&ch, buf, buf_size, out_buf, out_buf_size) != (int)EOD) + { + if (ch != tmpbuf[1]) + { + // send no. of repeated bytes to be encoded + put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); + // send the byte's value being repeated + put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); + /* save the non-matching character just read */ + tmpbuf[1]=(unsigned char) ch; + return NON_MATCH; + } + /* we know the new byte is part of the repeating seq */ + len++; + if (len == 128) + { + // send no. of repeated bytes to be encoded + put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); + // send the byte's value being repeated + put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); + return LIMIT; + } + } // end while + + // if flow comes here, we just read an EOD + // send no. of repeated bytes to be encoded + put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); + // send the byte's value being repeated + put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); + return EOD_FOUND; +} + + +//---------------------------------------------------------------- +// This adds 1 non-repeating byte to outbuf. If outbuf becomes full +// with 128 bytes, it flushes outbuf. +// There are no return codes and no bytes are read from the input. +//---------------------------------------------------------------- +void process_uncomp( + unsigned char char1, unsigned char *out_buf, int out_buf_size + ) +{ + outbuf[outbuf_cnt++] = char1; + if (outbuf_cnt == 128) + flush_outbuf(out_buf, out_buf_size); +} +//----------------------------------------------------------- +// This flushes any non-compressed data not yet sent. +// On exit, outbuf_cnt will equal zero. +//----------------------------------------------------------- +void flush_outbuf(unsigned char *out_buf, int out_buf_size) +{ + register int pos=0; + + if(!outbuf_cnt) + return; // nothing to do */ + + // send no. of unencoded bytes to be sent + put_byte((unsigned char)(outbuf_cnt - 1), out_buf, out_buf_size); + + for ( ; outbuf_cnt; outbuf_cnt--) + put_byte((unsigned char)outbuf[pos++], out_buf, out_buf_size); +} +//--------------------------------------------------- +void put_byte(unsigned char ch, unsigned char *out_buf, int out_buf_size) +{ + if (nCodedBytes<=(out_buf_size-1)) + { out_buf[nCodedBytes++]=ch; + out_buf[nCodedBytes]=0; + } +} +//--------------------------------------------------- +// This reads the next byte into ch. It returns EOD +// at end-of-data +//--------------------------------------------------- +unsigned long get_byte( + unsigned char *ch, + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ) +{ + if (nReadedBytes>=in_buf_size) + { + // there are either 0, 1, or 2 char's to write before we quit + if (tmpbuf_cnt == 1) + process_uncomp(tmpbuf[1], out_buf, out_buf_size); + else + { + if (tmpbuf_cnt == 2) + { + process_uncomp(tmpbuf[1], out_buf, out_buf_size); + process_uncomp(tmpbuf[2], out_buf, out_buf_size); + } + } + nReadedBytes =0; + + return EOD; + } + + (*ch) = (unsigned char)in_buf[nReadedBytes++]; + + return 0; +} +//----------------------------------------------------------- +int rle_decode ( + unsigned char *in_buf, int in_buf_size, + unsigned char *out_buf, int out_buf_size + ) +{ + nDecodedBytes=0; + nReadedBytes=0; + + int ch, i; + while (1) + { + + if (nReadedBytes>=in_buf_size) + break; + else + ch=in_buf[nReadedBytes]; + nReadedBytes++; + + if (ch > 127) + { + i = ch - 127; // i is the number of repetitions + // get the byte to be repeated + if (nReadedBytes>=in_buf_size) + break; + else + ch=in_buf[nReadedBytes]; + nReadedBytes++; + + // uncompress a chunk + for ( ; i ; i--) + { + if (nDecodedBytes=in_buf_size) + break; + else + ch=in_buf[nReadedBytes]; + nReadedBytes++; + + if (nDecodedBytesgrab(); +} + + +CMY3DMeshFileLoader::~CMY3DMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); +} + + +bool CMY3DMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "my3d" ); +} + + +IAnimatedMesh* CMY3DMeshFileLoader::createMesh(io::IReadFile* file) +{ + MaterialEntry.clear(); + MeshBufferEntry.clear(); + ChildNodes.clear(); + + // working directory (from which we load the scene) + core::stringc filepath = FileSystem->getFileDir(file->getFileName()); + if (filepath==".") + filepath=""; + else + filepath.append("/"); + + // read file into memory + SMyFileHeader fileHeader; + file->read(&fileHeader, sizeof(SMyFileHeader)); +#ifdef __BIG_ENDIAN__ + fileHeader.MyId = os::Byteswap::byteswap(fileHeader.MyId); + fileHeader.Ver = os::Byteswap::byteswap(fileHeader.Ver); +#endif + + if (fileHeader.MyId!=MY3D_ID || fileHeader.Ver!=MY3D_VER) + { + os::Printer::log("Bad MY3D file header, loading failed!", ELL_ERROR); + return 0; + } + + u16 id; + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_SCENE_HEADER_ID) + { + os::Printer::log("Cannot find MY3D_SCENE_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + SMySceneHeader sceneHeader; + file->read(&sceneHeader, sizeof(SMySceneHeader)); +#ifdef __BIG_ENDIAN__ + sceneHeader.MaterialCount = os::Byteswap::byteswap(sceneHeader.MaterialCount); + sceneHeader.MeshCount = os::Byteswap::byteswap(sceneHeader.MeshCount); +#endif + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_MAT_LIST_ID) + { + os::Printer::log("Can not find MY3D_MAT_LIST_ID, loading failed!", ELL_ERROR); + return 0; + } + + core::stringc texturePath = + SceneManager->getParameters()->getAttributeAsString(MY3D_TEXTURE_PATH); + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + c8 namebuf[256]; + for (s32 m=0; mread(&(me.Header), sizeof(SMyMaterialHeader)); + + // read next identificator + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + bool gotLightMap=false, gotMainMap=false; + + for (u32 t=0; tread(namebuf, 256); + else + { + me.Texture2 = readEmbeddedLightmap(file, namebuf); + if (!me.Texture2) + return 0; + gotLightMap = true; + } + + const core::stringc name(namebuf); + const s32 pos = name.findLast('.'); + const core::stringc LightingMapStr = "LightingMap"; + const s32 ls = LightingMapStr.size(); + const bool isSubString = (LightingMapStr == name.subString(core::max_(0, (pos - ls)), ls)); + if ((isSubString || (name[pos-1]=='m' && + name[pos-2]=='l' && name[pos-3]=='_')) && + !gotLightMap) + { + const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + me.Texture2FileName = texturePath.size() ? texturePath : filepath; + me.Texture2FileName.append("Lightmaps/"); + me.Texture2FileName.append(name); + + if (name.size()) + me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName); + + me.MaterialType = video::EMT_LIGHTMAP_M2; + gotLightMap = true; + + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + } + else + if (!gotLightMap && gotMainMap) + { + me.Texture2FileName = texturePath.size() ? texturePath : filepath; + me.Texture2FileName.append(name); + + if (name.size()) + me.Texture2 = SceneManager->getVideoDriver()->getTexture(me.Texture2FileName); + + me.MaterialType = video::EMT_REFLECTION_2_LAYER; + } + else + if (!gotMainMap && !gotLightMap) + { + me.Texture1FileName = filepath; + me.Texture1FileName.append(name); + if (name.size()) + me.Texture1 = SceneManager->getVideoDriver()->getTexture(me.Texture1FileName); + + gotMainMap = true; + me.MaterialType = video::EMT_SOLID; + } + else + if (gotLightMap) + { + me.MaterialType = video::EMT_LIGHTMAP_M2; + } + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + } + + // override material types based on their names + if (!strncmp(me.Header.Name, "AlphaChannel-", 13)) + me.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else + if (!strncmp(me.Header.Name, "SphereMap-", 10)) + me.MaterialType = video::EMT_SPHERE_MAP; + } + + // loading meshes + + if (id!=MY3D_MESH_LIST_ID) + { + os::Printer::log("Can not find MY3D_MESH_LIST_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + for (s32 mesh_id=0; mesh_idread(&meshHeader, sizeof(SMyMeshHeader)); + + core::array Vertex; + core::array Face; + core::array TVertex1, TVertex2; + core::array TFace1, TFace2; + + s32 vertsNum=0; + s32 facesNum=0; + + // vertices + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_VERTS_ID) + { + os::Printer::log("Can not find MY3D_VERTS_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&vertsNum, sizeof(vertsNum)); + Vertex.set_used(vertsNum); + file->read(Vertex.pointer(), sizeof(SMyVertex)*vertsNum); + + // faces + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_FACES_ID) + { + os::Printer::log("Can not find MY3D_FACES_ID, loading failed!", ELL_ERROR); + return 0; + } + + file->read(&facesNum, sizeof(facesNum)); + Face.set_used(facesNum); + file->read(Face.pointer(), sizeof(SMyFace)*facesNum); + + // reading texture channels + for (s32 tex=0; tex<(s32)meshHeader.TChannelCnt; tex++) + { + // Max 2 texture channels allowed (but in format .my3d can be more) + s32 tVertsNum=0, tFacesNum=0; + + // reading texture coords + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_TVERTS_ID) + { + core::stringc msg="Can not find MY3D_TVERTS_ID ("; + msg.append(core::stringc(tex)); + msg.append("texture channel), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + file->read(&tVertsNum, sizeof(tVertsNum)); + + if (tex==0) + { + // 1st texture channel + TVertex1.set_used(tVertsNum); + file->read(TVertex1.pointer(), sizeof(SMyTVertex)*tVertsNum); + } + else + if (tex==1) + { + // 2nd texture channel + TVertex2.set_used(tVertsNum); + file->read(TVertex2.pointer(), sizeof(SMyTVertex)*tVertsNum); + } + else + { + // skip other texture channels + file->seek(file->getPos()+sizeof(SMyTVertex)*tVertsNum); + } + + // reading texture faces + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + + if (id!=MY3D_TFACES_ID) + { + core::stringc msg="Can not find MY3D_TFACES_ID ("; + msg.append(core::stringc(tex)); + msg.append("texture channel), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + file->read(&tFacesNum, sizeof(tFacesNum)); + + if (tex==0) + { + // 1st texture channel + TFace1.set_used(tFacesNum); + file->read(TFace1.pointer(), sizeof(SMyFace)*tFacesNum); + } + else if (tex==1) + { + // 2nd texture channel + TFace2.set_used(tFacesNum); + file->read(TFace2.pointer(), sizeof(SMyFace)*tFacesNum); + } + else + { + // skip other texture channels + file->seek(file->getPos()+sizeof(SMyFace)*tFacesNum); + } + } + + // trying to find material + + SMyMaterialEntry* matEnt = getMaterialEntryByIndex(meshHeader.MatIndex); + + // creating geometry for the mesh + + // trying to find mesh buffer for this material + SMeshBufferLightMap* buffer = getMeshBufferByMaterialIndex(meshHeader.MatIndex); + + if (!buffer || + (buffer->Vertices.size()+vertsNum) > SceneManager->getVideoDriver()->getMaximalPrimitiveCount()) + { + // creating new mesh buffer for this material + buffer = new scene::SMeshBufferLightMap(); + + buffer->Material.MaterialType = video::EMT_LIGHTMAP_M2; // EMT_LIGHTMAP_M4 also possible + buffer->Material.Wireframe = false; + buffer->Material.Lighting = false; + + if (matEnt) + { + buffer->Material.MaterialType = matEnt->MaterialType; + + if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER) + { + buffer->Material.Lighting = true; + buffer->Material.setTexture(1, matEnt->Texture1); + buffer->Material.setTexture(0, matEnt->Texture2); + } + else + { + buffer->Material.setTexture(0, matEnt->Texture1); + buffer->Material.setTexture(1, matEnt->Texture2); + } + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + buffer->Material.BackfaceCulling = true; + buffer->Material.Lighting = true; + } + else + if (buffer->Material.MaterialType == video::EMT_SPHERE_MAP) + { + buffer->Material.Lighting = true; + } + + buffer->Material.AmbientColor = video::SColor( + matEnt->Header.AmbientColor.A, matEnt->Header.AmbientColor.R, + matEnt->Header.AmbientColor.G, matEnt->Header.AmbientColor.B + ); + buffer->Material.DiffuseColor = video::SColor( + matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, + matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B + ); + buffer->Material.EmissiveColor = video::SColor( + matEnt->Header.EmissiveColor.A, matEnt->Header.EmissiveColor.R, + matEnt->Header.EmissiveColor.G, matEnt->Header.EmissiveColor.B + ); + buffer->Material.SpecularColor = video::SColor( + matEnt->Header.SpecularColor.A, matEnt->Header.SpecularColor.R, + matEnt->Header.SpecularColor.G, matEnt->Header.SpecularColor.B + ); + } + else + { + buffer->Material.setTexture(0, 0); + buffer->Material.setTexture(1, 0); + + buffer->Material.AmbientColor = video::SColor(255, 255, 255, 255); + buffer->Material.DiffuseColor = video::SColor(255, 255, 255, 255); + buffer->Material.EmissiveColor = video::SColor(0, 0, 0, 0); + buffer->Material.SpecularColor = video::SColor(0, 0, 0, 0); + } + + if (matEnt && matEnt->Header.Transparency!=0) + { + if (buffer->Material.MaterialType == video::EMT_REFLECTION_2_LAYER ) + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_REFLECTION_2_LAYER; + buffer->Material.Lighting = true; + buffer->Material.BackfaceCulling = true; + } + else + { + buffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + buffer->Material.Lighting = false; + buffer->Material.BackfaceCulling = false; + } + } + else if ( + !buffer->Material.getTexture(1) && + buffer->Material.MaterialType != video::EMT_TRANSPARENT_ALPHA_CHANNEL && + buffer->Material.MaterialType != video::EMT_SPHERE_MAP) + { + buffer->Material.MaterialType = video::EMT_SOLID; + buffer->Material.Lighting = true; + } + + MeshBufferEntry.push_back( + SMyMeshBufferEntry(meshHeader.MatIndex, buffer)); + } + + video::S3DVertex2TCoords VertexA, VertexB, VertexC; + + // vertices (A, B, C) color + video::SColor vert_color; + if (matEnt && + (buffer->Material.MaterialType == video::EMT_TRANSPARENT_VERTEX_ALPHA || + buffer->Material.MaterialType == video::EMT_TRANSPARENT_REFLECTION_2_LAYER)) + { + video::SColor color( + matEnt->Header.DiffuseColor.A, matEnt->Header.DiffuseColor.R, + matEnt->Header.DiffuseColor.G, matEnt->Header.DiffuseColor.B); + + vert_color = color.getInterpolated(video::SColor(0,0,0,0), + 1-matEnt->Header.Transparency); + } + else + { + vert_color = buffer->Material.DiffuseColor; + } + + VertexA.Color = VertexB.Color = VertexC.Color = vert_color; + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + buffer->Indices.reallocate(buffer->Indices.size()+6*facesNum); + buffer->Vertices.reallocate(buffer->Vertices.size()+6*facesNum); + } + else + { + buffer->Indices.reallocate(buffer->Indices.size()+3*facesNum); + buffer->Vertices.reallocate(buffer->Vertices.size()+3*facesNum); + } + for (int f=0; f0) + { + VertexA.TCoords.X = TVertex1[TFace1[f].C].TCoord.X; + VertexA.TCoords.Y = TVertex1[TFace1[f].C].TCoord.Y; + } + + if (meshHeader.TChannelCnt>1) + { + VertexA.TCoords2.X = TVertex2[TFace2[f].C].TCoord.X; + VertexA.TCoords2.Y = TVertex2[TFace2[f].C].TCoord.Y; + } + + // vertex B + + VertexB.Pos.X = Vertex[Face[f].B].Coord.X; + VertexB.Pos.Y = Vertex[Face[f].B].Coord.Y; + VertexB.Pos.Z = Vertex[Face[f].B].Coord.Z; + + VertexB.Normal.X = Vertex[Face[f].B].Normal.X; + VertexB.Normal.Y = Vertex[Face[f].B].Normal.Y; + VertexB.Normal.Z = Vertex[Face[f].B].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexB.TCoords.X = TVertex1[TFace1[f].B].TCoord.X; + VertexB.TCoords.Y = TVertex1[TFace1[f].B].TCoord.Y; + } + + if (meshHeader.TChannelCnt>1) + { + VertexB.TCoords2.X = TVertex2[TFace2[f].B].TCoord.X; + VertexB.TCoords2.Y = TVertex2[TFace2[f].B].TCoord.Y; + } + + // vertex C + + VertexC.Pos.X = Vertex[Face[f].A].Coord.X; + VertexC.Pos.Y = Vertex[Face[f].A].Coord.Y; + VertexC.Pos.Z = Vertex[Face[f].A].Coord.Z; + + VertexC.Normal.X = Vertex[Face[f].A].Normal.X; + VertexC.Normal.Y = Vertex[Face[f].A].Normal.Y; + VertexC.Normal.Z = Vertex[Face[f].A].Normal.Z; + + if (meshHeader.TChannelCnt>0) + { + VertexC.TCoords.X = TVertex1[TFace1[f].A].TCoord.X; + VertexC.TCoords.Y = TVertex1[TFace1[f].A].TCoord.Y; + } + if (meshHeader.TChannelCnt>1) + { + VertexC.TCoords2.X = TVertex2[TFace2[f].A].TCoord.X; + VertexC.TCoords2.Y = TVertex2[TFace2[f].A].TCoord.Y; + } + + // store 3d data in mesh buffer + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexA); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexB); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexC); + + //***************************************************************** + // !!!!!! W A R N I N G !!!!!!! + //***************************************************************** + // For materials with alpha channel we duplicate all faces. + // This has be done for proper lighting calculation of the back faces. + // So you must remember this while you creating your models !!!!! + //***************************************************************** + // !!!!!! W A R N I N G !!!!!!! + //***************************************************************** + + if (buffer->Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) + { + VertexA.Normal = core::vector3df(-VertexA.Normal.X, -VertexA.Normal.Y, -VertexA.Normal.Z); + VertexB.Normal = core::vector3df(-VertexB.Normal.X, -VertexB.Normal.Y, -VertexB.Normal.Z); + VertexC.Normal = core::vector3df(-VertexC.Normal.X, -VertexC.Normal.Y, -VertexC.Normal.Z); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexC); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexB); + + buffer->Indices.push_back(buffer->Vertices.size()); + buffer->Vertices.push_back(VertexA); + } + } + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + } + + // creating mesh + SMesh* mesh = new SMesh(); + + for (u32 num=0; numaddMeshBuffer(buffer); + + buffer->recalculateBoundingBox(); + buffer->drop(); + } + + mesh->recalculateBoundingBox(); + + if (id != MY3D_FILE_END_ID) + os::Printer::log("Loading finished, but can not find MY3D_FILE_END_ID token.", ELL_WARNING); + + SAnimatedMesh* am = new SAnimatedMesh(); + + am->addMesh(mesh); + mesh->drop(); + am->recalculateBoundingBox(); + + return am; +} + + +video::ITexture* CMY3DMeshFileLoader::readEmbeddedLightmap(io::IReadFile* file, char* namebuf) +{ + static int LightMapIndex=0; + u16 id; + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_TEXDATA_HEADER_ID) + { + os::Printer::log("Can not find MY3D_TEXDATA_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + SMyTexDataHeader texDataHeader; + + file->read(&texDataHeader, sizeof(SMyTexDataHeader)); + + strcpy(texDataHeader.Name, namebuf); + + char LightMapName[255]; + sprintf(LightMapName,"My3D.Lightmap.%d",++LightMapIndex); + + core::stringc pixFormatStr; + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + pixFormatStr = "24bit,"; + else + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_16) + pixFormatStr = "16bit,"; + else + { + core::stringc msg="Unknown format of image data ("; + msg.append(LightMapName); + msg.append("), loading failed!"); + os::Printer::log(msg.c_str(), ELL_ERROR); + return 0; + } + + if (texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_NONE_ID && + texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_RLE_ID && + texDataHeader.ComprMode != MY3D_TEXDATA_COMPR_SIMPLE_ID ) + { + os::Printer::log("Unknown method of compression image data, loading failed!", ELL_ERROR); + return 0; + } + + const u32 num_pixels = texDataHeader.Width*texDataHeader.Height; + + void* data = 0; + + if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_NONE_ID) + { + // none compressed image data + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + { + data = (void*) new SMyPixelColor24[num_pixels]; + file->read(data, sizeof(SMyPixelColor24)*num_pixels); + } + else + { + data = (void*) new SMyPixelColor16[num_pixels]; + file->read(data, sizeof(SMyPixelColor16)*num_pixels); + } + } + else + if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_RLE_ID) + { + // read RLE header identificator + file->read(&id, sizeof(id)); +#ifdef __BIG_ENDIAN__ + id = os::Byteswap::byteswap(id); +#endif + if (id!=MY3D_TEXDATA_RLE_HEADER_ID) + { + os::Printer::log("Can not find MY3D_TEXDATA_RLE_HEADER_ID, loading failed!", ELL_ERROR); + return 0; + } + + // read RLE header + SMyRLEHeader rleHeader; + file->read(&rleHeader, sizeof(SMyRLEHeader)); + + //allocate memory for input and output buffers + void *input_buffer = (void*) new unsigned char[rleHeader.nEncodedBytes]; + void *output_buffer = (void*) new unsigned char[rleHeader.nDecodedBytes]; + + // read encoded data + file->read(input_buffer, rleHeader.nEncodedBytes); + + // decode data + data = 0;//(void*) new unsigned char[rleHeader.nDecodedBytes]; + s32 decodedBytes = core::rle_decode( + (unsigned char*)input_buffer, rleHeader.nEncodedBytes, + (unsigned char*)output_buffer, rleHeader.nDecodedBytes); + + if (decodedBytes!=(s32)rleHeader.nDecodedBytes) + { + os::Printer::log("Error extracting data from RLE compression, loading failed!", ELL_ERROR); + return 0; + } + + // free input buffer + delete [] (unsigned char*)input_buffer; + + // here decoded data + data = output_buffer; + } + else if (texDataHeader.ComprMode==MY3D_TEXDATA_COMPR_SIMPLE_ID) + { + // simple compressed image data + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + data = (void*) new SMyPixelColor24[num_pixels]; + else + data = (void*) new SMyPixelColor16[num_pixels]; + + u32 nReadedPixels=0, nToRead=0; + while (true) + { + file->read(&nToRead, sizeof(nToRead)); + + if ((nReadedPixels+nToRead) > num_pixels) + break; + + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + { + SMyPixelColor24 col24; + file->read(&col24, sizeof(SMyPixelColor24)); + for (u32 p=0; pread(&col16, sizeof(SMyPixelColor16)); + for (u32 p=0; p= num_pixels) + break; + } + + if (nReadedPixels != num_pixels) + { + os::Printer::log("Image data seems to be corrupted, loading failed!", ELL_ERROR); + return 0; + } + } + + //! Creates a software image from a byte array. + video::IImage* light_img = 0; + + if (texDataHeader.PixelFormat == MY3D_PIXEL_FORMAT_24) + { + // 24 bit lightmap format + light_img = SceneManager->getVideoDriver()->createImageFromData( + video::ECF_R8G8B8, + core::dimension2d(texDataHeader.Width, texDataHeader.Height), + data, true); + } + else + { + // 16 bit lightmap format + light_img = SceneManager->getVideoDriver()->createImageFromData( + video::ECF_A1R5G5B5, + core::dimension2d(texDataHeader.Width, texDataHeader.Height), + data, true); + } + + const bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + video::ITexture* lmtex = SceneManager->getVideoDriver()->addTexture(LightMapName, light_img); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + light_img->drop(); + return lmtex; +} + + +CMY3DMeshFileLoader::SMyMaterialEntry* CMY3DMeshFileLoader::getMaterialEntryByIndex(u32 matInd) +{ + for (u32 m=0; m& CMY3DMeshFileLoader::getChildNodes() const +{ + return ChildNodes; +} + + +} // end namespace scnene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_MY3D_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DMeshFileLoader.h new file mode 100644 index 0000000..716478d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMY3DMeshFileLoader.h @@ -0,0 +1,131 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// This file was originally written by ZDimitor. +// I (Nikolaus Gebhardt) did some few changes to this: +// - replaced logging calls to their os:: counterparts +// - removed some logging calls +// - removed setTexture path and replaced it with the directory of the mesh +// - added EAMT_MY3D file type +// - fixed a memory leak when decompressing RLE data. +// - cleaned multi character constant problems with gcc +// - removed octree child scene node generation because irrlicht is now able to draw +// scene nodes with transparent and sold materials in them at the same time. (see changes.txt) +// Thanks a lot to ZDimitor for his work on this and that he gave me +// his permission to add it into Irrlicht. + +//-------------------------------------------------------------------------------- +// This tool created by ZDimitor everyone can use it as wants +//-------------------------------------------------------------------------------- + +#ifndef __CMY3D_MESH_FILE_LOADER_H_INCLUDED__ +#define __CMY3D_MESH_FILE_LOADER_H_INCLUDED__ + + +#ifdef _MSC_VER +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +#endif + + +#include "IMeshLoader.h" +#include "SMesh.h" +#include "SMeshBufferLightMap.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +// byte-align structures +#include "irrpack.h" + +struct SMyColor +{ SMyColor () {;} + SMyColor (s32 __R, s32 __G, s32 __B, s32 __A) + : R(__R), G(__G), B(__B), A(__A) {} + s32 R, G, B, A; +} PACK_STRUCT; + +// material header +struct SMyMaterialHeader +{ c8 Name[256]; // material name + u32 Index; + SMyColor AmbientColor; + SMyColor DiffuseColor; + SMyColor EmissiveColor; + SMyColor SpecularColor; + f32 Shininess; + f32 Transparency; + u32 TextureCount; // texture count +} PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + +class CMY3DMeshFileLoader : public IMeshLoader +{ +public: + CMY3DMeshFileLoader(ISceneManager *scmgr, io::IFileSystem* fs); + virtual ~CMY3DMeshFileLoader(); + + virtual bool isALoadableFileExtension(const io::path& filename) const; + + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + //! getting access to the nodes (with transparent material), creating + //! while loading .my3d file + const core::array& getChildNodes() const; + +private: + + video::ITexture* readEmbeddedLightmap(io::IReadFile* file, char* namebuf); + + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + + struct SMyMaterialEntry + { + SMyMaterialEntry () + : Texture1FileName("null"), Texture2FileName("null"), + Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {} + + SMyMaterialHeader Header; + core::stringc Texture1FileName; + core::stringc Texture2FileName; + video::ITexture *Texture1; + video::ITexture *Texture2; + video::E_MATERIAL_TYPE MaterialType; + }; + + struct SMyMeshBufferEntry + { + SMyMeshBufferEntry() : MaterialIndex(-1), MeshBuffer(0) {} + SMyMeshBufferEntry(s32 mi, SMeshBufferLightMap* mb) + : MaterialIndex(mi), MeshBuffer(mb) {} + + s32 MaterialIndex; + SMeshBufferLightMap* MeshBuffer; + }; + + SMyMaterialEntry* getMaterialEntryByIndex (u32 matInd); + SMeshBufferLightMap* getMeshBufferByMaterialIndex(u32 matInd); + + core::array MaterialEntry; + core::array MeshBufferEntry; + + core::array ChildNodes; +}; + + +} // end namespace scene +} // end namespace irr + + +#endif // __CMY3D_MESH_FILE_LOADER_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.cpp new file mode 100644 index 0000000..d25c1f2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMemoryFile.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + + +CMemoryFile::CMemoryFile(void* memory, long len, const io::path& fileName, bool d) +: Buffer(memory), Len(len), Pos(0), Filename(fileName), deleteMemoryWhenDropped(d) +{ + #ifdef _DEBUG + setDebugName("CMemoryFile"); + #endif +} + + +CMemoryFile::~CMemoryFile() +{ + if (deleteMemoryWhenDropped) + delete [] (c8*)Buffer; +} + + +//! returns how much was read +s32 CMemoryFile::read(void* buffer, u32 sizeToRead) +{ + s32 amount = static_cast(sizeToRead); + if (Pos + amount > Len) + amount -= Pos + amount - Len; + + if (amount <= 0) + return 0; + + c8* p = (c8*)Buffer; + memcpy(buffer, p + Pos, amount); + + Pos += amount; + + return amount; +} + +//! returns how much was written +s32 CMemoryFile::write(const void* buffer, u32 sizeToWrite) +{ + s32 amount = static_cast(sizeToWrite); + if (Pos + amount > Len) + amount -= Pos + amount - Len; + + if (amount <= 0) + return 0; + + c8* p = (c8*)Buffer; + memcpy(p + Pos, buffer, amount); + + Pos += amount; + + return amount; +} + + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CMemoryFile::seek(long finalPos, bool relativeMovement) +{ + if (relativeMovement) + { + if (Pos + finalPos > Len) + return false; + + Pos += finalPos; + } + else + { + if (finalPos > Len) + return false; + + Pos = finalPos; + } + + return true; +} + + +//! returns size of file +long CMemoryFile::getSize() const +{ + return Len; +} + + +//! returns where in the file we are. +long CMemoryFile::getPos() const +{ + return Pos; +} + + +//! returns name of file +const io::path& CMemoryFile::getFileName() const +{ + return Filename; +} + + +IReadFile* createMemoryReadFile(void* memory, long size, const io::path& fileName, bool deleteMemoryWhenDropped) +{ + CMemoryFile* file = new CMemoryFile(memory, size, fileName, deleteMemoryWhenDropped); + return file; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.h new file mode 100644 index 0000000..98b4c25 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMemoryFile.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MEMORY_READ_FILE_H_INCLUDED__ +#define __C_MEMORY_READ_FILE_H_INCLUDED__ + +#include "IReadFile.h" +#include "IWriteFile.h" +#include "irrString.h" + +namespace irr +{ + +namespace io +{ + + /*! + Class for reading and writing from memory. + */ + class CMemoryFile : public IReadFile, public IWriteFile + { + public: + + //! Constructor + CMemoryFile(void* memory, long len, const io::path& fileName, bool deleteMemoryWhenDropped); + + //! Destructor + virtual ~CMemoryFile(); + + //! returns how much was read + virtual s32 read(void* buffer, u32 sizeToRead); + + //! returns how much was written + virtual s32 write(const void* buffer, u32 sizeToWrite); + + //! changes position in file, returns true if successful + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const io::path& getFileName() const; + + private: + + void *Buffer; + long Len; + long Pos; + io::path Filename; + bool deleteMemoryWhenDropped; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.cpp new file mode 100644 index 0000000..5bcce19 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.cpp @@ -0,0 +1,178 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMeshCache.h" +#include "IAnimatedMesh.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + +static const io::SNamedPath emptyNamedPath; + + +CMeshCache::~CMeshCache() +{ + clear(); +} + + +//! adds a mesh to the list +void CMeshCache::addMesh(const io::path& filename, IAnimatedMesh* mesh) +{ + mesh->grab(); + + MeshEntry e ( filename ); + e.Mesh = mesh; + + Meshes.push_back(e); +} + + +//! Removes a mesh from the cache. +void CMeshCache::removeMesh(const IMesh* const mesh) +{ + if ( !mesh ) + return; + for (u32 i=0; igetMesh(0) == mesh)) + { + Meshes[i].Mesh->drop(); + Meshes.erase(i); + return; + } + } +} + + +//! Returns amount of loaded meshes +u32 CMeshCache::getMeshCount() const +{ + return Meshes.size(); +} + + +//! Returns current number of the mesh +s32 CMeshCache::getMeshIndex(const IMesh* const mesh) const +{ + for (u32 i=0; igetMesh(0) == mesh)) + return (s32)i; + } + + return -1; +} + + +//! Returns a mesh based on its index number +IAnimatedMesh* CMeshCache::getMeshByIndex(u32 number) +{ + if (number >= Meshes.size()) + return 0; + + return Meshes[number].Mesh; +} + + +//! Returns a mesh based on its name. +IAnimatedMesh* CMeshCache::getMeshByName(const io::path& name) +{ + MeshEntry e ( name ); + s32 id = Meshes.binary_search(e); + return (id != -1) ? Meshes[id].Mesh : 0; +} + + +//! Get the name of a loaded mesh, based on its index. +const io::SNamedPath& CMeshCache::getMeshName(u32 index) const +{ + if (index >= Meshes.size()) + return emptyNamedPath; + + return Meshes[index].NamedPath; +} + + +//! Get the name of a loaded mesh, if there is any. +const io::SNamedPath& CMeshCache::getMeshName(const IMesh* const mesh) const +{ + if (!mesh) + return emptyNamedPath; + + for (u32 i=0; igetMesh(0) == mesh)) + return Meshes[i].NamedPath; + } + + return emptyNamedPath; +} + +//! Renames a loaded mesh. +bool CMeshCache::renameMesh(u32 index, const io::path& name) +{ + if (index >= Meshes.size()) + return false; + + Meshes[index].NamedPath.setPath(name); + Meshes.sort(); + return true; +} + + +//! Renames a loaded mesh. +bool CMeshCache::renameMesh(const IMesh* const mesh, const io::path& name) +{ + for (u32 i=0; igetMesh(0) == mesh)) + { + Meshes[i].NamedPath.setPath(name); + Meshes.sort(); + return true; + } + } + + return false; +} + + +//! returns if a mesh already was loaded +bool CMeshCache::isMeshLoaded(const io::path& name) +{ + return getMeshByName(name) != 0; +} + + +//! Clears the whole mesh cache, removing all meshes. +void CMeshCache::clear() +{ + for (u32 i=0; idrop(); + + Meshes.clear(); +} + +//! Clears all meshes that are held in the mesh cache but not used anywhere else. +void CMeshCache::clearUnusedMeshes() +{ + for (u32 i=0; igetReferenceCount() == 1) + { + Meshes[i].Mesh->drop(); + Meshes.erase(i); + --i; + } + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.h new file mode 100644 index 0000000..e3cdc9f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshCache.h @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MESH_CACHE_H_INCLUDED__ +#define __C_MESH_CACHE_H_INCLUDED__ + +#include "IMeshCache.h" +#include "irrArray.h" + +namespace irr +{ + +namespace scene +{ + class CMeshCache : public IMeshCache + { + public: + + virtual ~CMeshCache(); + + //! Adds a mesh to the internal list of loaded meshes. + /** Usually, ISceneManager::getMesh() is called to load a mesh from file. + That method searches the list of loaded meshes if a mesh has already been loaded and + returns a pointer to if it is in that list and already in memory. Otherwise it loads + the mesh. With IMeshCache::addMesh(), it is possible to pretend that a mesh already + has been loaded. This method can be used for example by mesh loaders who need to + load more than one mesh with one call. They can add additional meshes with this + method to the scene manager. The COLLADA loader for example uses this method. + \param filename: Filename of the mesh. When called ISceneManager::getMesh() with this + parameter, the method will return the mesh parameter given with this method. + \param mesh: Pointer to a mesh which will now be referenced by this name. */ + virtual void addMesh(const io::path& filename, IAnimatedMesh* mesh); + + //! Removes a mesh from the cache. + /** After loading a mesh with getMesh(), the mesh can be removed from the cache + using this method, freeing a lot of memory. */ + virtual void removeMesh(const IMesh* const mesh); + + //! Returns amount of loaded meshes in the cache. + /** You can load new meshes into the cache using getMesh() and addMesh(). + If you ever need to access the internal mesh cache, you can do this using + removeMesh(), getMeshNumber(), getMeshByIndex() and getMeshFilename() */ + virtual u32 getMeshCount() const; + + //! Returns current index number of the mesh, and -1 if it is not in the cache. + virtual s32 getMeshIndex(const IMesh* const mesh) const; + + //! Returns a mesh based on its index number. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + Note that this number is only valid until a new mesh is loaded or removed * + \return Returns pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByIndex(u32 index); + + //! Returns a mesh based on its name. + /** \param name Name of the mesh. Usually a filename. + \return Pointer to the mesh or 0 if there is none with this number. */ + virtual IAnimatedMesh* getMeshByName(const io::path& name); + + //! Get the name of a loaded mesh, based on its index. + /** \param index: Index of the mesh, number between 0 and getMeshCount()-1. + \return The name if mesh was found and has a name, else the path is empty. */ + virtual const io::SNamedPath& getMeshName(u32 index) const; + + //! Get the name of a loaded mesh, if there is any. + /** \param mesh Pointer to mesh to query. + \return The name if mesh was found and has a name, else the path is empty. */ + virtual const io::SNamedPath& getMeshName(const IMesh* const mesh) const; + + //! Renames a loaded mesh. + /** Note that renaming meshes might change the ordering of the + meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. + \param index The index of the mesh in the cache. + \param name New name for the mesh. + \return True if mesh was renamed. */ + virtual bool renameMesh(u32 index, const io::path& name); + + //! Renames a loaded mesh. + /** Note that renaming meshes might change the ordering of the + meshes, and so the index of the meshes as returned by + getMeshIndex() or taken by some methods will change. + \param mesh Mesh to be renamed. + \param name New name for the mesh. + \return True if mesh was renamed. */ + virtual bool renameMesh(const IMesh* const mesh, const io::path& name); + + //! returns if a mesh already was loaded + virtual bool isMeshLoaded(const io::path& name); + + //! Clears the whole mesh cache, removing all meshes. + virtual void clear(); + + //! Clears all meshes that are held in the mesh cache but not used anywhere else. + virtual void clearUnusedMeshes(); + + protected: + + struct MeshEntry + { + MeshEntry ( const io::path& name ) + : NamedPath ( name ) + { + } + io::SNamedPath NamedPath; + IAnimatedMesh* Mesh; + + bool operator < (const MeshEntry& other) const + { + return (NamedPath < other.NamedPath); + } + }; + + //! loaded meshes + core::array Meshes; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.cpp new file mode 100644 index 0000000..823c4e3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.cpp @@ -0,0 +1,1820 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMeshManipulator.h" +#include "SMesh.h" +#include "CMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "os.h" +#include "irrMap.h" + +namespace irr +{ +namespace scene +{ + +static inline core::vector3df getAngleWeight(const core::vector3df& v1, + const core::vector3df& v2, + const core::vector3df& v3) +{ + // Calculate this triangle's weight for each of its three vertices + // start by calculating the lengths of its sides + const f32 a = v2.getDistanceFromSQ(v3); + const f32 asqrt = sqrtf(a); + const f32 b = v1.getDistanceFromSQ(v3); + const f32 bsqrt = sqrtf(b); + const f32 c = v1.getDistanceFromSQ(v2); + const f32 csqrt = sqrtf(c); + + // use them to find the angle at each vertex + return core::vector3df( + acosf((b + c - a) / (2.f * bsqrt * csqrt)), + acosf((-b + c + a) / (2.f * asqrt * csqrt)), + acosf((b - c + a) / (2.f * bsqrt * asqrt))); +} + + +//! Flips the direction of surfaces. Changes backfacing triangles to frontfacing +//! triangles and vice versa. +//! \param mesh: Mesh on which the operation is performed. +void CMeshManipulator::flipSurfaces(scene::IMesh* mesh) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for (u32 b=0; bgetMeshBuffer(b); + const u32 idxcnt = buffer->getIndexCount(); + if (buffer->getIndexType() == video::EIT_16BIT) + { + u16* idx = buffer->getIndices(); + for (u32 i=0; i(buffer->getIndices()); + for (u32 i=0; i +void recalculateNormalsT(IMeshBuffer* buffer, bool smooth, bool angleWeighted) +{ + const u32 vtxcnt = buffer->getVertexCount(); + const u32 idxcnt = buffer->getIndexCount(); + const T* idx = reinterpret_cast(buffer->getIndices()); + + if (!smooth) + { + for (u32 i=0; igetPosition(idx[i+0]); + const core::vector3df& v2 = buffer->getPosition(idx[i+1]); + const core::vector3df& v3 = buffer->getPosition(idx[i+2]); + const core::vector3df normal = core::plane3d(v1, v2, v3).Normal; + buffer->getNormal(idx[i+0]) = normal; + buffer->getNormal(idx[i+1]) = normal; + buffer->getNormal(idx[i+2]) = normal; + } + } + else + { + u32 i; + + for ( i = 0; i!= vtxcnt; ++i ) + buffer->getNormal(i).set(0.f, 0.f, 0.f); + + for ( i=0; igetPosition(idx[i+0]); + const core::vector3df& v2 = buffer->getPosition(idx[i+1]); + const core::vector3df& v3 = buffer->getPosition(idx[i+2]); + const core::vector3df normal = core::plane3d(v1, v2, v3).Normal; + + core::vector3df weight(1.f,1.f,1.f); + if (angleWeighted) + weight = irr::scene::getAngleWeight(v1,v2,v3); // writing irr::scene:: necessary for borland + + buffer->getNormal(idx[i+0]) += weight.X*normal; + buffer->getNormal(idx[i+1]) += weight.Y*normal; + buffer->getNormal(idx[i+2]) += weight.Z*normal; + } + + for ( i = 0; i!= vtxcnt; ++i ) + buffer->getNormal(i).normalize(); + } +} +} + + +//! Recalculates all normals of the mesh buffer. +/** \param buffer: Mesh buffer on which the operation is performed. */ +void CMeshManipulator::recalculateNormals(IMeshBuffer* buffer, bool smooth, bool angleWeighted) const +{ + if (!buffer) + return; + + if (buffer->getIndexType()==video::EIT_16BIT) + recalculateNormalsT(buffer, smooth, angleWeighted); + else + recalculateNormalsT(buffer, smooth, angleWeighted); +} + + +//! Recalculates all normals of the mesh. +//! \param mesh: Mesh on which the operation is performed. +void CMeshManipulator::recalculateNormals(scene::IMesh* mesh, bool smooth, bool angleWeighted) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b), smooth, angleWeighted); +} + + +namespace +{ +void calculateTangents( + core::vector3df& normal, + core::vector3df& tangent, + core::vector3df& binormal, + const core::vector3df& vt1, const core::vector3df& vt2, const core::vector3df& vt3, // vertices + const core::vector2df& tc1, const core::vector2df& tc2, const core::vector2df& tc3) // texture coords +{ + // choose one of them: + //#define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers + #define USE_IRR_VERSION + +#ifdef USE_IRR_VERSION + + core::vector3df v1 = vt1 - vt2; + core::vector3df v2 = vt3 - vt1; + normal = v2.crossProduct(v1); + normal.normalize(); + + // binormal + + f32 deltaX1 = tc1.X - tc2.X; + f32 deltaX2 = tc3.X - tc1.X; + binormal = (v1 * deltaX2) - (v2 * deltaX1); + binormal.normalize(); + + // tangent + + f32 deltaY1 = tc1.Y - tc2.Y; + f32 deltaY2 = tc3.Y - tc1.Y; + tangent = (v1 * deltaY2) - (v2 * deltaY1); + tangent.normalize(); + + // adjust + + core::vector3df txb = tangent.crossProduct(binormal); + if (txb.dotProduct(normal) < 0.0f) + { + tangent *= -1.0f; + binormal *= -1.0f; + } + +#endif // USE_IRR_VERSION + +#ifdef USE_NVIDIA_GLH_VERSION + + tangent.set(0,0,0); + binormal.set(0,0,0); + + core::vector3df v1(vt2.X - vt1.X, tc2.X - tc1.X, tc2.Y - tc1.Y); + core::vector3df v2(vt3.X - vt1.X, tc3.X - tc1.X, tc3.Y - tc1.Y); + + core::vector3df txb = v1.crossProduct(v2); + if ( !core::iszero ( txb.X ) ) + { + tangent.X = -txb.Y / txb.X; + binormal.X = -txb.Z / txb.X; + } + + v1.X = vt2.Y - vt1.Y; + v2.X = vt3.Y - vt1.Y; + txb = v1.crossProduct(v2); + + if ( !core::iszero ( txb.X ) ) + { + tangent.Y = -txb.Y / txb.X; + binormal.Y = -txb.Z / txb.X; + } + + v1.X = vt2.Z - vt1.Z; + v2.X = vt3.Z - vt1.Z; + txb = v1.crossProduct(v2); + + if ( !core::iszero ( txb.X ) ) + { + tangent.Z = -txb.Y / txb.X; + binormal.Z = -txb.Z / txb.X; + } + + tangent.normalize(); + binormal.normalize(); + + normal = tangent.crossProduct(binormal); + normal.normalize(); + + binormal = tangent.crossProduct(normal); + binormal.normalize(); + + core::plane3d pl(vt1, vt2, vt3); + + if(normal.dotProduct(pl.Normal) < 0.0f ) + normal *= -1.0f; + +#endif // USE_NVIDIA_GLH_VERSION +} + + +//! Recalculates tangents for a tangent mesh buffer +template +void recalculateTangentsT(IMeshBuffer* buffer, bool recalculateNormals, bool smooth, bool angleWeighted) +{ + if (!buffer || (buffer->getVertexType()!= video::EVT_TANGENTS)) + return; + + const u32 vtxCnt = buffer->getVertexCount(); + const u32 idxCnt = buffer->getIndexCount(); + + T* idx = reinterpret_cast(buffer->getIndices()); + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)buffer->getVertices(); + + if (smooth) + { + u32 i; + + for ( i = 0; i!= vtxCnt; ++i ) + { + if (recalculateNormals) + v[i].Normal.set( 0.f, 0.f, 0.f ); + v[i].Tangent.set( 0.f, 0.f, 0.f ); + v[i].Binormal.set( 0.f, 0.f, 0.f ); + } + + //Each vertex gets the sum of the tangents and binormals from the faces around it + for ( i=0; igetVertexType() == video::EVT_TANGENTS)) + { + if (buffer->getIndexType() == video::EIT_16BIT) + recalculateTangentsT(buffer, recalculateNormals, smooth, angleWeighted); + else + recalculateTangentsT(buffer, recalculateNormals, smooth, angleWeighted); + } +} + + +//! Recalculates tangents for all tangent mesh buffers +void CMeshManipulator::recalculateTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted) const +{ + if (!mesh) + return; + + const u32 meshBufferCount = mesh->getMeshBufferCount(); + for (u32 b=0; bgetMeshBuffer(b), recalculateNormals, smooth, angleWeighted); + } +} + + +namespace +{ +//! Creates a planar texture mapping on the meshbuffer +template +void makePlanarTextureMappingT(scene::IMeshBuffer* buffer, f32 resolution) +{ + u32 idxcnt = buffer->getIndexCount(); + T* idx = reinterpret_cast(buffer->getIndices()); + + for (u32 i=0; igetPosition(idx[i+0]), buffer->getPosition(idx[i+1]), buffer->getPosition(idx[i+2])); + p.Normal.X = fabsf(p.Normal.X); + p.Normal.Y = fabsf(p.Normal.Y); + p.Normal.Z = fabsf(p.Normal.Z); + // calculate planar mapping worldspace coordinates + + if (p.Normal.X > p.Normal.Y && p.Normal.X > p.Normal.Z) + { + for (u32 o=0; o!=3; ++o) + { + buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).Y * resolution; + buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Z * resolution; + } + } + else + if (p.Normal.Y > p.Normal.X && p.Normal.Y > p.Normal.Z) + { + for (u32 o=0; o!=3; ++o) + { + buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).X * resolution; + buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Z * resolution; + } + } + else + { + for (u32 o=0; o!=3; ++o) + { + buffer->getTCoords(idx[i+o]).X = buffer->getPosition(idx[i+o]).X * resolution; + buffer->getTCoords(idx[i+o]).Y = buffer->getPosition(idx[i+o]).Y * resolution; + } + } + } +} +} + + +//! Creates a planar texture mapping on the meshbuffer +void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolution) const +{ + if (!buffer) + return; + + if (buffer->getIndexType()==video::EIT_16BIT) + makePlanarTextureMappingT(buffer, resolution); + else + makePlanarTextureMappingT(buffer, resolution); +} + + +//! Creates a planar texture mapping on the mesh +void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b), resolution); + } +} + + +namespace +{ +//! Creates a planar texture mapping on the meshbuffer +template +void makePlanarTextureMappingT(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) +{ + u32 idxcnt = buffer->getIndexCount(); + T* idx = reinterpret_cast(buffer->getIndices()); + + for (u32 i=0; igetTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).Z + offset.Z) * resolutionS; + buffer->getTCoords(idx[i+o]).Y = 0.5f-(buffer->getPosition(idx[i+o]).Y + offset.Y) * resolutionT; + } + } + else if (axis==1) + { + for (u32 o=0; o!=3; ++o) + { + buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).X + offset.X) * resolutionS; + buffer->getTCoords(idx[i+o]).Y = 1.f-(buffer->getPosition(idx[i+o]).Z + offset.Z) * resolutionT; + } + } + else if (axis==2) + { + for (u32 o=0; o!=3; ++o) + { + buffer->getTCoords(idx[i+o]).X = 0.5f+(buffer->getPosition(idx[i+o]).X + offset.X) * resolutionS; + buffer->getTCoords(idx[i+o]).Y = 0.5f-(buffer->getPosition(idx[i+o]).Y + offset.Y) * resolutionT; + } + } + } +} +} + + +//! Creates a planar texture mapping on the meshbuffer +void CMeshManipulator::makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const +{ + if (!buffer) + return; + + if (buffer->getIndexType()==video::EIT_16BIT) + makePlanarTextureMappingT(buffer, resolutionS, resolutionT, axis, offset); + else + makePlanarTextureMappingT(buffer, resolutionS, resolutionT, axis, offset); +} + + +//! Creates a planar texture mapping on the mesh +void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const +{ + if (!mesh) + return; + + const u32 bcount = mesh->getMeshBufferCount(); + for ( u32 b=0; bgetMeshBuffer(b), resolutionS, resolutionT, axis, offset); + } +} + + +//! Clones a static IMesh into a modifyable SMesh. +// not yet 32bit +SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const +{ + if (!mesh) + return 0; + + SMesh* clone = new SMesh(); + + const u32 meshBufferCount = mesh->getMeshBufferCount(); + + for ( u32 b=0; bgetMeshBuffer(b); + switch(mb->getVertexType()) + { + case video::EVT_STANDARD: + { + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->Material = mb->getMaterial(); + const u32 vcount = mb->getVertexCount(); + buffer->Vertices.reallocate(vcount); + video::S3DVertex* vertices = (video::S3DVertex*)mb->getVertices(); + for (u32 i=0; i < vcount; ++i) + buffer->Vertices.push_back(vertices[i]); + const u32 icount = mb->getIndexCount(); + buffer->Indices.reallocate(icount); + const u16* indices = mb->getIndices(); + for (u32 i=0; i < icount; ++i) + buffer->Indices.push_back(indices[i]); + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->Material = mb->getMaterial(); + const u32 vcount = mb->getVertexCount(); + buffer->Vertices.reallocate(vcount); + video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)mb->getVertices(); + for (u32 i=0; i < vcount; ++i) + buffer->Vertices.push_back(vertices[i]); + const u32 icount = mb->getIndexCount(); + buffer->Indices.reallocate(icount); + const u16* indices = mb->getIndices(); + for (u32 i=0; i < icount; ++i) + buffer->Indices.push_back(indices[i]); + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_TANGENTS: + { + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->Material = mb->getMaterial(); + const u32 vcount = mb->getVertexCount(); + buffer->Vertices.reallocate(vcount); + video::S3DVertexTangents* vertices = (video::S3DVertexTangents*)mb->getVertices(); + for (u32 i=0; i < vcount; ++i) + buffer->Vertices.push_back(vertices[i]); + const u32 icount = mb->getIndexCount(); + buffer->Indices.reallocate(icount); + const u16* indices = mb->getIndices(); + for (u32 i=0; i < icount; ++i) + buffer->Indices.push_back(indices[i]); + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + }// end switch + + }// end for all mesh buffers + + clone->BoundingBox = mesh->getBoundingBox(); + return clone; +} + + +//! Creates a copy of the mesh, which will only consist of unique primitives +// not yet 32bit +IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const +{ + if (!mesh) + return 0; + + SMesh* clone = new SMesh(); + + const u32 meshBufferCount = mesh->getMeshBufferCount(); + + for ( u32 b=0; bgetMeshBuffer(b); + const s32 idxCnt = mb->getIndexCount(); + const u16* idx = mb->getIndices(); + + switch(mb->getVertexType()) + { + case video::EVT_STANDARD: + { + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->Material = mb->getMaterial(); + + video::S3DVertex* v = + (video::S3DVertex*)mb->getVertices(); + + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + for (s32 i=0; iVertices.push_back( v[idx[i + 0 ]] ); + buffer->Vertices.push_back( v[idx[i + 1 ]] ); + buffer->Vertices.push_back( v[idx[i + 2 ]] ); + + buffer->Indices.push_back( i + 0 ); + buffer->Indices.push_back( i + 1 ); + buffer->Indices.push_back( i + 2 ); + } + + buffer->setBoundingBox(mb->getBoundingBox()); + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->Material = mb->getMaterial(); + + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mb->getVertices(); + + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + for (s32 i=0; iVertices.push_back( v[idx[i + 0 ]] ); + buffer->Vertices.push_back( v[idx[i + 1 ]] ); + buffer->Vertices.push_back( v[idx[i + 2 ]] ); + + buffer->Indices.push_back( i + 0 ); + buffer->Indices.push_back( i + 1 ); + buffer->Indices.push_back( i + 2 ); + } + buffer->setBoundingBox(mb->getBoundingBox()); + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + case video::EVT_TANGENTS: + { + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->Material = mb->getMaterial(); + + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mb->getVertices(); + + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + for (s32 i=0; iVertices.push_back( v[idx[i + 0 ]] ); + buffer->Vertices.push_back( v[idx[i + 1 ]] ); + buffer->Vertices.push_back( v[idx[i + 2 ]] ); + + buffer->Indices.push_back( i + 0 ); + buffer->Indices.push_back( i + 1 ); + buffer->Indices.push_back( i + 2 ); + } + + buffer->setBoundingBox(mb->getBoundingBox()); + clone->addMeshBuffer(buffer); + buffer->drop(); + } + break; + }// end switch + + }// end for all mesh buffers + + clone->BoundingBox = mesh->getBoundingBox(); + return clone; +} + + +//! Creates a copy of a mesh, which will have identical vertices welded together +// not yet 32bit +IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const +{ + SMesh* clone = new SMesh(); + clone->BoundingBox = mesh->getBoundingBox(); + + core::array redirects; + + for (u32 b=0; bgetMeshBufferCount(); ++b) + { + const IMeshBuffer* const mb = mesh->getMeshBuffer(b); + // reset redirect list + redirects.set_used(mb->getVertexCount()); + + const u16* indices = 0; + u32 indexCount = 0; + core::array* outIdx = 0; + + switch(mb->getVertexType()) + { + case video::EVT_STANDARD: + { + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->BoundingBox = mb->getBoundingBox(); + buffer->Material = mb->getMaterial(); + clone->addMeshBuffer(buffer); + buffer->drop(); + + video::S3DVertex* v = + (video::S3DVertex*)mb->getVertices(); + + u32 vertexCount = mb->getVertexCount(); + + indices = mb->getIndices(); + indexCount = mb->getIndexCount(); + outIdx = &buffer->Indices; + + buffer->Vertices.reallocate(vertexCount); + + for (u32 i=0; i < vertexCount; ++i) + { + bool found = false; + for (u32 j=0; j < i; ++j) + { + if ( v[i].Pos.equals( v[j].Pos, tolerance) && + v[i].Normal.equals( v[j].Normal, tolerance) && + v[i].TCoords.equals( v[j].TCoords ) && + (v[i].Color == v[j].Color) ) + { + redirects[i] = redirects[j]; + found = true; + break; + } + } + if (!found) + { + redirects[i] = buffer->Vertices.size(); + buffer->Vertices.push_back(v[i]); + } + } + + break; + } + case video::EVT_2TCOORDS: + { + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->BoundingBox = mb->getBoundingBox(); + buffer->Material = mb->getMaterial(); + clone->addMeshBuffer(buffer); + buffer->drop(); + + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mb->getVertices(); + + u32 vertexCount = mb->getVertexCount(); + + indices = mb->getIndices(); + indexCount = mb->getIndexCount(); + outIdx = &buffer->Indices; + + buffer->Vertices.reallocate(vertexCount); + + for (u32 i=0; i < vertexCount; ++i) + { + bool found = false; + for (u32 j=0; j < i; ++j) + { + if ( v[i].Pos.equals( v[j].Pos, tolerance) && + v[i].Normal.equals( v[j].Normal, tolerance) && + v[i].TCoords.equals( v[j].TCoords ) && + v[i].TCoords2.equals( v[j].TCoords2 ) && + (v[i].Color == v[j].Color) ) + { + redirects[i] = redirects[j]; + found = true; + break; + } + } + if (!found) + { + redirects[i] = buffer->Vertices.size(); + buffer->Vertices.push_back(v[i]); + } + } + break; + } + case video::EVT_TANGENTS: + { + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + buffer->BoundingBox = mb->getBoundingBox(); + buffer->Material = mb->getMaterial(); + clone->addMeshBuffer(buffer); + buffer->drop(); + + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mb->getVertices(); + + u32 vertexCount = mb->getVertexCount(); + + indices = mb->getIndices(); + indexCount = mb->getIndexCount(); + outIdx = &buffer->Indices; + + buffer->Vertices.reallocate(vertexCount); + + for (u32 i=0; i < vertexCount; ++i) + { + bool found = false; + for (u32 j=0; j < i; ++j) + { + if ( v[i].Pos.equals( v[j].Pos, tolerance) && + v[i].Normal.equals( v[j].Normal, tolerance) && + v[i].TCoords.equals( v[j].TCoords ) && + v[i].Tangent.equals( v[j].Tangent, tolerance ) && + v[i].Binormal.equals( v[j].Binormal, tolerance ) && + (v[i].Color == v[j].Color) ) + { + redirects[i] = redirects[j]; + found = true; + break; + } + } + if (!found) + { + redirects[i] = buffer->Vertices.size(); + buffer->Vertices.push_back(v[i]); + } + } + break; + } + default: + os::Printer::log("Cannot create welded mesh, vertex type unsupported", ELL_ERROR); + break; + } + + // write the buffer's index list + core::array &Indices = *outIdx; + + Indices.set_used(indexCount); + for (u32 i=0; igetMeshBufferCount(); + + for (u32 b=0; bgetMeshBuffer(b); + const u32 idxCnt = original->getIndexCount(); + const u16* idx = original->getIndices(); + + SMeshBufferTangents* buffer = new SMeshBufferTangents(); + + buffer->Material = original->getMaterial(); + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + + core::map vertMap; + int vertLocation; + + // copy vertices + + const video::E_VERTEX_TYPE vType = original->getVertexType(); + video::S3DVertexTangents vNew; + for (u32 i=0; igetVertices(); + vNew = video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } + break; + case video::EVT_2TCOORDS: + { + const video::S3DVertex2TCoords* v = + (const video::S3DVertex2TCoords*)original->getVertices(); + vNew = video::S3DVertexTangents( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } + break; + case video::EVT_TANGENTS: + { + const video::S3DVertexTangents* v = + (const video::S3DVertexTangents*)original->getVertices(); + vNew = v[idx[i]]; + } + break; + } + core::map::Node* n = vertMap.find(vNew); + if (n) + { + vertLocation = n->getValue(); + } + else + { + vertLocation = buffer->Vertices.size(); + buffer->Vertices.push_back(vNew); + vertMap.insert(vNew, vertLocation); + } + + // create new indices + buffer->Indices.push_back(vertLocation); + } + buffer->recalculateBoundingBox(); + + // add new buffer + clone->addMeshBuffer(buffer); + buffer->drop(); + } + + clone->recalculateBoundingBox(); + if (calculateTangents) + recalculateTangents(clone, recalculateNormals, smooth, angleWeighted); + + return clone; +} + + +//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoords vertices. +// not yet 32bit +IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const +{ + if (!mesh) + return 0; + + // copy mesh and fill data into SMeshBufferLightMap + + SMesh* clone = new SMesh(); + const u32 meshBufferCount = mesh->getMeshBufferCount(); + + for (u32 b=0; bgetMeshBuffer(b); + const u32 idxCnt = original->getIndexCount(); + const u16* idx = original->getIndices(); + + SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); + buffer->Material = original->getMaterial(); + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + + core::map vertMap; + int vertLocation; + + // copy vertices + + const video::E_VERTEX_TYPE vType = original->getVertexType(); + video::S3DVertex2TCoords vNew; + for (u32 i=0; igetVertices(); + vNew = video::S3DVertex2TCoords( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords); + } + break; + case video::EVT_2TCOORDS: + { + const video::S3DVertex2TCoords* v = + (const video::S3DVertex2TCoords*)original->getVertices(); + vNew = v[idx[i]]; + } + break; + case video::EVT_TANGENTS: + { + const video::S3DVertexTangents* v = + (const video::S3DVertexTangents*)original->getVertices(); + vNew = video::S3DVertex2TCoords( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords); + } + break; + } + core::map::Node* n = vertMap.find(vNew); + if (n) + { + vertLocation = n->getValue(); + } + else + { + vertLocation = buffer->Vertices.size(); + buffer->Vertices.push_back(vNew); + vertMap.insert(vNew, vertLocation); + } + + // create new indices + buffer->Indices.push_back(vertLocation); + } + buffer->recalculateBoundingBox(); + + // add new buffer + clone->addMeshBuffer(buffer); + buffer->drop(); + } + + clone->recalculateBoundingBox(); + return clone; +} + + +//! Creates a copy of the mesh, which will only consist of S3DVertex vertices. +// not yet 32bit +IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const +{ + if (!mesh) + return 0; + + // copy mesh and fill data into SMeshBuffer + SMesh* clone = new SMesh(); + const u32 meshBufferCount = mesh->getMeshBufferCount(); + + for (u32 b=0; bgetMeshBuffer(b); + const u32 idxCnt = original->getIndexCount(); + const u16* idx = original->getIndices(); + + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->Material = original->getMaterial(); + buffer->Vertices.reallocate(idxCnt); + buffer->Indices.reallocate(idxCnt); + + core::map vertMap; + int vertLocation; + + // copy vertices + const video::E_VERTEX_TYPE vType = original->getVertexType(); + video::S3DVertex vNew; + for (u32 i=0; igetVertices(); + vNew = v[idx[i]]; + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)original->getVertices(); + vNew = video::S3DVertex( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)original->getVertices(); + vNew = video::S3DVertex( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords); + } + break; + } + core::map::Node* n = vertMap.find(vNew); + if (n) + { + vertLocation = n->getValue(); + } + else + { + vertLocation = buffer->Vertices.size(); + buffer->Vertices.push_back(vNew); + vertMap.insert(vNew, vertLocation); + } + + // create new indices + buffer->Indices.push_back(vertLocation); + } + buffer->recalculateBoundingBox(); + // add new buffer + clone->addMeshBuffer(buffer); + buffer->drop(); + } + + clone->recalculateBoundingBox(); + return clone; +} + + +//! Returns amount of polygons in mesh. +s32 CMeshManipulator::getPolyCount(scene::IMesh* mesh) const +{ + if (!mesh) + return 0; + + s32 trianglecount = 0; + + for (u32 g=0; ggetMeshBufferCount(); ++g) + trianglecount += mesh->getMeshBuffer(g)->getIndexCount() / 3; + + return trianglecount; +} + + +//! Returns amount of polygons in mesh. +s32 CMeshManipulator::getPolyCount(scene::IAnimatedMesh* mesh) const +{ + if (mesh && mesh->getFrameCount() != 0) + return getPolyCount(mesh->getMesh(0)); + + return 0; +} + + +//! create a new AnimatedMesh and adds the mesh to it +IAnimatedMesh * CMeshManipulator::createAnimatedMesh(scene::IMesh* mesh, scene::E_ANIMATED_MESH_TYPE type) const +{ + return new SAnimatedMesh(mesh, type); +} + +namespace +{ + +struct vcache +{ + core::array tris; + float score; + s16 cachepos; + u16 NumActiveTris; +}; + +struct tcache +{ + u16 ind[3]; + float score; + bool drawn; +}; + +const u16 cachesize = 32; + +float FindVertexScore(vcache *v) +{ + const float CacheDecayPower = 1.5f; + const float LastTriScore = 0.75f; + const float ValenceBoostScale = 2.0f; + const float ValenceBoostPower = 0.5f; + const float MaxSizeVertexCache = 32.0f; + + if (v->NumActiveTris == 0) + { + // No tri needs this vertex! + return -1.0f; + } + + float Score = 0.0f; + int CachePosition = v->cachepos; + if (CachePosition < 0) + { + // Vertex is not in FIFO cache - no score. + } + else + { + if (CachePosition < 3) + { + // This vertex was used in the last triangle, + // so it has a fixed score. + Score = LastTriScore; + } + else + { + // Points for being high in the cache. + const float Scaler = 1.0f / (MaxSizeVertexCache - 3); + Score = 1.0f - (CachePosition - 3) * Scaler; + Score = powf(Score, CacheDecayPower); + } + } + + // Bonus points for having a low number of tris still to + // use the vert, so we get rid of lone verts quickly. + float ValenceBoost = powf(v->NumActiveTris, + -ValenceBoostPower); + Score += ValenceBoostScale * ValenceBoost; + + return Score; +} + +/* + A specialized LRU cache for the Forsyth algorithm. +*/ + +class f_lru +{ + +public: + f_lru(vcache *v, tcache *t): vc(v), tc(t) + { + for (u16 i = 0; i < cachesize; i++) + { + cache[i] = -1; + } + } + + // Adds this vertex index and returns the highest-scoring triangle index + u32 add(u16 vert, bool updatetris = false) + { + bool found = false; + + // Mark existing pos as empty + for (u16 i = 0; i < cachesize; i++) + { + if (cache[i] == vert) + { + // Move everything down + for (u16 j = i; j; j--) + { + cache[j] = cache[j - 1]; + } + + found = true; + break; + } + } + + if (!found) + { + if (cache[cachesize-1] != -1) + vc[cache[cachesize-1]].cachepos = -1; + + // Move everything down + for (u16 i = cachesize - 1; i; i--) + { + cache[i] = cache[i - 1]; + } + } + + cache[0] = vert; + + u32 highest = 0; + float hiscore = 0; + + if (updatetris) + { + // Update cache positions + for (u16 i = 0; i < cachesize; i++) + { + if (cache[i] == -1) + break; + + vc[cache[i]].cachepos = i; + vc[cache[i]].score = FindVertexScore(&vc[cache[i]]); + } + + // Update triangle scores + for (u16 i = 0; i < cachesize; i++) + { + if (cache[i] == -1) + break; + + const u16 trisize = vc[cache[i]].tris.size(); + for (u16 t = 0; t < trisize; t++) + { + tcache *tri = &tc[vc[cache[i]].tris[t]]; + + tri->score = + vc[tri->ind[0]].score + + vc[tri->ind[1]].score + + vc[tri->ind[2]].score; + + if (tri->score > hiscore) + { + hiscore = tri->score; + highest = vc[cache[i]].tris[t]; + } + } + } + } + + return highest; + } + +private: + s32 cache[cachesize]; + vcache *vc; + tcache *tc; +}; + +} // end anonymous namespace + +/** +Vertex cache optimization according to the Forsyth paper: +http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html + +The function is thread-safe (read: you can optimize several meshes in different threads) + +\param mesh Source mesh for the operation. */ +IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const +{ + if (!mesh) + return 0; + + SMesh *newmesh = new SMesh(); + newmesh->BoundingBox = mesh->getBoundingBox(); + + const u32 mbcount = mesh->getMeshBufferCount(); + + for (u32 b = 0; b < mbcount; ++b) + { + const IMeshBuffer *mb = mesh->getMeshBuffer(b); + + if (mb->getIndexType() != video::EIT_16BIT) + { + os::Printer::log("Cannot optimize a mesh with 32bit indices", ELL_ERROR); + newmesh->drop(); + return 0; + } + + const u32 icount = mb->getIndexCount(); + const u32 tcount = icount / 3; + const u32 vcount = mb->getVertexCount(); + const u16 *ind = mb->getIndices(); + + vcache *vc = new vcache[vcount]; + tcache *tc = new tcache[tcount]; + + f_lru lru(vc, tc); + + // init + for (u16 i = 0; i < vcount; i++) + { + vc[i].score = 0; + vc[i].cachepos = -1; + vc[i].NumActiveTris = 0; + } + + // First pass: count how many times a vert is used + for (u32 i = 0; i < icount; i += 3) + { + vc[ind[i]].NumActiveTris++; + vc[ind[i + 1]].NumActiveTris++; + vc[ind[i + 2]].NumActiveTris++; + + const u32 tri_ind = i/3; + tc[tri_ind].ind[0] = ind[i]; + tc[tri_ind].ind[1] = ind[i + 1]; + tc[tri_ind].ind[2] = ind[i + 2]; + } + + // Second pass: list of each triangle + for (u32 i = 0; i < tcount; i++) + { + vc[tc[i].ind[0]].tris.push_back(i); + vc[tc[i].ind[1]].tris.push_back(i); + vc[tc[i].ind[2]].tris.push_back(i); + + tc[i].drawn = false; + } + + // Give initial scores + for (u16 i = 0; i < vcount; i++) + { + vc[i].score = FindVertexScore(&vc[i]); + } + for (u32 i = 0; i < tcount; i++) + { + tc[i].score = + vc[tc[i].ind[0]].score + + vc[tc[i].ind[1]].score + + vc[tc[i].ind[2]].score; + } + + switch(mb->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex *v = (video::S3DVertex *) mb->getVertices(); + + SMeshBuffer *buf = new SMeshBuffer(); + buf->Material = mb->getMaterial(); + + buf->Vertices.reallocate(vcount); + buf->Indices.reallocate(icount); + + core::map sind; // search index for fast operation + typedef core::map::Node snode; + + // Main algorithm + u32 highest = 0; + u32 drawcalls = 0; + for (;;) + { + if (tc[highest].drawn) + { + bool found = false; + float hiscore = 0; + for (u32 t = 0; t < tcount; t++) + { + if (!tc[t].drawn) + { + if (tc[t].score > hiscore) + { + highest = t; + hiscore = tc[t].score; + found = true; + } + } + } + if (!found) + break; + } + + // Output the best triangle + u16 newind = buf->Vertices.size(); + + snode *s = sind.find(v[tc[highest].ind[0]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[0]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[0]], newind); + newind++; + } + else + { + buf->Indices.push_back(s->getValue()); + } + + s = sind.find(v[tc[highest].ind[1]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[1]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[1]], newind); + newind++; + } + else + { + buf->Indices.push_back(s->getValue()); + } + + s = sind.find(v[tc[highest].ind[2]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[2]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[2]], newind); + } + else + { + buf->Indices.push_back(s->getValue()); + } + + vc[tc[highest].ind[0]].NumActiveTris--; + vc[tc[highest].ind[1]].NumActiveTris--; + vc[tc[highest].ind[2]].NumActiveTris--; + + tc[highest].drawn = true; + + for (u16 j = 0; j < 3; j++) + { + vcache *vert = &vc[tc[highest].ind[j]]; + for (u16 t = 0; t < vert->tris.size(); t++) + { + if (highest == vert->tris[t]) + { + vert->tris.erase(t); + break; + } + } + } + + lru.add(tc[highest].ind[0]); + lru.add(tc[highest].ind[1]); + highest = lru.add(tc[highest].ind[2], true); + drawcalls++; + } + + buf->setBoundingBox(mb->getBoundingBox()); + newmesh->addMeshBuffer(buf); + buf->drop(); + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords *v = (video::S3DVertex2TCoords *) mb->getVertices(); + + SMeshBufferLightMap *buf = new SMeshBufferLightMap(); + buf->Material = mb->getMaterial(); + + buf->Vertices.reallocate(vcount); + buf->Indices.reallocate(icount); + + core::map sind; // search index for fast operation + typedef core::map::Node snode; + + // Main algorithm + u32 highest = 0; + u32 drawcalls = 0; + for (;;) + { + if (tc[highest].drawn) + { + bool found = false; + float hiscore = 0; + for (u32 t = 0; t < tcount; t++) + { + if (!tc[t].drawn) + { + if (tc[t].score > hiscore) + { + highest = t; + hiscore = tc[t].score; + found = true; + } + } + } + if (!found) + break; + } + + // Output the best triangle + u16 newind = buf->Vertices.size(); + + snode *s = sind.find(v[tc[highest].ind[0]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[0]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[0]], newind); + newind++; + } + else + { + buf->Indices.push_back(s->getValue()); + } + + s = sind.find(v[tc[highest].ind[1]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[1]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[1]], newind); + newind++; + } + else + { + buf->Indices.push_back(s->getValue()); + } + + s = sind.find(v[tc[highest].ind[2]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[2]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[2]], newind); + } + else + { + buf->Indices.push_back(s->getValue()); + } + + vc[tc[highest].ind[0]].NumActiveTris--; + vc[tc[highest].ind[1]].NumActiveTris--; + vc[tc[highest].ind[2]].NumActiveTris--; + + tc[highest].drawn = true; + + for (u16 j = 0; j < 3; j++) + { + vcache *vert = &vc[tc[highest].ind[j]]; + for (u16 t = 0; t < vert->tris.size(); t++) + { + if (highest == vert->tris[t]) + { + vert->tris.erase(t); + break; + } + } + } + + lru.add(tc[highest].ind[0]); + lru.add(tc[highest].ind[1]); + highest = lru.add(tc[highest].ind[2]); + drawcalls++; + } + + buf->setBoundingBox(mb->getBoundingBox()); + newmesh->addMeshBuffer(buf); + buf->drop(); + + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents *v = (video::S3DVertexTangents *) mb->getVertices(); + + SMeshBufferTangents *buf = new SMeshBufferTangents(); + buf->Material = mb->getMaterial(); + + buf->Vertices.reallocate(vcount); + buf->Indices.reallocate(icount); + + core::map sind; // search index for fast operation + typedef core::map::Node snode; + + // Main algorithm + u32 highest = 0; + u32 drawcalls = 0; + for (;;) + { + if (tc[highest].drawn) + { + bool found = false; + float hiscore = 0; + for (u32 t = 0; t < tcount; t++) + { + if (!tc[t].drawn) + { + if (tc[t].score > hiscore) + { + highest = t; + hiscore = tc[t].score; + found = true; + } + } + } + if (!found) + break; + } + + // Output the best triangle + u16 newind = buf->Vertices.size(); + + snode *s = sind.find(v[tc[highest].ind[0]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[0]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[0]], newind); + newind++; + } + else + { + buf->Indices.push_back(s->getValue()); + } + + s = sind.find(v[tc[highest].ind[1]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[1]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[1]], newind); + newind++; + } + else + { + buf->Indices.push_back(s->getValue()); + } + + s = sind.find(v[tc[highest].ind[2]]); + + if (!s) + { + buf->Vertices.push_back(v[tc[highest].ind[2]]); + buf->Indices.push_back(newind); + sind.insert(v[tc[highest].ind[2]], newind); + } + else + { + buf->Indices.push_back(s->getValue()); + } + + vc[tc[highest].ind[0]].NumActiveTris--; + vc[tc[highest].ind[1]].NumActiveTris--; + vc[tc[highest].ind[2]].NumActiveTris--; + + tc[highest].drawn = true; + + for (u16 j = 0; j < 3; j++) + { + vcache *vert = &vc[tc[highest].ind[j]]; + for (u16 t = 0; t < vert->tris.size(); t++) + { + if (highest == vert->tris[t]) + { + vert->tris.erase(t); + break; + } + } + } + + lru.add(tc[highest].ind[0]); + lru.add(tc[highest].ind[1]); + highest = lru.add(tc[highest].ind[2]); + drawcalls++; + } + + buf->setBoundingBox(mb->getBoundingBox()); + newmesh->addMeshBuffer(buf); + buf->drop(); + } + break; + } + + delete [] vc; + delete [] tc; + + } // for each meshbuffer + + return newmesh; +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.h new file mode 100644 index 0000000..c8029be --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshManipulator.h @@ -0,0 +1,95 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MESH_MANIPULATOR_H_INCLUDED__ +#define __C_MESH_MANIPULATOR_H_INCLUDED__ + +#include "IMeshManipulator.h" + +namespace irr +{ +namespace scene +{ + +//! An interface for easy manipulation of meshes. +/** Scale, set alpha value, flip surfaces, and so on. This exists for fixing +problems with wrong imported or exported meshes quickly after loading. It is +not intended for doing mesh modifications and/or animations during runtime. +*/ +class CMeshManipulator : public IMeshManipulator +{ +public: + //! Flips the direction of surfaces. + /** Changes backfacing triangles to frontfacing triangles and vice versa. + \param mesh: Mesh on which the operation is performed. */ + virtual void flipSurfaces(scene::IMesh* mesh) const; + + //! Recalculates all normals of the mesh. + /** \param mesh: Mesh on which the operation is performed. + \param smooth: Whether to use smoothed normals. */ + virtual void recalculateNormals(scene::IMesh* mesh, bool smooth = false, bool angleWeighted = false) const; + + //! Recalculates all normals of the mesh buffer. + /** \param buffer: Mesh buffer on which the operation is performed. + \param smooth: Whether to use smoothed normals. */ + virtual void recalculateNormals(IMeshBuffer* buffer, bool smooth = false, bool angleWeighted = false) const; + + //! Clones a static IMesh into a modifiable SMesh. + virtual SMesh* createMeshCopy(scene::IMesh* mesh) const; + + //! Creates a planar texture mapping on the mesh + /** \param mesh: Mesh on which the operation is performed. + \param resolution: resolution of the planar mapping. This is the value + specifying which is the relation between world space and + texture coordinate space. */ + virtual void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolution=0.001f) const; + + //! Creates a planar texture mapping on the meshbuffer + virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const; + + //! Creates a planar texture mapping on the meshbuffer + void makePlanarTextureMapping(scene::IMeshBuffer* buffer, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const; + + //! Creates a planar texture mapping on the mesh + void makePlanarTextureMapping(scene::IMesh* mesh, f32 resolutionS, f32 resolutionT, u8 axis, const core::vector3df& offset) const; + + //! Recalculates tangents, requires a tangent mesh buffer + virtual void recalculateTangents(IMeshBuffer* buffer, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const; + + //! Recalculates tangents, requires a tangent mesh + virtual void recalculateTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false) const; + + //! Creates a copy of the mesh, which will only consist of S3DVertexTangents vertices. + virtual IMesh* createMeshWithTangents(IMesh* mesh, bool recalculateNormals=false, bool smooth=false, bool angleWeighted=false, bool recalculateTangents=true) const; + + //! Creates a copy of the mesh, which will only consist of S3D2TCoords vertices. + virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const; + + //! Creates a copy of the mesh, which will only consist of S3DVertex vertices. + virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const; + + //! Creates a copy of the mesh, which will only consist of unique triangles, i.e. no vertices are shared. + virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const; + + //! Creates a copy of the mesh, which will have all duplicated vertices removed, i.e. maximal amount of vertices are shared via indexing. + virtual IMesh* createMeshWelded(IMesh *mesh, f32 tolerance=core::ROUNDING_ERROR_f32) const; + + //! Returns amount of polygons in mesh. + virtual s32 getPolyCount(scene::IMesh* mesh) const; + + //! Returns amount of polygons in mesh. + virtual s32 getPolyCount(scene::IAnimatedMesh* mesh) const; + + //! create a new AnimatedMesh and adds the mesh to it + virtual IAnimatedMesh * createAnimatedMesh(scene::IMesh* mesh,scene::E_ANIMATED_MESH_TYPE type) const; + + //! create a mesh optimized for the vertex cache + virtual IMesh* createForsythOptimizedMesh(const scene::IMesh *mesh) const; +}; + +} // end namespace scene +} // end namespace irr + + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.cpp new file mode 100644 index 0000000..5205b4d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.cpp @@ -0,0 +1,447 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMeshSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "ICameraSceneNode.h" +#include "IMeshCache.h" +#include "IAnimatedMesh.h" +#include "IMaterialRenderer.h" +#include "IFileSystem.h" +#include "CShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + + + +//! constructor +CMeshSceneNode::CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) +: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0), + PassCount(0), ReadOnlyMaterials(false) +{ + #ifdef _DEBUG + setDebugName("CMeshSceneNode"); + #endif + + setMesh(mesh); +} + + +//! destructor +CMeshSceneNode::~CMeshSceneNode() +{ + if (Shadow) + Shadow->drop(); + if (Mesh) + Mesh->drop(); +} + + +//! frame +void CMeshSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + // because this node supports rendering of mixed mode meshes consisting of + // transparent and solid material at the same time, we need to go through all + // materials, check of what type they are and register this node for the right + // render pass according to that. + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + PassCount = 0; + int transparentCount = 0; + int solidCount = 0; + + // count transparent and solid materials in this scene node + if (ReadOnlyMaterials && Mesh) + { + // count mesh materials + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + video::IMaterialRenderer* rnd = mb ? driver->getMaterialRenderer(mb->getMaterial().MaterialType) : 0; + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + } + else + { + // count copied materials + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + } + + // register according to material types counted + + if (solidCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + + if (transparentCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! renders the node. +void CMeshSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (!Mesh || !driver) + return; + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + + ++PassCount; + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + Box = Mesh->getBoundingBox(); + + if (Shadow && PassCount==1) + Shadow->updateShadowVolumes(); + + // for debug purposes only: + + bool renderMeshes = true; + video::SMaterial mat; + if (DebugDataVisible && PassCount==1) + { + // overwrite half transparency + if (DebugDataVisible & scene::EDS_HALF_TRANSPARENCY) + { + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + mat = Materials[g]; + mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; + driver->setMaterial(mat); + driver->drawMeshBuffer(Mesh->getMeshBuffer(g)); + } + renderMeshes = false; + } + } + + // render original meshes + if (renderMeshes) + { + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (mb) + { + const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; + + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(material); + driver->drawMeshBuffer(mb); + } + } + } + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + // for debug purposes only: + if (DebugDataVisible && PassCount==1) + { + video::SMaterial m; + m.Lighting = false; + m.AntiAliasing=0; + driver->setMaterial(m); + + if (DebugDataVisible & scene::EDS_BBOX) + { + driver->draw3DBox(Box, video::SColor(255,255,255,255)); + } + if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) + { + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + driver->draw3DBox( + Mesh->getMeshBuffer(g)->getBoundingBox(), + video::SColor(255,190,128,128)); + } + } + + if (DebugDataVisible & scene::EDS_NORMALS) + { + // draw normals + const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); + const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); + const u32 count = Mesh->getMeshBufferCount(); + + for (u32 i=0; i != count; ++i) + { + driver->drawMeshBufferNormals(Mesh->getMeshBuffer(i), debugNormalLength, debugNormalColor); + } + } + + // show mesh + if (DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) + { + m.Wireframe = true; + driver->setMaterial(m); + + for (u32 g=0; ggetMeshBufferCount(); ++g) + { + driver->drawMeshBuffer(Mesh->getMeshBuffer(g)); + } + } + } +} + + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool CMeshSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + } + + return ISceneNode::removeChild(child); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CMeshSceneNode::getBoundingBox() const +{ + return Mesh ? Mesh->getBoundingBox() : Box; +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hierarchy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CMeshSceneNode::getMaterial(u32 i) +{ + if (Mesh && ReadOnlyMaterials && igetMeshBufferCount()) + { + ReadOnlyMaterial = Mesh->getMeshBuffer(i)->getMaterial(); + return ReadOnlyMaterial; + } + + if (i >= Materials.size()) + return ISceneNode::getMaterial(i); + + return Materials[i]; +} + + +//! returns amount of materials used by this scene node. +u32 CMeshSceneNode::getMaterialCount() const +{ + if (Mesh && ReadOnlyMaterials) + return Mesh->getMeshBufferCount(); + + return Materials.size(); +} + + +//! Sets a new mesh +void CMeshSceneNode::setMesh(IMesh* mesh) +{ + if (mesh) + { + mesh->grab(); + if (Mesh) + Mesh->drop(); + + Mesh = mesh; + copyMaterials(); + } +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* CMeshSceneNode::addShadowVolumeSceneNode( + const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (!shadowMesh) + shadowMesh = Mesh; // if null is given, use the mesh of node + + if (Shadow) + Shadow->drop(); + + Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + + +void CMeshSceneNode::copyMaterials() +{ + Materials.clear(); + + if (Mesh) + { + video::SMaterial mat; + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (mb) + mat = mb->getMaterial(); + + Materials.push_back(mat); + } + } +} + + +//! Writes attributes of the scene node. +void CMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IMeshSceneNode::serializeAttributes(out, options); + + if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename) + { + const io::path path = SceneManager->getFileSystem()->getRelativeFilename( + SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()), + options->Filename); + out->addString("Mesh", path.c_str()); + } + else + out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str()); + out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); +} + + +//! Reads attributes of the scene node. +void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh); + io::path newMeshStr = in->getAttributeAsString("Mesh"); + ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials"); + + if (newMeshStr != "" && oldMeshStr != newMeshStr) + { + IMesh* newMesh = 0; + IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); + + if (newAnimatedMesh) + newMesh = newAnimatedMesh->getMesh(0); + + if (newMesh) + setMesh(newMesh); + } + + // optional attribute to assign the hint to the whole mesh + if (in->existsAttribute("HardwareMappingHint") && + in->existsAttribute("HardwareMappingBufferType")) + { + scene::E_HARDWARE_MAPPING mapping = scene::EHM_NEVER; + scene::E_BUFFER_TYPE bufferType = scene::EBT_NONE; + + core::stringc smapping = in->getAttributeAsString("HardwareMappingHint"); + if (smapping.equals_ignore_case("static")) + mapping = scene::EHM_STATIC; + else if (smapping.equals_ignore_case("dynamic")) + mapping = scene::EHM_DYNAMIC; + else if (smapping.equals_ignore_case("stream")) + mapping = scene::EHM_STREAM; + + core::stringc sbufferType = in->getAttributeAsString("HardwareMappingBufferType"); + if (sbufferType.equals_ignore_case("vertex")) + bufferType = scene::EBT_VERTEX; + else if (sbufferType.equals_ignore_case("index")) + bufferType = scene::EBT_INDEX; + else if (sbufferType.equals_ignore_case("vertexindex")) + bufferType = scene::EBT_VERTEX_AND_INDEX; + + IMesh* mesh = getMesh(); + if (mesh) + mesh->setHardwareMappingHint(mapping, bufferType); + } + + IMeshSceneNode::deserializeAttributes(in, options); +} + + +//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. +/* In this way it is possible to change the materials a mesh causing all mesh scene nodes +referencing this mesh to change too. */ +void CMeshSceneNode::setReadOnlyMaterials(bool readonly) +{ + ReadOnlyMaterials = readonly; +} + + +//! Returns if the scene node should not copy the materials of the mesh but use them in a read only style +bool CMeshSceneNode::isReadOnlyMaterials() const +{ + return ReadOnlyMaterials; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CMeshSceneNode* nb = new CMeshSceneNode(Mesh, newParent, + newManager, ID, RelativeTranslation, RelativeRotation, RelativeScale); + + nb->cloneMembers(this, newManager); + nb->ReadOnlyMaterials = ReadOnlyMaterials; + nb->Materials = Materials; + nb->Shadow = Shadow; + if ( nb->Shadow ) + nb->Shadow->grab(); + + if (newParent) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.h new file mode 100644 index 0000000..513664f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMeshSceneNode.h @@ -0,0 +1,103 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MESH_SCENE_NODE_H_INCLUDED__ +#define __C_MESH_SCENE_NODE_H_INCLUDED__ + +#include "IMeshSceneNode.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + + class CMeshSceneNode : public IMeshSceneNode + { + public: + + //! constructor + CMeshSceneNode(IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CMeshSceneNode(); + + //! frame + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_MESH; } + + //! Sets a new mesh + virtual void setMesh(IMesh* mesh); + + //! Returns the current mesh + virtual IMesh* getMesh(void) { return Mesh; } + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh, + s32 id, bool zfailmethod=true, f32 infinity=10000.0f); + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly); + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const; + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + + protected: + + void copyMaterials(); + + core::array Materials; + core::aabbox3d Box; + video::SMaterial ReadOnlyMaterial; + + IMesh* Mesh; + IShadowVolumeSceneNode* Shadow; + + s32 PassCount; + bool ReadOnlyMaterials; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.cpp new file mode 100644 index 0000000..843fa79 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.cpp @@ -0,0 +1,188 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMetaTriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CMetaTriangleSelector::CMetaTriangleSelector() +{ + #ifdef _DEBUG + setDebugName("CMetaTriangleSelector"); + #endif +} + + +//! destructor +CMetaTriangleSelector::~CMetaTriangleSelector() +{ + removeAllTriangleSelectors(); +} + + +//! Returns amount of all available triangles in this selector +s32 CMetaTriangleSelector::getTriangleCount() const +{ + s32 count = 0; + for (u32 i=0; igetTriangleCount(); + + return count; +} + + +//! Gets all triangles. +void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform) const +{ + s32 outWritten = 0; + for (u32 i=0; igetTriangles(triangles + outWritten, + arraySize - outWritten, t, transform); + outWritten += t; + if (outWritten==arraySize) + break; + } + + outTriangleCount = outWritten; +} + + +//! Gets all triangles which lie within a specific bounding box. +void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::aabbox3d& box, + const core::matrix4* transform) const +{ + s32 outWritten = 0; + for (u32 i=0; igetTriangles(triangles + outWritten, + arraySize - outWritten, t, box, transform); + outWritten += t; + if (outWritten==arraySize) + break; + } + + outTriangleCount = outWritten; +} + + +//! Gets all triangles which have or may have contact with a 3d line. +void CMetaTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform) const +{ + s32 outWritten = 0; + for (u32 i=0; igetTriangles(triangles + outWritten, + arraySize - outWritten, t, line, transform); + outWritten += t; + if (outWritten==arraySize) + break; + } + + outTriangleCount = outWritten; +} + + +//! Adds a triangle selector to the collection of triangle selectors +//! in this metaTriangleSelector. +void CMetaTriangleSelector::addTriangleSelector(ITriangleSelector* toAdd) +{ + if (!toAdd) + return; + + TriangleSelectors.push_back(toAdd); + toAdd->grab(); +} + + +//! Removes a specific triangle selector which was added before from the collection. +bool CMetaTriangleSelector::removeTriangleSelector(ITriangleSelector* toRemove) +{ + for (u32 i=0; idrop(); + TriangleSelectors.erase(i); + return true; + } + } + + return false; +} + + +//! Removes all triangle selectors from the collection. +void CMetaTriangleSelector::removeAllTriangleSelectors() +{ + for (u32 i=0; idrop(); + + TriangleSelectors.clear(); +} + + +//! Return the scene node associated with a given triangle. +ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleIndex) const +{ + u32 totalTriangles = 0; + + for (u32 i=0; igetTriangleCount(); + + if(totalTriangles > triangleIndex) + return TriangleSelectors[i]->getSceneNodeForTriangle(0); + } + + // For lack of anything more sensible, return the first selector. + return TriangleSelectors[0]->getSceneNodeForTriangle(0); +} + + +/* Return the number of TriangleSelectors that are inside this one, +Only useful for MetaTriangleSelector others return 1 +*/ +u32 CMetaTriangleSelector::getSelectorCount() const +{ + return TriangleSelectors.size(); +} + + +/* Returns the TriangleSelector based on index based on getSelectorCount +Only useful for MetaTriangleSelector others return 'this' +*/ +ITriangleSelector* CMetaTriangleSelector::getSelector(u32 index) +{ + if (index >= TriangleSelectors.size()) + return 0; + return TriangleSelectors[index]; +} + + +/* Returns the TriangleSelector based on index based on getSelectorCount +Only useful for MetaTriangleSelector others return 'this' +*/ +const ITriangleSelector* CMetaTriangleSelector::getSelector(u32 index) const +{ + if (index >= TriangleSelectors.size()) + return 0; + return TriangleSelectors[index]; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.h new file mode 100644 index 0000000..1294675 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMetaTriangleSelector.h @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_META_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __C_META_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "IMetaTriangleSelector.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! Interface for making multiple triangle selectors work as one big selector. +class CMetaTriangleSelector : public IMetaTriangleSelector +{ +public: + + //! constructor + CMetaTriangleSelector(); + + //! destructor + virtual ~CMetaTriangleSelector(); + + //! Get amount of all available triangles in this selector + virtual s32 getTriangleCount() const; + + //! Gets all triangles. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::matrix4* transform=0) const; + + //! Gets all triangles which lie within a specific bounding box. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::aabbox3d& box, + const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + + //! Adds a triangle selector to the collection of triangle selectors + //! in this metaTriangleSelector. + virtual void addTriangleSelector(ITriangleSelector* toAdd); + + //! Removes a specific triangle selector which was added before from the collection. + virtual bool removeTriangleSelector(ITriangleSelector* toRemove); + + //! Removes all triangle selectors from the collection. + virtual void removeAllTriangleSelectors(); + + //! Get the scene node associated with a given triangle. + virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const; + + // Get the number of TriangleSelectors that are part of this one + virtual u32 getSelectorCount() const; + + // Get the TriangleSelector based on index based on getSelectorCount + virtual ITriangleSelector* getSelector(u32 index); + + // Get the TriangleSelector based on index based on getSelectorCount + virtual const ITriangleSelector* getSelector(u32 index) const; + +private: + + core::array TriangleSelectors; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.cpp new file mode 100644 index 0000000..e78c3ff --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.cpp @@ -0,0 +1,175 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CMountPointReader.h" + +#ifdef __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ + +#include "CReadFile.h" +#include "os.h" + +namespace irr +{ +namespace io +{ + +//! Constructor +CArchiveLoaderMount::CArchiveLoaderMount( io::IFileSystem* fs) +: FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("CArchiveLoaderMount"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CArchiveLoaderMount::isALoadableFileFormat(const io::path& filename) const +{ + io::path fname(filename); + deletePathFromFilename(fname); + + if (!fname.size()) + return true; + IFileList* list = FileSystem->createFileList(); + bool ret = false; + if (list) + { + // check if name is found as directory + if (list->findFile(filename, true)) + ret=true; + list->drop(); + } + return ret; +} + +//! Check to see if the loader can create archives of this type. +bool CArchiveLoaderMount::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const +{ + return fileType == EFAT_FOLDER; +} + +//! Check if the file might be loaded by this class +bool CArchiveLoaderMount::isALoadableFileFormat(io::IReadFile* file) const +{ + return false; +} + +//! Creates an archive from the filename +IFileArchive* CArchiveLoaderMount::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + + EFileSystemType current = FileSystem->setFileListSystem(FILESYSTEM_NATIVE); + + const io::path save = FileSystem->getWorkingDirectory(); + io::path fullPath = FileSystem->getAbsolutePath(filename); + FileSystem->flattenFilename(fullPath); + + if (FileSystem->changeWorkingDirectoryTo(fullPath)) + { + archive = new CMountPointReader(FileSystem, fullPath, ignoreCase, ignorePaths); + } + + FileSystem->changeWorkingDirectoryTo(save); + FileSystem->setFileListSystem(current); + + return archive; +} + +//! creates/loads an archive from the file. +//! \return Pointer to the created archive. Returns 0 if loading failed. +IFileArchive* CArchiveLoaderMount::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const +{ + return 0; +} + +//! compatible Folder Architecture +CMountPointReader::CMountPointReader(IFileSystem * parent, const io::path& basename, bool ignoreCase, bool ignorePaths) + : CFileList(basename, ignoreCase, ignorePaths), Parent(parent) +{ + //! ensure CFileList path ends in a slash + if (Path.lastChar() != '/' ) + Path.append('/'); + + const io::path& work = Parent->getWorkingDirectory(); + + Parent->changeWorkingDirectoryTo(basename); + buildDirectory(); + Parent->changeWorkingDirectoryTo(work); + + sort(); +} + + +//! returns the list of files +const IFileList* CMountPointReader::getFileList() const +{ + return this; +} + +void CMountPointReader::buildDirectory() +{ + IFileList * list = Parent->createFileList(); + if (!list) + return; + + const u32 size = list->getFileCount(); + for (u32 i=0; i < size; ++i) + { + io::path full = list->getFullFileName(i); + full = full.subString(Path.size(), full.size() - Path.size()); + + if (!list->isDirectory(i)) + { + addItem(full, list->getFileOffset(i), list->getFileSize(i), false, RealFileNames.size()); + RealFileNames.push_back(list->getFullFileName(i)); + } + else + { + const io::path rel = list->getFileName(i); + RealFileNames.push_back(list->getFullFileName(i)); + + io::path pwd = Parent->getWorkingDirectory(); + if (pwd.lastChar() != '/') + pwd.append('/'); + pwd.append(rel); + + if ( rel != "." && rel != ".." ) + { + addItem(full, 0, 0, true, 0); + Parent->changeWorkingDirectoryTo(pwd); + buildDirectory(); + Parent->changeWorkingDirectoryTo(".."); + } + } + } + + list->drop(); +} + +//! opens a file by index +IReadFile* CMountPointReader::createAndOpenFile(u32 index) +{ + if (index >= Files.size()) + return 0; + + return createReadFile(RealFileNames[Files[index].ID]); +} + +//! opens a file by file name +IReadFile* CMountPointReader::createAndOpenFile(const io::path& filename) +{ + s32 index = findFile(filename, false); + if (index != -1) + return createAndOpenFile(index); + else + return 0; +} + + +} // io +} // irr + +#endif // __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.h new file mode 100644 index 0000000..a5ea86c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CMountPointReader.h @@ -0,0 +1,89 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_MOUNT_READER_H_INCLUDED__ +#define __C_MOUNT_READER_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ + +#include "IFileSystem.h" +#include "CFileList.h" + +namespace irr +{ +namespace io +{ + + //! Archiveloader capable of loading MountPoint Archives + class CArchiveLoaderMount : public IArchiveLoader + { + public: + + //! Constructor + CArchiveLoaderMount(io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".zip") + virtual bool isALoadableFileFormat(const io::path& filename) const; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const; + + //! Creates an archive from the filename + /** \param file File handle to check. + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const; + + //! creates/loads an archive from the file. + //! \return Pointer to the created archive. Returns 0 if loading failed. + virtual IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const; + + private: + io::IFileSystem* FileSystem; + }; + + //! A File Archive which uses a mountpoint + class CMountPointReader : public virtual IFileArchive, virtual CFileList + { + public: + + //! Constructor + CMountPointReader(IFileSystem *parent, const io::path& basename, + bool ignoreCase, bool ignorePaths); + + //! opens a file by index + virtual IReadFile* createAndOpenFile(u32 index); + + //! opens a file by file name + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! returns the list of files + virtual const IFileList* getFileList() const; + + //! get the class Type + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_FOLDER; } + + private: + + core::array RealFileNames; + + IFileSystem *Parent; + void buildDirectory(); + }; +} // io +} // irr + +#endif // __IRR_COMPILE_WITH_MOUNT_ARCHIVE_LOADER_ +#endif // __C_MOUNT_READER_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.cpp new file mode 100644 index 0000000..fc02786 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// Copyright (C) 2009-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Based on the NPK reader from Irrlicht + +#include "CNPKReader.h" + +#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ + +#include "os.h" +#include "coreutil.h" + +#ifdef _DEBUG +#define IRR_DEBUG_NPK_READER +#endif + +namespace irr +{ +namespace io +{ + +namespace +{ + bool isHeaderValid(const SNPKHeader& header) + { + const c8* const tag = header.Tag; + return tag[0] == '0' && + tag[1] == 'K' && + tag[2] == 'P' && + tag[3] == 'N'; + } +} // end namespace + + +//! Constructor +CArchiveLoaderNPK::CArchiveLoaderNPK( io::IFileSystem* fs) +: FileSystem(fs) +{ +#ifdef _DEBUG + setDebugName("CArchiveLoaderNPK"); +#endif +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CArchiveLoaderNPK::isALoadableFileFormat(const io::path& filename) const +{ + return core::hasFileExtension(filename, "npk"); +} + +//! Check to see if the loader can create archives of this type. +bool CArchiveLoaderNPK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const +{ + return fileType == EFAT_NPK; +} + +//! Creates an archive from the filename +/** \param file File handle to check. +\return Pointer to newly created archive, or 0 upon error. */ +IFileArchive* CArchiveLoaderNPK::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + archive = createArchive(file, ignoreCase, ignorePaths); + file->drop (); + } + + return archive; +} + +//! creates/loads an archive from the file. +//! \return Pointer to the created archive. Returns 0 if loading failed. +IFileArchive* CArchiveLoaderNPK::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + if ( file ) + { + file->seek ( 0 ); + archive = new CNPKReader(file, ignoreCase, ignorePaths); + } + return archive; +} + + +//! Check if the file might be loaded by this class +/** Check might look into the file. +\param file File handle to check. +\return True if file seems to be loadable. */ +bool CArchiveLoaderNPK::isALoadableFileFormat(io::IReadFile* file) const +{ + SNPKHeader header; + + file->read(&header, sizeof(header)); + + return isHeaderValid(header); +} + + +/*! + NPK Reader +*/ +CNPKReader::CNPKReader(IReadFile* file, bool ignoreCase, bool ignorePaths) +: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file) +{ +#ifdef _DEBUG + setDebugName("CNPKReader"); +#endif + + if (File) + { + File->grab(); + if (scanLocalHeader()) + sort(); + else + os::Printer::log("Failed to load NPK archive."); + } +} + + +CNPKReader::~CNPKReader() +{ + if (File) + File->drop(); +} + + +const IFileList* CNPKReader::getFileList() const +{ + return this; +} + + +bool CNPKReader::scanLocalHeader() +{ + SNPKHeader header; + + // Read and validate the header + File->read(&header, sizeof(header)); + if (!isHeaderValid(header)) + return false; + + // Seek to the table of contents +#ifdef __BIG_ENDIAN__ + header.Offset = os::Byteswap::byteswap(header.Offset); + header.Length = os::Byteswap::byteswap(header.Length); +#endif + header.Offset += 8; + core::stringc dirName; + bool inTOC=true; + // Loop through each entry in the table of contents + while (inTOC && (File->getPos() < File->getSize())) + { + // read an entry + char tag[4]={0}; + SNPKFileEntry entry; + File->read(tag, 4); + const int numTag = MAKE_IRR_ID(tag[3],tag[2],tag[1],tag[0]); + int size; + + bool isDir=true; + + switch (numTag) + { + case MAKE_IRR_ID('D','I','R','_'): + { + File->read(&size, 4); + readString(entry.Name); + entry.Length=0; + entry.Offset=0; +#ifdef IRR_DEBUG_NPK_READER + os::Printer::log("Dir", entry.Name); +#endif + } + break; + case MAKE_IRR_ID('F','I','L','E'): + { + File->read(&size, 4); + File->read(&entry.Offset, 4); + File->read(&entry.Length, 4); + readString(entry.Name); + isDir=false; +#ifdef IRR_DEBUG_NPK_READER + os::Printer::log("File", entry.Name); +#endif +#ifdef __BIG_ENDIAN__ + entry.Offset = os::Byteswap::byteswap(entry.Offset); + entry.Length = os::Byteswap::byteswap(entry.Length); +#endif + } + break; + case MAKE_IRR_ID('D','E','N','D'): + { + File->read(&size, 4); + entry.Name=""; + entry.Length=0; + entry.Offset=0; + const s32 pos = dirName.findLast('/', dirName.size()-2); + if (pos==-1) + dirName=""; + else + dirName=dirName.subString(0, pos); +#ifdef IRR_DEBUG_NPK_READER + os::Printer::log("Dirend", dirName); +#endif + } + break; + default: + inTOC=false; + } + // skip root dir + if (isDir) + { + if (!entry.Name.size() || (entry.Name==".") || (entry.Name=="")) + continue; + dirName += entry.Name; + dirName += "/"; + } +#ifdef IRR_DEBUG_NPK_READER + os::Printer::log("Name", entry.Name); +#endif + addItem((isDir?dirName:dirName+entry.Name), entry.Offset+header.Offset, entry.Length, isDir); + } + return true; +} + + +//! opens a file by file name +IReadFile* CNPKReader::createAndOpenFile(const io::path& filename) +{ + s32 index = findFile(filename, false); + + if (index != -1) + return createAndOpenFile(index); + + return 0; +} + + +//! opens a file by index +IReadFile* CNPKReader::createAndOpenFile(u32 index) +{ + if (index >= Files.size() ) + return 0; + + const SFileListEntry &entry = Files[index]; + return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size ); +} + +void CNPKReader::readString(core::stringc& name) +{ + short stringSize; + char buf[256]; + File->read(&stringSize, 2); +#ifdef __BIG_ENDIAN__ + stringSize = os::Byteswap::byteswap(stringSize); +#endif + name.reserve(stringSize); + while(stringSize) + { + const short next = core::min_(stringSize, (short)255); + File->read(buf,next); + buf[next]=0; + name.append(buf); + stringSize -= next; + } +} + + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.h new file mode 100644 index 0000000..e7792a6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CNPKReader.h @@ -0,0 +1,128 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// Copyright (C) 2009-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_NPK_READER_H_INCLUDED__ +#define __C_NPK_READER_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ + +#include "IReferenceCounted.h" +#include "IReadFile.h" +#include "irrArray.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "CFileList.h" + +namespace irr +{ +namespace io +{ + namespace + { + //! File header containing location and size of the table of contents + struct SNPKHeader + { + // Don't change the order of these fields! They must match the order stored on disk. + c8 Tag[4]; + u32 Length; + u32 Offset; + }; + + //! An entry in the NPK file's table of contents. + struct SNPKFileEntry + { + core::stringc Name; + u32 Offset; + u32 Length; + }; + } // end namespace + + //! Archiveloader capable of loading Nebula Device 2 NPK Archives + class CArchiveLoaderNPK : public IArchiveLoader + { + public: + + //! Constructor + CArchiveLoaderNPK(io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".zip") + virtual bool isALoadableFileFormat(const io::path& filename) const; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const; + + //! Creates an archive from the filename + /** \param file File handle to check. + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const; + + //! creates/loads an archive from the file. + //! \return Pointer to the created archive. Returns 0 if loading failed. + virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const; + + //! Returns the type of archive created by this loader + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_NPK; } + + private: + io::IFileSystem* FileSystem; + }; + + + //! reads from NPK + class CNPKReader : public virtual IFileArchive, virtual CFileList + { + public: + + CNPKReader(IReadFile* file, bool ignoreCase, bool ignorePaths); + virtual ~CNPKReader(); + + // file archive methods + + //! return the id of the file Archive + virtual const io::path& getArchiveName() const + { + return File->getFileName(); + } + + //! opens a file by file name + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! opens a file by index + virtual IReadFile* createAndOpenFile(u32 index); + + //! returns the list of files + virtual const IFileList* getFileList() const; + + //! get the class Type + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_NPK; } + + private: + + //! scans for a local header, returns false if the header is invalid + bool scanLocalHeader(); + void readString(core::stringc& name); + + IReadFile* File; + }; + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ + +#endif // __C_NPK_READER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.cpp new file mode 100644 index 0000000..3d02abe --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.cpp @@ -0,0 +1,2448 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CNullDriver.h" +#include "os.h" +#include "CImage.h" +#include "CAttributes.h" +#include "IReadFile.h" +#include "IWriteFile.h" +#include "IImageLoader.h" +#include "IImageWriter.h" +#include "IMaterialRenderer.h" +#include "IAnimatedMeshSceneNode.h" +#include "CMeshManipulator.h" +#include "CColorConverter.h" +#include "IAttributeExchangingObject.h" + + +namespace irr +{ +namespace video +{ + +//! creates a loader which is able to load windows bitmaps +IImageLoader* createImageLoaderBMP(); + +//! creates a loader which is able to load jpeg images +IImageLoader* createImageLoaderJPG(); + +//! creates a loader which is able to load targa images +IImageLoader* createImageLoaderTGA(); + +//! creates a loader which is able to load psd images +IImageLoader* createImageLoaderPSD(); + +//! creates a loader which is able to load dds images +IImageLoader* createImageLoaderDDS(); + +//! creates a loader which is able to load pcx images +IImageLoader* createImageLoaderPCX(); + +//! creates a loader which is able to load png images +IImageLoader* createImageLoaderPNG(); + +//! creates a loader which is able to load WAL images +IImageLoader* createImageLoaderWAL(); + +//! creates a loader which is able to load halflife images +IImageLoader* createImageLoaderHalfLife(); + +//! creates a loader which is able to load lmp images +IImageLoader* createImageLoaderLMP(); + +//! creates a loader which is able to load ppm/pgm/pbm images +IImageLoader* createImageLoaderPPM(); + +//! creates a loader which is able to load rgb images +IImageLoader* createImageLoaderRGB(); + + +//! creates a writer which is able to save bmp images +IImageWriter* createImageWriterBMP(); + +//! creates a writer which is able to save jpg images +IImageWriter* createImageWriterJPG(); + +//! creates a writer which is able to save tga images +IImageWriter* createImageWriterTGA(); + +//! creates a writer which is able to save psd images +IImageWriter* createImageWriterPSD(); + +//! creates a writer which is able to save pcx images +IImageWriter* createImageWriterPCX(); + +//! creates a writer which is able to save png images +IImageWriter* createImageWriterPNG(); + +//! creates a writer which is able to save ppm images +IImageWriter* createImageWriterPPM(); + +//! constructor +CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize) +: FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize), + PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0), + OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false) +{ + #ifdef _DEBUG + setDebugName("CNullDriver"); + #endif + + DriverAttributes = new io::CAttributes(); + DriverAttributes->addInt("MaxTextures", _IRR_MATERIAL_MAX_TEXTURES_); + DriverAttributes->addInt("MaxSupportedTextures", _IRR_MATERIAL_MAX_TEXTURES_); + DriverAttributes->addInt("MaxLights", getMaximalDynamicLightAmount()); + DriverAttributes->addInt("MaxAnisotropy", 1); +// DriverAttributes->addInt("MaxUserClipPlanes", 0); +// DriverAttributes->addInt("MaxAuxBuffers", 0); + DriverAttributes->addInt("MaxMultipleRenderTargets", 1); + DriverAttributes->addInt("MaxIndices", -1); + DriverAttributes->addInt("MaxTextureSize", -1); +// DriverAttributes->addInt("MaxGeometryVerticesOut", 0); +// DriverAttributes->addFloat("MaxTextureLODBias", 0.f); + DriverAttributes->addInt("Version", 1); +// DriverAttributes->addInt("ShaderLanguageVersion", 0); +// DriverAttributes->addInt("AntiAlias", 0); + + setFog(); + + setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true); + setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true); + + ViewPort = core::rect(core::position2d(0,0), core::dimension2di(screenSize)); + + // create manipulator + MeshManipulator = new scene::CMeshManipulator(); + + if (FileSystem) + FileSystem->grab(); + + // create surface loader + +#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderHalfLife()); +#endif +#ifdef _IRR_COMPILE_WITH_WAL_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderWAL()); +#endif +#ifdef _IRR_COMPILE_WITH_LMP_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderLMP()); +#endif +#ifdef _IRR_COMPILE_WITH_PPM_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPPM()); +#endif +#ifdef _IRR_COMPILE_WITH_RGB_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderRGB()); +#endif +#ifdef _IRR_COMPILE_WITH_PSD_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPSD()); +#endif +#ifdef _IRR_COMPILE_WITH_DDS_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderDDS()); +#endif +#ifdef _IRR_COMPILE_WITH_PCX_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPCX()); +#endif +#ifdef _IRR_COMPILE_WITH_TGA_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderTGA()); +#endif +#ifdef _IRR_COMPILE_WITH_PNG_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderPNG()); +#endif +#ifdef _IRR_COMPILE_WITH_JPG_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderJPG()); +#endif +#ifdef _IRR_COMPILE_WITH_BMP_LOADER_ + SurfaceLoader.push_back(video::createImageLoaderBMP()); +#endif + + +#ifdef _IRR_COMPILE_WITH_PPM_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPPM()); +#endif +#ifdef _IRR_COMPILE_WITH_PCX_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPCX()); +#endif +#ifdef _IRR_COMPILE_WITH_PSD_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPSD()); +#endif +#ifdef _IRR_COMPILE_WITH_TGA_WRITER_ + SurfaceWriter.push_back(video::createImageWriterTGA()); +#endif +#ifdef _IRR_COMPILE_WITH_JPG_WRITER_ + SurfaceWriter.push_back(video::createImageWriterJPG()); +#endif +#ifdef _IRR_COMPILE_WITH_PNG_WRITER_ + SurfaceWriter.push_back(video::createImageWriterPNG()); +#endif +#ifdef _IRR_COMPILE_WITH_BMP_WRITER_ + SurfaceWriter.push_back(video::createImageWriterBMP()); +#endif + + + // set ExposedData to 0 + memset(&ExposedData, 0, sizeof(ExposedData)); + for (u32 i=0; idrop(); + + if (FileSystem) + FileSystem->drop(); + + if (MeshManipulator) + MeshManipulator->drop(); + deleteAllTextures(); + + u32 i; + for (i=0; idrop(); + + for (i=0; idrop(); + + // delete material renderers + deleteMaterialRenders(); + + // delete hardware mesh buffers + removeAllHardwareBuffers(); +} + + +//! Adds an external surface loader to the engine. +void CNullDriver::addExternalImageLoader(IImageLoader* loader) +{ + if (!loader) + return; + + loader->grab(); + SurfaceLoader.push_back(loader); +} + + +//! Adds an external surface writer to the engine. +void CNullDriver::addExternalImageWriter(IImageWriter* writer) +{ + if (!writer) + return; + + writer->grab(); + SurfaceWriter.push_back(writer); +} + + +//! Retrieve the number of image loaders +u32 CNullDriver::getImageLoaderCount() const +{ + return SurfaceLoader.size(); +} + + +//! Retrieve the given image loader +IImageLoader* CNullDriver::getImageLoader(u32 n) +{ + if (n < SurfaceLoader.size()) + return SurfaceLoader[n]; + return 0; +} + + +//! Retrieve the number of image writers +u32 CNullDriver::getImageWriterCount() const +{ + return SurfaceWriter.size(); +} + + +//! Retrieve the given image writer +IImageWriter* CNullDriver::getImageWriter(u32 n) +{ + if (n < SurfaceWriter.size()) + return SurfaceWriter[n]; + return 0; +} + + +//! deletes all textures +void CNullDriver::deleteAllTextures() +{ + // we need to remove previously set textures which might otherwise be kept in the + // last set material member. Could be optimized to reduce state changes. + setMaterial(SMaterial()); + + for (u32 i=0; idrop(); + + Textures.clear(); +} + + + +//! applications must call this method before performing any rendering. returns false if failed. +bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, + const SExposedVideoData& videoData, core::rect* sourceRect) +{ + core::clearFPUException(); + PrimitivesDrawn = 0; + return true; +} + + +//! applications must call this method after performing any rendering. returns false if failed. +bool CNullDriver::endScene() +{ + FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn); + updateAllHardwareBuffers(); + updateAllOcclusionQueries(); + return true; +} + + +//! Disable a feature of the driver. +void CNullDriver::disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag) +{ + FeatureEnabled[feature]=!flag; +} + + +//! queries the features of the driver, returns true if feature is available +bool CNullDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + return false; +} + + +//! Get attributes of the actual video driver +const io::IAttributes& CNullDriver::getDriverAttributes() const +{ + return *DriverAttributes; +} + + +//! sets transformation +void CNullDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CNullDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return TransformationMatrix; +} + + +//! sets a material +void CNullDriver::setMaterial(const SMaterial& material) +{ +} + + +//! Removes a texture from the texture cache and deletes it, freeing lot of +//! memory. +void CNullDriver::removeTexture(ITexture* texture) +{ + if (!texture) + return; + + for (u32 i=0; idrop(); + Textures.erase(i); + } + } +} + + +//! Removes all texture from the texture cache and deletes them, freeing lot of +//! memory. +void CNullDriver::removeAllTextures() +{ + setMaterial ( SMaterial() ); + deleteAllTextures(); +} + + +//! Returns a texture by index +ITexture* CNullDriver::getTextureByIndex(u32 i) +{ + if ( i < Textures.size() ) + return Textures[i].Surface; + + return 0; +} + + +//! Returns amount of textures currently loaded +u32 CNullDriver::getTextureCount() const +{ + return Textures.size(); +} + + +//! Renames a texture +void CNullDriver::renameTexture(ITexture* texture, const io::path& newName) +{ + // we can do a const_cast here safely, the name of the ITexture interface + // is just readonly to prevent the user changing the texture name without invoking + // this method, because the textures will need resorting afterwards + + io::SNamedPath& name = const_cast(texture->getName()); + name.setPath(newName); + + Textures.sort(); +} + + +//! loads a Texture +ITexture* CNullDriver::getTexture(const io::path& filename) +{ + // Identify textures by their absolute filenames if possible. + const io::path absolutePath = FileSystem->getAbsolutePath(filename); + + ITexture* texture = findTexture(absolutePath); + if (texture) + return texture; + + // Then try the raw filename, which might be in an Archive + texture = findTexture(filename); + if (texture) + return texture; + + // Now try to open the file using the complete path. + io::IReadFile* file = FileSystem->createAndOpenFile(absolutePath); + + if (!file) + { + // Try to open it using the raw filename. + file = FileSystem->createAndOpenFile(filename); + } + + if (file) + { + // Re-check name for actual archive names + texture = findTexture(file->getFileName()); + if (texture) + { + file->drop(); + return texture; + } + + texture = loadTextureFromFile(file); + file->drop(); + + if (texture) + { + addTexture(texture); + texture->drop(); // drop it because we created it, one grab too much + } + else + os::Printer::log("Could not load texture", filename, ELL_ERROR); + return texture; + } + else + { + os::Printer::log("Could not open file of texture", filename, ELL_WARNING); + return 0; + } +} + + +//! loads a Texture +ITexture* CNullDriver::getTexture(io::IReadFile* file) +{ + ITexture* texture = 0; + + if (file) + { + texture = findTexture(file->getFileName()); + + if (texture) + return texture; + + texture = loadTextureFromFile(file); + + if (texture) + { + addTexture(texture); + texture->drop(); // drop it because we created it, one grab too much + } + + if (!texture) + os::Printer::log("Could not load texture", file->getFileName(), ELL_WARNING); + } + + return texture; +} + + +//! opens the file and loads it into the surface +video::ITexture* CNullDriver::loadTextureFromFile(io::IReadFile* file, const io::path& hashName ) +{ + ITexture* texture = 0; + IImage* image = createImageFromFile(file); + + if (image) + { + // create texture from surface + texture = createDeviceDependentTexture(image, hashName.size() ? hashName : file->getFileName() ); + os::Printer::log("Loaded texture", file->getFileName()); + image->drop(); + } + + return texture; +} + + +//! adds a surface, not loaded or created by the Irrlicht Engine +void CNullDriver::addTexture(video::ITexture* texture) +{ + if (texture) + { + SSurface s; + s.Surface = texture; + texture->grab(); + + Textures.push_back(s); + + // the new texture is now at the end of the texture list. when searching for + // the next new texture, the texture array will be sorted and the index of this texture + // will be changed. to let the order be more consistent to the user, sort + // the textures now already although this isn't necessary: + + Textures.sort(); + } +} + + +//! looks if the image is already loaded +video::ITexture* CNullDriver::findTexture(const io::path& filename) +{ + SSurface s; + SDummyTexture dummy(filename); + s.Surface = &dummy; + + s32 index = Textures.binary_search(s); + if (index != -1) + return Textures[index].Surface; + + return 0; +} + + +//! Creates a texture from a loaded IImage. +ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData) +{ + if ( 0 == name.size() || !image) + return 0; + + ITexture* t = createDeviceDependentTexture(image, name, mipmapData); + if (t) + { + addTexture(t); + t->drop(); + } + return t; +} + + +//! creates a Texture +ITexture* CNullDriver::addTexture(const core::dimension2d& size, + const io::path& name, ECOLOR_FORMAT format) +{ + if(IImage::isRenderTargetOnlyFormat(format)) + { + os::Printer::log("Could not create ITexture, format only supported for render target textures.", ELL_WARNING); + return 0; + } + + if ( 0 == name.size () ) + return 0; + + IImage* image = new CImage(format, size); + ITexture* t = createDeviceDependentTexture(image, name); + image->drop(); + addTexture(t); + + if (t) + t->drop(); + + return t; +} + + + +//! returns a device dependent texture from a software surface (IImage) +//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES +ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) +{ + return new SDummyTexture(name); +} + + +//! set or reset special render targets +bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, + bool clearZBuffer, SColor color) +{ + if (ERT_FRAME_BUFFER==target) + return setRenderTarget(0,clearTarget, clearZBuffer, color); + else + return false; +} + + +//! sets a render target +bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + return false; +} + + +//! Sets multiple render targets +bool CNullDriver::setRenderTarget(const core::array& texture, + bool clearBackBuffer, bool clearZBuffer, SColor color) +{ + return false; +} + + +//! sets a viewport +void CNullDriver::setViewPort(const core::rect& area) +{ +} + + +//! gets the area of the current viewport +const core::rect& CNullDriver::getViewPort() const +{ + return ViewPort; +} + + +//! draws a vertex primitive list +void CNullDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) +{ + if ((iType==EIT_16BIT) && (vertexCount>65536)) + os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur."); + PrimitivesDrawn += primitiveCount; +} + + +//! draws a vertex primitive list in 2d +void CNullDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) +{ + if ((iType==EIT_16BIT) && (vertexCount>65536)) + os::Printer::log("Too many vertices for 16bit index type, render artifacts may occur."); + PrimitivesDrawn += primitiveCount; +} + + +//! Draws a 3d line. +void CNullDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ +} + + +//! Draws a 3d triangle. +void CNullDriver::draw3DTriangle(const core::triangle3df& triangle, SColor color) +{ + S3DVertex vertices[3]; + vertices[0].Pos=triangle.pointA; + vertices[0].Color=color; + vertices[0].Normal=triangle.getNormal().normalize(); + vertices[0].TCoords.set(0.f,0.f); + vertices[1].Pos=triangle.pointB; + vertices[1].Color=color; + vertices[1].Normal=vertices[0].Normal; + vertices[1].TCoords.set(0.5f,1.f); + vertices[2].Pos=triangle.pointC; + vertices[2].Color=color; + vertices[2].Normal=vertices[0].Normal; + vertices[2].TCoords.set(1.f,0.f); + const u16 indexList[] = {0,1,2}; + drawVertexPrimitiveList(vertices, 3, indexList, 1, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT); +} + + +//! Draws a 3d axis aligned box. +void CNullDriver::draw3DBox(const core::aabbox3d& box, SColor color) +{ + core::vector3df edges[8]; + box.getEdges(edges); + + // TODO: optimize into one big drawIndexPrimitive call. + + draw3DLine(edges[5], edges[1], color); + draw3DLine(edges[1], edges[3], color); + draw3DLine(edges[3], edges[7], color); + draw3DLine(edges[7], edges[5], color); + draw3DLine(edges[0], edges[2], color); + draw3DLine(edges[2], edges[6], color); + draw3DLine(edges[6], edges[4], color); + draw3DLine(edges[4], edges[0], color); + draw3DLine(edges[1], edges[0], color); + draw3DLine(edges[3], edges[2], color); + draw3DLine(edges[7], edges[6], color); + draw3DLine(edges[5], edges[4], color); +} + + + +//! draws an 2d image +void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos) +{ + if (!texture) + return; + + draw2DImage(texture,destPos, core::rect(core::position2d(0,0), + core::dimension2di(texture->getOriginalSize()))); +} + + + +//! draws a set of 2d images, using a color and the alpha channel of the +//! texture if desired. The images are drawn beginning at pos and concatenated +//! in one line. All drawings are clipped against clipRect (if != 0). +//! The subtextures are defined by the array of sourceRects and are chosen +//! by the indices given. +void CNullDriver::draw2DImageBatch(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + s32 kerningWidth, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + core::position2d target(pos); + + for (u32 i=0; i >& positions, + const core::array >& sourceRects, + const core::rect* clipRect, + SColor color, + bool useAlphaChannelOfTexture) +{ + const irr::u32 drawCount = core::min_(positions.size(), sourceRects.size()); + + for (u32 i=0; i& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + if (destRect.isValid()) + draw2DImage(texture, core::position2d(destRect.UpperLeftCorner), + sourceRect, clipRect, colors?colors[0]:video::SColor(0xffffffff), + useAlphaChannelOfTexture); +} + + +//! Draws a 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CNullDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ +} + + +//! Draws the outline of a 2d rectangle +void CNullDriver::draw2DRectangleOutline(const core::recti& pos, SColor color) +{ + draw2DLine(pos.UpperLeftCorner, core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), color); + draw2DLine(core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), pos.LowerRightCorner, color); + draw2DLine(pos.LowerRightCorner, core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), color); + draw2DLine(core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), pos.UpperLeftCorner, color); +} + + +//! Draw a 2d rectangle +void CNullDriver::draw2DRectangle(SColor color, const core::rect& pos, const core::rect* clip) +{ + draw2DRectangle(pos, color, color, color, color, clip); +} + + + +//! Draws a 2d rectangle with a gradient. +void CNullDriver::draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ +} + + + +//! Draws a 2d line. +void CNullDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, SColor color) +{ +} + +//! Draws a pixel +void CNullDriver::drawPixel(u32 x, u32 y, const SColor & color) +{ +} + + +//! Draws a non filled concyclic regular 2d polyon. +void CNullDriver::draw2DPolygon(core::position2d center, + f32 radius, video::SColor color, s32 count) +{ + if (count < 2) + return; + + core::position2d first; + core::position2d a,b; + + for (s32 j=0; j((s32)(sin(p)*radius), (s32)(cos(p)*radius)); + + if (j==0) + first = a; + else + draw2DLine(a, b, color); + } + + draw2DLine(a, first, color); +} + + +//! returns color format +ECOLOR_FORMAT CNullDriver::getColorFormat() const +{ + return ECF_R5G6B5; +} + + +//! returns screen size +const core::dimension2d& CNullDriver::getScreenSize() const +{ + return ScreenSize; +} + + +//! returns the current render target size, +//! or the screen size if render targets are not implemented +const core::dimension2d& CNullDriver::getCurrentRenderTargetSize() const +{ + return ScreenSize; +} + + +// returns current frames per second value +s32 CNullDriver::getFPS() const +{ + return FPSCounter.getFPS(); +} + + + +//! returns amount of primitives (mostly triangles) were drawn in the last frame. +//! very useful method for statistics. +u32 CNullDriver::getPrimitiveCountDrawn( u32 param ) const +{ + return (0 == param) ? FPSCounter.getPrimitive() : (1 == param) ? FPSCounter.getPrimitiveAverage() : FPSCounter.getPrimitiveTotal(); +} + + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CNullDriver::setAmbientLight(const SColorf& color) +{ +} + + + +//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 +//! driver, it would return "Direct3D8". + +const wchar_t* CNullDriver::getName() const +{ + return L"Irrlicht NullDevice"; +} + + + +//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do +//! this: Frist, draw all geometry. Then use this method, to draw the shadow +//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CNullDriver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) +{ +} + + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CNullDriver::drawStencilShadow(bool clearStencilBuffer, + video::SColor leftUpEdge, video::SColor rightUpEdge, + video::SColor leftDownEdge, video::SColor rightDownEdge) +{ +} + + +//! deletes all dynamic lights there are +void CNullDriver::deleteAllDynamicLights() +{ + Lights.set_used(0); +} + + +//! adds a dynamic light +s32 CNullDriver::addDynamicLight(const SLight& light) +{ + Lights.push_back(light); + return Lights.size() - 1; +} + +//! Turns a dynamic light on or off +//! \param lightIndex: the index returned by addDynamicLight +//! \param turnOn: true to turn the light on, false to turn it off +void CNullDriver::turnLightOn(s32 lightIndex, bool turnOn) +{ + // Do nothing +} + + +//! returns the maximal amount of dynamic lights the device can handle +u32 CNullDriver::getMaximalDynamicLightAmount() const +{ + return 0; +} + + +//! Returns current amount of dynamic lights set +//! \return Current amount of dynamic lights set +u32 CNullDriver::getDynamicLightCount() const +{ + return Lights.size(); +} + + +//! Returns light data which was previously set by IVideoDriver::addDynamicLight(). +//! \param idx: Zero based index of the light. Must be greater than 0 and smaller +//! than IVideoDriver()::getDynamicLightCount. +//! \return Light data. +const SLight& CNullDriver::getDynamicLight(u32 idx) const +{ + if ( idx < Lights.size() ) + return Lights[idx]; + else + return *((SLight*)0); +} + + +//! Creates a boolean alpha channel of the texture based of an color key. +void CNullDriver::makeColorKeyTexture(video::ITexture* texture, + video::SColor color, + bool zeroTexels) const +{ + if (!texture) + return; + + if (texture->getColorFormat() != ECF_A1R5G5B5 && + texture->getColorFormat() != ECF_A8R8G8B8 ) + { + os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); + return; + } + + if (texture->getColorFormat() == ECF_A1R5G5B5) + { + u16 *p = (u16*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + const core::dimension2d dim = texture->getSize(); + const u32 pitch = texture->getPitch() / 2; + + // color with alpha disabled (i.e. fully transparent) + const u16 refZeroAlpha = (0x7fff & color.toA1R5G5B5()); + + const u32 pixels = pitch * dim.Height; + + for (u32 pixel = 0; pixel < pixels; ++ pixel) + { + // If the color matches the reference color, ignoring alphas, + // set the alpha to zero. + if(((*p) & 0x7fff) == refZeroAlpha) + { + if(zeroTexels) + (*p) = 0; + else + (*p) = refZeroAlpha; + } + + ++p; + } + + texture->unlock(); + } + else + { + u32 *p = (u32*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + u32 pitch = texture->getPitch() / 4; + + // color with alpha disabled (fully transparent) + const u32 refZeroAlpha = 0x00ffffff & color.color; + + const u32 pixels = pitch * dim.Height; + for (u32 pixel = 0; pixel < pixels; ++ pixel) + { + // If the color matches the reference color, ignoring alphas, + // set the alpha to zero. + if(((*p) & 0x00ffffff) == refZeroAlpha) + { + if(zeroTexels) + (*p) = 0; + else + (*p) = refZeroAlpha; + } + + ++p; + } + + texture->unlock(); + } + texture->regenerateMipMapLevels(); +} + + + +//! Creates an boolean alpha channel of the texture based of an color key position. +void CNullDriver::makeColorKeyTexture(video::ITexture* texture, + core::position2d colorKeyPixelPos, + bool zeroTexels) const +{ + if (!texture) + return; + + if (texture->getColorFormat() != ECF_A1R5G5B5 && + texture->getColorFormat() != ECF_A8R8G8B8 ) + { + os::Printer::log("Error: Unsupported texture color format for making color key channel.", ELL_ERROR); + return; + } + + SColor colorKey; + + if (texture->getColorFormat() == ECF_A1R5G5B5) + { + u16 *p = (u16*)texture->lock(ETLM_READ_ONLY); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + u32 pitch = texture->getPitch() / 2; + + const u16 key16Bit = 0x7fff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X]; + + colorKey = video::A1R5G5B5toA8R8G8B8(key16Bit); + } + else + { + u32 *p = (u32*)texture->lock(ETLM_READ_ONLY); + + if (!p) + { + os::Printer::log("Could not lock texture for making color key channel.", ELL_ERROR); + return; + } + + u32 pitch = texture->getPitch() / 4; + colorKey = 0x00ffffff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X]; + } + + texture->unlock(); + makeColorKeyTexture(texture, colorKey, zeroTexels); +} + + + +//! Creates a normal map from a height map texture. +//! \param amplitude: Constant value by which the height information is multiplied. +void CNullDriver::makeNormalMapTexture(video::ITexture* texture, f32 amplitude) const +{ + if (!texture) + return; + + if (texture->getColorFormat() != ECF_A1R5G5B5 && + texture->getColorFormat() != ECF_A8R8G8B8 ) + { + os::Printer::log("Error: Unsupported texture color format for making normal map.", ELL_ERROR); + return; + } + + core::dimension2d dim = texture->getSize(); + amplitude = amplitude / 255.0f; + f32 vh = dim.Height / (f32)dim.Width; + f32 hh = dim.Width / (f32)dim.Height; + + if (texture->getColorFormat() == ECF_A8R8G8B8) + { + // ECF_A8R8G8B8 version + + s32 *p = (s32*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); + return; + } + + // copy texture + + u32 pitch = texture->getPitch() / 4; + + s32* in = new s32[dim.Height * pitch]; + memcpy(in, p, dim.Height * pitch * 4); + + for (s32 x=0; x < s32(pitch); ++x) + for (s32 y=0; y < s32(dim.Height); ++y) + { + // TODO: this could be optimized really a lot + + core::vector3df h1((x-1)*hh, nml32(x-1, y, pitch, dim.Height, in)*amplitude, y*vh); + core::vector3df h2((x+1)*hh, nml32(x+1, y, pitch, dim.Height, in)*amplitude, y*vh); + //core::vector3df v1(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh); + //core::vector3df v2(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh); + core::vector3df v1(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y-1)*vh); + core::vector3df v2(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y+1)*vh); + + core::vector3df v = v1-v2; + core::vector3df h = h1-h2; + + core::vector3df n = v.crossProduct(h); + n.normalize(); + n *= 0.5f; + n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1 + n *= 255.0f; + + s32 height = (s32)nml32(x, y, pitch, dim.Height, in); + p[y*pitch + x] = video::SColor( + height, // store height in alpha + (s32)n.X, (s32)n.Z, (s32)n.Y).color; + } + + delete [] in; + texture->unlock(); + } + else + { + // ECF_A1R5G5B5 version + + s16 *p = (s16*)texture->lock(); + + if (!p) + { + os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR); + return; + } + + u32 pitch = texture->getPitch() / 2; + + // copy texture + + s16* in = new s16[dim.Height * pitch]; + memcpy(in, p, dim.Height * pitch * 2); + + for (s32 x=0; x < s32(pitch); ++x) + for (s32 y=0; y < s32(dim.Height); ++y) + { + // TODO: this could be optimized really a lot + + core::vector3df h1((x-1)*hh, nml16(x-1, y, pitch, dim.Height, in)*amplitude, y*vh); + core::vector3df h2((x+1)*hh, nml16(x+1, y, pitch, dim.Height, in)*amplitude, y*vh); + core::vector3df v1(x*hh, nml16(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh); + core::vector3df v2(x*hh, nml16(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh); + + core::vector3df v = v1-v2; + core::vector3df h = h1-h2; + + core::vector3df n = v.crossProduct(h); + n.normalize(); + n *= 0.5f; + n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1 + n *= 255.0f; + + p[y*pitch + x] = video::RGBA16((u32)n.X, (u32)n.Z, (u32)n.Y); + } + + delete [] in; + texture->unlock(); + } + + texture->regenerateMipMapLevels(); +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CNullDriver::getMaximalPrimitiveCount() const +{ + return 0xFFFFFFFF; +} + + +//! checks triangle count and print warning if wrong +bool CNullDriver::checkPrimitiveCount(u32 prmCount) const +{ + const u32 m = getMaximalPrimitiveCount(); + + if (prmCount > m) + { + char tmp[1024]; + sprintf(tmp,"Could not draw triangles, too many primitives(%u), maxium is %u.", prmCount, m); + os::Printer::log(tmp, ELL_ERROR); + return false; + } + + return true; +} + +//! Enables or disables a texture creation flag. +void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled) +{ + if (enabled && ((flag == ETCF_ALWAYS_16_BIT) || (flag == ETCF_ALWAYS_32_BIT) + || (flag == ETCF_OPTIMIZED_FOR_QUALITY) || (flag == ETCF_OPTIMIZED_FOR_SPEED))) + { + // disable other formats + setTextureCreationFlag(ETCF_ALWAYS_16_BIT, false); + setTextureCreationFlag(ETCF_ALWAYS_32_BIT, false); + setTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY, false); + setTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED, false); + } + + // set flag + TextureCreationFlags = (TextureCreationFlags & (~flag)) | + ((((u32)!enabled)-1) & flag); +} + + +//! Returns if a texture creation flag is enabled or disabled. +bool CNullDriver::getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const +{ + return (TextureCreationFlags & flag)!=0; +} + + +//! Creates a software image from a file. +IImage* CNullDriver::createImageFromFile(const io::path& filename) +{ + if (!filename.size()) + return 0; + + IImage* image = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + image = createImageFromFile(file); + file->drop(); + } + else + os::Printer::log("Could not open file of image", filename, ELL_WARNING); + + return image; +} + + +//! Creates a software image from a file. +IImage* CNullDriver::createImageFromFile(io::IReadFile* file) +{ + if (!file) + return 0; + + IImage* image = 0; + + s32 i; + + // try to load file based on file extension + for (i=SurfaceLoader.size()-1; i>=0; --i) + { + if (SurfaceLoader[i]->isALoadableFileExtension(file->getFileName())) + { + // reset file position which might have changed due to previous loadImage calls + file->seek(0); + image = SurfaceLoader[i]->loadImage(file); + if (image) + return image; + } + } + + // try to load file based on what is in it + for (i=SurfaceLoader.size()-1; i>=0; --i) + { + // dito + file->seek(0); + if (SurfaceLoader[i]->isALoadableFileFormat(file)) + { + file->seek(0); + image = SurfaceLoader[i]->loadImage(file); + if (image) + return image; + } + } + + return 0; // failed to load +} + + +//! Writes the provided image to disk file +bool CNullDriver::writeImageToFile(IImage* image, const io::path& filename,u32 param) +{ + io::IWriteFile* file = FileSystem->createAndWriteFile(filename); + if(!file) + return false; + + bool result = writeImageToFile(image, file, param); + file->drop(); + + return result; +} + +//! Writes the provided image to a file. +bool CNullDriver::writeImageToFile(IImage* image, io::IWriteFile * file, u32 param) +{ + if(!file) + return false; + + for (s32 i=SurfaceWriter.size()-1; i>=0; --i) + { + if (SurfaceWriter[i]->isAWriteableFileExtension(file->getFileName())) + { + bool written = SurfaceWriter[i]->writeImage(file, image, param); + if (written) + return true; + } + } + return false; // failed to write +} + + +//! Creates a software image from a byte array. +IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format, + const core::dimension2d& size, + void *data, bool ownForeignMemory, + bool deleteMemory) +{ + if(IImage::isRenderTargetOnlyFormat(format)) + { + os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); + return 0; + } + + return new CImage(format, size, data, ownForeignMemory, deleteMemory); +} + + +//! Creates an empty software image. +IImage* CNullDriver::createImage(ECOLOR_FORMAT format, const core::dimension2d& size) +{ + if(IImage::isRenderTargetOnlyFormat(format)) + { + os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); + return 0; + } + + return new CImage(format, size); +} + + +//! Creates a software image from another image. +IImage* CNullDriver::createImage(ECOLOR_FORMAT format, IImage *imageToCopy) +{ + os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING); + if(IImage::isRenderTargetOnlyFormat(format)) + { + os::Printer::log("Could not create IImage, format only supported for render target textures.", ELL_WARNING); + return 0; + } + + CImage* tmp = new CImage(format, imageToCopy->getDimension()); + imageToCopy->copyTo(tmp); + return tmp; +} + + +//! Creates a software image from part of another image. +IImage* CNullDriver::createImage(IImage* imageToCopy, const core::position2d& pos, const core::dimension2d& size) +{ + os::Printer::log("Deprecated method, please create an empty image instead and use copyTo().", ELL_WARNING); + CImage* tmp = new CImage(imageToCopy->getColorFormat(), imageToCopy->getDimension()); + imageToCopy->copyTo(tmp, core::position2di(0,0), core::recti(pos,size)); + return tmp; +} + + +//! Creates a software image from part of a texture. +IImage* CNullDriver::createImage(ITexture* texture, const core::position2d& pos, const core::dimension2d& size) +{ + if ((pos==core::position2di(0,0)) && (size == texture->getSize())) + { + IImage* image = new CImage(texture->getColorFormat(), size, texture->lock(ETLM_READ_ONLY), false); + texture->unlock(); + return image; + } + else + { + // make sure to avoid buffer overruns + // make the vector a separate variable for g++ 3.x + const core::vector2d leftUpper(core::clamp(static_cast(pos.X), 0u, texture->getSize().Width), + core::clamp(static_cast(pos.Y), 0u, texture->getSize().Height)); + const core::rect clamped(leftUpper, + core::dimension2du(core::clamp(static_cast(size.Width), 0u, texture->getSize().Width), + core::clamp(static_cast(size.Height), 0u, texture->getSize().Height))); + if (!clamped.isValid()) + return 0; + u8* src = static_cast(texture->lock(ETLM_READ_ONLY)); + if (!src) + return 0; + IImage* image = new CImage(texture->getColorFormat(), clamped.getSize()); + u8* dst = static_cast(image->lock()); + src += clamped.UpperLeftCorner.Y * texture->getPitch() + image->getBytesPerPixel() * clamped.UpperLeftCorner.X; + for (u32 i=0; igetColorFormat(), clamped.getWidth(), dst, image->getColorFormat()); + src += texture->getPitch(); + dst += image->getPitch(); + } + image->unlock(); + texture->unlock(); + return image; + } +} + + +//! Sets the fog mode. +void CNullDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, f32 end, + f32 density, bool pixelFog, bool rangeFog) +{ + FogColor = color; + FogType = fogType; + FogStart = start; + FogEnd = end; + FogDensity = density; + PixelFog = pixelFog; + RangeFog = rangeFog; +} + +//! Gets the fog mode. +void CNullDriver::getFog(SColor& color, E_FOG_TYPE& fogType, f32& start, f32& end, + f32& density, bool& pixelFog, bool& rangeFog) +{ + color = FogColor; + fogType = FogType; + start = FogStart; + end = FogEnd; + density = FogDensity; + pixelFog = PixelFog; + rangeFog = RangeFog; +} + +//! Draws a mesh buffer +void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) +{ + if (!mb) + return; + + //IVertexBuffer and IIndexBuffer later + SHWBufferLink *HWBuffer=getBufferLink(mb); + + if (HWBuffer) + drawHardwareBuffer(HWBuffer); + else + drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); +} + + +//! Draws the normals of a mesh buffer +void CNullDriver::drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length, SColor color) +{ + const u32 count = mb->getVertexCount(); + const bool normalize = mb->getMaterial().NormalizeNormals; + + for (u32 i=0; i < count; ++i) + { + core::vector3df normalizedNormal = mb->getNormal(i); + if (normalize) + normalizedNormal.normalize(); + + const core::vector3df& pos = mb->getPosition(i); + draw3DLine(pos, pos + (normalizedNormal * length), color); + } +} + + +CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* mb) +{ + if (!mb || !isHardwareBufferRecommend(mb)) + return 0; + + //search for hardware links + core::map< const scene::IMeshBuffer*,SHWBufferLink* >::Node* node = HWBufferMap.find(mb); + if (node) + return node->getValue(); + + return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it +} + + +//! Update all hardware buffers, remove unused ones +void CNullDriver::updateAllHardwareBuffers() +{ + core::map::ParentFirstIterator Iterator=HWBufferMap.getParentFirstIterator(); + + for (;!Iterator.atEnd();Iterator++) + { + SHWBufferLink *Link=Iterator.getNode()->getValue(); + + Link->LastUsed++; + if (Link->LastUsed>20000) + { + deleteHardwareBuffer(Link); + + // todo: needs better fix + Iterator = HWBufferMap.getParentFirstIterator(); + } + } +} + + +void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer) +{ + if (!HWBuffer) + return; + HWBufferMap.remove(HWBuffer->MeshBuffer); + delete HWBuffer; +} + + +//! Remove hardware buffer +void CNullDriver::removeHardwareBuffer(const scene::IMeshBuffer* mb) +{ + core::map::Node* node = HWBufferMap.find(mb); + if (node) + deleteHardwareBuffer(node->getValue()); +} + + +//! Remove all hardware buffers +void CNullDriver::removeAllHardwareBuffers() +{ + while (HWBufferMap.size()) + deleteHardwareBuffer(HWBufferMap.getRoot()->getValue()); +} + + +bool CNullDriver::isHardwareBufferRecommend(const scene::IMeshBuffer* mb) +{ + if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) + return false; + + if (mb->getVertexCount()getType() != scene::ESNT_MESH) && (node->getType() != scene::ESNT_ANIMATED_MESH)) + return; + else if (node->getType() == scene::ESNT_MESH) + mesh = static_cast(node)->getMesh(); + else + mesh = static_cast(node)->getMesh()->getMesh(0); + if (!mesh) + return; + } + + //search for query + s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + if (OcclusionQueries[index].Mesh != mesh) + { + OcclusionQueries[index].Mesh->drop(); + OcclusionQueries[index].Mesh = mesh; + mesh->grab(); + } + } + else + { + OcclusionQueries.push_back(SOccQuery(node, mesh)); + node->setAutomaticCulling(node->getAutomaticCulling() | scene::EAC_OCC_QUERY); + } +} + + +//! Remove occlusion query. +void CNullDriver::removeOcclusionQuery(scene::ISceneNode* node) +{ + //search for query + s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + node->setAutomaticCulling(node->getAutomaticCulling() & ~scene::EAC_OCC_QUERY); + OcclusionQueries.erase(index); + } +} + + +//! Remove all occlusion queries. +void CNullDriver::removeAllOcclusionQueries() +{ + for (s32 i=OcclusionQueries.size()-1; i>=0; --i) + { + removeOcclusionQuery(OcclusionQueries[i].Node); + } +} + + +//! Run occlusion query. Draws mesh stored in query. +/** If the mesh shall be rendered visible, use +flag to enable the proper material setting. */ +void CNullDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) +{ + if(!node) + return; + s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index==-1) + return; + OcclusionQueries[index].Run=0; + if (!visible) + { + SMaterial mat; + mat.Lighting=false; + mat.AntiAliasing=0; + mat.ColorMask=ECP_NONE; + mat.GouraudShading=false; + mat.ZWriteEnable=false; + setMaterial(mat); + } + setTransform(video::ETS_WORLD, node->getAbsoluteTransformation()); + const scene::IMesh* mesh = OcclusionQueries[index].Mesh; + for (u32 i=0; igetMeshBufferCount(); ++i) + { + if (visible) + setMaterial(mesh->getMeshBuffer(i)->getMaterial()); + drawMeshBuffer(mesh->getMeshBuffer(i)); + } +} + + +//! Run all occlusion queries. Draws all meshes stored in queries. +/** If the meshes shall not be rendered visible, use +overrideMaterial to disable the color and depth buffer. */ +void CNullDriver::runAllOcclusionQueries(bool visible) +{ + for (u32 i=0; i1000) + removeOcclusionQuery(OcclusionQueries[i].Node); + } +} + + +//! Return query result. +/** Return value is the number of visible pixels/fragments. +The value is a safe approximation, i.e. can be larger then the +actual value of pixels. */ +u32 CNullDriver::getOcclusionQueryResult(scene::ISceneNode* node) const +{ + return ~0; +} + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void CNullDriver::OnResize(const core::dimension2d& size) +{ + if (ViewPort.getWidth() == (s32)ScreenSize.Width && + ViewPort.getHeight() == (s32)ScreenSize.Height) + ViewPort = core::rect(core::position2d(0,0), + core::dimension2di(size)); + + ScreenSize = size; +} + + +// adds a material renderer and drops it afterwards. To be used for internal creation +s32 CNullDriver::addAndDropMaterialRenderer(IMaterialRenderer* m) +{ + s32 i = addMaterialRenderer(m); + + if (m) + m->drop(); + + return i; +} + + +//! Adds a new material renderer to the video device. +s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* name) +{ + if (!renderer) + return -1; + + SMaterialRenderer r; + r.Renderer = renderer; + r.Name = name; + + if (name == 0 && (MaterialRenderers.size() < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 )) + { + // set name of built in renderer so that we don't have to implement name + // setting in all available renderers. + r.Name = sBuiltInMaterialTypeNames[MaterialRenderers.size()]; + } + + MaterialRenderers.push_back(r); + renderer->grab(); + + return MaterialRenderers.size()-1; +} + + +//! Sets the name of a material renderer. +void CNullDriver::setMaterialRendererName(s32 idx, const char* name) +{ + if (idx < s32(sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 || + idx >= (s32)MaterialRenderers.size()) + return; + + MaterialRenderers[idx].Name = name; +} + + +//! Creates material attributes list from a material, usable for serialization and more. +io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material, + io::SAttributeReadWriteOptions* options) +{ + io::CAttributes* attr = new io::CAttributes(this); + + attr->addEnum("Type", material.MaterialType, sBuiltInMaterialTypeNames); + + attr->addColor("Ambient", material.AmbientColor); + attr->addColor("Diffuse", material.DiffuseColor); + attr->addColor("Emissive", material.EmissiveColor); + attr->addColor("Specular", material.SpecularColor); + + attr->addFloat("Shininess", material.Shininess); + attr->addFloat("Param1", material.MaterialTypeParam); + attr->addFloat("Param2", material.MaterialTypeParam2); + + core::stringc prefix="Texture"; + u32 i; + for (i=0; iFlags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename && material.getTexture(i)) + { + io::path path = FileSystem->getRelativeFilename( + FileSystem->getAbsolutePath(material.getTexture(i)->getName()), options->Filename); + attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i), path); + } + else + attr->addTexture((prefix+core::stringc(i+1)).c_str(), material.getTexture(i)); + } + + attr->addBool("Wireframe", material.Wireframe); + attr->addBool("GouraudShading", material.GouraudShading); + attr->addBool("Lighting", material.Lighting); + attr->addBool("ZWriteEnable", material.ZWriteEnable); + attr->addInt("ZBuffer", material.ZBuffer); + attr->addBool("BackfaceCulling", material.BackfaceCulling); + attr->addBool("FrontfaceCulling", material.FrontfaceCulling); + attr->addBool("FogEnable", material.FogEnable); + attr->addBool("NormalizeNormals", material.NormalizeNormals); + attr->addBool("UseMipMaps", material.UseMipMaps); + attr->addInt("AntiAliasing", material.AntiAliasing); + attr->addInt("ColorMask", material.ColorMask); + attr->addInt("ColorMaterial", material.ColorMaterial); + attr->addInt("PolygonOffsetFactor", material.PolygonOffsetFactor); + attr->addEnum("PolygonOffsetDirection", material.PolygonOffsetDirection, video::PolygonOffsetDirectionNames); + + prefix = "BilinearFilter"; + for (i=0; iaddBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].BilinearFilter); + prefix = "TrilinearFilter"; + for (i=0; iaddBool((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TrilinearFilter); + prefix = "AnisotropicFilter"; + for (i=0; iaddInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].AnisotropicFilter); + prefix="TextureWrapU"; + for (i=0; iaddEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapU, aTextureClampNames); + prefix="TextureWrapV"; + for (i=0; iaddEnum((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].TextureWrapV, aTextureClampNames); + prefix="LODBias"; + for (i=0; iaddInt((prefix+core::stringc(i+1)).c_str(), material.TextureLayer[i].LODBias); + + return attr; +} + + +//! Fills an SMaterial structure from attributes. +void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attr) +{ + outMaterial.MaterialType = video::EMT_SOLID; + + core::stringc name = attr->getAttributeAsString("Type"); + + u32 i; + + for ( i=0; i < MaterialRenderers.size(); ++i) + if ( name == MaterialRenderers[i].Name ) + { + outMaterial.MaterialType = (video::E_MATERIAL_TYPE)i; + break; + } + + outMaterial.AmbientColor = attr->getAttributeAsColor("Ambient"); + outMaterial.DiffuseColor = attr->getAttributeAsColor("Diffuse"); + outMaterial.EmissiveColor = attr->getAttributeAsColor("Emissive"); + outMaterial.SpecularColor = attr->getAttributeAsColor("Specular"); + + outMaterial.Shininess = attr->getAttributeAsFloat("Shininess"); + outMaterial.MaterialTypeParam = attr->getAttributeAsFloat("Param1"); + outMaterial.MaterialTypeParam2 = attr->getAttributeAsFloat("Param2"); + + core::stringc prefix="Texture"; + for (i=0; igetAttributeAsTexture((prefix+core::stringc(i+1)).c_str())); + + outMaterial.Wireframe = attr->getAttributeAsBool("Wireframe"); + outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading"); + outMaterial.Lighting = attr->getAttributeAsBool("Lighting"); + outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable"); + outMaterial.ZBuffer = (u8)attr->getAttributeAsInt("ZBuffer"); + outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling"); + outMaterial.FrontfaceCulling = attr->getAttributeAsBool("FrontfaceCulling"); + outMaterial.FogEnable = attr->getAttributeAsBool("FogEnable"); + outMaterial.NormalizeNormals = attr->getAttributeAsBool("NormalizeNormals"); + if (attr->existsAttribute("UseMipMaps")) // legacy + outMaterial.UseMipMaps = attr->getAttributeAsBool("UseMipMaps"); + else + outMaterial.UseMipMaps = true; + + // default 0 is ok + outMaterial.AntiAliasing = attr->getAttributeAsInt("AntiAliasing"); + if (attr->existsAttribute("ColorMask")) + outMaterial.ColorMask = attr->getAttributeAsInt("ColorMask"); + if (attr->existsAttribute("ColorMaterial")) + outMaterial.ColorMaterial = attr->getAttributeAsInt("ColorMaterial"); + if (attr->existsAttribute("PolygonOffsetFactor")) + outMaterial.PolygonOffsetFactor = attr->getAttributeAsInt("PolygonOffsetFactor"); + if (attr->existsAttribute("PolygonOffsetDirection")) + outMaterial.PolygonOffsetDirection = (video::E_POLYGON_OFFSET)attr->getAttributeAsEnumeration("PolygonOffsetDirection", video::PolygonOffsetDirectionNames); + prefix = "BilinearFilter"; + if (attr->existsAttribute(prefix.c_str())) // legacy + outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); + else + for (i=0; igetAttributeAsBool((prefix+core::stringc(i+1)).c_str()); + + prefix = "TrilinearFilter"; + if (attr->existsAttribute(prefix.c_str())) // legacy + outMaterial.setFlag(EMF_TRILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); + else + for (i=0; igetAttributeAsBool((prefix+core::stringc(i+1)).c_str()); + + prefix = "AnisotropicFilter"; + if (attr->existsAttribute(prefix.c_str())) // legacy + outMaterial.setFlag(EMF_ANISOTROPIC_FILTER, attr->getAttributeAsBool(prefix.c_str())); + else + for (i=0; igetAttributeAsInt((prefix+core::stringc(i+1)).c_str()); + + prefix = "TextureWrap"; + if (attr->existsAttribute(prefix.c_str())) // legacy + { + for (i=0; igetAttributeAsEnumeration((prefix+core::stringc(i+1)).c_str(), aTextureClampNames); + outMaterial.TextureLayer[i].TextureWrapV = outMaterial.TextureLayer[i].TextureWrapU; + } + } + else + { + for (i=0; igetAttributeAsEnumeration((prefix+"U"+core::stringc(i+1)).c_str(), aTextureClampNames); + outMaterial.TextureLayer[i].TextureWrapV = (E_TEXTURE_CLAMP)attr->getAttributeAsEnumeration((prefix+"V"+core::stringc(i+1)).c_str(), aTextureClampNames); + } + } + + // default 0 is ok + prefix="LODBias"; + for (i=0; igetAttributeAsInt((prefix+core::stringc(i+1)).c_str()); +} + + +//! Returns driver and operating system specific data about the IVideoDriver. +const SExposedVideoData& CNullDriver::getExposedVideoData() +{ + return ExposedData; +} + + +//! Returns type of video driver +E_DRIVER_TYPE CNullDriver::getDriverType() const +{ + return EDT_NULL; +} + + +//! deletes all material renderers +void CNullDriver::deleteMaterialRenders() +{ + // delete material renderers + for (u32 i=0; idrop(); + + MaterialRenderers.clear(); +} + + +//! Returns pointer to material renderer or null +IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx) +{ + if ( idx < MaterialRenderers.size() ) + return MaterialRenderers[idx].Renderer; + else + return 0; +} + + +//! Returns amount of currently available material renderers. +u32 CNullDriver::getMaterialRendererCount() const +{ + return MaterialRenderers.size(); +} + + +//! Returns name of the material renderer +const char* CNullDriver::getMaterialRendererName(u32 idx) const +{ + if ( idx < MaterialRenderers.size() ) + return MaterialRenderers[idx].Name.c_str(); + + return 0; +} + + +//! Returns pointer to the IGPUProgrammingServices interface. +IGPUProgrammingServices* CNullDriver::getGPUProgrammingServices() +{ + return this; +} + + +//! Adds a new material renderer to the VideoDriver, based on a high level shading language. +s32 CNullDriver::addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName, + E_GEOMETRY_SHADER_TYPE gsCompileTarget, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) +{ + os::Printer::log("High level shader materials not available (yet) in this driver, sorry"); + return -1; +} + + +//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), +//! but tries to load the programs from files. +s32 CNullDriver::addHighLevelShaderMaterialFromFiles( + const io::path& vertexShaderProgramFileName, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const io::path& pixelShaderProgramFileName, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const io::path& geometryShaderProgramFileName, + const c8* geometryShaderEntryPointName, + E_GEOMETRY_SHADER_TYPE gsCompileTarget, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) +{ + io::IReadFile* vsfile = 0; + io::IReadFile* psfile = 0; + io::IReadFile* gsfile = 0; + + if (vertexShaderProgramFileName.size() ) + { + vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); + if (!vsfile) + { + os::Printer::log("Could not open vertex shader program file", + vertexShaderProgramFileName, ELL_WARNING); + } + } + + if (pixelShaderProgramFileName.size() ) + { + psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); + if (!psfile) + { + os::Printer::log("Could not open pixel shader program file", + pixelShaderProgramFileName, ELL_WARNING); + } + } + + if (geometryShaderProgramFileName.size() ) + { + gsfile = FileSystem->createAndOpenFile(geometryShaderProgramFileName); + if (!gsfile) + { + os::Printer::log("Could not open geometry shader program file", + geometryShaderProgramFileName, ELL_WARNING); + } + } + + s32 result = addHighLevelShaderMaterialFromFiles( + vsfile, vertexShaderEntryPointName, vsCompileTarget, + psfile, pixelShaderEntryPointName, psCompileTarget, + gsfile, geometryShaderEntryPointName, gsCompileTarget, + inType, outType, verticesOut, + callback, baseMaterial, userData, shadingLang); + + if (psfile) + psfile->drop(); + + if (vsfile) + vsfile->drop(); + + if (gsfile) + gsfile->drop(); + + return result; +} + + +//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), +//! but tries to load the programs from files. +s32 CNullDriver::addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + io::IReadFile* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + io::IReadFile* geometryShaderProgram, + const c8* geometryShaderEntryPointName, + E_GEOMETRY_SHADER_TYPE gsCompileTarget, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) +{ + c8* vs = 0; + c8* ps = 0; + c8* gs = 0; + + if (vertexShaderProgram) + { + const long size = vertexShaderProgram->getSize(); + if (size) + { + vs = new c8[size+1]; + vertexShaderProgram->read(vs, size); + vs[size] = 0; + } + } + + if (pixelShaderProgram) + { + const long size = pixelShaderProgram->getSize(); + if (size) + { + // if both handles are the same we must reset the file + if (pixelShaderProgram==vertexShaderProgram) + pixelShaderProgram->seek(0); + ps = new c8[size+1]; + pixelShaderProgram->read(ps, size); + ps[size] = 0; + } + } + + if (geometryShaderProgram) + { + const long size = geometryShaderProgram->getSize(); + if (size) + { + // if both handles are the same we must reset the file + if ((geometryShaderProgram==vertexShaderProgram) || + (geometryShaderProgram==pixelShaderProgram)) + geometryShaderProgram->seek(0); + gs = new c8[size+1]; + geometryShaderProgram->read(gs, size); + gs[size] = 0; + } + } + + s32 result = this->addHighLevelShaderMaterial( + vs, vertexShaderEntryPointName, vsCompileTarget, + ps, pixelShaderEntryPointName, psCompileTarget, + gs, geometryShaderEntryPointName, gsCompileTarget, + inType, outType, verticesOut, + callback, baseMaterial, userData, shadingLang); + + delete [] vs; + delete [] ps; + delete [] gs; + + return result; +} + + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 CNullDriver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + os::Printer::log("Shader materials not implemented yet in this driver, sorry."); + return -1; +} + + +//! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the +//! programs from files. +s32 CNullDriver::addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram, + io::IReadFile* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + c8* vs = 0; + c8* ps = 0; + + if (vertexShaderProgram) + { + const long size = vertexShaderProgram->getSize(); + if (size) + { + vs = new c8[size+1]; + vertexShaderProgram->read(vs, size); + vs[size] = 0; + } + } + + if (pixelShaderProgram) + { + const long size = pixelShaderProgram->getSize(); + if (size) + { + ps = new c8[size+1]; + pixelShaderProgram->read(ps, size); + ps[size] = 0; + } + } + + s32 result = addShaderMaterial(vs, ps, callback, baseMaterial, userData); + + delete [] vs; + delete [] ps; + + return result; +} + + +//! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the +//! programs from files. +s32 CNullDriver::addShaderMaterialFromFiles(const io::path& vertexShaderProgramFileName, + const io::path& pixelShaderProgramFileName, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData) +{ + io::IReadFile* vsfile = 0; + io::IReadFile* psfile = 0; + + if (vertexShaderProgramFileName.size()) + { + vsfile = FileSystem->createAndOpenFile(vertexShaderProgramFileName); + if (!vsfile) + { + os::Printer::log("Could not open vertex shader program file", + vertexShaderProgramFileName, ELL_WARNING); + return -1; + } + } + + if (pixelShaderProgramFileName.size()) + { + psfile = FileSystem->createAndOpenFile(pixelShaderProgramFileName); + if (!psfile) + { + os::Printer::log("Could not open pixel shader program file", + pixelShaderProgramFileName, ELL_WARNING); + if (vsfile) + vsfile->drop(); + return -1; + } + } + + s32 result = addShaderMaterialFromFiles(vsfile, psfile, callback, + baseMaterial, userData); + + if (psfile) + psfile->drop(); + + if (vsfile) + vsfile->drop(); + + return result; +} + + +//! Creates a render target texture. +ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d& size, + const io::path&name, const ECOLOR_FORMAT format) +{ + return 0; +} + + +//! Clears the ZBuffer. +void CNullDriver::clearZBuffer() +{ +} + + +//! Returns a pointer to the mesh manipulator. +scene::IMeshManipulator* CNullDriver::getMeshManipulator() +{ + return MeshManipulator; +} + + +//! Returns an image created from the last rendered frame. +IImage* CNullDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) +{ + return 0; +} + + +// prints renderer version +void CNullDriver::printVersion() +{ + core::stringw namePrint = L"Using renderer: "; + namePrint += getName(); + os::Printer::log(namePrint.c_str(), ELL_INFORMATION); +} + + +//! creates a video driver +IVideoDriver* createNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize) +{ + CNullDriver* nullDriver = new CNullDriver(io, screenSize); + + // create empty material renderers + for(u32 i=0; sBuiltInMaterialTypeNames[i]; ++i) + { + IMaterialRenderer* imr = new IMaterialRenderer(); + nullDriver->addMaterialRenderer(imr); + imr->drop(); + } + + return nullDriver; +} + + +//! Set/unset a clipping plane. +//! There are at least 6 clipping planes available for the user to set at will. +//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. +//! \param plane: The plane itself. +//! \param enable: If true, enable the clipping plane else disable it. +bool CNullDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) +{ + return false; +} + + +//! Enable/disable a clipping plane. +void CNullDriver::enableClipPlane(u32 index, bool enable) +{ + // not necessary +} + + +ITexture* CNullDriver::createRenderTargetTexture(const core::dimension2d& size, + const c8* name) +{ + os::Printer::log("createRenderTargetTexture is deprecated, use addRenderTargetTexture instead"); + ITexture* tex = addRenderTargetTexture(size, name); + tex->grab(); + return tex; +} + + +void CNullDriver::setMinHardwareBufferVertexCount(u32 count) +{ + MinVertexCountForVBO = count; +} + + +SOverrideMaterial& CNullDriver::getOverrideMaterial() +{ + return OverrideMaterial; +} + + +//! Get the 2d override material for altering its values +SMaterial& CNullDriver::getMaterial2D() +{ + return OverrideMaterial2D; +} + + +//! Enable the 2d override material +void CNullDriver::enableMaterial2D(bool enable) +{ + OverrideMaterial2DEnabled=enable; +} + + +core::dimension2du CNullDriver::getMaxTextureSize() const +{ + return core::dimension2du(0x10000,0x10000); // maybe large enough +} + + +//! Color conversion convenience function +/** Convert an image (as array of pixels) from source to destination +array, thereby converting the color format. The pixel size is +determined by the color formats. +\param sP Pointer to source +\param sF Color format of source +\param sN Number of pixels to convert, both array must be large enough +\param dP Pointer to destination +\param dF Color format of destination +*/ +void CNullDriver::convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF) const +{ + video::CColorConverter::convert_viaFormat(sP, sF, sN, dP, dF); +} + + +} // end namespace +} // end namespace diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.h new file mode 100644 index 0000000..ead4776 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CNullDriver.h @@ -0,0 +1,849 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_NULL_H_INCLUDED__ +#define __C_VIDEO_NULL_H_INCLUDED__ + +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "IImagePresenter.h" +#include "IGPUProgrammingServices.h" +#include "irrArray.h" +#include "irrString.h" +#include "irrMap.h" +#include "IAttributes.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IMeshSceneNode.h" +#include "CFPSCounter.h" +#include "S3DVertex.h" +#include "SVertexIndex.h" +#include "SLight.h" +#include "SExposedVideoData.h" + +#ifdef _MSC_VER +#pragma warning( disable: 4996) +#endif + +namespace irr +{ +namespace io +{ + class IWriteFile; + class IReadFile; +} // end namespace io +namespace video +{ + class IImageLoader; + class IImageWriter; + + class CNullDriver : public IVideoDriver, public IGPUProgrammingServices + { + public: + + //! constructor + CNullDriver(io::IFileSystem* io, const core::dimension2d& screenSize); + + //! destructor + virtual ~CNullDriver(); + + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect* sourceRect=0); + + virtual bool endScene(); + + //! Disable a feature of the driver. + virtual void disableFeature(E_VIDEO_DRIVER_FEATURE feature, bool flag=true); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! Get attributes of the actual video driver + const io::IAttributes& getDriverAttributes() const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! Retrieve the number of image loaders + virtual u32 getImageLoaderCount() const; + + //! Retrieve the given image loader + virtual IImageLoader* getImageLoader(u32 n); + + //! Retrieve the number of image writers + virtual u32 getImageWriterCount() const; + + //! Retrieve the given image writer + virtual IImageWriter* getImageWriter(u32 n); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + //! loads a Texture + virtual ITexture* getTexture(const io::path& filename); + + //! loads a Texture + virtual ITexture* getTexture(io::IReadFile* file); + + //! Returns a texture by index + virtual ITexture* getTextureByIndex(u32 index); + + //! Returns amount of textures currently loaded + virtual u32 getTextureCount() const; + + //! Renames a texture + virtual void renameTexture(ITexture* texture, const io::path& newName); + + //! creates a Texture + virtual ITexture* addTexture(const core::dimension2d& size, const io::path& name, ECOLOR_FORMAT format = ECF_A8R8G8B8); + + //! sets a render target + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! set or reset special render targets + virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, + bool clearZBuffer, SColor color); + + //! Sets multiple render targets + virtual bool setRenderTarget(const core::array& texture, + bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! gets the area of the current viewport + virtual const core::rect& getViewPort() const; + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType=EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType=scene::EPT_TRIANGLES, E_INDEX_TYPE iType=EIT_16BIT); + + //! draws a vertex primitive list in 2d + virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType=EVT_STANDARD, scene::E_PRIMITIVE_TYPE pType=scene::EPT_TRIANGLES, E_INDEX_TYPE iType=EIT_16BIT); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! Draws a 3d triangle. + virtual void draw3DTriangle(const core::triangle3df& triangle, + SColor color = SColor(255,255,255,255)); + + //! Draws a 3d axis aligned box. + virtual void draw3DBox(const core::aabbox3d& box, + SColor color = SColor(255,255,255,255)); + + //! draws an 2d image + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos); + + //! draws a set of 2d images, using a color and the alpha + /** channel of the texture if desired. The images are drawn + beginning at pos and concatenated in one line. All drawings + are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects + and are chosen by the indices given. + \param texture: Texture to be drawn. + \param pos: Upper left 2d destination position where the image will be drawn. + \param sourceRects: Source rectangles of the image. + \param indices: List of indices which choose the actual rectangle used each time. + \param kerningWidth: offset on position + \param clipRect: Pointer to rectangle on the screen where the image is clipped to. + This pointer can be 0. Then the image is not clipped. + \param color: Color with which the image is colored. + Note that the alpha component is used: If alpha is other than 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is + used to draw the image. */ + virtual void draw2DImageBatch(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + s32 kerningWidth = 0, + const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false); + + //! Draws a set of 2d images, using a color and the alpha channel of the texture. + /** All drawings are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects and are + positioned using the array of positions. + \param texture Texture to be drawn. + \param pos Array of upper left 2d destinations where the images + will be drawn. + \param sourceRects Source rectangles of the image. + \param clipRect Pointer to rectangle on the screen where the + images are clipped to. + If this pointer is 0 then the image is not clipped. + \param color Color with which the image is drawn. + Note that the alpha component is used. If alpha is other than + 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of + the texture is used to draw the image. */ + virtual void draw2DImageBatch(const video::ITexture* texture, + const core::array >& positions, + const core::array >& sourceRects, + const core::rect* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false); + + //! Draws a 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); + + //! Draws a 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, const core::rect* clip = 0); + + //! Draws a 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws the outline of a 2d rectangle + virtual void draw2DRectangleOutline(const core::recti& pos, SColor color=SColor(255,255,255,255)); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a pixel + virtual void drawPixel(u32 x, u32 y, const SColor & color); + + //! Draws a non filled concyclic reqular 2d polyon. + virtual void draw2DPolygon(core::position2d center, + f32 radius, video::SColor Color, s32 vertexCount); + + virtual void setFog(SColor color=SColor(0,255,255,255), + E_FOG_TYPE fogType=EFT_FOG_LINEAR, + f32 start=50.0f, f32 end=100.0f, f32 density=0.01f, + bool pixelFog=false, bool rangeFog=false); + + virtual void getFog(SColor& color, E_FOG_TYPE& fogType, + f32& start, f32& end, f32& density, + bool& pixelFog, bool& rangeFog); + + //! get color format of the current color buffer + virtual ECOLOR_FORMAT getColorFormat() const; + + //! get screen size + virtual const core::dimension2d& getScreenSize() const; + + //! get render target size + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + // get current frames per second value + virtual s32 getFPS() const; + + //! returns amount of primitives (mostly triangles) were drawn in the last frame. + //! very useful method for statistics. + virtual u32 getPrimitiveCountDrawn( u32 param = 0 ) const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light, returning an index to the light + //! \param light: the light data to use to create the light + //! \return An index to the light, or -1 if an error occurs + virtual s32 addDynamicLight(const SLight& light); + + //! Turns a dynamic light on or off + //! \param lightIndex: the index returned by addDynamicLight + //! \param turnOn: true to turn the light on, false to turn it off + virtual void turnLightOn(s32 lightIndex, bool turnOn); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! Adds an external image loader to the engine. + virtual void addExternalImageLoader(IImageLoader* loader); + + //! Adds an external image writer to the engine. + virtual void addExternalImageWriter(IImageWriter* writer); + + //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do + //! this: Frist, draw all geometry. Then use this method, to draw the shadow + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail=true, u32 debugDataVisible=0); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns current amount of dynamic lights set + //! \return Current amount of dynamic lights set + virtual u32 getDynamicLightCount() const; + + //! Returns light data which was previously set with IVideDriver::addDynamicLight(). + //! \param idx: Zero based index of the light. Must be greater than 0 and smaller + //! than IVideoDriver()::getDynamicLightCount. + //! \return Light data. + virtual const SLight& getDynamicLight(u32 idx) const; + + //! Removes a texture from the texture cache and deletes it, freeing lot of + //! memory. + virtual void removeTexture(ITexture* texture); + + //! Removes all texture from the texture cache and deletes them, freeing lot of + //! memory. + virtual void removeAllTextures(); + + //! Creates a render target texture. + virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! Creates an 1bit alpha channel of the texture based of an color key. + virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color, bool zeroTexels) const; + + //! Creates an 1bit alpha channel of the texture based of an color key position. + virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d colorKeyPixelPos, bool zeroTexels) const; + + //! Creates a normal map from a height map texture. + //! \param amplitude: Constant value by which the height information is multiplied. + virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const; + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Enables or disables a texture creation flag. + virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); + + //! Returns if a texture creation flag is enabled or disabled. + virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const; + + //! Creates a software image from a file. + virtual IImage* createImageFromFile(const io::path& filename); + + //! Creates a software image from a file. + virtual IImage* createImageFromFile(io::IReadFile* file); + + //! Creates a software image from a byte array. + /** \param useForeignMemory: If true, the image will use the data pointer + directly and own it from now on, which means it will also try to delete [] the + data when the image will be destructed. If false, the memory will by copied. */ + virtual IImage* createImageFromData(ECOLOR_FORMAT format, + const core::dimension2d& size, void *data, + bool ownForeignMemory=true, bool deleteForeignMemory = true); + + //! Creates an empty software image. + virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d& size); + + + //! Creates a software image from another image. + virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy); + + //! Creates a software image from part of another image. + virtual IImage* createImage(IImage* imageToCopy, + const core::position2d& pos, + const core::dimension2d& size); + + //! Creates a software image from part of a texture. + virtual IImage* createImage(ITexture* texture, + const core::position2d& pos, + const core::dimension2d& size); + + //! Draws a mesh buffer + virtual void drawMeshBuffer(const scene::IMeshBuffer* mb); + + //! Draws the normals of a mesh buffer + virtual void drawMeshBufferNormals(const scene::IMeshBuffer* mb, f32 length=10.f, SColor color=0xffffffff); + + protected: + struct SHWBufferLink + { + SHWBufferLink(const scene::IMeshBuffer *_MeshBuffer) + :MeshBuffer(_MeshBuffer), + ChangedID_Vertex(0),ChangedID_Index(0),LastUsed(0), + Mapped_Vertex(scene::EHM_NEVER),Mapped_Index(scene::EHM_NEVER) + { + if (MeshBuffer) + MeshBuffer->grab(); + } + + virtual ~SHWBufferLink() + { + if (MeshBuffer) + MeshBuffer->drop(); + } + + const scene::IMeshBuffer *MeshBuffer; + u32 ChangedID_Vertex; + u32 ChangedID_Index; + u32 LastUsed; + scene::E_HARDWARE_MAPPING Mapped_Vertex; + scene::E_HARDWARE_MAPPING Mapped_Index; + }; + + //! Gets hardware buffer link from a meshbuffer (may create or update buffer) + virtual SHWBufferLink *getBufferLink(const scene::IMeshBuffer* mb); + + //! updates hardware buffer if needed (only some drivers can) + virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer) {return false;} + + //! Draw hardware buffer (only some drivers can) + virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer) {} + + //! Delete hardware buffer + virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Create hardware buffer from mesh (only some drivers can) + virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb) {return 0;} + + public: + //! Update all hardware buffers, remove unused ones + virtual void updateAllHardwareBuffers(); + + //! Remove hardware buffer + virtual void removeHardwareBuffer(const scene::IMeshBuffer* mb); + + //! Remove all hardware buffers + virtual void removeAllHardwareBuffers(); + + //! is vbo recommended on this mesh? + virtual bool isHardwareBufferRecommend(const scene::IMeshBuffer* mb); + + //! Create occlusion query. + /** Use node for identification and mesh for occlusion test. */ + virtual void addOcclusionQuery(scene::ISceneNode* node, + const scene::IMesh* mesh=0); + + //! Remove occlusion query. + virtual void removeOcclusionQuery(scene::ISceneNode* node); + + //! Remove all occlusion queries. + virtual void removeAllOcclusionQueries(); + + //! Run occlusion query. Draws mesh stored in query. + /** If the mesh shall not be rendered visible, use + overrideMaterial to disable the color and depth buffer. */ + virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false); + + //! Run all occlusion queries. Draws all meshes stored in queries. + /** If the meshes shall not be rendered visible, use + overrideMaterial to disable the color and depth buffer. */ + virtual void runAllOcclusionQueries(bool visible=false); + + //! Update occlusion query. Retrieves results from GPU. + /** If the query shall not block, set the flag to false. + Update might not occur in this case, though */ + virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true); + + //! Update all occlusion queries. Retrieves results from GPU. + /** If the query shall not block, set the flag to false. + Update might not occur in this case, though */ + virtual void updateAllOcclusionQueries(bool block=true); + + //! Return query result. + /** Return value is the number of visible pixels/fragments. + The value is a safe approximation, i.e. can be larger than the + actual value of pixels. */ + virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const; + + //! Only used by the engine internally. + /** Used to notify the driver that the window was resized. */ + virtual void OnResize(const core::dimension2d& size); + + //! Adds a new material renderer to the video device. + virtual s32 addMaterialRenderer(IMaterialRenderer* renderer, + const char* name = 0); + + //! Returns driver and operating system specific data about the IVideoDriver. + virtual const SExposedVideoData& getExposedVideoData(); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Returns pointer to the IGPUProgrammingServices interface. + virtual IGPUProgrammingServices* getGPUProgrammingServices(); + + //! Adds a new material renderer to the VideoDriver, using pixel and/or + //! vertex shaders to render geometry. + virtual s32 addShaderMaterial(const c8* vertexShaderProgram = 0, + const c8* pixelShaderProgram = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the + //! programs from files. + virtual s32 addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram = 0, + io::IReadFile* pixelShaderProgram = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the + //! programs from files. + virtual s32 addShaderMaterialFromFiles(const io::path& vertexShaderProgramFileName, + const io::path& pixelShaderProgramFileName, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData=0); + + //! Returns pointer to material renderer or null + virtual IMaterialRenderer* getMaterialRenderer(u32 idx); + + //! Returns amount of currently available material renderers. + virtual u32 getMaterialRendererCount() const; + + //! Returns name of the material renderer + virtual const char* getMaterialRendererName(u32 idx) const; + + //! Adds a new material renderer to the VideoDriver, based on a high level shading + //! language. Currently only HLSL in D3D9 is supported. + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName = 0, + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = 0, + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + const c8* geometryShaderProgram = 0, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT); + + //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), + //! but tries to load the programs from files. + virtual s32 addHighLevelShaderMaterialFromFiles( + const io::path& vertexShaderProgramFile, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + const io::path& pixelShaderProgramFile = "", + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + const io::path& geometryShaderProgramFileName="", + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT); + + //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), + //! but tries to load the programs from files. + virtual s32 addHighLevelShaderMaterialFromFiles( + io::IReadFile* vertexShaderProgram, + const c8* vertexShaderEntryPointName = "main", + E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, + io::IReadFile* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = "main", + E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, + io::IReadFile* geometryShaderProgram= 0, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT); + + //! Returns a pointer to the mesh manipulator. + virtual scene::IMeshManipulator* getMeshManipulator(); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); + + //! Writes the provided image to disk file + virtual bool writeImageToFile(IImage* image, const io::path& filename, u32 param = 0); + + //! Writes the provided image to a file. + virtual bool writeImageToFile(IImage* image, io::IWriteFile * file, u32 param = 0); + + //! Sets the name of a material renderer. + virtual void setMaterialRendererName(s32 idx, const char* name); + + //! Creates material attributes list from a material, usable for serialization and more. + virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material, + io::SAttributeReadWriteOptions* options=0); + + //! Fills an SMaterial structure from attributes. + virtual void fillMaterialStructureFromAttributes(video::SMaterial& outMaterial, io::IAttributes* attributes); + + //! looks if the image is already loaded + virtual video::ITexture* findTexture(const io::path& filename); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + //! Returns the graphics card vendor name. + virtual core::stringc getVendorInfo() {return "Not available on this driver.";} + + //! Set the minimum number of vertices for which a hw buffer will be created + /** \param count Number of vertices to set as minimum. */ + virtual void setMinHardwareBufferVertexCount(u32 count); + + //! Get the global Material, which might override local materials. + /** Depending on the enable flags, values from this Material + are used to override those of local materials of some + meshbuffer being rendered. */ + virtual SOverrideMaterial& getOverrideMaterial(); + + //! Get the 2d override material for altering its values + virtual SMaterial& getMaterial2D(); + + //! Enable the 2d override material + virtual void enableMaterial2D(bool enable=true); + + //! Only used by the engine internally. + virtual void setAllowZWriteOnTransparent(bool flag) + { AllowZWriteOnTransparent=flag; } + + //! Returns the maximum texture size supported. + virtual core::dimension2du getMaxTextureSize() const; + + //! Color conversion convenience function + /** Convert an image (as array of pixels) from source to destination + array, thereby converting the color format. The pixel size is + determined by the color formats. + \param sP Pointer to source + \param sF Color format of source + \param sN Number of pixels to convert, both array must be large enough + \param dP Pointer to destination + \param dF Color format of destination + */ + virtual void convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN, + void* dP, ECOLOR_FORMAT dF) const; + + //! deprecated method + virtual ITexture* createRenderTargetTexture(const core::dimension2d& size, + const c8* name=0); + + virtual bool checkDriverReset() {return false;} + protected: + + //! deletes all textures + void deleteAllTextures(); + + //! opens the file and loads it into the surface + video::ITexture* loadTextureFromFile(io::IReadFile* file, const io::path& hashName = ""); + + //! adds a surface, not loaded or created by the Irrlicht Engine + void addTexture(video::ITexture* surface); + + //! Creates a texture from a loaded IImage. + virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); + + //! checks triangle count and print warning if wrong + bool checkPrimitiveCount(u32 prmcnt) const; + + // adds a material renderer and drops it afterwards. To be used for internal creation + s32 addAndDropMaterialRenderer(IMaterialRenderer* m); + + //! deletes all material renderers + void deleteMaterialRenders(); + + // prints renderer version + void printVersion(); + + //! normal map lookup 32 bit version + inline f32 nml32(int x, int y, int pitch, int height, s32 *p) const + { + if (x < 0) x = pitch-1; if (x >= pitch) x = 0; + if (y < 0) y = height-1; if (y >= height) y = 0; + return (f32)(((p[(y * pitch) + x])>>16) & 0xff); + } + + //! normal map lookup 16 bit version + inline f32 nml16(int x, int y, int pitch, int height, s16 *p) const + { + if (x < 0) x = pitch-1; if (x >= pitch) x = 0; + if (y < 0) y = height-1; if (y >= height) y = 0; + + return (f32) getAverage ( p[(y * pitch) + x] ); + } + + struct SSurface + { + video::ITexture* Surface; + + bool operator < (const SSurface& other) const + { + return Surface->getName() < other.Surface->getName(); + } + }; + + struct SMaterialRenderer + { + core::stringc Name; + IMaterialRenderer* Renderer; + }; + + struct SDummyTexture : public ITexture + { + SDummyTexture(const io::path& name) : ITexture(name), size(0,0) {}; + + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) { return 0; }; + virtual void unlock(){} + virtual const core::dimension2d& getOriginalSize() const { return size; } + virtual const core::dimension2d& getSize() const { return size; } + virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; } + virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; }; + virtual u32 getPitch() const { return 0; } + virtual void regenerateMipMapLevels(void* mipmapData=0) {}; + core::dimension2d size; + }; + core::array Textures; + + struct SOccQuery + { + SOccQuery(scene::ISceneNode* node, const scene::IMesh* mesh=0) : Node(node), Mesh(mesh), PID(0), Result(~0), Run(~0) + { + if (Node) + Node->grab(); + if (Mesh) + Mesh->grab(); + } + + SOccQuery(const SOccQuery& other) : Node(other.Node), Mesh(other.Mesh), PID(other.PID), Result(other.Result), Run(other.Run) + { + if (Node) + Node->grab(); + if (Mesh) + Mesh->grab(); + } + + ~SOccQuery() + { + if (Node) + Node->drop(); + if (Mesh) + Mesh->drop(); + } + + SOccQuery& operator=(const SOccQuery& other) + { + Node=other.Node; + Mesh=other.Mesh; + PID=other.PID; + Result=other.Result; + Run=other.Run; + if (Node) + Node->grab(); + if (Mesh) + Mesh->grab(); + return *this; + } + + bool operator==(const SOccQuery& other) const + { + return other.Node==Node; + } + + scene::ISceneNode* Node; + const scene::IMesh* Mesh; + union + { + void* PID; + unsigned int UID; + }; + u32 Result; + u32 Run; + }; + core::array OcclusionQueries; + + core::array SurfaceLoader; + core::array SurfaceWriter; + core::array Lights; + core::array MaterialRenderers; + + //core::array HWBufferLinks; + core::map< const scene::IMeshBuffer* , SHWBufferLink* > HWBufferMap; + + io::IFileSystem* FileSystem; + + //! mesh manipulator + scene::IMeshManipulator* MeshManipulator; + + core::rect ViewPort; + core::dimension2d ScreenSize; + core::matrix4 TransformationMatrix; + + CFPSCounter FPSCounter; + + u32 PrimitivesDrawn; + u32 MinVertexCountForVBO; + + u32 TextureCreationFlags; + + f32 FogStart; + f32 FogEnd; + f32 FogDensity; + SColor FogColor; + SExposedVideoData ExposedData; + + io::IAttributes* DriverAttributes; + + SOverrideMaterial OverrideMaterial; + SMaterial OverrideMaterial2D; + SMaterial InitMaterial2D; + bool OverrideMaterial2DEnabled; + + E_FOG_TYPE FogType; + bool PixelFog; + bool RangeFog; + bool AllowZWriteOnTransparent; + + bool FeatureEnabled[video::EVDF_COUNT]; + }; + +} // end namespace video +} // end namespace irr + + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.cpp new file mode 100644 index 0000000..47a4dad --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.cpp @@ -0,0 +1,931 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_ + +#include "COBJMeshFileLoader.h" +#include "IMeshManipulator.h" +#include "IVideoDriver.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "IAttributes.h" +#include "fast_atof.h" +#include "coreutil.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +#ifdef _DEBUG +#define _IRR_DEBUG_OBJ_LOADER_ +#endif + +static const u32 WORD_BUFFER_LENGTH = 512; + +//! Constructor +COBJMeshFileLoader::COBJMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs) +: SceneManager(smgr), FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("COBJMeshFileLoader"); + #endif + + if (FileSystem) + FileSystem->grab(); +} + + +//! destructor +COBJMeshFileLoader::~COBJMeshFileLoader() +{ + if (FileSystem) + FileSystem->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool COBJMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "obj" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file) +{ + const long filesize = file->getSize(); + if (!filesize) + return 0; + + const u32 WORD_BUFFER_LENGTH = 512; + + core::array vertexBuffer; + core::array normalsBuffer; + core::array textureCoordBuffer; + + SObjMtl * currMtl = new SObjMtl(); + Materials.push_back(currMtl); + u32 smoothingGroup=0; + + const io::path fullName = file->getFileName(); + const io::path relPath = FileSystem->getFileDir(fullName)+"/"; + + c8* buf = new c8[filesize]; + memset(buf, 0, filesize); + file->read((void*)buf, filesize); + const c8* const bufEnd = buf+filesize; + + // Process obj information + const c8* bufPtr = buf; + core::stringc grpName, mtlName; + bool mtlChanged=false; + bool useGroups = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_GROUPS); + bool useMaterials = !SceneManager->getParameters()->getAttributeAsBool(OBJ_LOADER_IGNORE_MATERIAL_FILES); + while(bufPtr != bufEnd) + { + switch(bufPtr[0]) + { + case 'm': // mtllib (material) + { + if (useMaterials) + { + c8 name[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(name, bufPtr, WORD_BUFFER_LENGTH, bufEnd); +#ifdef _IRR_DEBUG_OBJ_LOADER_ + os::Printer::log("Reading material file",name); +#endif + readMTL(name, relPath); + } + } + break; + + case 'v': // v, vn, vt + switch(bufPtr[1]) + { + case ' ': // vertex + { + core::vector3df vec; + bufPtr = readVec3(bufPtr, vec, bufEnd); + vertexBuffer.push_back(vec); + } + break; + + case 'n': // normal + { + core::vector3df vec; + bufPtr = readVec3(bufPtr, vec, bufEnd); + normalsBuffer.push_back(vec); + } + break; + + case 't': // texcoord + { + core::vector2df vec; + bufPtr = readUV(bufPtr, vec, bufEnd); + textureCoordBuffer.push_back(vec); + } + break; + } + break; + + case 'g': // group name + { + c8 grp[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(grp, bufPtr, WORD_BUFFER_LENGTH, bufEnd); +#ifdef _IRR_DEBUG_OBJ_LOADER_ + os::Printer::log("Loaded group start",grp, ELL_DEBUG); +#endif + if (useGroups) + { + if (0 != grp[0]) + grpName = grp; + else + grpName = "default"; + } + mtlChanged=true; + } + break; + + case 's': // smoothing can be a group or off (equiv. to 0) + { + c8 smooth[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(smooth, bufPtr, WORD_BUFFER_LENGTH, bufEnd); +#ifdef _IRR_DEBUG_OBJ_LOADER_ + os::Printer::log("Loaded smoothing group start",smooth, ELL_DEBUG); +#endif + if (core::stringc("off")==smooth) + smoothingGroup=0; + else + smoothingGroup=core::strtoul10(smooth); + } + break; + + case 'u': // usemtl + // get name of material + { + c8 matName[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(matName, bufPtr, WORD_BUFFER_LENGTH, bufEnd); +#ifdef _IRR_DEBUG_OBJ_LOADER_ + os::Printer::log("Loaded material start",matName, ELL_DEBUG); +#endif + mtlName=matName; + mtlChanged=true; + } + break; + + case 'f': // face + { + c8 vertexWord[WORD_BUFFER_LENGTH]; // for retrieving vertex data + video::S3DVertex v; + // Assign vertex color from currently active material's diffuse color + if (mtlChanged) + { + // retrieve the material + SObjMtl *useMtl = findMtl(mtlName, grpName); + // only change material if we found it + if (useMtl) + currMtl = useMtl; + mtlChanged=false; + } + if (currMtl) + v.Color = currMtl->Meshbuffer->Material.DiffuseColor; + + // get all vertices data in this face (current line of obj file) + const core::stringc wordBuffer = copyLine(bufPtr, bufEnd); + const c8* linePtr = wordBuffer.c_str(); + const c8* const endPtr = linePtr+wordBuffer.size(); + + core::array faceCorners; + faceCorners.reallocate(32); // should be large enough + + // read in all vertices + linePtr = goNextWord(linePtr, endPtr); + while (0 != linePtr[0]) + { + // Array to communicate with retrieveVertexIndices() + // sends the buffer sizes and gets the actual indices + // if index not set returns -1 + s32 Idx[3]; + Idx[1] = Idx[2] = -1; + + // read in next vertex's data + u32 wlength = copyWord(vertexWord, linePtr, WORD_BUFFER_LENGTH, endPtr); + // this function will also convert obj's 1-based index to c++'s 0-based index + retrieveVertexIndices(vertexWord, Idx, vertexWord+wlength+1, vertexBuffer.size(), textureCoordBuffer.size(), normalsBuffer.size()); + v.Pos = vertexBuffer[Idx[0]]; + if ( -1 != Idx[1] ) + v.TCoords = textureCoordBuffer[Idx[1]]; + else + v.TCoords.set(0.0f,0.0f); + if ( -1 != Idx[2] ) + v.Normal = normalsBuffer[Idx[2]]; + else + { + v.Normal.set(0.0f,0.0f,0.0f); + currMtl->RecalculateNormals=true; + } + + int vertLocation; + core::map::Node* n = currMtl->VertMap.find(v); + if (n) + { + vertLocation = n->getValue(); + } + else + { + currMtl->Meshbuffer->Vertices.push_back(v); + vertLocation = currMtl->Meshbuffer->Vertices.size() -1; + currMtl->VertMap.insert(v, vertLocation); + } + + faceCorners.push_back(vertLocation); + + // go to next vertex + linePtr = goNextWord(linePtr, endPtr); + } + + // triangulate the face + for ( u32 i = 1; i < faceCorners.size() - 1; ++i ) + { + // Add a triangle + currMtl->Meshbuffer->Indices.push_back( faceCorners[i+1] ); + currMtl->Meshbuffer->Indices.push_back( faceCorners[i] ); + currMtl->Meshbuffer->Indices.push_back( faceCorners[0] ); + } + faceCorners.set_used(0); // fast clear + faceCorners.reallocate(32); + } + break; + + case '#': // comment + default: + break; + } // end switch(bufPtr[0]) + // eat up rest of line + bufPtr = goNextLine(bufPtr, bufEnd); + } // end while(bufPtr && (bufPtr-bufMeshbuffer->getIndexCount() > 0 ) + { + Materials[m]->Meshbuffer->recalculateBoundingBox(); + if (Materials[m]->RecalculateNormals) + SceneManager->getMeshManipulator()->recalculateNormals(Materials[m]->Meshbuffer); + if (Materials[m]->Meshbuffer->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID) + { + SMesh tmp; + tmp.addMeshBuffer(Materials[m]->Meshbuffer); + IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp); + mesh->addMeshBuffer(tangentMesh->getMeshBuffer(0)); + tangentMesh->drop(); + } + else + mesh->addMeshBuffer( Materials[m]->Meshbuffer ); + } + } + + // Create the Animated mesh if there's anything in the mesh + SAnimatedMesh* animMesh = 0; + if ( 0 != mesh->getMeshBufferCount() ) + { + mesh->recalculateBoundingBox(); + animMesh = new SAnimatedMesh(); + animMesh->Type = EAMT_OBJ; + animMesh->addMesh(mesh); + animMesh->recalculateBoundingBox(); + } + + // Clean up the allocate obj file contents + delete [] buf; + // more cleaning up + cleanUp(); + mesh->drop(); + + return animMesh; +} + + +const c8* COBJMeshFileLoader::readTextures(const c8* bufPtr, const c8* const bufEnd, SObjMtl* currMaterial, const io::path& relPath) +{ + u8 type=0; // map_Kd - diffuse color texture map + // map_Ks - specular color texture map + // map_Ka - ambient color texture map + // map_Ns - shininess texture map + if ((!strncmp(bufPtr,"map_bump",8)) || (!strncmp(bufPtr,"bump",4))) + type=1; // normal map + else if ((!strncmp(bufPtr,"map_d",5)) || (!strncmp(bufPtr,"map_opacity",11))) + type=2; // opacity map + else if (!strncmp(bufPtr,"map_refl",8)) + type=3; // reflection map + // extract new material's name + c8 textureNameBuf[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + + f32 bumpiness = 6.0f; + bool clamp = false; + // handle options + while (textureNameBuf[0]=='-') + { + if (!strncmp(bufPtr,"-bm",3)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + currMaterial->Meshbuffer->Material.MaterialTypeParam=core::fast_atof(textureNameBuf); + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + continue; + } + else + if (!strncmp(bufPtr,"-blendu",7)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + else + if (!strncmp(bufPtr,"-blendv",7)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + else + if (!strncmp(bufPtr,"-cc",3)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + else + if (!strncmp(bufPtr,"-clamp",6)) + bufPtr = readBool(bufPtr, clamp, bufEnd); + else + if (!strncmp(bufPtr,"-texres",7)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + else + if (!strncmp(bufPtr,"-type",5)) + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + else + if (!strncmp(bufPtr,"-mm",3)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + } + else + if (!strncmp(bufPtr,"-o",2)) // texture coord translation + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + // next parameters are optional, so skip rest of loop if no number is found + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + } + else + if (!strncmp(bufPtr,"-s",2)) // texture coord scale + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + // next parameters are optional, so skip rest of loop if no number is found + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + } + else + if (!strncmp(bufPtr,"-t",2)) + { + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + // next parameters are optional, so skip rest of loop if no number is found + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + if (!core::isdigit(textureNameBuf[0])) + continue; + } + // get next word + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + } + + if ((type==1) && (core::isdigit(textureNameBuf[0]))) + { + currMaterial->Meshbuffer->Material.MaterialTypeParam=core::fast_atof(textureNameBuf); + bufPtr = goAndCopyNextWord(textureNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + } + if (clamp) + currMaterial->Meshbuffer->Material.setFlag(video::EMF_TEXTURE_WRAP, video::ETC_CLAMP); + + io::path texname(textureNameBuf); + texname.replace('\\', '/'); + + video::ITexture * texture = 0; + bool newTexture=false; + if (texname.size()) + { + io::path texnameWithUserPath( SceneManager->getParameters()->getAttributeAsString(OBJ_TEXTURE_PATH) ); + if ( texnameWithUserPath.size() ) + { + texnameWithUserPath += '/'; + texnameWithUserPath += texname; + } + if (FileSystem->existFile(texnameWithUserPath)) + texture = SceneManager->getVideoDriver()->getTexture(texnameWithUserPath); + else if (FileSystem->existFile(texname)) + { + newTexture = SceneManager->getVideoDriver()->findTexture(texname) == 0; + texture = SceneManager->getVideoDriver()->getTexture(texname); + } + else + { + newTexture = SceneManager->getVideoDriver()->findTexture(relPath + texname) == 0; + // try to read in the relative path, the .obj is loaded from + texture = SceneManager->getVideoDriver()->getTexture( relPath + texname ); + } + } + if ( texture ) + { + if (type==0) + currMaterial->Meshbuffer->Material.setTexture(0, texture); + else if (type==1) + { + if (newTexture) + SceneManager->getVideoDriver()->makeNormalMapTexture(texture, bumpiness); + currMaterial->Meshbuffer->Material.setTexture(1, texture); + currMaterial->Meshbuffer->Material.MaterialType=video::EMT_PARALLAX_MAP_SOLID; + currMaterial->Meshbuffer->Material.MaterialTypeParam=0.035f; + } + else if (type==2) + { + currMaterial->Meshbuffer->Material.setTexture(0, texture); + currMaterial->Meshbuffer->Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + } + else if (type==3) + { +// currMaterial->Meshbuffer->Material.Textures[1] = texture; +// currMaterial->Meshbuffer->Material.MaterialType=video::EMT_REFLECTION_2_LAYER; + } + // Set diffuse material color to white so as not to affect texture color + // Because Maya set diffuse color Kd to black when you use a diffuse color map + // But is this the right thing to do? + currMaterial->Meshbuffer->Material.DiffuseColor.set( + currMaterial->Meshbuffer->Material.DiffuseColor.getAlpha(), 255, 255, 255 ); + } + return bufPtr; +} + + +void COBJMeshFileLoader::readMTL(const c8* fileName, const io::path& relPath) +{ + const io::path realFile(fileName); + io::IReadFile * mtlReader; + + if (FileSystem->existFile(realFile)) + mtlReader = FileSystem->createAndOpenFile(realFile); + else if (FileSystem->existFile(relPath + realFile)) + mtlReader = FileSystem->createAndOpenFile(relPath + realFile); + else if (FileSystem->existFile(FileSystem->getFileBasename(realFile))) + mtlReader = FileSystem->createAndOpenFile(FileSystem->getFileBasename(realFile)); + else + mtlReader = FileSystem->createAndOpenFile(relPath + FileSystem->getFileBasename(realFile)); + if (!mtlReader) // fail to open and read file + { + os::Printer::log("Could not open material file", realFile, ELL_WARNING); + return; + } + + const long filesize = mtlReader->getSize(); + if (!filesize) + { + os::Printer::log("Skipping empty material file", realFile, ELL_WARNING); + mtlReader->drop(); + return; + } + + c8* buf = new c8[filesize]; + mtlReader->read((void*)buf, filesize); + const c8* bufEnd = buf+filesize; + + SObjMtl* currMaterial = 0; + + const c8* bufPtr = buf; + while(bufPtr != bufEnd) + { + switch(*bufPtr) + { + case 'n': // newmtl + { + // if there's an existing material, store it first + if ( currMaterial ) + Materials.push_back( currMaterial ); + + // extract new material's name + c8 mtlNameBuf[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(mtlNameBuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + + currMaterial = new SObjMtl; + currMaterial->Name = mtlNameBuf; + } + break; + case 'i': // illum - illumination + if ( currMaterial ) + { + const u32 COLOR_BUFFER_LENGTH = 16; + c8 illumStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(illumStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + currMaterial->Illumination = (c8)atol(illumStr); + } + break; + case 'N': + if ( currMaterial ) + { + switch(bufPtr[1]) + { + case 's': // Ns - shininess + { + const u32 COLOR_BUFFER_LENGTH = 16; + c8 nsStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(nsStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + f32 shininessValue = core::fast_atof(nsStr); + + // wavefront shininess is from [0, 1000], so scale for OpenGL + shininessValue *= 0.128f; + currMaterial->Meshbuffer->Material.Shininess = shininessValue; + } + break; + case 'i': // Ni - refraction index + { + c8 tmpbuf[WORD_BUFFER_LENGTH]; + bufPtr = goAndCopyNextWord(tmpbuf, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + } + break; + } + } + break; + case 'K': + if ( currMaterial ) + { + switch(bufPtr[1]) + { + case 'd': // Kd = diffuse + { + bufPtr = readColor(bufPtr, currMaterial->Meshbuffer->Material.DiffuseColor, bufEnd); + + } + break; + + case 's': // Ks = specular + { + bufPtr = readColor(bufPtr, currMaterial->Meshbuffer->Material.SpecularColor, bufEnd); + } + break; + + case 'a': // Ka = ambience + { + bufPtr=readColor(bufPtr, currMaterial->Meshbuffer->Material.AmbientColor, bufEnd); + } + break; + case 'e': // Ke = emissive + { + bufPtr=readColor(bufPtr, currMaterial->Meshbuffer->Material.EmissiveColor, bufEnd); + } + break; + } // end switch(bufPtr[1]) + } // end case 'K': if ( 0 != currMaterial )... + break; + case 'b': // bump + case 'm': // texture maps + if (currMaterial) + { + bufPtr=readTextures(bufPtr, bufEnd, currMaterial, relPath); + } + break; + case 'd': // d - transparency + if ( currMaterial ) + { + const u32 COLOR_BUFFER_LENGTH = 16; + c8 dStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(dStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + f32 dValue = core::fast_atof(dStr); + + currMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(dValue * 255) ); + if (dValue<1.0f) + currMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + break; + case 'T': + if ( currMaterial ) + { + switch ( bufPtr[1] ) + { + case 'f': // Tf - Transmitivity + const u32 COLOR_BUFFER_LENGTH = 16; + c8 redStr[COLOR_BUFFER_LENGTH]; + c8 greenStr[COLOR_BUFFER_LENGTH]; + c8 blueStr[COLOR_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(redStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + bufPtr = goAndCopyNextWord(greenStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + bufPtr = goAndCopyNextWord(blueStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + + f32 transparency = ( core::fast_atof(redStr) + core::fast_atof(greenStr) + core::fast_atof(blueStr) ) / 3; + + currMaterial->Meshbuffer->Material.DiffuseColor.setAlpha( (s32)(transparency * 255) ); + if (transparency < 1.0f) + currMaterial->Meshbuffer->Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + } + } + break; + default: // comments or not recognised + break; + } // end switch(bufPtr[0]) + // go to next line + bufPtr = goNextLine(bufPtr, bufEnd); + } // end while (bufPtr) + + // end of file. if there's an existing material, store it + if ( currMaterial ) + Materials.push_back( currMaterial ); + + delete [] buf; + mtlReader->drop(); +} + + +//! Read RGB color +const c8* COBJMeshFileLoader::readColor(const c8* bufPtr, video::SColor& color, const c8* const bufEnd) +{ + const u32 COLOR_BUFFER_LENGTH = 16; + c8 colStr[COLOR_BUFFER_LENGTH]; + + color.setAlpha(255); + bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + color.setRed((s32)(core::fast_atof(colStr) * 255.0f)); + bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + color.setGreen((s32)(core::fast_atof(colStr) * 255.0f)); + bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); + color.setBlue((s32)(core::fast_atof(colStr) * 255.0f)); + return bufPtr; +} + + +//! Read 3d vector of floats +const c8* COBJMeshFileLoader::readVec3(const c8* bufPtr, core::vector3df& vec, const c8* const bufEnd) +{ + const u32 WORD_BUFFER_LENGTH = 256; + c8 wordBuffer[WORD_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + vec.X=-core::fast_atof(wordBuffer); // change handedness + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + vec.Y=core::fast_atof(wordBuffer); + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + vec.Z=core::fast_atof(wordBuffer); + return bufPtr; +} + + +//! Read 2d vector of floats +const c8* COBJMeshFileLoader::readUV(const c8* bufPtr, core::vector2df& vec, const c8* const bufEnd) +{ + const u32 WORD_BUFFER_LENGTH = 256; + c8 wordBuffer[WORD_BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + vec.X=core::fast_atof(wordBuffer); + bufPtr = goAndCopyNextWord(wordBuffer, bufPtr, WORD_BUFFER_LENGTH, bufEnd); + vec.Y=1-core::fast_atof(wordBuffer); // change handedness + return bufPtr; +} + + +//! Read boolean value represented as 'on' or 'off' +const c8* COBJMeshFileLoader::readBool(const c8* bufPtr, bool& tf, const c8* const bufEnd) +{ + const u32 BUFFER_LENGTH = 8; + c8 tfStr[BUFFER_LENGTH]; + + bufPtr = goAndCopyNextWord(tfStr, bufPtr, BUFFER_LENGTH, bufEnd); + tf = strcmp(tfStr, "off") != 0; + return bufPtr; +} + + +COBJMeshFileLoader::SObjMtl* COBJMeshFileLoader::findMtl(const core::stringc& mtlName, const core::stringc& grpName) +{ + COBJMeshFileLoader::SObjMtl* defMaterial = 0; + // search existing Materials for best match + // exact match does return immediately, only name match means a new group + for (u32 i = 0; i < Materials.size(); ++i) + { + if ( Materials[i]->Name == mtlName ) + { + if ( Materials[i]->Group == grpName ) + return Materials[i]; + else + defMaterial = Materials[i]; + } + } + // we found a partial match + if (defMaterial) + { + Materials.push_back(new SObjMtl(*defMaterial)); + Materials.getLast()->Group = grpName; + return Materials.getLast(); + } + // we found a new group for a non-existant material + else if (grpName.size()) + { + Materials.push_back(new SObjMtl(*Materials[0])); + Materials.getLast()->Group = grpName; + return Materials.getLast(); + } + return 0; +} + + +//! skip space characters and stop on first non-space +const c8* COBJMeshFileLoader::goFirstWord(const c8* buf, const c8* const bufEnd, bool acrossNewlines) +{ + // skip space characters + if (acrossNewlines) + while((buf != bufEnd) && core::isspace(*buf)) + ++buf; + else + while((buf != bufEnd) && core::isspace(*buf) && (*buf != '\n')) + ++buf; + + return buf; +} + + +//! skip current word and stop at beginning of next one +const c8* COBJMeshFileLoader::goNextWord(const c8* buf, const c8* const bufEnd, bool acrossNewlines) +{ + // skip current word + while(( buf != bufEnd ) && !core::isspace(*buf)) + ++buf; + + return goFirstWord(buf, bufEnd, acrossNewlines); +} + + +//! Read until line break is reached and stop at the next non-space character +const c8* COBJMeshFileLoader::goNextLine(const c8* buf, const c8* const bufEnd) +{ + // look for newline characters + while(buf != bufEnd) + { + // found it, so leave + if (*buf=='\n' || *buf=='\r') + break; + ++buf; + } + return goFirstWord(buf, bufEnd); +} + + +u32 COBJMeshFileLoader::copyWord(c8* outBuf, const c8* const inBuf, u32 outBufLength, const c8* const bufEnd) +{ + if (!outBufLength) + return 0; + if (!inBuf) + { + *outBuf = 0; + return 0; + } + + u32 i = 0; + while(inBuf[i]) + { + if (core::isspace(inBuf[i]) || &(inBuf[i]) == bufEnd) + break; + ++i; + } + + u32 length = core::min_(i, outBufLength-1); + for (u32 j=0; j 2 ) + { + // error checking, shouldn't reach here unless file is wrong + idxType = 0; + } + } + else + { + // set all missing values to disable (=-1) + while (++idxType < 3) + idx[idxType]=-1; + ++p; + break; // while + } + } + + // go to the next char + ++p; + } + + return true; +} + + +void COBJMeshFileLoader::cleanUp() +{ + for (u32 i=0; i < Materials.size(); ++i ) + { + Materials[i]->Meshbuffer->drop(); + delete Materials[i]; + } + + Materials.clear(); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_OBJ_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.h new file mode 100644 index 0000000..06e71d6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshFileLoader.h @@ -0,0 +1,122 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_OBJ_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IFileSystem.h" +#include "ISceneManager.h" +#include "irrString.h" +#include "SMeshBuffer.h" +#include "irrMap.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading obj meshes. +class COBJMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + COBJMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~COBJMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".obj") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + struct SObjMtl + { + SObjMtl() : Meshbuffer(0), Bumpiness (1.0f), Illumination(0), + RecalculateNormals(false) + { + Meshbuffer = new SMeshBuffer(); + Meshbuffer->Material.Shininess = 0.0f; + Meshbuffer->Material.AmbientColor = video::SColorf(0.2f, 0.2f, 0.2f, 1.0f).toSColor(); + Meshbuffer->Material.DiffuseColor = video::SColorf(0.8f, 0.8f, 0.8f, 1.0f).toSColor(); + Meshbuffer->Material.SpecularColor = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f).toSColor(); + } + + SObjMtl(const SObjMtl& o) + : Name(o.Name), Group(o.Group), + Bumpiness(o.Bumpiness), Illumination(o.Illumination), + RecalculateNormals(false) + { + Meshbuffer = new SMeshBuffer(); + Meshbuffer->Material = o.Meshbuffer->Material; + } + + core::map VertMap; + scene::SMeshBuffer *Meshbuffer; + core::stringc Name; + core::stringc Group; + f32 Bumpiness; + c8 Illumination; + bool RecalculateNormals; + }; + + // helper method for material reading + const c8* readTextures(const c8* bufPtr, const c8* const bufEnd, SObjMtl* currMaterial, const io::path& relPath); + + // returns a pointer to the first printable character available in the buffer + const c8* goFirstWord(const c8* buf, const c8* const bufEnd, bool acrossNewlines=true); + // returns a pointer to the first printable character after the first non-printable + const c8* goNextWord(const c8* buf, const c8* const bufEnd, bool acrossNewlines=true); + // returns a pointer to the next printable character after the first line break + const c8* goNextLine(const c8* buf, const c8* const bufEnd); + // copies the current word from the inBuf to the outBuf + u32 copyWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd); + // copies the current line from the inBuf to the outBuf + core::stringc copyLine(const c8* inBuf, const c8* const bufEnd); + + // combination of goNextWord followed by copyWord + const c8* goAndCopyNextWord(c8* outBuf, const c8* inBuf, u32 outBufLength, const c8* const pBufEnd); + + //! Read the material from the given file + void readMTL(const c8* fileName, const io::path& relPath); + + //! Find and return the material with the given name + SObjMtl* findMtl(const core::stringc& mtlName, const core::stringc& grpName); + + //! Read RGB color + const c8* readColor(const c8* bufPtr, video::SColor& color, const c8* const pBufEnd); + //! Read 3d vector of floats + const c8* readVec3(const c8* bufPtr, core::vector3df& vec, const c8* const pBufEnd); + //! Read 2d vector of floats + const c8* readUV(const c8* bufPtr, core::vector2df& vec, const c8* const pBufEnd); + //! Read boolean value represented as 'on' or 'off' + const c8* readBool(const c8* bufPtr, bool& tf, const c8* const bufEnd); + + // reads and convert to integer the vertex indices in a line of obj file's face statement + // -1 for the index if it doesn't exist + // indices are changed to 0-based index instead of 1-based from the obj file + bool retrieveVertexIndices(c8* vertexData, s32* idx, const c8* bufEnd, u32 vbsize, u32 vtsize, u32 vnsize); + + void cleanUp(); + + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + + core::array Materials; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.cpp new file mode 100644 index 0000000..3555324 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.cpp @@ -0,0 +1,243 @@ +// Copyright (C) 2008-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OBJ_WRITER_ + +#include "COBJMeshWriter.h" +#include "os.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IAttributes.h" +#include "ISceneManager.h" +#include "IMeshCache.h" +#include "IWriteFile.h" +#include "IFileSystem.h" +#include "ITexture.h" + +namespace irr +{ +namespace scene +{ + +COBJMeshWriter::COBJMeshWriter(scene::ISceneManager* smgr, io::IFileSystem* fs) + : SceneManager(smgr), FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("COBJMeshWriter"); + #endif + + if (SceneManager) + SceneManager->grab(); + + if (FileSystem) + FileSystem->grab(); +} + + +COBJMeshWriter::~COBJMeshWriter() +{ + if (SceneManager) + SceneManager->drop(); + + if (FileSystem) + FileSystem->drop(); +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE COBJMeshWriter::getType() const +{ + return EMWT_OBJ; +} + + +//! writes a mesh +bool COBJMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + os::Printer::log("Writing mesh", file->getFileName()); + + // write OBJ MESH header + + const core::stringc name(FileSystem->getFileBasename(SceneManager->getMeshCache()->getMeshName(mesh), false)+".mtl"); + file->write("# exported by Irrlicht\n",23); + file->write("mtllib ",7); + file->write(name.c_str(),name.size()); + file->write("\n\n",2); + + // write mesh buffers + + core::array mat; + + u32 allVertexCount=1; // count vertices over the whole file + for (u32 i=0; igetMeshBufferCount(); ++i) + { + core::stringc num(i+1); + IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer && buffer->getVertexCount()) + { + file->write("g grp", 5); + file->write(num.c_str(), num.size()); + file->write("\n",1); + + u32 j; + const u32 vertexCount = buffer->getVertexCount(); + for (j=0; jwrite("v ",2); + getVectorAsStringLine(buffer->getPosition(j), num); + file->write(num.c_str(), num.size()); + } + + for (j=0; jwrite("vt ",3); + getVectorAsStringLine(buffer->getTCoords(j), num); + file->write(num.c_str(), num.size()); + } + + for (j=0; jwrite("vn ",3); + getVectorAsStringLine(buffer->getNormal(j), num); + file->write(num.c_str(), num.size()); + } + + file->write("usemtl mat",10); + num = ""; + for (j=0; jgetMaterial()) + { + num = core::stringc(j); + break; + } + } + if (num == "") + { + num = core::stringc(mat.size()); + mat.push_back(&buffer->getMaterial()); + } + file->write(num.c_str(), num.size()); + file->write("\n",1); + + const u32 indexCount = buffer->getIndexCount(); + for (j=0; jwrite("f ",2); + num = core::stringc(buffer->getIndices()[j+2]+allVertexCount); + file->write(num.c_str(), num.size()); + file->write("/",1); + file->write(num.c_str(), num.size()); + file->write("/",1); + file->write(num.c_str(), num.size()); + file->write(" ",1); + + num = core::stringc(buffer->getIndices()[j+1]+allVertexCount); + file->write(num.c_str(), num.size()); + file->write("/",1); + file->write(num.c_str(), num.size()); + file->write("/",1); + file->write(num.c_str(), num.size()); + file->write(" ",1); + + num = core::stringc(buffer->getIndices()[j+0]+allVertexCount); + file->write(num.c_str(), num.size()); + file->write("/",1); + file->write(num.c_str(), num.size()); + file->write("/",1); + file->write(num.c_str(), num.size()); + file->write(" ",1); + + file->write("\n",1); + } + file->write("\n",1); + allVertexCount += vertexCount; + } + } + + if (mat.size() == 0) + return true; + + file = FileSystem->createAndWriteFile( name ); + if (file) + { + os::Printer::log("Writing material", file->getFileName()); + + file->write("# exported by Irrlicht\n\n",24); + for (u32 i=0; iwrite("newmtl mat",10); + file->write(num.c_str(),num.size()); + file->write("\n",1); + + getColorAsStringLine(mat[i]->AmbientColor, "Ka", num); + file->write(num.c_str(),num.size()); + getColorAsStringLine(mat[i]->DiffuseColor, "Kd", num); + file->write(num.c_str(),num.size()); + getColorAsStringLine(mat[i]->SpecularColor, "Ks", num); + file->write(num.c_str(),num.size()); + getColorAsStringLine(mat[i]->EmissiveColor, "Ke", num); + file->write(num.c_str(),num.size()); + num = core::stringc((double)(mat[i]->Shininess/0.128f)); + file->write("Ns ", 3); + file->write(num.c_str(),num.size()); + file->write("\n", 1); + if (mat[i]->getTexture(0)) + { + file->write("map_Kd ", 7); + file->write(mat[i]->getTexture(0)->getName().getPath().c_str(), mat[i]->getTexture(0)->getName().getPath().size()); + file->write("\n",1); + } + file->write("\n",1); + } + file->drop(); + } + return true; +} + + +void COBJMeshWriter::getVectorAsStringLine(const core::vector3df& v, core::stringc& s) const +{ + s = core::stringc(-v.X); + s += " "; + s += core::stringc(v.Y); + s += " "; + s += core::stringc(v.Z); + s += "\n"; +} + + +void COBJMeshWriter::getVectorAsStringLine(const core::vector2df& v, core::stringc& s) const +{ + s = core::stringc(v.X); + s += " "; + s += core::stringc(-v.Y); + s += "\n"; +} + + +void COBJMeshWriter::getColorAsStringLine(const video::SColor& color, const c8* const prefix, core::stringc& s) const +{ + s = prefix; + s += " "; + s += core::stringc((double)(color.getRed()/255.f)); + s += " "; + s += core::stringc((double)(color.getGreen()/255.f)); + s += " "; + s += core::stringc((double)(color.getBlue()/255.f)); + s += "\n"; +} + + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.h new file mode 100644 index 0000000..34b9108 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COBJMeshWriter.h @@ -0,0 +1,58 @@ +// Copyright (C) 2008-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_OBJ_MESH_WRITER_H_INCLUDED__ +#define __IRR_OBJ_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "S3DVertex.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + class IFileSystem; +} // end namespace io +namespace scene +{ + class IMeshBuffer; + class ISceneManager; + + //! class to write meshes, implementing a OBJ writer + class COBJMeshWriter : public IMeshWriter + { + public: + + COBJMeshWriter(scene::ISceneManager* smgr, io::IFileSystem* fs); + virtual ~COBJMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + protected: + // create vector output with line end into string + void getVectorAsStringLine(const core::vector3df& v, + core::stringc& s) const; + + // create vector output with line end into string + void getVectorAsStringLine(const core::vector2df& v, + core::stringc& s) const; + + // create color output with line end into string + void getColorAsStringLine(const video::SColor& color, + const c8* const prefix, core::stringc& s) const; + + scene::ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.cpp new file mode 100644 index 0000000..fd03a9b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.cpp @@ -0,0 +1,336 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// originally written by Murphy McCauley, see COCTLoader.h for details. +// +// COCTLoader by Murphy McCauley (February 2005) +// An Irrlicht loader for OCT files +// +// See the header file for additional information including use and distribution rights. + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OCT_LOADER_ + +#include "COCTLoader.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "os.h" +#include "SAnimatedMesh.h" +#include "SMeshBufferLightMap.h" +#include "irrString.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +COCTLoader::COCTLoader(ISceneManager* smgr, io::IFileSystem* fs) + : SceneManager(smgr), FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("COCTLoader"); + #endif + if (FileSystem) + FileSystem->grab(); +} + + +//! destructor +COCTLoader::~COCTLoader() +{ + if (FileSystem) + FileSystem->drop(); +} + + +// Doesn't really belong here, but it's jammed in for now. +void COCTLoader::OCTLoadLights(io::IReadFile* file, scene::ISceneNode * parent, f32 radius, f32 intensityScale, bool rewind) +{ + if (rewind) + file->seek(0); + + octHeader header; + file->read(&header, sizeof(octHeader)); + + file->seek(sizeof(octVert)*header.numVerts, true); + file->seek(sizeof(octFace)*header.numFaces, true); + file->seek(sizeof(octTexture)*header.numTextures, true); + file->seek(sizeof(octLightmap)*header.numLightmaps, true); + + octLight * lights = new octLight[header.numLights]; + file->read(lights, header.numLights * sizeof(octLight)); + + //TODO: Skip past my extended data just for good form + + for (u32 i = 0; i < header.numLights; i++) + { + const f32 intensity = lights[i].intensity * intensityScale; + + SceneManager->addLightSceneNode(parent, core::vector3df(lights[i].pos[0], lights[i].pos[2], lights[i].pos[1]), + video::SColorf(lights[i].color[0] * intensity, lights[i].color[1] * intensity, lights[i].color[2] * intensity, 1.0f), + radius); + } +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* COCTLoader::createMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + octHeader header; + file->read(&header, sizeof(octHeader)); + + octVert * verts = new octVert[header.numVerts]; + octFace * faces = new octFace[header.numFaces]; + octTexture * textures = new octTexture[header.numTextures]; + octLightmap * lightmaps = new octLightmap[header.numLightmaps]; + octLight * lights = new octLight[header.numLights]; + + file->read(verts, sizeof(octVert) * header.numVerts); + file->read(faces, sizeof(octFace) * header.numFaces); + //TODO: Make sure id is in the legal range for Textures and Lightmaps + + u32 i; + for (i = 0; i < header.numTextures; i++) { + octTexture t; + file->read(&t, sizeof(octTexture)); + textures[t.id] = t; + } + for (i = 0; i < header.numLightmaps; i++) { + octLightmap t; + file->read(&t, sizeof(octLightmap)); + lightmaps[t.id] = t; + } + file->read(lights, sizeof(octLight) * header.numLights); + + //TODO: Now read in my extended OCT header (flexible lightmaps and vertex normals) + + + // This is the method Nikolaus Gebhardt used in the Q3 loader -- create a + // meshbuffer for every possible combination of lightmap and texture including + // a "null" texture and "null" lightmap. Ones that end up with nothing in them + // will be removed later. + + SMesh * Mesh = new SMesh(); + for (i=0; i<(header.numTextures+1) * (header.numLightmaps+1); ++i) + { + scene::SMeshBufferLightMap* buffer = new scene::SMeshBufferLightMap(); + + buffer->Material.MaterialType = video::EMT_LIGHTMAP; + buffer->Material.Lighting = false; + Mesh->addMeshBuffer(buffer); + buffer->drop(); + } + + + // Build the mesh buffers + for (i = 0; i < header.numFaces; i++) + { + if (faces[i].numVerts < 3) + continue; + + const f32* const a = verts[faces[i].firstVert].pos; + const f32* const b = verts[faces[i].firstVert+1].pos; + const f32* const c = verts[faces[i].firstVert+2].pos; + const core::vector3df normal = + core::plane3df(core::vector3df(a[0],a[1],a[2]), core::vector3df(b[0],c[1],c[2]), core::vector3df(c[0],c[1],c[2])).Normal; + + const u32 textureID = core::min_(s32(faces[i].textureID), s32(header.numTextures - 1)) + 1; + const u32 lightmapID = core::min_(s32(faces[i].lightmapID),s32(header.numLightmaps - 1)) + 1; + SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer(lightmapID * (header.numTextures + 1) + textureID); + const u32 base = meshBuffer->Vertices.size(); + + // Add this face's verts + u32 v; + for (v = 0; v < faces[i].numVerts; ++v) + { + octVert * vv = &verts[faces[i].firstVert + v]; + video::S3DVertex2TCoords vert; + vert.Pos.set(vv->pos[0], vv->pos[1], vv->pos[2]); + vert.Color = video::SColor(0,255,255,255); + vert.Normal.set(normal); + + if (textureID == 0) + { + // No texture -- just a lightmap. Thus, use lightmap coords for texture 1. + // (the actual texture will be swapped later) + vert.TCoords.set(vv->lc[0], vv->lc[1]); + } + else + { + vert.TCoords.set(vv->tc[0], vv->tc[1]); + vert.TCoords2.set(vv->lc[0], vv->lc[1]); + } + + meshBuffer->Vertices.push_back(vert); + } + + // Now add the indices + // This weird loop turns convex polygons into triangle strips. + // I do it this way instead of a simple fan because it usually looks a lot better in wireframe, for example. + // High, Low + u32 h = faces[i].numVerts - 1; + u32 l = 0; + for (v = 0; v < faces[i].numVerts - 2; ++v) + { + const u32 center = (v & 1)? h - 1: l + 1; + + meshBuffer->Indices.push_back(base + h); + meshBuffer->Indices.push_back(base + l); + meshBuffer->Indices.push_back(base + center); + + if (v & 1) + --h; + else + ++l; + } + } + + // load textures + core::array tex; + tex.reallocate(header.numTextures + 1); + tex.push_back(0); + + const core::stringc relpath = FileSystem->getFileDir(file->getFileName())+"/"; + for (i = 1; i < (header.numTextures + 1); i++) + { + core::stringc path(textures[i-1].fileName); + path.replace('\\','/'); + if (FileSystem->existFile(path)) + tex.push_back(SceneManager->getVideoDriver()->getTexture(path)); + else + // try to read in the relative path of the OCT file + tex.push_back(SceneManager->getVideoDriver()->getTexture( (relpath + path) )); + } + + // prepare lightmaps + core::array lig; + lig.set_used(header.numLightmaps + 1); + lig[0] = 0; + + const u32 lightmapWidth = 128; + const u32 lightmapHeight = 128; + const core::dimension2d lmapsize(lightmapWidth, lightmapHeight); + + bool oldMipMapState = SceneManager->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + + video::IImage* tmpImage = SceneManager->getVideoDriver()->createImage(video::ECF_R8G8B8, lmapsize); + for (i = 1; i < (header.numLightmaps + 1); ++i) + { + core::stringc lightmapname = file->getFileName(); + lightmapname += ".lightmap."; + lightmapname += (int)i; + + const octLightmap* lm = &lightmaps[i-1]; + + for (u32 x=0; xsetPixel(x, y, + video::SColor(255, + lm->data[x][y][2], + lm->data[x][y][1], + lm->data[x][y][0])); + } + } + + lig[i] = SceneManager->getVideoDriver()->addTexture(lightmapname.c_str(), tmpImage); + } + tmpImage->drop(); + SceneManager->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + // Free stuff + delete [] verts; + delete [] faces; + delete [] textures; + delete [] lightmaps; + delete [] lights; + + // attach materials + for (i = 0; i < header.numLightmaps + 1; i++) + { + for (u32 j = 0; j < header.numTextures + 1; j++) + { + u32 mb = i * (header.numTextures + 1) + j; + SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)Mesh->getMeshBuffer(mb); + meshBuffer->Material.setTexture(0, tex[j]); + meshBuffer->Material.setTexture(1, lig[i]); + + if (meshBuffer->Material.getTexture(0) == 0) + { + // This material has no texture, so we'll just show the lightmap if there is one. + // We swapped the texture coordinates earlier. + meshBuffer->Material.setTexture(0, meshBuffer->Material.getTexture(1)); + meshBuffer->Material.setTexture(1, 0); + } + if (meshBuffer->Material.getTexture(1) == 0) + { + // If there is only one texture, it should be solid and lit. + // Among other things, this way you can preview OCT lights. + meshBuffer->Material.MaterialType = video::EMT_SOLID; + meshBuffer->Material.Lighting = true; + } + } + } + + // delete all buffers without geometry in it. + i = 0; + while(i < Mesh->MeshBuffers.size()) + { + if (Mesh->MeshBuffers[i]->getVertexCount() == 0 || + Mesh->MeshBuffers[i]->getIndexCount() == 0 || + Mesh->MeshBuffers[i]->getMaterial().getTexture(0) == 0) + { + // Meshbuffer is empty -- drop it + Mesh->MeshBuffers[i]->drop(); + Mesh->MeshBuffers.erase(i); + } + else + { + ++i; + } + } + + + // create bounding box + for (i = 0; i < Mesh->MeshBuffers.size(); ++i) + { + Mesh->MeshBuffers[i]->recalculateBoundingBox(); + } + Mesh->recalculateBoundingBox(); + + + // Set up an animated mesh to hold the mesh + SAnimatedMesh* AMesh = new SAnimatedMesh(); + AMesh->Type = EAMT_OCT; + AMesh->addMesh(Mesh); + AMesh->recalculateBoundingBox(); + Mesh->drop(); + + return AMesh; +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool COCTLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "oct" ); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_OCT_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.h new file mode 100644 index 0000000..57eef61 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COCTLoader.h @@ -0,0 +1,141 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// Because I (Nikolaus Gebhardt) did some changes to Murphy McCauley's loader, +// I'm writing this down here: +// - Replaced all dependencies to STL and stdio with irr:: methods/constructs +// - Disabled logging define +// - Changed some minor things (Don't remember what exactly.) +// Thanks a lot to Murphy McCauley for writing this loader. + +// +// COCTLoader by Murphy McCauley (February 2005) +// An Irrlicht loader for OCT files +// +// OCT file format information comes from the sourcecode of the Fluid Studios +// Radiosity Processor by Paul Nettle. You can get that sourcecode from +// http://www.fluidstudios.com . +// +// Parts of this code are from Irrlicht's CQ3LevelMesh and C3DSMeshFileLoader, +// and are Copyright (C) 2002-2004 Nikolaus Gebhardt. +// +// Use of this code is subject to the following: +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// 4. You may not use this software to directly or indirectly cause harm to others. + + +#ifndef __C_OCT_LOADER_H_INCLUDED__ +#define __C_OCT_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "IReadFile.h" +#include "SMesh.h" +#include "irrString.h" + +namespace irr +{ +namespace io +{ + class IFileSystem; +} // end namespace io +namespace scene +{ + class ISceneManager; + class ISceneNode; + + class COCTLoader : public IMeshLoader + { + public: + //! constructor + COCTLoader(ISceneManager* smgr, io::IFileSystem* fs); + + //! destructor + virtual ~COCTLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + void OCTLoadLights(io::IReadFile* file, + ISceneNode * parent = 0, f32 radius = 500.0f, + f32 intensityScale = 0.0000001f*2.5, + bool rewind = true); + + private: + struct octHeader { + u32 numVerts; + u32 numFaces; + u32 numTextures; + u32 numLightmaps; + u32 numLights; + }; + + struct octHeaderEx { + u32 magic; // 'OCTX' - 0x4F435458L + u32 numLightmaps; + u32 lightmapWidth; + u32 lightmapHeight; + u32 containsVertexNormals; + }; + + struct octFace { + u32 firstVert; + u32 numVerts; + u32 textureID; + u32 lightmapID; + f32 plane[4]; + }; + + struct octVert { + f32 tc[2]; + f32 lc[2]; + f32 pos[3]; + }; + + struct octTexture { + u32 id; + char fileName[64]; + }; + + struct octLightmap { + u32 id; + u8 data[128][128][3]; + }; + + struct octLight { + f32 pos[3]; + f32 color[3]; + u32 intensity; + }; + + ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.cpp new file mode 100644 index 0000000..0899d1d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.cpp @@ -0,0 +1,212 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COSOperator.h" + +#ifdef _IRR_WINDOWS_API_ +#ifndef _IRR_XBOX_PLATFORM_ +#include +#endif +#else +#include +#include +#ifndef _IRR_SOLARIS_PLATFORM_ +#include +#include +#endif +#endif + +#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) +#include "CIrrDeviceLinux.h" +#endif +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ +#include "MacOSX/OSXClipboard.h" +#endif + +namespace irr +{ + +#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) +// constructor linux + COSOperator::COSOperator(const core::stringc& osVersion, CIrrDeviceLinux* device) +: OperatingSystem(osVersion), IrrDeviceLinux(device) +{ +} +#endif + +// constructor +COSOperator::COSOperator(const core::stringc& osVersion) : OperatingSystem(osVersion) +{ + #ifdef _DEBUG + setDebugName("COSOperator"); + #endif +} + + +//! returns the current operating system version as string. +const core::stringc& COSOperator::getOperatingSystemVersion() const +{ + return OperatingSystem; +} + + +//! copies text to the clipboard +void COSOperator::copyToClipboard(const c8* text) const +{ + if (strlen(text)==0) + return; + +// Windows version +#if defined(_IRR_XBOX_PLATFORM_) +#elif defined(_IRR_WINDOWS_API_) + if (!OpenClipboard(NULL) || text == 0) + return; + + EmptyClipboard(); + + HGLOBAL clipbuffer; + char * buffer; + + clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1); + buffer = (char*)GlobalLock(clipbuffer); + + strcpy(buffer, text); + + GlobalUnlock(clipbuffer); + SetClipboardData(CF_TEXT, clipbuffer); + CloseClipboard(); + +// MacOSX version +#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) + + OSXCopyToClipboard(text); + +#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) + if ( IrrDeviceLinux ) + IrrDeviceLinux->copyToClipboard(text); +#else + +#endif +} + + +//! gets text from the clipboard +//! \return Returns 0 if no string is in there. +const c8* COSOperator::getTextFromClipboard() const +{ +#if defined(_IRR_XBOX_PLATFORM_) + return 0; +#elif defined(_IRR_WINDOWS_API_) + if (!OpenClipboard(NULL)) + return 0; + + char * buffer = 0; + + HANDLE hData = GetClipboardData( CF_TEXT ); + buffer = (char*)GlobalLock( hData ); + GlobalUnlock( hData ); + CloseClipboard(); + return buffer; + +#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) + return (OSXCopyFromClipboard()); + +#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) + if ( IrrDeviceLinux ) + return IrrDeviceLinux->getTextFromClipboard(); + return 0; + +#else + + return 0; +#endif +} + + +bool COSOperator::getProcessorSpeedMHz(u32* MHz) const +{ +#if defined(_IRR_WINDOWS_API_) && !defined(_WIN32_WCE ) && !defined (_IRR_XBOX_PLATFORM_) + LONG Error; + + HKEY Key; + Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + __TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), + 0, KEY_READ, &Key); + + if(Error != ERROR_SUCCESS) + return false; + + DWORD Speed = 0; + DWORD Size = sizeof(Speed); + Error = RegQueryValueEx(Key, __TEXT("~MHz"), NULL, NULL, (LPBYTE)&Speed, &Size); + + RegCloseKey(Key); + + if (Error != ERROR_SUCCESS) + return false; + else if (MHz) + *MHz = Speed; + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; + +#elif defined(_IRR_OSX_PLATFORM_) + struct clockinfo CpuClock; + size_t Size = sizeof(clockinfo); + + if (!sysctlbyname("kern.clockrate", &CpuClock, &Size, NULL, 0)) + return false; + else if (MHz) + *MHz = CpuClock.hz; + return true; +#else + // could probably be read from "/proc/cpuinfo" or "/proc/cpufreq" + + return false; +#endif +} + +bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const +{ +#if defined(_IRR_WINDOWS_API_) && !defined (_IRR_XBOX_PLATFORM_) + MEMORYSTATUS MemoryStatus; + MemoryStatus.dwLength = sizeof(MEMORYSTATUS); + + // cannot fail + GlobalMemoryStatus(&MemoryStatus); + + if (Total) + *Total = (u32)(MemoryStatus.dwTotalPhys>>10); + if (Avail) + *Avail = (u32)(MemoryStatus.dwAvailPhys>>10); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return true; + +#elif defined(_IRR_POSIX_API_) && !defined(__FreeBSD__) +#if defined(_SC_PHYS_PAGES) && defined(_SC_AVPHYS_PAGES) + long ps = sysconf(_SC_PAGESIZE); + long pp = sysconf(_SC_PHYS_PAGES); + long ap = sysconf(_SC_AVPHYS_PAGES); + + if ((ps==-1)||(pp==-1)||(ap==-1)) + return false; + + if (Total) + *Total = (u32)((ps*(long long)pp)>>10); + if (Avail) + *Avail = (u32)((ps*(long long)ap)>>10); + return true; +#else + // TODO: implement for non-availablity of symbols/features + return false; +#endif +#else + // TODO: implement for OSX + return false; +#endif +} + + +} // end namespace + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.h new file mode 100644 index 0000000..819805f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COSOperator.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OS_OPERATOR_H_INCLUDED__ +#define __C_OS_OPERATOR_H_INCLUDED__ + +#include "IOSOperator.h" + +namespace irr +{ + +class CIrrDeviceLinux; + +//! The Operating system operator provides operation system specific methods and informations. +class COSOperator : public IOSOperator +{ +public: + + // constructor +#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) + COSOperator(const core::stringc& osversion, CIrrDeviceLinux* device); +#endif + COSOperator(const core::stringc& osversion); + + //! returns the current operation system version as string. + virtual const core::stringc& getOperatingSystemVersion() const; + + //! copies text to the clipboard + virtual void copyToClipboard(const c8* text) const; + + //! gets text from the clipboard + //! \return Returns 0 if no string is in there. + virtual const c8* getTextFromClipboard() const; + + //! gets the processor speed in megahertz + //! \param Mhz: + //! \return Returns true if successful, false if not + virtual bool getProcessorSpeedMHz(u32* MHz) const; + + //! gets the total and available system RAM in kB + //! \param Total: will contain the total system memory + //! \param Avail: will contain the available memory + //! \return Returns true if successful, false if not + virtual bool getSystemMemory(u32* Total, u32* Avail) const; + +private: + + core::stringc OperatingSystem; + +#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) + CIrrDeviceLinux * IrrDeviceLinux; +#endif + +}; + +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.cpp new file mode 100644 index 0000000..226f6f6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.cpp @@ -0,0 +1,636 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COctreeSceneNode.h" +#include "Octree.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "IMeshCache.h" +#include "IAnimatedMesh.h" +#include "IMaterialRenderer.h" +#include "os.h" +#include "CShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr, + s32 id, s32 minimalPolysPerNode) + : IMeshSceneNode(parent, mgr, id), StdOctree(0), LightMapOctree(0), + TangentsOctree(0), VertexType((video::E_VERTEX_TYPE)-1), + MinimalPolysPerNode(minimalPolysPerNode), Mesh(0), Shadow(0), + UseVBOs(OCTREE_USE_HARDWARE), UseVisibilityAndVBOs(OCTREE_USE_VISIBILITY), + BoxBased(OCTREE_BOX_BASED) +{ +#ifdef _DEBUG + setDebugName("COctreeSceneNode"); +#endif +} + + +//! destructor +COctreeSceneNode::~COctreeSceneNode() +{ + if (Shadow) + Shadow->drop(); + deleteTree(); +} + + +void COctreeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + // because this node supports rendering of mixed mode meshes consisting of + // transparent and solid material at the same time, we need to go through all + // materials, check of what type they are and register this node for the right + // render pass according to that. + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + PassCount = 0; + u32 transparentCount = 0; + u32 solidCount = 0; + + // count transparent and solid materials in this scene node + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + + if (rnd && rnd->isTransparent()) + ++transparentCount; + else + ++solidCount; + + if (solidCount && transparentCount) + break; + } + + // register according to material types counted + + if (solidCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + + if (transparentCount) + SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! renders the node. +void COctreeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (VertexType == -1 || !driver) + return; + + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + if (!camera) + return; + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + ++PassCount; + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + if (Shadow) + Shadow->updateShadowVolumes(); + + SViewFrustum frust = *camera->getViewFrustum(); + + //transform the frustum to the current absolute transformation + if ( !AbsoluteTransformation.isIdentity() ) + { + core::matrix4 invTrans(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE); + frust.transform(invTrans); + } + + const core::aabbox3d &box = frust.getBoundingBox(); + + switch (VertexType) + { + case video::EVT_STANDARD: + { + if (BoxBased) + StdOctree->calculatePolys(box); + else + StdOctree->calculatePolys(frust); + + const Octree::SIndexData* d = StdOctree->getIndexData(); + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + const bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(Materials[i]); + driver->drawIndexedTriangleList( + &StdMeshes[i].Vertices[0], StdMeshes[i].Vertices.size(), + d[i].Indices, d[i].CurrentSize / 3); + } + } + + // for debug purposes only + if (DebugDataVisible && !Materials.empty() && PassCount==1) + { + const core::aabbox3df& box = frust.getBoundingBox(); + core::array< const core::aabbox3d* > boxes; + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + StdOctree->getBoundingBoxes(box, boxes); + for (u32 b=0; b!=boxes.size(); ++b) + driver->draw3DBox(*boxes[b]); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox(Box,video::SColor(0,255,0,0)); + } + } + break; + case video::EVT_2TCOORDS: + { + if (BoxBased) + LightMapOctree->calculatePolys(box); + else + LightMapOctree->calculatePolys(frust); + + const Octree::SIndexData* d = LightMapOctree->getIndexData(); + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + const bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(Materials[i]); + if (UseVBOs) + { + if (UseVisibilityAndVBOs) + { + u16* oldPointer = LightMapMeshes[i].Indices.pointer(); + const u32 oldSize = LightMapMeshes[i].Indices.size(); + LightMapMeshes[i].Indices.set_free_when_destroyed(false); + LightMapMeshes[i].Indices.set_pointer(d[i].Indices, d[i].CurrentSize, false, false); + LightMapMeshes[i].setDirty(scene::EBT_INDEX); + driver->drawMeshBuffer ( &LightMapMeshes[i] ); + LightMapMeshes[i].Indices.set_pointer(oldPointer, oldSize); + LightMapMeshes[i].setDirty(scene::EBT_INDEX); + } + else + driver->drawMeshBuffer ( &LightMapMeshes[i] ); + } + else + driver->drawIndexedTriangleList( + &LightMapMeshes[i].Vertices[0], + LightMapMeshes[i].Vertices.size(), + d[i].Indices, d[i].CurrentSize / 3); + } + } + + // for debug purposes only + if (DebugDataVisible && !Materials.empty() && PassCount==1) + { + const core::aabbox3d &box = frust.getBoundingBox(); + core::array< const core::aabbox3d* > boxes; + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + LightMapOctree->getBoundingBoxes(box, boxes); + for (u32 b=0; bdraw3DBox(*boxes[b]); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox(Box,video::SColor(0,255,0,0)); + } + } + break; + case video::EVT_TANGENTS: + { + if (BoxBased) + TangentsOctree->calculatePolys(box); + else + TangentsOctree->calculatePolys(frust); + + const Octree::SIndexData* d = TangentsOctree->getIndexData(); + + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + const bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(Materials[i]); + driver->drawIndexedTriangleList( + &TangentsMeshes[i].Vertices[0], TangentsMeshes[i].Vertices.size(), + d[i].Indices, d[i].CurrentSize / 3); + } + } + + // for debug purposes only + if (DebugDataVisible && !Materials.empty() && PassCount==1) + { + const core::aabbox3d &box = frust.getBoundingBox(); + core::array< const core::aabbox3d* > boxes; + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) + { + TangentsOctree->getBoundingBoxes(box, boxes); + for (u32 b=0; bdraw3DBox(*boxes[b]); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + driver->draw3DBox(Box,video::SColor(0,255,0,0)); + } + } + break; + } +} + + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool COctreeSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + } + + return ISceneNode::removeChild(child); +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* COctreeSceneNode::addShadowVolumeSceneNode( + const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (!shadowMesh) + shadowMesh = Mesh; // if null is given, use the mesh of node + + if (Shadow) + Shadow->drop(); + + Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& COctreeSceneNode::getBoundingBox() const +{ + return Box; +} + + +//! creates the tree +/* This method has a lot of duplication and overhead. Moreover, the tangents mesh conversion does not really work. I think we need a a proper mesh implementation for octrees, which handle all vertex types internally. Converting all structures to just one vertex type is always problematic. +Thanks to Auria for fixing major parts of this method. */ +bool COctreeSceneNode::createTree(IMesh* mesh) +{ + if (!mesh) + return false; + + MeshName = SceneManager->getMeshCache()->getMeshName(mesh); + + mesh->grab(); + deleteTree(); + + Mesh = mesh; + + const u32 beginTime = os::Timer::getRealTime(); + + u32 nodeCount = 0; + u32 polyCount = 0; + u32 i; + + Box = mesh->getBoundingBox(); + + if (mesh->getMeshBufferCount()) + { + // check for "larger" buffer types + VertexType = video::EVT_STANDARD; + u32 meshReserve = 0; + for (i=0; igetMeshBufferCount(); ++i) + { + const IMeshBuffer* b = mesh->getMeshBuffer(i); + if (b->getVertexCount() && b->getIndexCount()) + { + ++meshReserve; + if (b->getVertexType() == video::EVT_2TCOORDS) + VertexType = video::EVT_2TCOORDS; + else if (b->getVertexType() == video::EVT_TANGENTS) + VertexType = video::EVT_TANGENTS; + } + } + Materials.reallocate(Materials.size()+meshReserve); + + switch(VertexType) + { + case video::EVT_STANDARD: + { + StdMeshes.reallocate(StdMeshes.size() + meshReserve); + for (i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* b = mesh->getMeshBuffer(i); + + if (b->getVertexCount() && b->getIndexCount()) + { + Materials.push_back(b->getMaterial()); + + StdMeshes.push_back(Octree::SMeshChunk()); + Octree::SMeshChunk &nchunk = StdMeshes.getLast(); + nchunk.MaterialId = Materials.size() - 1; + + u32 v; + nchunk.Vertices.reallocate(b->getVertexCount()); + switch (b->getVertexType()) + { + case video::EVT_STANDARD: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); + break; + case video::EVT_2TCOORDS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); + break; + case video::EVT_TANGENTS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + break; + } + + polyCount += b->getIndexCount(); + + nchunk.Indices.reallocate(b->getIndexCount()); + for (v=0; vgetIndexCount(); ++v) + nchunk.Indices.push_back(b->getIndices()[v]); + } + } + + StdOctree = new Octree(StdMeshes, MinimalPolysPerNode); + nodeCount = StdOctree->getNodeCount(); + } + break; + case video::EVT_2TCOORDS: + { + LightMapMeshes.reallocate(LightMapMeshes.size() + meshReserve); + + for ( i=0; i < mesh->getMeshBufferCount(); ++i) + { + IMeshBuffer* b = mesh->getMeshBuffer(i); + + if (b->getVertexCount() && b->getIndexCount()) + { + Materials.push_back(b->getMaterial()); + LightMapMeshes.push_back(Octree::SMeshChunk()); + Octree::SMeshChunk& nchunk = LightMapMeshes.getLast(); + nchunk.MaterialId = Materials.size() - 1; + + if (UseVisibilityAndVBOs) + { + nchunk.setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_VERTEX); + nchunk.setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_INDEX); + } + else + nchunk.setHardwareMappingHint(scene::EHM_STATIC); + + u32 v; + nchunk.Vertices.reallocate(b->getVertexCount()); + switch (b->getVertexType()) + { + case video::EVT_STANDARD: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex*)b->getVertices())[v]); + break; + case video::EVT_2TCOORDS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertex2TCoords*)b->getVertices())[v]); + break; + case video::EVT_TANGENTS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + break; + } + + polyCount += b->getIndexCount(); + nchunk.Indices.reallocate(b->getIndexCount()); + for (v=0; vgetIndexCount(); ++v) + nchunk.Indices.push_back(b->getIndices()[v]); + } + } + + LightMapOctree = new Octree(LightMapMeshes, MinimalPolysPerNode); + nodeCount = LightMapOctree->getNodeCount(); + } + break; + case video::EVT_TANGENTS: + { + TangentsMeshes.reallocate(TangentsMeshes.size() + meshReserve); + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* b = mesh->getMeshBuffer(i); + + if (b->getVertexCount() && b->getIndexCount()) + { + Materials.push_back(b->getMaterial()); + TangentsMeshes.push_back(Octree::SMeshChunk()); + Octree::SMeshChunk& nchunk = TangentsMeshes.getLast(); + nchunk.MaterialId = Materials.size() - 1; + + u32 v; + nchunk.Vertices.reallocate(b->getVertexCount()); + switch (b->getVertexType()) + { + case video::EVT_STANDARD: + for (v=0; vgetVertexCount(); ++v) + { + const video::S3DVertex& tmpV = ((video::S3DVertex*)b->getVertices())[v]; + nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); + } + break; + case video::EVT_2TCOORDS: + for (v=0; vgetVertexCount(); ++v) + { + const video::S3DVertex2TCoords& tmpV = ((video::S3DVertex2TCoords*)b->getVertices())[v]; + nchunk.Vertices.push_back(video::S3DVertexTangents(tmpV.Pos, tmpV.Color, tmpV.TCoords)); + } + break; + case video::EVT_TANGENTS: + for (v=0; vgetVertexCount(); ++v) + nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); + break; + } + + polyCount += b->getIndexCount(); + nchunk.Indices.reallocate(b->getIndexCount()); + for (v=0; vgetIndexCount(); ++v) + nchunk.Indices.push_back(b->getIndices()[v]); + } + } + + TangentsOctree = new Octree(TangentsMeshes, MinimalPolysPerNode); + nodeCount = TangentsOctree->getNodeCount(); + } + break; + } + } + + const u32 endTime = os::Timer::getRealTime(); + c8 tmp[255]; + sprintf(tmp, "Needed %ums to create Octree SceneNode.(%u nodes, %u polys)", + endTime - beginTime, nodeCount, polyCount/3); + os::Printer::log(tmp, ELL_INFORMATION); + + return true; +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& COctreeSceneNode::getMaterial(u32 i) +{ + if ( i >= Materials.size() ) + return ISceneNode::getMaterial(i); + + return Materials[i]; +} + + +//! returns amount of materials used by this scene node. +u32 COctreeSceneNode::getMaterialCount() const +{ + return Materials.size(); +} + + +//! Writes attributes of the scene node. +void COctreeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addInt("MinimalPolysPerNode", MinimalPolysPerNode); + out->addString("Mesh", MeshName.c_str()); +} + + +//! Reads attributes of the scene node. +void COctreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + const s32 oldMinimal = MinimalPolysPerNode; + + MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode"); + io::path newMeshStr = in->getAttributeAsString("Mesh"); + + IMesh* newMesh = 0; + + if (newMeshStr == "") + newMeshStr = MeshName; + + IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str()); + + if (newAnimatedMesh) + newMesh = newAnimatedMesh->getMesh(0); + + if (newMesh && ((MeshName != newMeshStr) || (MinimalPolysPerNode != oldMinimal))) + { + // recalculate tree + createTree(newMesh); + } + + ISceneNode::deserializeAttributes(in, options); +} + + +void COctreeSceneNode::deleteTree() +{ + delete StdOctree; + StdOctree = 0; + StdMeshes.clear(); + + delete LightMapOctree; + LightMapOctree = 0; + LightMapMeshes.clear(); + + delete TangentsOctree; + TangentsOctree = 0; + TangentsMeshes.clear(); + + Materials.clear(); + + if(Mesh) + Mesh->drop(); +} + +void COctreeSceneNode::setMesh(IMesh* mesh) +{ + createTree(mesh); +} + +IMesh* COctreeSceneNode::getMesh(void) +{ + return Mesh; +} + +void COctreeSceneNode::setReadOnlyMaterials(bool readonly) +{ + // Do nothing +} + +bool COctreeSceneNode::isReadOnlyMaterials() const +{ + return false; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.h new file mode 100644 index 0000000..203be70 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeSceneNode.h @@ -0,0 +1,115 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OCTREE_SCENE_NODE_H_INCLUDED__ +#define __C_OCTREE_SCENE_NODE_H_INCLUDED__ + +#include "IMeshSceneNode.h" +#include "Octree.h" + +namespace irr +{ +namespace scene +{ + //! implementation of the IBspTreeSceneNode + class COctreeSceneNode : public IMeshSceneNode + { + public: + + //! constructor + COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + s32 minimalPolysPerNode=512); + + //! destructor + virtual ~COctreeSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! creates the tree + bool createTree(IMesh* mesh); + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_OCTREE; } + + //! Sets a new mesh to display + virtual void setMesh(IMesh* mesh); + + //! Get the currently defined mesh for display. + virtual IMesh* getMesh(void); + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + virtual void setReadOnlyMaterials(bool readonly); + + //! Check if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const; + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh, + s32 id, bool zfailmethod=true, f32 infinity=10000.0f); + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + + private: + + void deleteTree(); + + core::aabbox3d Box; + + Octree* StdOctree; + core::array< Octree::SMeshChunk > StdMeshes; + + Octree* LightMapOctree; + core::array< Octree::SMeshChunk > LightMapMeshes; + + Octree* TangentsOctree; + core::array< Octree::SMeshChunk > TangentsMeshes; + + video::E_VERTEX_TYPE VertexType; + core::array< video::SMaterial > Materials; + + core::stringc MeshName; + s32 MinimalPolysPerNode; + s32 PassCount; + + IMesh * Mesh; + IShadowVolumeSceneNode* Shadow; + //! use VBOs for rendering where possible + bool UseVBOs; + //! use visibility information together with VBOs + bool UseVisibilityAndVBOs; + //! use bounding box or frustum for calculate polys + bool BoxBased; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.cpp new file mode 100644 index 0000000..657f911 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.cpp @@ -0,0 +1,265 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COctreeTriangleSelector.h" +#include "ISceneNode.h" + +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +COctreeTriangleSelector::COctreeTriangleSelector(const IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode) + : CTriangleSelector(mesh, node), Root(0), NodeCount(0), + MinimalPolysPerNode(minimalPolysPerNode) +{ + #ifdef _DEBUG + setDebugName("COctreeTriangleSelector"); + #endif + + if (!Triangles.empty()) + { + const u32 start = os::Timer::getRealTime(); + + // create the triangle octree + Root = new SOctreeNode(); + Root->Triangles = Triangles; + constructOctree(Root); + + c8 tmp[256]; + sprintf(tmp, "Needed %ums to create OctreeTriangleSelector.(%d nodes, %u polys)", + os::Timer::getRealTime() - start, NodeCount, Triangles.size()); + os::Printer::log(tmp, ELL_INFORMATION); + } +} + + +//! destructor +COctreeTriangleSelector::~COctreeTriangleSelector() +{ + delete Root; +} + + +void COctreeTriangleSelector::constructOctree(SOctreeNode* node) +{ + ++NodeCount; + + node->Box.reset(node->Triangles[0].pointA); + + // get bounding box + const u32 cnt = node->Triangles.size(); + for (u32 i=0; iBox.addInternalPoint(node->Triangles[i].pointA); + node->Box.addInternalPoint(node->Triangles[i].pointB); + node->Box.addInternalPoint(node->Triangles[i].pointC); + } + + const core::vector3df& middle = node->Box.getCenter(); + core::vector3df edges[8]; + node->Box.getEdges(edges); + + core::aabbox3d box; + core::array keepTriangles; + + // calculate children + + if (!node->Box.isEmpty() && (s32)node->Triangles.size() > MinimalPolysPerNode) + for (s32 ch=0; ch<8; ++ch) + { + box.reset(middle); + box.addInternalPoint(edges[ch]); + node->Child[ch] = new SOctreeNode(); + + for (s32 i=0; i<(s32)node->Triangles.size(); ++i) + { + if (node->Triangles[i].isTotalInsideBox(box)) + { + node->Child[ch]->Triangles.push_back(node->Triangles[i]); + //node->Triangles.erase(i); + //--i; + } + else + { + keepTriangles.push_back(node->Triangles[i]); + } + } + memcpy(node->Triangles.pointer(), keepTriangles.pointer(), + sizeof(core::triangle3df)*keepTriangles.size()); + + node->Triangles.set_used(keepTriangles.size()); + keepTriangles.set_used(0); + + if (node->Child[ch]->Triangles.empty()) + { + delete node->Child[ch]; + node->Child[ch] = 0; + } + else + constructOctree(node->Child[ch]); + } +} + + +//! Gets all triangles which lie within a specific bounding box. +void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, + const core::matrix4* transform) const +{ + core::matrix4 mat(core::matrix4::EM4CONST_NOTHING); + core::aabbox3d invbox = box; + + if (SceneNode) + { + SceneNode->getAbsoluteTransformation().getInverse(mat); + mat.transformBoxEx(invbox); + } + + if (transform) + mat = *transform; + else + mat.makeIdentity(); + + if (SceneNode) + mat *= SceneNode->getAbsoluteTransformation(); + + s32 trianglesWritten = 0; + + if (Root) + getTrianglesFromOctree(Root, trianglesWritten, + arraySize, invbox, &mat, triangles); + + outTriangleCount = trianglesWritten; +} + + +void COctreeTriangleSelector::getTrianglesFromOctree( + SOctreeNode* node, s32& trianglesWritten, + s32 maximumSize, const core::aabbox3d& box, + const core::matrix4* mat, core::triangle3df* triangles) const +{ + if (!box.intersectsWithBox(node->Box)) + return; + + const u32 cnt = node->Triangles.size(); + + for (u32 i=0; iTriangles[i]; + // This isn't an accurate test, but it's fast, and the + // API contract doesn't guarantee complete accuracy. + if (srcTri.isTotalOutsideBox(box)) + continue; + + core::triangle3df& dstTri = triangles[trianglesWritten]; + mat->transformVect(dstTri.pointA, srcTri.pointA ); + mat->transformVect(dstTri.pointB, srcTri.pointB ); + mat->transformVect(dstTri.pointC, srcTri.pointC ); + ++trianglesWritten; + + // Halt when the out array is full. + if (trianglesWritten == maximumSize) + return; + } + + for (u32 i=0; i<8; ++i) + if (node->Child[i]) + getTrianglesFromOctree(node->Child[i], trianglesWritten, + maximumSize, box, mat, triangles); +} + + +//! Gets all triangles which have or may have contact with a 3d line. +// new version: from user Piraaate +void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform) const +{ +#if 0 + core::aabbox3d box(line.start); + box.addInternalPoint(line.end); + + // TODO: Could be optimized for line a little bit more. + COctreeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, + box, transform); +#else + + core::matrix4 mat ( core::matrix4::EM4CONST_NOTHING ); + + core::vector3df vectStartInv ( line.start ), vectEndInv ( line.end ); + if (SceneNode) + { + mat = SceneNode->getAbsoluteTransformation(); + mat.makeInverse(); + mat.transformVect(vectStartInv, line.start); + mat.transformVect(vectEndInv, line.end); + } + core::line3d invline(vectStartInv, vectEndInv); + + mat.makeIdentity(); + + if (transform) + mat = (*transform); + + if (SceneNode) + mat *= SceneNode->getAbsoluteTransformation(); + + s32 trianglesWritten = 0; + + if (Root) + getTrianglesFromOctree(Root, trianglesWritten, arraySize, invline, &mat, triangles); + + outTriangleCount = trianglesWritten; +#endif +} + +void COctreeTriangleSelector::getTrianglesFromOctree(SOctreeNode* node, + s32& trianglesWritten, s32 maximumSize, const core::line3d& line, + const core::matrix4* transform, core::triangle3df* triangles) const +{ + if (!node->Box.intersectsWithLine(line)) + return; + + s32 cnt = node->Triangles.size(); + if (cnt + trianglesWritten > maximumSize) + cnt -= cnt + trianglesWritten - maximumSize; + + s32 i; + + if ( transform->isIdentity() ) + { + for (i=0; iTriangles[i]; + ++trianglesWritten; + } + } + else + { + for (i=0; iTriangles[i]; + transform->transformVect(triangles[trianglesWritten].pointA); + transform->transformVect(triangles[trianglesWritten].pointB); + transform->transformVect(triangles[trianglesWritten].pointC); + ++trianglesWritten; + } + } + + for (i=0; i<8; ++i) + if (node->Child[i]) + getTrianglesFromOctree(node->Child[i], trianglesWritten, + maximumSize, line, transform, triangles); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.h new file mode 100644 index 0000000..2445467 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COctreeTriangleSelector.h @@ -0,0 +1,80 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OCTREE_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __C_OCTREE_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "CTriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +class ISceneNode; + +//! Stupid triangle selector without optimization +class COctreeTriangleSelector : public CTriangleSelector +{ +public: + + //! Constructs a selector based on a mesh + COctreeTriangleSelector(const IMesh* mesh, ISceneNode* node, s32 minimalPolysPerNode); + + virtual ~COctreeTriangleSelector(); + + //! Gets all triangles which lie within a specific bounding box. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + +private: + + struct SOctreeNode + { + SOctreeNode() + { + for (u32 i=0; i!=8; ++i) + Child[i] = 0; + } + + ~SOctreeNode() + { + for (u32 i=0; i!=8; ++i) + delete Child[i]; + } + + core::array Triangles; + SOctreeNode* Child[8]; + core::aabbox3d Box; + }; + + + void constructOctree(SOctreeNode* node); + void deleteEmptyNodes(SOctreeNode* node); + void getTrianglesFromOctree(SOctreeNode* node, s32& trianglesWritten, + s32 maximumSize, const core::aabbox3d& box, + const core::matrix4* transform, + core::triangle3df* triangles) const; + + void getTrianglesFromOctree(SOctreeNode* node, s32& trianglesWritten, + s32 maximumSize, const core::line3d& line, + const core::matrix4* transform, + core::triangle3df* triangles) const; + + SOctreeNode* Root; + s32 NodeCount; + s32 MinimalPolysPerNode; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COgreMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COgreMeshFileLoader.cpp new file mode 100644 index 0000000..7a2be26 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COgreMeshFileLoader.cpp @@ -0,0 +1,1592 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// orginally written by Christian Stehno, modified by Nikolaus Gebhardt + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ + +#include "COgreMeshFileLoader.h" +#include "os.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "fast_atof.h" +#include "coreutil.h" + +#ifdef _DEBUG +#define IRR_OGRE_LOADER_DEBUG +#endif + +namespace irr +{ +namespace scene +{ + +namespace +{ + enum OGRE_CHUNKS + { + // Main Chunks + COGRE_HEADER= 0x1000, + COGRE_SKELETON= 0x2000, + COGRE_MESH= 0x3000, + + // sub chunks of COGRE_MESH + COGRE_SUBMESH= 0x4000, + COGRE_GEOMETRY= 0x5000, + COGRE_SKELETON_LINK= 0x6000, + COGRE_BONE_ASSIGNMENT= 0x7000, + COGRE_MESH_LOD= 0x8000, + COGRE_MESH_BOUNDS= 0x9000, + COGRE_MESH_SUBMESH_NAME_TABLE= 0xA000, + COGRE_MESH_EDGE_LISTS= 0xB000, + + // sub chunks of COGRE_SKELETON + COGRE_BONE_PARENT= 0x3000, + COGRE_ANIMATION= 0x4000, + COGRE_ANIMATION_TRACK= 0x4100, + COGRE_ANIMATION_KEYFRAME= 0x4110, + COGRE_ANIMATION_LINK= 0x5000, + + // sub chunks of COGRE_SUBMESH + COGRE_SUBMESH_OPERATION= 0x4010, + COGRE_SUBMESH_BONE_ASSIGNMENT= 0x4100, + COGRE_SUBMESH_TEXTURE_ALIAS= 0x4200, + + // sub chunks of COGRE_GEOMETRY + COGRE_GEOMETRY_VERTEX_DECLARATION= 0x5100, + COGRE_GEOMETRY_VERTEX_ELEMENT= 0x5110, + COGRE_GEOMETRY_VERTEX_BUFFER= 0x5200, + COGRE_GEOMETRY_VERTEX_BUFFER_DATA= 0x5210 + }; +} + +//! Constructor +COgreMeshFileLoader::COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver) +: FileSystem(fs), Driver(driver), SwapEndian(false), Mesh(0), NumUV(0) +{ + + #ifdef _DEBUG + setDebugName("COgreMeshFileLoader"); + #endif + + if (FileSystem) + FileSystem->grab(); + + if (Driver) + Driver->grab(); +} + + +//! destructor +COgreMeshFileLoader::~COgreMeshFileLoader() +{ + clearMeshes(); + + if (FileSystem) + FileSystem->drop(); + + if (Driver) + Driver->drop(); + + if (Mesh) + Mesh->drop(); +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool COgreMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "mesh" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* COgreMeshFileLoader::createMesh(io::IReadFile* file) +{ + s16 id; + + file->read(&id, 2); + + if (id == COGRE_HEADER) + SwapEndian=false; + else if (id == 0x0010) + SwapEndian=true; + else + return 0; + ChunkData data; + readString(file, data, Version); + if ((Version != "[MeshSerializer_v1.30]") && (Version != "[MeshSerializer_v1.40]") && (Version != "[MeshSerializer_v1.41]")) + return 0; + + clearMeshes(); + if (Mesh) + Mesh->drop(); + + CurrentlyLoadingFromPath = FileSystem->getFileDir(file->getFileName()); + loadMaterials(file); + + if (readChunk(file)) + { + // delete data loaded from file + clearMeshes(); + + if (Skeleton.Bones.size()) + { + ISkinnedMesh* tmp = static_cast(Mesh); + static_cast(Mesh)->updateBoundingBox(); + Skeleton.Animations.clear(); + Skeleton.Bones.clear(); + Mesh=0; + return tmp; + } + else + { + for (u32 i=0; igetMeshBufferCount(); ++i) + ((SMeshBuffer*)Mesh->getMeshBuffer(i))->recalculateBoundingBox(); + + ((SMesh*)Mesh)->recalculateBoundingBox(); + SAnimatedMesh* am = new SAnimatedMesh(); + am->Type = EAMT_3DS; + am->addMesh(Mesh); + am->recalculateBoundingBox(); + Mesh->drop(); + Mesh = 0; + return am; + } + } + + Mesh->drop(); + Mesh = 0; + + return 0; +} + + +bool COgreMeshFileLoader::readChunk(io::IReadFile* file) +{ + while(file->getPos() < file->getSize()) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_MESH: + { + Meshes.push_back(OgreMesh()); + readObjectChunk(file, data, Meshes.getLast()); + if (Skeleton.Bones.size()) + Mesh = new CSkinnedMesh(); + else + Mesh = new SMesh(); + composeObject(); + } + break; + default: + return true; + } + } + + return true; +} + + +bool COgreMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Object Chunk", ELL_DEBUG); +#endif + readBool(file, parent, mesh.SkeletalAnimation); + bool skeleton_loaded=false; + while ((parent.read < parent.header.length)&&(file->getPos() < file->getSize())) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_GEOMETRY: + readGeometry(file, data, mesh.Geometry); + break; + case COGRE_SUBMESH: + mesh.SubMeshes.push_back(OgreSubMesh()); + readSubMesh(file, data, mesh.SubMeshes.getLast()); + break; + case COGRE_MESH_BOUNDS: + { +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Mesh Bounds", ELL_DEBUG); +#endif + readVector(file, data, mesh.BBoxMinEdge); + readVector(file, data, mesh.BBoxMaxEdge); + readFloat(file, data, &mesh.BBoxRadius); + } + break; + case COGRE_SKELETON_LINK: + { +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Skeleton link", ELL_DEBUG); +#endif + core::stringc name; + readString(file, data, name); + loadSkeleton(file, name); + skeleton_loaded=true; + } + break; + case COGRE_BONE_ASSIGNMENT: + { + mesh.BoneAssignments.push_back(OgreBoneAssignment()); + readInt(file, data, &mesh.BoneAssignments.getLast().VertexID); + readShort(file, data, &mesh.BoneAssignments.getLast().BoneID); + readFloat(file, data, &mesh.BoneAssignments.getLast().Weight); + } + break; + case COGRE_MESH_LOD: + case COGRE_MESH_SUBMESH_NAME_TABLE: + case COGRE_MESH_EDGE_LISTS: + // ignore chunk + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + break; + default: +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG); +#endif + // ignore chunk + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + break; + } + parent.read += data.read; + } + if (!skeleton_loaded) + loadSkeleton(file, FileSystem->getFileBasename(file->getFileName(), false)); + return true; +} + + +bool COgreMeshFileLoader::readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Geometry", ELL_DEBUG); +#endif + readInt(file, parent, &geometry.NumVertex); + while(parent.read < parent.header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_GEOMETRY_VERTEX_DECLARATION: + readVertexDeclaration(file, data, geometry); + break; + case COGRE_GEOMETRY_VERTEX_BUFFER: + readVertexBuffer(file, data, geometry); + break; + default: + // ignore chunk +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Skipping", core::stringc(data.header.id), ELL_DEBUG); +#endif + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + } + parent.read += data.read; + } + if (parent.read != parent.header.length) + os::Printer::log("Incorrect geometry length. File might be corrupted."); + return true; +} + + +bool COgreMeshFileLoader::readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Vertex Declaration", ELL_DEBUG); +#endif + NumUV = 0; + while(parent.read < parent.header.length) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_GEOMETRY_VERTEX_ELEMENT: + { + geometry.Elements.push_back(OgreVertexElement()); + OgreVertexElement& elem = geometry.Elements.getLast(); + readShort(file, data, &elem.Source); + readShort(file, data, &elem.Type); + readShort(file, data, &elem.Semantic); + if (elem.Semantic == 7) //Tex coords + { + ++NumUV; + } + readShort(file, data, &elem.Offset); + elem.Offset /= sizeof(f32); + readShort(file, data, &elem.Index); + } + break; + default: + // ignore chunk + file->seek(data.header.length-data.read, true); + data.read += data.header.length-data.read; + } + parent.read += data.read; + } + if (parent.read != parent.header.length) + os::Printer::log("Incorrect vertex declaration length. File might be corrupted."); + return true; +} + + +bool COgreMeshFileLoader::readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Vertex Buffer", ELL_DEBUG); +#endif + OgreVertexBuffer buf; + readShort(file, parent, &buf.BindIndex); + readShort(file, parent, &buf.VertexSize); + buf.VertexSize /= sizeof(f32); + ChunkData data; + readChunkData(file, data); + + if (data.header.id == COGRE_GEOMETRY_VERTEX_BUFFER_DATA) + { + buf.Data.set_used(geometry.NumVertex*buf.VertexSize); + readFloat(file, data, buf.Data.pointer(), geometry.NumVertex*buf.VertexSize); + } + + geometry.Buffers.push_back(buf); + parent.read += data.read; + if (parent.read != parent.header.length) + os::Printer::log("Incorrect vertex buffer length. File might be corrupted."); + return true; +} + + +bool COgreMeshFileLoader::readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Submesh", ELL_DEBUG); +#endif + readString(file, parent, subMesh.Material); +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("using material", subMesh.Material, ELL_DEBUG); +#endif + readBool(file, parent, subMesh.SharedVertices); + + s32 numIndices; + readInt(file, parent, &numIndices); + subMesh.Indices.set_used(numIndices); + + readBool(file, parent, subMesh.Indices32Bit); + + if (subMesh.Indices32Bit) + readInt(file, parent, subMesh.Indices.pointer(), numIndices); + else + { + for (s32 i=0; iseek(-(long)sizeof(ChunkHeader), true); + return true; + } + parent.read += data.read; + } + if (parent.read != parent.header.length) + os::Printer::log("Incorrect submesh length. File might be corrupted."); +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Done with submesh", ELL_DEBUG); +#endif + return true; +} + + +void COgreMeshFileLoader::composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName) +{ + video::SMaterial& material=mb->getMaterial(); + for (u32 k=0; kexistFile(Materials[k].Techniques[0].Passes[0].Texture.Filename[i])) + material.setTexture(i, Driver->getTexture(Materials[k].Techniques[0].Passes[0].Texture.Filename[i])); + else + material.setTexture(i, Driver->getTexture((CurrentlyLoadingFromPath+"/"+FileSystem->getFileBasename(Materials[k].Techniques[0].Passes[0].Texture.Filename[i])))); + } + break; + } + } +} + + +scene::SMeshBuffer* COgreMeshFileLoader::composeMeshBuffer(const core::array& indices, const OgreGeometry& geom) +{ + scene::SMeshBuffer *mb=new scene::SMeshBuffer(); + + u32 i; + mb->Indices.set_used(indices.size()); + for (i=0; iIndices[i]=indices[i]; + + mb->Vertices.set_used(geom.NumVertex); + for (i=0; iVertices[k].Color=mb->Material.DiffuseColor; + mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==4) //Normal + { + for (u32 j=0; jVertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==7) //TexCoord + { + for (u32 j=0; jVertices[k].TCoords.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1]); + ePos += eSize; + } + } + } + } + } + return mb; +} + + +scene::SMeshBufferLightMap* COgreMeshFileLoader::composeMeshBufferLightMap(const core::array& indices, const OgreGeometry& geom) +{ + scene::SMeshBufferLightMap *mb=new scene::SMeshBufferLightMap(); + + u32 i; + mb->Indices.set_used(indices.size()); + for (i=0; iIndices[i]=indices[i]; + + mb->Vertices.set_used(geom.NumVertex); + + for (i=0; iVertices[k].Color=mb->Material.DiffuseColor; + mb->Vertices[k].Pos.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==4) //Normal + { + for (u32 j=0; jVertices[k].Normal.set(geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==7) //TexCoord + { + for (u32 j=0; jePos+3); + for (s32 k=0; kVertices[k].TCoords.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); + if (secondCoord) + mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]); + else + mb->Vertices[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); + ePos += eSize; + } + } + } + } + } + + return mb; +} + + +scene::IMeshBuffer* COgreMeshFileLoader::composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array& indices, const OgreGeometry& geom) +{ + scene::SSkinMeshBuffer *mb=mesh.addMeshBuffer(); + if (NumUV>1) + { + mb->convertTo2TCoords(); + mb->Vertices_2TCoords.set_used(geom.NumVertex); + } + else + mb->Vertices_Standard.set_used(geom.NumVertex); + + u32 i; + mb->Indices.set_used(indices.size()); + for (i=0; iIndices[i+0]=indices[i+2]; + mb->Indices[i+1]=indices[i+1]; + mb->Indices[i+2]=indices[i+0]; + } + + for (i=0; i1) + mb->Vertices_2TCoords[k].Color=mb->Material.DiffuseColor; + else + mb->Vertices_Standard[k].Color=mb->Material.DiffuseColor; + mb->getPosition(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==4) //Normal + { + for (u32 j=0; jgetNormal(k).set(-geom.Buffers[j].Data[ePos],geom.Buffers[j].Data[ePos+1],geom.Buffers[j].Data[ePos+2]); + ePos += eSize; + } + } + } + } + + if (geom.Elements[i].Semantic==7) //TexCoord + { + for (u32 j=0; jePos+3); + for (s32 k=0; kgetTCoords(k).set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); + if (NumUV>1) + { + if (secondCoord) + mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos+2], geom.Buffers[j].Data[ePos+3]); + else + mb->Vertices_2TCoords[k].TCoords2.set(geom.Buffers[j].Data[ePos], geom.Buffers[j].Data[ePos+1]); + } + ePos += eSize; + } + } + } + } + } + + return mb; +} + + +void COgreMeshFileLoader::composeObject(void) +{ + for (u32 i=0; iaddMeshBuffer(mb); + mb->drop(); + } + } + } + } + if (Skeleton.Bones.size()) + { + CSkinnedMesh* m = (CSkinnedMesh*)Mesh; + // Create Joints + for (u32 i=0; iaddJoint(); + joint->Name=Skeleton.Bones[i].Name; + + // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility. + // Not tested so far if this was correct or wrong before quaternion fix! + Skeleton.Bones[i].Orientation.getMatrix_transposed(joint->LocalMatrix); + + if (Skeleton.Bones[i].Scale != core::vector3df(1,1,1)) + { + core::matrix4 scaleMatrix; + scaleMatrix.setScale( Skeleton.Bones[i].Scale ); + joint->LocalMatrix *= scaleMatrix; + } + joint->LocalMatrix.setTranslation( Skeleton.Bones[i].Position ); + } + // Joints hierarchy + for (u32 i=0; igetJointCount()) + { + m->getAllJoints()[Skeleton.Bones[i].Parent]->Children.push_back(m->getAllJoints()[Skeleton.Bones[i].Handle]); + } + } + + // Weights + u32 bufCount=0; + for (u32 i=0; igetJointCount()) + { + ISkinnedMesh::SWeight* w = m->addWeight(m->getAllJoints()[ba.BoneID]); + w->strength=ba.Weight; + w->vertex_id=ba.VertexID; + w->buffer_id=bufCount; + } + } + ++bufCount; + } + } + + for (u32 i=0; igetAllJoints()[frame.BoneID]; + ISkinnedMesh::SPositionKey* poskey = m->addPositionKey(keyjoint); + poskey->frame=frame.Time*25; + poskey->position=keyjoint->LocalMatrix.getTranslation()+frame.Position; + ISkinnedMesh::SRotationKey* rotkey = m->addRotationKey(keyjoint); + rotkey->frame=frame.Time*25; + + // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from keyjoint->LocalMatrix to keyjoint->LocalMatrix.getTransposed() for downward compatibility. + // Not tested so far if this was correct or wrong before quaternion fix! + rotkey->rotation=core::quaternion(keyjoint->LocalMatrix.getTransposed())*frame.Orientation; + + ISkinnedMesh::SScaleKey* scalekey = m->addScaleKey(keyjoint); + scalekey->frame=frame.Time*25; + scalekey->scale=frame.Scale; + } + } + m->finalize(); + } +} + + +void COgreMeshFileLoader::getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine) +{ + bool parseString=false; + c8 c=0; + token = ""; + + if (file->getPos() >= file->getSize()) + return; + + file->read(&c, sizeof(c8)); + // search for word beginning + while ( core::isspace(c) && (file->getPos() < file->getSize())) + { + if (noNewLine && c=='\n') + { + file->seek(-1, true); + return; + } + file->read(&c, sizeof(c8)); + } + // check if we read a string + if (c=='"') + { + parseString = true; + file->read(&c, sizeof(c8)); + } + do + { + if (c=='/') + { + file->read(&c, sizeof(c8)); + // check for comments, cannot be part of strings + if (!parseString && (c=='/')) + { + // skip comments + while(c!='\n') + file->read(&c, sizeof(c8)); + if (!token.size()) + { + // if we start with a comment we need to skip + // following whitespaces, so restart + getMaterialToken(file, token, noNewLine); + return; + } + else + { + // else continue with next character + file->read(&c, sizeof(c8)); + continue; + } + } + else + { + // else append first slash and check if second char + // ends this token + token.append('/'); + if ((!parseString && core::isspace(c)) || + (parseString && (c=='"'))) + return; + } + } + token.append(c); + file->read(&c, sizeof(c8)); + // read until a token delimiter is found + } + while (((!parseString && !core::isspace(c)) || (parseString && (c!='"'))) && + (file->getPos() < file->getSize())); + // we want to skip the last quotes of a string , but other chars might be the next + // token already. + if (!parseString) + file->seek(-1, true); +} + + +bool COgreMeshFileLoader::readColor(io::IReadFile* file, video::SColor& col) +{ + core::stringc token; + + getMaterialToken(file, token); + if (token!="vertexcolour") + { + video::SColorf col_f; + col_f.r=core::fast_atof(token.c_str()); + getMaterialToken(file, token); + col_f.g=core::fast_atof(token.c_str()); + getMaterialToken(file, token); + col_f.b=core::fast_atof(token.c_str()); + getMaterialToken(file, token, true); + if (token.size()) + col_f.a=core::fast_atof(token.c_str()); + else + col_f.a=1.0f; + if ((col_f.r==0.0f)&&(col_f.g==0.0f)&&(col_f.b==0.0f)) + col.set(255,255,255,255); + else + col=col_f.toSColor(); + return false; + } + return true; +} + + +void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Pass"); +#endif + core::stringc token; + technique.Passes.push_back(OgrePass()); + OgrePass& pass=technique.Passes.getLast(); + + getMaterialToken(file, token); //open brace or name + if (token != "{") + getMaterialToken(file, token); //open brace + + getMaterialToken(file, token); + if (token == "}") + return; + u32 inBlocks=1; + u32 textureUnit=0; + while(inBlocks) + { + if (token=="ambient") + pass.AmbientTokenColor=readColor(file, pass.Material.AmbientColor); + else if (token=="diffuse") + pass.DiffuseTokenColor=readColor(file, pass.Material.DiffuseColor); + else if (token=="specular") + { + pass.SpecularTokenColor=readColor(file, pass.Material.SpecularColor); + getMaterialToken(file, token); + pass.Material.Shininess=core::fast_atof(token.c_str()); + } + else if (token=="emissive") + pass.EmissiveTokenColor=readColor(file, pass.Material.EmissiveColor); + else if (token=="scene_blend") + { // TODO: Choose correct values + getMaterialToken(file, token); + if (token=="add") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + else if (token=="modulate") + pass.Material.MaterialType=video::EMT_SOLID; + else if (token=="alpha_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else if (token=="colour_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + else + getMaterialToken(file, token); + } + else if (token=="depth_check") + { + getMaterialToken(file, token); + if (token!="on") + pass.Material.ZBuffer=video::ECFN_NEVER; + } + else if (token=="depth_write") + { + getMaterialToken(file, token); + pass.Material.ZWriteEnable=(token=="on"); + } + else if (token=="depth_func") + { + getMaterialToken(file, token); // Function name + if (token=="always_fail") + pass.Material.ZBuffer=video::ECFN_NEVER; + else if (token=="always_pass") + pass.Material.ZBuffer=video::ECFN_ALWAYS; + else if (token=="equal") + pass.Material.ZBuffer=video::ECFN_EQUAL; + else if (token=="greater") + pass.Material.ZBuffer=video::ECFN_GREATER; + else if (token=="greater_equal") + pass.Material.ZBuffer=video::ECFN_GREATEREQUAL; + else if (token=="less") + pass.Material.ZBuffer=video::ECFN_LESS; + else if (token=="less_equal") + pass.Material.ZBuffer=video::ECFN_LESSEQUAL; + else if (token=="not_equal") + pass.Material.ZBuffer=video::ECFN_NOTEQUAL; + } + else if (token=="normalise_normals") + { + getMaterialToken(file, token); + pass.Material.NormalizeNormals=(token=="on"); + } + else if (token=="depth_bias") + { + getMaterialToken(file, token); // bias value + } + else if (token=="alpha_rejection") + { + getMaterialToken(file, token); // function name + getMaterialToken(file, token); // value + pass.Material.MaterialTypeParam=core::fast_atof(token.c_str()); + } + else if (token=="alpha_to_coverage") + { + getMaterialToken(file, token); + if (token=="on") + pass.Material.AntiAliasing |= video::EAAM_ALPHA_TO_COVERAGE; + } + else if (token=="colour_write") + { + getMaterialToken(file, token); + pass.Material.ColorMask = (token=="on")?video::ECP_ALL:video::ECP_NONE; + } + else if (token=="cull_hardware") + { + getMaterialToken(file, token); // rotation name + } + else if (token=="cull_software") + { + getMaterialToken(file, token); // culling side + } + else if (token=="lighting") + { + getMaterialToken(file, token); + pass.Material.Lighting=(token=="on"); + } + else if (token=="shading") + { + getMaterialToken(file, token); + // We take phong as gouraud + pass.Material.GouraudShading=(token!="flat"); + } + else if (token=="polygon_mode") + { + getMaterialToken(file, token); + pass.Material.Wireframe=(token=="wireframe"); + pass.Material.PointCloud=(token=="points"); + } + else if (token=="max_lights") + { + getMaterialToken(file, token); + pass.MaxLights=core::strtoul10(token.c_str()); + } + else if (token=="point_size") + { + getMaterialToken(file, token); + pass.PointSize=core::fast_atof(token.c_str()); + } + else if (token=="point_sprites") + { + getMaterialToken(file, token); + pass.PointSprites=(token=="on"); + } + else if (token=="point_size_min") + { + getMaterialToken(file, token); + pass.PointSizeMin=core::strtoul10(token.c_str()); + } + else if (token=="point_size_max") + { + getMaterialToken(file, token); + pass.PointSizeMax=core::strtoul10(token.c_str()); + } + else if (token=="texture_unit") + { +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Texture unit", ELL_DEBUG); +#endif + getMaterialToken(file, token); //open brace + getMaterialToken(file, token); + while(token != "}") + { + if (token=="texture") + { + getMaterialToken(file, token); + pass.Texture.Filename.push_back(token); +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Texture", token, ELL_DEBUG); +#endif + getMaterialToken(file, pass.Texture.CoordsType, true); + getMaterialToken(file, pass.Texture.MipMaps, true); + getMaterialToken(file, pass.Texture.Alpha, true); + // Hmm, we might need more hints for other material types using two textures... + if (textureUnit>0) + pass.Material.MaterialType=video::EMT_LIGHTMAP; + } + else if (token=="filtering") + { + getMaterialToken(file, token); + pass.Material.TextureLayer[textureUnit].AnisotropicFilter=0; + if (token=="point") + { + pass.Material.TextureLayer[textureUnit].BilinearFilter=false; + pass.Material.TextureLayer[textureUnit].TrilinearFilter=false; + getMaterialToken(file, token); + getMaterialToken(file, token); + } + else if (token=="linear") + { + getMaterialToken(file, token); + if (token=="point") + { + pass.Material.TextureLayer[textureUnit].BilinearFilter=false; + pass.Material.TextureLayer[textureUnit].TrilinearFilter=false; + getMaterialToken(file, token); + } + else + { + pass.Material.TextureLayer[textureUnit].BilinearFilter=true; + getMaterialToken(file, token); + pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="linear"); + } + } + else + { + pass.Material.TextureLayer[textureUnit].BilinearFilter=(token=="bilinear"); + pass.Material.TextureLayer[textureUnit].TrilinearFilter=(token=="trilinear"); + pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(token=="anisotropic")?2:1; + } + } + else if (token=="max_anisotropy") + { + getMaterialToken(file, token); + pass.Material.TextureLayer[textureUnit].AnisotropicFilter=(u8)core::strtoul10(token.c_str()); + } + else if (token=="texture_alias") + { + getMaterialToken(file, pass.Texture.Alias); + } + else if (token=="mipmap_bias") + { + getMaterialToken(file, token); + pass.Material.TextureLayer[textureUnit].LODBias=(s8)core::fast_atof(token.c_str()); + } + else if (token=="colour_op") + { // TODO: Choose correct values + getMaterialToken(file, token); + if (token=="add") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ADD_COLOR; + else if (token=="modulate") + pass.Material.MaterialType=video::EMT_SOLID; + else if (token=="alpha_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else if (token=="colour_blend") + pass.Material.MaterialType=video::EMT_TRANSPARENT_VERTEX_ALPHA; + else + getMaterialToken(file, token); + } + getMaterialToken(file, token); + } + ++textureUnit; + } + else if (token=="shadow_caster_program_ref") + { + do + { + getMaterialToken(file, token); + } while (token != "}"); + } + else if (token=="shadow_caster_vertex_program_ref") + { + do + { + getMaterialToken(file, token); + } while (token != "}"); + } + else if (token=="vertex_program_ref") + { + do + { + getMaterialToken(file, token); + } while (token != "}"); + } + //fog_override, iteration, point_size_attenuation + //not considered yet! + getMaterialToken(file, token); + if (token=="{") + ++inBlocks; + else if (token=="}") + --inBlocks; + } +} + + +void COgreMeshFileLoader::readTechnique(io::IReadFile* file, OgreMaterial& mat) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Read Technique"); +#endif + core::stringc token; + mat.Techniques.push_back(OgreTechnique()); + OgreTechnique& technique=mat.Techniques.getLast(); + + getMaterialToken(file, technique.Name); //open brace or name + if (technique.Name != "{") + getMaterialToken(file, token); //open brace + else + technique.Name=core::stringc((int)mat.Techniques.size()); + + getMaterialToken(file, token); + while (token != "}") + { + if (token == "pass") + readPass(file, technique); + else if (token == "scheme") + getMaterialToken(file, token); + else if (token == "lod_index") + getMaterialToken(file, token); + getMaterialToken(file, token); + } +} + + +void COgreMeshFileLoader::loadMaterials(io::IReadFile* meshFile) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Load Materials", ELL_DEBUG); +#endif + core::stringc token; + io::IReadFile* file = 0; + io::path filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".material"; + if (FileSystem->existFile(filename)) + file = FileSystem->createAndOpenFile(filename); + else + file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename); + + if (!file) + { + os::Printer::log("Could not load OGRE material", filename); + return; + } + + getMaterialToken(file, token); + + while (file->getPos() < file->getSize()) + { + if ((token == "fragment_program") || (token == "vertex_program")) + { + // skip whole block + u32 blocks=1; + do + { + getMaterialToken(file, token); + } while (token != "{"); + do + { + getMaterialToken(file, token); + if (token == "{") + ++blocks; + else if (token == "}") + --blocks; + } while (blocks); + getMaterialToken(file, token); + continue; + } + if (token != "material") + { + if (token.trim().size()) + os::Printer::log("Unknown material group", token.c_str()); + break; + } + + Materials.push_back(OgreMaterial()); + OgreMaterial& mat = Materials.getLast(); + + getMaterialToken(file, mat.Name); +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Load Material", mat.Name.c_str(), ELL_DEBUG); +#endif + getMaterialToken(file, token); //open brace + getMaterialToken(file, token); + while(token != "}") + { + if (token=="lod_distances") // can have several items + getMaterialToken(file, token); + else if (token=="receive_shadows") + { + getMaterialToken(file, token); + mat.ReceiveShadows=(token=="on"); + } + else if (token=="transparency_casts_shadows") + { + getMaterialToken(file, token); + mat.TransparencyCastsShadows=(token=="on"); + } + else if (token=="set_texture_alias") + { + getMaterialToken(file, token); + getMaterialToken(file, token); + } + else if (token=="technique") + readTechnique(file, mat); + getMaterialToken(file, token); + } + getMaterialToken(file, token); + } + + file->drop(); +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Finished loading Materials", ELL_DEBUG); +#endif +} + + +bool COgreMeshFileLoader::loadSkeleton(io::IReadFile* meshFile, const core::stringc& name) +{ +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Load Skeleton", name, ELL_DEBUG); +#endif + io::IReadFile* file = 0; + io::path filename; + if (FileSystem->existFile(name)) + file = FileSystem->createAndOpenFile(name); + else if (FileSystem->existFile(filename = FileSystem->getFileDir(meshFile->getFileName())+"/"+name)) + file = FileSystem->createAndOpenFile(filename); + else if (FileSystem->existFile(filename = FileSystem->getFileBasename(meshFile->getFileName(), false) + ".skeleton")) + file = FileSystem->createAndOpenFile(filename); + else + file = FileSystem->createAndOpenFile(FileSystem->getFileDir(meshFile->getFileName())+"/"+filename); + if (!file) + { + os::Printer::log("Could not load matching skeleton", name); + return false; + } + + s16 id; + file->read(&id, 2); + if (SwapEndian) + id = os::Byteswap::byteswap(id); + if (id != COGRE_HEADER) + { + file->drop(); + return false; + } + + core::stringc skeletonVersion; + ChunkData head; + readString(file, head, skeletonVersion); + if (skeletonVersion != "[Serializer_v1.10]") + { + file->drop(); + return false; + } + + u16 bone=0; + f32 animationTotal=0.f; + while(file->getPos() < file->getSize()) + { + ChunkData data; + readChunkData(file, data); + + switch(data.header.id) + { + case COGRE_SKELETON: + { + Skeleton.Bones.push_back(OgreBone()); + OgreBone& bone = Skeleton.Bones.getLast(); + readString(file, data, bone.Name); + readShort(file, data, &bone.Handle); + readVector(file, data, bone.Position); + readQuaternion(file, data, bone.Orientation); +#ifdef IRR_OGRE_LOADER_DEBUG + os::Printer::log("Bone", bone.Name+" ("+core::stringc(bone.Handle)+")", ELL_DEBUG); + os::Printer::log("Position", core::stringc(bone.Position.X)+" "+core::stringc(bone.Position.Y)+" "+core::stringc(bone.Position.Z), ELL_DEBUG); + os::Printer::log("Rotation quat", core::stringc(bone.Orientation.W)+" "+core::stringc(bone.Orientation.X)+" "+core::stringc(bone.Orientation.Y)+" "+core::stringc(bone.Orientation.Z), ELL_DEBUG); +// core::vector3df rot; +// bone.Orientation.toEuler(rot); +// rot *= core::RADTODEG; +// os::Printer::log("Rotation", core::stringc(rot.X)+" "+core::stringc(rot.Y)+" "+core::stringc(rot.Z)); +#endif + if (data.read<(data.header.length-bone.Name.size())) + { + readVector(file, data, bone.Scale); + bone.Scale.X *= -1.f; + } + else + bone.Scale=core::vector3df(1,1,1); + bone.Parent=0xffff; + } + break; + case COGRE_BONE_PARENT: + { + u16 parent; + readShort(file, data, &bone); + readShort(file, data, &parent); + if (bonedrop(); + return true; +} + + +void COgreMeshFileLoader::readChunkData(io::IReadFile* file, ChunkData& data) +{ + file->read(&data.header, sizeof(ChunkHeader)); + if (SwapEndian) + { + data.header.id = os::Byteswap::byteswap(data.header.id); + data.header.length = os::Byteswap::byteswap(data.header.length); + } + data.read += sizeof(ChunkHeader); +} + + +void COgreMeshFileLoader::readString(io::IReadFile* file, ChunkData& data, core::stringc& out) +{ + c8 c = 0; + out = ""; + + while (c!='\n') + { + file->read(&c, sizeof(c8)); + if (c!='\n') + out.append(c); + + } + data.read+=out.size()+1; +} + + +void COgreMeshFileLoader::readBool(io::IReadFile* file, ChunkData& data, bool& out) +{ + // normal C type because we read a bit string + char c = 0; + file->read(&c, sizeof(char)); + out=(c!=0); + ++data.read; +} + + +void COgreMeshFileLoader::readInt(io::IReadFile* file, ChunkData& data, s32* out, u32 num) +{ + // normal C type because we read a bit string + file->read(out, sizeof(int)*num); + if (SwapEndian) + { + for (u32 i=0; iread(out, sizeof(short)*num); + if (SwapEndian) + { + for (u32 i=0; iread(out, sizeof(float)*num); + if (SwapEndian) + { + for (u32 i=0; i Filename; + core::stringc Alias; + core::stringc CoordsType; + core::stringc MipMaps; + core::stringc Alpha; + }; + + struct OgrePass + { + OgrePass() : AmbientTokenColor(false), + DiffuseTokenColor(false), SpecularTokenColor(false), + EmissiveTokenColor(false), + MaxLights(8), PointSize(1.0f), PointSprites(false), + PointSizeMin(0), PointSizeMax(0) {} + + video::SMaterial Material; + OgreTexture Texture; + bool AmbientTokenColor; + bool DiffuseTokenColor; + bool SpecularTokenColor; + bool EmissiveTokenColor; + u32 MaxLights; + f32 PointSize; + bool PointSprites; + u32 PointSizeMin; + u32 PointSizeMax; + }; + + struct OgreTechnique + { + OgreTechnique() : Name(""), LODIndex(0) {} + + core::stringc Name; + core::stringc Scheme; + u16 LODIndex; + core::array Passes; + }; + + struct OgreMaterial + { + OgreMaterial() : Name(""), ReceiveShadows(true), + TransparencyCastsShadows(false) {} + + core::stringc Name; + bool ReceiveShadows; + bool TransparencyCastsShadows; + core::array LODDistances; + core::array Techniques; + }; + + struct OgreVertexBuffer + { + OgreVertexBuffer() : BindIndex(0), VertexSize(0), Data(0) {} + + u16 BindIndex; + u16 VertexSize; + core::array Data; + }; + + struct OgreVertexElement + { + u16 Source, + Type, + Semantic, + Offset, + Index; + }; + + struct OgreGeometry + { + s32 NumVertex; + core::array Elements; + core::array Buffers; + core::array Vertices; + core::array Normals; + core::array Colors; + core::array TexCoords; + }; + + struct OgreTextureAlias + { + OgreTextureAlias() {}; + OgreTextureAlias(const core::stringc& a, const core::stringc& b) : Texture(a), Alias(b) {}; + core::stringc Texture; + core::stringc Alias; + }; + + struct OgreBoneAssignment + { + s32 VertexID; + u16 BoneID; + f32 Weight; + }; + + struct OgreSubMesh + { + core::stringc Material; + bool SharedVertices; + core::array Indices; + OgreGeometry Geometry; + u16 Operation; + core::array TextureAliases; + core::array BoneAssignments; + bool Indices32Bit; + }; + + struct OgreMesh + { + bool SkeletalAnimation; + OgreGeometry Geometry; + core::array SubMeshes; + core::array BoneAssignments; + core::vector3df BBoxMinEdge; + core::vector3df BBoxMaxEdge; + f32 BBoxRadius; + }; + + struct OgreBone + { + core::stringc Name; + core::vector3df Position; + core::quaternion Orientation; + core::vector3df Scale; + u16 Handle; + u16 Parent; + }; + + struct OgreKeyframe + { + u16 BoneID; + f32 Time; + core::vector3df Position; + core::quaternion Orientation; + core::vector3df Scale; + }; + + struct OgreAnimation + { + core::stringc Name; + f32 Length; + core::array Keyframes; + }; + + struct OgreSkeleton + { + core::array Bones; + core::array Animations; + }; + + bool readChunk(io::IReadFile* file); + bool readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh); + bool readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry); + bool readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry); + bool readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry); + bool readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh); + + void readChunkData(io::IReadFile* file, ChunkData& data); + void readString(io::IReadFile* file, ChunkData& data, core::stringc& out); + void readBool(io::IReadFile* file, ChunkData& data, bool& out); + void readInt(io::IReadFile* file, ChunkData& data, s32* out, u32 num=1); + void readShort(io::IReadFile* file, ChunkData& data, u16* out, u32 num=1); + void readFloat(io::IReadFile* file, ChunkData& data, f32* out, u32 num=1); + void readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out); + void readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out); + + void composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName); + scene::SMeshBuffer* composeMeshBuffer(const core::array& indices, const OgreGeometry& geom); + scene::SMeshBufferLightMap* composeMeshBufferLightMap(const core::array& indices, const OgreGeometry& geom); + scene::IMeshBuffer* composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array& indices, const OgreGeometry& geom); + void composeObject(void); + bool readColor(io::IReadFile* meshFile, video::SColor& col); + void getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine=false); + void readTechnique(io::IReadFile* meshFile, OgreMaterial& mat); + void readPass(io::IReadFile* file, OgreTechnique& technique); + void loadMaterials(io::IReadFile* file); + bool loadSkeleton(io::IReadFile* meshFile, const core::stringc& name); + void clearMeshes(); + + io::IFileSystem* FileSystem; + video::IVideoDriver* Driver; + + core::stringc Version; + bool SwapEndian; + core::array Meshes; + io::path CurrentlyLoadingFromPath; + + core::array Materials; + OgreSkeleton Skeleton; + + IMesh* Mesh; + u32 NumUV; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp new file mode 100644 index 0000000..3550dba --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.cpp @@ -0,0 +1,244 @@ +// Copyright (C) 2012-2012 Patryk Nadrowski +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#if defined(_IRR_COMPILE_WITH_OPENGL_) && defined(_IRR_COMPILE_WITH_CG_) + +#include "COpenGLCgMaterialRenderer.h" +#include "COpenGLDriver.h" +#include "COpenGLTexture.h" + +namespace irr +{ +namespace video +{ + +COpenGLCgUniformSampler2D::COpenGLCgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) +{ + Type = CG_SAMPLER2D; +} + +void COpenGLCgUniformSampler2D::update(const void* data, const SMaterial& material) const +{ + s32* Data = (s32*)data; + s32 LayerID = *Data; + + if (material.TextureLayer[LayerID].Texture) + { + int TextureID = reinterpret_cast(material.TextureLayer[LayerID].Texture)->getOpenGLTextureName(); + + cgGLSetTextureParameter(Parameter, TextureID); + cgGLEnableTextureParameter(Parameter); + } +} + +COpenGLCgMaterialRenderer::COpenGLCgMaterialRenderer(COpenGLDriver* driver, s32& materialType, + const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, + const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, + const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) : + Driver(driver), CCgMaterialRenderer(callback, baseMaterial, userData) +{ + #ifdef _DEBUG + setDebugName("COpenGLCgMaterialRenderer"); + #endif + + init(materialType, vertexProgram, vertexEntry, vertexProfile, fragmentProgram, fragmentEntry, fragmentProfile, + geometryProgram, geometryEntry, geometryProfile, inType, outType, vertices); +} + +COpenGLCgMaterialRenderer::~COpenGLCgMaterialRenderer() +{ + if (VertexProgram) + { + cgGLUnloadProgram(VertexProgram); + cgDestroyProgram(VertexProgram); + } + if (FragmentProgram) + { + cgGLUnloadProgram(FragmentProgram); + cgDestroyProgram(FragmentProgram); + } + if (GeometryProgram) + { + cgGLUnloadProgram(GeometryProgram); + cgDestroyProgram(GeometryProgram); + } +} + +void COpenGLCgMaterialRenderer::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services) +{ + Material = material; + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexProgram) + { + cgGLEnableProfile(VertexProfile); + cgGLBindProgram(VertexProgram); + } + + if (FragmentProgram) + { + cgGLEnableProfile(FragmentProfile); + cgGLBindProgram(FragmentProgram); + } + + if (GeometryProgram) + { + cgGLEnableProfile(GeometryProfile); + cgGLBindProgram(GeometryProgram); + } + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, this); + } + + if (CallBack) + CallBack->OnSetMaterial(material); + + for (u32 i=0; isetActiveTexture(i, material.getTexture(i)); + + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +bool COpenGLCgMaterialRenderer::OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype) +{ + if (CallBack && (VertexProgram || FragmentProgram || GeometryProgram)) + CallBack->OnSetConstants(this, UserData); + + return true; +} + +void COpenGLCgMaterialRenderer::OnUnsetMaterial() +{ + if (VertexProgram) + { + cgGLUnbindProgram(VertexProfile); + cgGLDisableProfile(VertexProfile); + } + if (FragmentProgram) + { + cgGLUnbindProgram(FragmentProfile); + cgGLDisableProfile(FragmentProfile); + } + if (GeometryProgram) + { + cgGLUnbindProgram(GeometryProfile); + cgGLDisableProfile(GeometryProfile); + } + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); + + Material = IdentityMaterial;; +} + +void COpenGLCgMaterialRenderer::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) +{ + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + +IVideoDriver* COpenGLCgMaterialRenderer::getVideoDriver() +{ + return Driver; +} + +void COpenGLCgMaterialRenderer::init(s32& materialType, + const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, + const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, + const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices) +{ + bool Status = true; + CGerror Error = CG_NO_ERROR; + materialType = -1; + + // TODO: add profile selection + + if (vertexProgram) + { + VertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); + + if (VertexProfile) + VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, vertexProgram, VertexProfile, vertexEntry, 0); + + if (!VertexProgram) + { + Error = cgGetError(); + os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); + os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); + + Status = false; + } + else + cgGLLoadProgram(VertexProgram); + } + + if (fragmentProgram) + { + FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); + + if (FragmentProfile) + FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, fragmentProgram, FragmentProfile, fragmentEntry, 0); + + if (!FragmentProgram) + { + Error = cgGetError(); + os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); + os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); + + Status = false; + } + else + cgGLLoadProgram(FragmentProgram); + } + + if (geometryProgram) + { + GeometryProfile = cgGLGetLatestProfile(CG_GL_GEOMETRY); + + if (GeometryProfile) + GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, geometryProgram, GeometryProfile, geometryEntry, 0); + + if (!GeometryProgram) + { + Error = cgGetError(); + os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); + os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); + + Status = false; + } + else + cgGLLoadProgram(GeometryProgram); + } + + getUniformList(); + + // create OpenGL specifics sampler uniforms. + for (unsigned int i = 0; i < UniformInfo.size(); ++i) + { + if (UniformInfo[i]->getType() == CG_SAMPLER2D) + { + bool IsGlobal = true; + + if (UniformInfo[i]->getSpace() == CG_PROGRAM) + IsGlobal = false; + + CCgUniform* Uniform = new COpenGLCgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); + delete UniformInfo[i]; + UniformInfo[i] = Uniform; + } + } + + if (Status) + materialType = Driver->addMaterialRenderer(this); +} + +} +} + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.h new file mode 100644 index 0000000..74c43c5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLCgMaterialRenderer.h @@ -0,0 +1,99 @@ +// Copyright (C) 2012-2012 Patryk Nadrowski +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_CG_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_CG_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#if defined(_IRR_COMPILE_WITH_OPENGL_) && defined(_IRR_COMPILE_WITH_CG_) + +#ifdef _IRR_WINDOWS_API_ + #define WIN32_LEAN_AND_MEAN + #include + #include + #include "glext.h" +#else +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 +#else + #define GL_GLEXT_PROTOTYPES 1 +#endif +#if defined(_IRR_OSX_PLATFORM_) + #include +#else + #include +#endif +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" +#endif +#endif + +#include "CCgMaterialRenderer.h" +#include "Cg/cgGL.h" + +#ifdef _MSC_VER + #pragma comment(lib, "cgGL.lib") +#endif + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +class IShaderConstantSetCallBack; + +class COpenGLCgUniformSampler2D : public CCgUniform +{ +public: + COpenGLCgUniformSampler2D(const CGparameter& parameter, bool global); + + void update(const void* data, const SMaterial& material) const; +}; + +class COpenGLCgMaterialRenderer : public CCgMaterialRenderer +{ +public: + COpenGLCgMaterialRenderer(COpenGLDriver* driver, s32& materialType, + const c8* vertexProgram = 0, const c8* vertexEntry = "main", + E_VERTEX_SHADER_TYPE vertexProfile = video::EVST_VS_1_1, + const c8* fragmentProgram = 0, const c8* fragmentEntry = "main", + E_PIXEL_SHADER_TYPE fragmentProfile = video::EPST_PS_1_1, + const c8* geometryProgram = 0, const c8* geometryEntry = "main", + E_GEOMETRY_SHADER_TYPE geometryProfile = video::EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 vertices = 0, IShaderConstantSetCallBack* callback = 0, + IMaterialRenderer* baseMaterial = 0, s32 userData = 0); + + virtual ~COpenGLCgMaterialRenderer(); + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services); + virtual bool OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype); + virtual void OnUnsetMaterial(); + + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates); + virtual IVideoDriver* getVideoDriver(); + +protected: + void init(s32& materialType, + const c8* vertexProgram = 0, const c8* vertexEntry = "main", + E_VERTEX_SHADER_TYPE vertexProfile = video::EVST_VS_1_1, + const c8* fragmentProgram = 0, const c8* fragmentEntry = "main", + E_PIXEL_SHADER_TYPE fragmentProfile = video::EPST_PS_1_1, + const c8* geometryProgram = 0, const c8* geometryEntry = "main", + E_GEOMETRY_SHADER_TYPE geometryProfile = video::EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 vertices = 0); + + COpenGLDriver* Driver; +}; + +} +} + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.cpp new file mode 100644 index 0000000..1dbeac5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.cpp @@ -0,0 +1,4830 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "COpenGLDriver.h" +// needed here also because of the create methods' parameters +#include "CNullDriver.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLTexture.h" +#include "COpenGLMaterialRenderer.h" +#include "COpenGLShaderMaterialRenderer.h" +#include "COpenGLSLMaterialRenderer.h" +#include "COpenGLCgMaterialRenderer.h" +#include "COpenGLNormalMapRenderer.h" +#include "COpenGLParallaxMapRenderer.h" +#include "os.h" + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ +#include "MacOSX/CIrrDeviceMacOSX.h" +#endif + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include +#endif + +namespace irr +{ +namespace video +{ + +// ----------------------------------------------------------------------- +// WINDOWS CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ +//! Windows constructor and init code +COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceWin32* device) +: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), + AntiAlias(params.AntiAlias), RenderTargetTexture(0), + CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), + CurrentTarget(ERT_FRAME_BUFFER), Params(params), + HDc(0), Window(static_cast(params.WindowId)), Win32Device(device), + DeviceType(EIDT_WIN32) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + + #ifdef _IRR_COMPILE_WITH_CG_ + CgContext = 0; + #endif +} + + +bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device) +{ + if (videoData.OpenGLWin32.HWnd && videoData.OpenGLWin32.HDc && videoData.OpenGLWin32.HRc) + { + if (!wglMakeCurrent((HDC)videoData.OpenGLWin32.HDc, (HGLRC)videoData.OpenGLWin32.HRc)) + { + os::Printer::log("Render Context switch failed."); + return false; + } + else + { + HDc = (HDC)videoData.OpenGLWin32.HDc; + } + } + // set back to main context + else if (HDc != ExposedData.OpenGLWin32.HDc) + { + if (!wglMakeCurrent((HDC)ExposedData.OpenGLWin32.HDc, (HGLRC)ExposedData.OpenGLWin32.HRc)) + { + os::Printer::log("Render Context switch failed."); + return false; + } + else + { + HDc = (HDC)ExposedData.OpenGLWin32.HDc; + } + } + return true; +} + +//! inits the open gl driver +bool COpenGLDriver::initDriver(CIrrDeviceWin32* device) +{ + // Create a window to test antialiasing support + const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32"); + HINSTANCE lhInstance = GetModuleHandle(0); + + // Register Class + WNDCLASSEX wcex; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)DefWindowProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = lhInstance; + wcex.hIcon = NULL; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = 0; + wcex.lpszClassName = ClassName; + wcex.hIconSm = 0; + wcex.hIcon = 0; + RegisterClassEx(&wcex); + + RECT clientSize; + clientSize.top = 0; + clientSize.left = 0; + clientSize.right = Params.WindowSize.Width; + clientSize.bottom = Params.WindowSize.Height; + + DWORD style = WS_POPUP; + if (!Params.Fullscreen) + style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + AdjustWindowRect(&clientSize, style, FALSE); + + const s32 realWidth = clientSize.right - clientSize.left; + const s32 realHeight = clientSize.bottom - clientSize.top; + + const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; + const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + + HWND temporary_wnd=CreateWindow(ClassName, __TEXT(""), style, windowLeft, + windowTop, realWidth, realHeight, NULL, NULL, lhInstance, NULL); + + if (!temporary_wnd) + { + os::Printer::log("Cannot create a temporary window.", ELL_ERROR); + UnregisterClass(ClassName, lhInstance); + return false; + } + + HDc = GetDC(temporary_wnd); + + // Set up pixel format descriptor with desired parameters + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + (Params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering + (Params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer + PFD_TYPE_RGBA, // Request An RGBA Format + Params.Bits, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + Params.ZBufferBits, // Z-Buffer (Depth Buffer) + BYTE(Params.Stencilbuffer ? 1 : 0), // Stencil Buffer Depth + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + GLuint PixelFormat; + + for (u32 i=0; i<6; ++i) + { + if (i == 1) + { + if (Params.Stencilbuffer) + { + os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); + Params.Stencilbuffer = false; + pfd.cStencilBits = 0; + } + else + continue; + } + else + if (i == 2) + { + pfd.cDepthBits = 24; + } + else + if (i == 3) + { + if (Params.Bits!=16) + pfd.cDepthBits = 16; + else + continue; + } + else + if (i == 4) + { + // try single buffer + if (Params.Doublebuffer) + pfd.dwFlags &= ~PFD_DOUBLEBUFFER; + else + continue; + } + else + if (i == 5) + { + os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR); + ReleaseDC(temporary_wnd, HDc); + DestroyWindow(temporary_wnd); + UnregisterClass(ClassName, lhInstance); + return false; + } + + // choose pixelformat + PixelFormat = ChoosePixelFormat(HDc, &pfd); + if (PixelFormat) + break; + } + + SetPixelFormat(HDc, PixelFormat, &pfd); + HGLRC hrc=wglCreateContext(HDc); + if (!hrc) + { + os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR); + ReleaseDC(temporary_wnd, HDc); + DestroyWindow(temporary_wnd); + UnregisterClass(ClassName, lhInstance); + return false; + } + + SExposedVideoData data; + data.OpenGLWin32.HDc = HDc; + data.OpenGLWin32.HRc = hrc; + data.OpenGLWin32.HWnd = temporary_wnd; + + + if (!changeRenderContext(data, device)) + { + os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR); + wglDeleteContext(hrc); + ReleaseDC(temporary_wnd, HDc); + DestroyWindow(temporary_wnd); + UnregisterClass(ClassName, lhInstance); + return false; + } + + core::stringc wglExtensions; +#ifdef WGL_ARB_extensions_string + PFNWGLGETEXTENSIONSSTRINGARBPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if (irrGetExtensionsString) + wglExtensions = irrGetExtensionsString(HDc); +#elif defined(WGL_EXT_extensions_string) + PFNWGLGETEXTENSIONSSTRINGEXTPROC irrGetExtensionsString = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT"); + if (irrGetExtensionsString) + wglExtensions = irrGetExtensionsString(HDc); +#endif + const bool pixel_format_supported = (wglExtensions.find("WGL_ARB_pixel_format") != -1); + const bool multi_sample_supported = ((wglExtensions.find("WGL_ARB_multisample") != -1) || + (wglExtensions.find("WGL_EXT_multisample") != -1) || (wglExtensions.find("WGL_3DFX_multisample") != -1) ); +#ifdef _DEBUG + os::Printer::log("WGL_extensions", wglExtensions); +#endif + +#ifdef WGL_ARB_pixel_format + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + if (pixel_format_supported && wglChoosePixelFormat_ARB) + { + // This value determines the number of samples used for antialiasing + // My experience is that 8 does not show a big + // improvement over 4, but 4 shows a big improvement + // over 2. + + if(AntiAlias > 32) + AntiAlias = 32; + + f32 fAttributes[] = {0.0, 0.0}; + s32 iAttributes[] = + { + WGL_DRAW_TO_WINDOW_ARB,1, + WGL_SUPPORT_OPENGL_ARB,1, + WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB,(Params.Bits==32) ? 24 : 15, + WGL_ALPHA_BITS_ARB,(Params.Bits==32) ? 8 : 1, + WGL_DEPTH_BITS_ARB,Params.ZBufferBits, // 10,11 + WGL_STENCIL_BITS_ARB,Params.Stencilbuffer ? 1 : 0, + WGL_DOUBLE_BUFFER_ARB,Params.Doublebuffer ? 1 : 0, + WGL_STEREO_ARB,Params.Stereobuffer ? 1 : 0, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, +#ifdef WGL_ARB_multisample + WGL_SAMPLES_ARB,AntiAlias, // 20,21 + WGL_SAMPLE_BUFFERS_ARB, 1, +#elif defined(WGL_EXT_multisample) + WGL_SAMPLES_EXT,AntiAlias, // 20,21 + WGL_SAMPLE_BUFFERS_EXT, 1, +#elif defined(WGL_3DFX_multisample) + WGL_SAMPLES_3DFX,AntiAlias, // 20,21 + WGL_SAMPLE_BUFFERS_3DFX, 1, +#endif +#ifdef WGL_ARB_framebuffer_sRGB + WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB ? 1:0, +#elif defined(WGL_EXT_framebuffer_sRGB) + WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB ? 1:0, +#endif +// WGL_DEPTH_FLOAT_EXT, 1, + 0,0,0,0 + }; + int iAttrSize = sizeof(iAttributes)/sizeof(int); + const bool framebuffer_srgb_supported = ((wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1) || + (wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1)); + if (!framebuffer_srgb_supported) + { + memmove(&iAttributes[24],&iAttributes[26],sizeof(int)*(iAttrSize-26)); + iAttrSize -= 2; + } + if (!multi_sample_supported) + { + memmove(&iAttributes[20],&iAttributes[24],sizeof(int)*(iAttrSize-24)); + iAttrSize -= 4; + } + + s32 rv=0; + // Try to get an acceptable pixel format + do + { + int pixelFormat=0; + UINT numFormats=0; + const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats); + + if (valid && numFormats) + rv = pixelFormat; + else + iAttributes[21] -= 1; + } + while(rv==0 && iAttributes[21]>1); + if (rv) + { + PixelFormat=rv; + AntiAlias=iAttributes[21]; + } + } + else +#endif + AntiAlias=0; + + wglMakeCurrent(HDc, NULL); + wglDeleteContext(hrc); + ReleaseDC(temporary_wnd, HDc); + DestroyWindow(temporary_wnd); + UnregisterClass(ClassName, lhInstance); + + // get hdc + HDc=GetDC(Window); + if (!HDc) + { + os::Printer::log("Cannot create a GL device context.", ELL_ERROR); + return false; + } + + // search for pixel format the simple way + if (PixelFormat==0 || (!SetPixelFormat(HDc, PixelFormat, &pfd))) + { + for (u32 i=0; i<5; ++i) + { + if (i == 1) + { + if (Params.Stencilbuffer) + { + os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); + Params.Stencilbuffer = false; + pfd.cStencilBits = 0; + } + else + continue; + } + else + if (i == 2) + { + pfd.cDepthBits = 24; + } + if (i == 3) + { + if (Params.Bits!=16) + pfd.cDepthBits = 16; + else + continue; + } + else + if (i == 4) + { + os::Printer::log("Cannot create a GL device context", "No suitable format.", ELL_ERROR); + return false; + } + + // choose pixelformat + PixelFormat = ChoosePixelFormat(HDc, &pfd); + if (PixelFormat) + break; + } + } + + // set pixel format + if (!SetPixelFormat(HDc, PixelFormat, &pfd)) + { + os::Printer::log("Cannot set the pixel format.", ELL_ERROR); + return false; + } + os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG); + + // create rendering context +#ifdef WGL_ARB_create_context + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + if (wglCreateContextAttribs_ARB) + { + int iAttribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 1, + 0 + }; + hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs); + } + else +#endif + hrc=wglCreateContext(HDc); + + if (!hrc) + { + os::Printer::log("Cannot create a GL rendering context.", ELL_ERROR); + return false; + } + + // set exposed data + ExposedData.OpenGLWin32.HDc = HDc; + ExposedData.OpenGLWin32.HRc = hrc; + ExposedData.OpenGLWin32.HWnd = Window; + + // activate rendering context + + if (!changeRenderContext(ExposedData, device)) + { + os::Printer::log("Cannot activate GL rendering context", ELL_ERROR); + wglDeleteContext(hrc); + return false; + } + + int pf = GetPixelFormat(HDc); + DescribePixelFormat(HDc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + if (pfd.cAlphaBits != 0) + { + if (pfd.cRedBits == 8) + ColorFormat = ECF_A8R8G8B8; + else + ColorFormat = ECF_A1R5G5B5; + } + else + { + if (pfd.cRedBits == 8) + ColorFormat = ECF_R8G8B8; + else + ColorFormat = ECF_R5G6B5; + } + + genericDriverInit(); + + extGlSwapInterval(Params.Vsync ? 1 : 0); + return true; +} + +#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + +// ----------------------------------------------------------------------- +// MacOSX CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ +//! Windows constructor and init code +COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceMacOSX *device) +: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), + AntiAlias(params.AntiAlias), RenderTargetTexture(0), + CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), + CurrentTarget(ERT_FRAME_BUFFER), Params(params), + OSXDevice(device), DeviceType(EIDT_OSX) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + + #ifdef _IRR_COMPILE_WITH_CG_ + CgContext = 0; + #endif + + genericDriverInit(); +} + +#endif + +// ----------------------------------------------------------------------- +// LINUX CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ +//! Linux constructor and init code +COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceLinux* device) +: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), + Transformation3DChanged(true), AntiAlias(params.AntiAlias), + RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), + CurrentTarget(ERT_FRAME_BUFFER), Params(params), + X11Device(device), DeviceType(EIDT_X11) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + + #ifdef _IRR_COMPILE_WITH_CG_ + CgContext = 0; + #endif +} + + +bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device) +{ + if (videoData.OpenGLLinux.X11Window) + { + if (videoData.OpenGLLinux.X11Display && videoData.OpenGLLinux.X11Context) + { + if (!glXMakeCurrent((Display*)videoData.OpenGLLinux.X11Display, videoData.OpenGLLinux.X11Window, (GLXContext)videoData.OpenGLLinux.X11Context)) + { + os::Printer::log("Render Context switch failed."); + return false; + } + else + { + Drawable = videoData.OpenGLLinux.X11Window; + X11Display = (Display*)videoData.OpenGLLinux.X11Display; + } + } + else + { + // in case we only got a window ID, try with the existing values for display and context + if (!glXMakeCurrent((Display*)ExposedData.OpenGLLinux.X11Display, videoData.OpenGLLinux.X11Window, (GLXContext)ExposedData.OpenGLLinux.X11Context)) + { + os::Printer::log("Render Context switch failed."); + return false; + } + else + { + Drawable = videoData.OpenGLLinux.X11Window; + X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; + } + } + } + // set back to main context + else if (X11Display != ExposedData.OpenGLLinux.X11Display) + { + if (!glXMakeCurrent((Display*)ExposedData.OpenGLLinux.X11Display, ExposedData.OpenGLLinux.X11Window, (GLXContext)ExposedData.OpenGLLinux.X11Context)) + { + os::Printer::log("Render Context switch failed."); + return false; + } + else + { + Drawable = ExposedData.OpenGLLinux.X11Window; + X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; + } + } + return true; +} + + +//! inits the open gl driver +bool COpenGLDriver::initDriver(CIrrDeviceLinux* device) +{ + ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext(); + ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay(); + ExposedData.OpenGLLinux.X11Window = (unsigned long)Params.WindowId; + Drawable = glXGetCurrentDrawable(); + X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; + + genericDriverInit(); + + // set vsync + extGlSwapInterval(Params.Vsync ? 1 : 0); + return true; +} + +#endif // _IRR_COMPILE_WITH_X11_DEVICE_ + + +// ----------------------------------------------------------------------- +// SDL CONSTRUCTOR +// ----------------------------------------------------------------------- +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +//! SDL constructor and init code +COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceSDL* device) +: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), + CurrentRenderMode(ERM_NONE), ResetRenderStates(true), + Transformation3DChanged(true), AntiAlias(params.AntiAlias), + RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), + CurrentTarget(ERT_FRAME_BUFFER), Params(params), + SDLDevice(device), DeviceType(EIDT_SDL) +{ + #ifdef _DEBUG + setDebugName("COpenGLDriver"); + #endif + + #ifdef _IRR_COMPILE_WITH_CG_ + CgContext = 0; + #endif + + genericDriverInit(); +} + +#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ + + +//! destructor +COpenGLDriver::~COpenGLDriver() +{ + #ifdef _IRR_COMPILE_WITH_CG_ + if (CgContext) + cgDestroyContext(CgContext); + #endif + + RequestedLights.clear(); + + deleteMaterialRenders(); + + CurrentTexture.clear(); + // I get a blue screen on my laptop, when I do not delete the + // textures manually before releasing the dc. Oh how I love this. + deleteAllTextures(); + removeAllOcclusionQueries(); + removeAllHardwareBuffers(); + +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + if (DeviceType == EIDT_WIN32) + { + + if (ExposedData.OpenGLWin32.HRc) + { + if (!wglMakeCurrent(HDc, 0)) + os::Printer::log("Release of dc and rc failed.", ELL_WARNING); + + if (!wglDeleteContext((HGLRC)ExposedData.OpenGLWin32.HRc)) + os::Printer::log("Release of rendering context failed.", ELL_WARNING); + } + + if (HDc) + ReleaseDC(Window, HDc); + } +#endif +} + +// ----------------------------------------------------------------------- +// METHODS +// ----------------------------------------------------------------------- + +bool COpenGLDriver::genericDriverInit() +{ + Name=L"OpenGL "; + Name.append(glGetString(GL_VERSION)); + s32 pos=Name.findNext(L' ', 7); + if (pos != -1) + Name=Name.subString(0, pos); + printVersion(); + + // print renderer information + const GLubyte* renderer = glGetString(GL_RENDERER); + const GLubyte* vendor = glGetString(GL_VENDOR); + if (renderer && vendor) + { + os::Printer::log(reinterpret_cast(renderer), reinterpret_cast(vendor), ELL_INFORMATION); + VendorName = reinterpret_cast(vendor); + } + + u32 i; + CurrentTexture.clear(); + // load extensions + initExtensions(Params.Stencilbuffer); + if (queryFeature(EVDF_ARB_GLSL)) + { + char buf[32]; + const u32 maj = ShaderLanguageVersion/100; + snprintf(buf, 32, "%u.%u", maj, ShaderLanguageVersion-maj*100); + os::Printer::log("GLSL version", buf, ELL_INFORMATION); + } + else + os::Printer::log("GLSL not available.", ELL_INFORMATION); + DriverAttributes->setAttribute("MaxTextures", MaxTextureUnits); + DriverAttributes->setAttribute("MaxSupportedTextures", MaxSupportedTextures); + DriverAttributes->setAttribute("MaxLights", MaxLights); + DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy); + DriverAttributes->setAttribute("MaxUserClipPlanes", MaxUserClipPlanes); + DriverAttributes->setAttribute("MaxAuxBuffers", MaxAuxBuffers); + DriverAttributes->setAttribute("MaxMultipleRenderTargets", MaxMultipleRenderTargets); + DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices); + DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize); + DriverAttributes->setAttribute("MaxGeometryVerticesOut", (s32)MaxGeometryVerticesOut); + DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias); + DriverAttributes->setAttribute("Version", Version); + DriverAttributes->setAttribute("ShaderLanguageVersion", ShaderLanguageVersion); + DriverAttributes->setAttribute("AntiAlias", AntiAlias); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + // Reset The Current Viewport + glViewport(0, 0, Params.WindowSize.Width, Params.WindowSize.Height); + + UserClipPlanes.reallocate(MaxUserClipPlanes); + for (i=0; i(i), core::IdentityMatrix); + + setAmbientLight(SColorf(0.0f,0.0f,0.0f,0.0f)); +#ifdef GL_EXT_separate_specular_color + if (FeatureAvailable[IRR_EXT_separate_specular_color]) + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); +#endif + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + + Params.HandleSRGB &= ((FeatureAvailable[IRR_ARB_framebuffer_sRGB] || FeatureAvailable[IRR_EXT_framebuffer_sRGB]) && + FeatureAvailable[IRR_EXT_texture_sRGB]); +#if defined(GL_ARB_framebuffer_sRGB) + if (Params.HandleSRGB) + glEnable(GL_FRAMEBUFFER_SRGB); +#elif defined(GL_EXT_framebuffer_sRGB) + if (Params.HandleSRGB) + glEnable(GL_FRAMEBUFFER_SRGB_EXT); +#endif + +// This is a fast replacement for NORMALIZE_NORMALS +// if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal]) +// glEnable(GL_RESCALE_NORMAL_EXT); + + glClearDepth(1.0); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); + glDepthFunc(GL_LEQUAL); + glFrontFace(GL_CW); + // adjust flat coloring scheme to DirectX version +#if defined(GL_ARB_provoking_vertex) || defined(GL_EXT_provoking_vertex) + extGlProvokingVertex(GL_FIRST_VERTEX_CONVENTION_EXT); +#endif + + // create material renderers + createMaterialRenderers(); + + // set the renderstates + setRenderStates3DMode(); + + glAlphaFunc(GL_GREATER, 0.f); + + // set fog mode + setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); + + // create matrix for flipping textures + TextureFlipMatrix.buildTextureTransform(0.0f, core::vector2df(0,0), core::vector2df(0,1.0f), core::vector2df(1.0f,-1.0f)); + + // We need to reset once more at the beginning of the first rendering. + // This fixes problems with intermediate changes to the material during texture load. + ResetRenderStates = true; + + #ifdef _IRR_COMPILE_WITH_CG_ + CgContext = cgCreateContext(); + #endif + + return true; +} + + +void COpenGLDriver::createMaterialRenderers() +{ + // create OpenGL material renderers + + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SOLID(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SOLID_2_LAYER(this)); + + // add the same renderer for all lightmap types + COpenGLMaterialRenderer_LIGHTMAP* lmr = new COpenGLMaterialRenderer_LIGHTMAP(this); + addMaterialRenderer(lmr); // for EMT_LIGHTMAP: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: + addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: + lmr->drop(); + + // add remaining material renderer + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_DETAIL_MAP(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_SPHERE_MAP(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_REFLECTION_2_LAYER(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(this)); + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(this)); + + // add normal map renderers + s32 tmp = 0; + video::IMaterialRenderer* renderer = 0; + renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + renderer = new COpenGLNormalMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add parallax map renderers + renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_SOLID].Renderer); + renderer->drop(); + renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); + renderer->drop(); + renderer = new COpenGLParallaxMapRenderer(this, tmp, MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); + renderer->drop(); + + // add basic 1 texture blending + addAndDropMaterialRenderer(new COpenGLMaterialRenderer_ONETEXTURE_BLEND(this)); +} + + +//! presents the rendered scene on the screen, returns false if failed +bool COpenGLDriver::endScene() +{ + CNullDriver::endScene(); + + glFlush(); + +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + if (DeviceType == EIDT_WIN32) + return SwapBuffers(HDc) == TRUE; +#endif + +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + if (DeviceType == EIDT_X11) + { + glXSwapBuffers(X11Display, Drawable); + return true; + } +#endif + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + if (DeviceType == EIDT_OSX) + { + OSXDevice->flush(); + return true; + } +#endif + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (DeviceType == EIDT_SDL) + { + SDL_GL_SwapBuffers(); + return true; + } +#endif + + // todo: console device present + + return false; +} + + +//! clears the zbuffer and color buffer +void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color) +{ + GLbitfield mask = 0; + if (backBuffer) + { + const f32 inv = 1.0f / 255.0f; + glClearColor(color.getRed() * inv, color.getGreen() * inv, + color.getBlue() * inv, color.getAlpha() * inv); + + mask |= GL_COLOR_BUFFER_BIT; + } + + if (zBuffer) + { + glDepthMask(GL_TRUE); + LastMaterial.ZWriteEnable=true; + mask |= GL_DEPTH_BUFFER_BIT; + } + + if (stencilBuffer) + mask |= GL_STENCIL_BUFFER_BIT; + + if (mask) + glClear(mask); +} + + +//! init call for rendering start +bool COpenGLDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, + const SExposedVideoData& videoData, core::rect* sourceRect) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); + + switch (DeviceType) + { +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + case EIDT_WIN32: + changeRenderContext(videoData, Win32Device); + break; +#endif +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + case EIDT_X11: + changeRenderContext(videoData, X11Device); + break; +#endif + default: + changeRenderContext(videoData, (void*)0); + break; + } + +#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + if (DeviceType == EIDT_SDL) + { + // todo: SDL sets glFrontFace(GL_CCW) after driver creation, + // it would be better if this was fixed elsewhere. + glFrontFace(GL_CW); + } +#endif + + clearBuffers(backBuffer, zBuffer, false, color); + return true; +} + + +//! Returns the transformation set by setTransform +const core::matrix4& COpenGLDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Matrices[state]; +} + + +//! sets transformation +void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + Matrices[state] = mat; + Transformation3DChanged = true; + + switch (state) + { + case ETS_VIEW: + case ETS_WORLD: + { + // OpenGL only has a model matrix, view and world is not existent. so lets fake these two. + glMatrixMode(GL_MODELVIEW); + + // first load the viewing transformation for user clip planes + glLoadMatrixf((Matrices[ETS_VIEW]).pointer()); + + // we have to update the clip planes to the latest view matrix + for (u32 i=0; i= MATERIAL_MAX_TEXTURES) + break; + + const bool isRTT = Material.getTexture(i) && Material.getTexture(i)->isRenderTarget(); + + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB + i); + + glMatrixMode(GL_TEXTURE); + if (!isRTT && mat.isIdentity() ) + glLoadIdentity(); + else + { + GLfloat glmat[16]; + if (isRTT) + getGLTextureMatrix(glmat, mat * TextureFlipMatrix); + else + getGLTextureMatrix(glmat, mat); + glLoadMatrixf(glmat); + } + break; + } + } +} + + +bool COpenGLDriver::updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer) +{ + if (!HWBuffer) + return false; + + if (!FeatureAvailable[IRR_ARB_vertex_buffer_object]) + return false; + +#if defined(GL_ARB_vertex_buffer_object) + const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; + const void* vertices=mb->getVertices(); + const u32 vertexCount=mb->getVertexCount(); + const E_VERTEX_TYPE vType=mb->getVertexType(); + const u32 vertexSize = getVertexPitchFromType(vType); + + const c8* vbuf = static_cast(vertices); + core::array buffer; + if (!FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra]) + { + //buffer vertex data, and convert colors... + buffer.set_used(vertexSize * vertexCount); + memcpy(buffer.pointer(), vertices, vertexSize * vertexCount); + vbuf = buffer.const_pointer(); + + // in order to convert the colors into opengl format (RGBA) + switch (vType) + { + case EVT_STANDARD: + { + S3DVertex* pb = reinterpret_cast(buffer.pointer()); + const S3DVertex* po = static_cast(vertices); + for (u32 i=0; i(buffer.pointer()); + const S3DVertex2TCoords* po = static_cast(vertices); + for (u32 i=0; i(buffer.pointer()); + const S3DVertexTangents* po = static_cast(vertices); + for (u32 i=0; ivbo_verticesID) + { + extGlGenBuffers(1, &HWBuffer->vbo_verticesID); + if (!HWBuffer->vbo_verticesID) + return false; + newBuffer=true; + } + else if (HWBuffer->vbo_verticesSize < vertexCount*vertexSize) + { + newBuffer=true; + } + + extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID); + + //copy data to graphics card + glGetError(); // clear error storage + if (!newBuffer) + extGlBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, vbuf); + else + { + HWBuffer->vbo_verticesSize = vertexCount*vertexSize; + + if (HWBuffer->Mapped_Vertex==scene::EHM_STATIC) + extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STATIC_DRAW); + else if (HWBuffer->Mapped_Vertex==scene::EHM_DYNAMIC) + extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_DYNAMIC_DRAW); + else //scene::EHM_STREAM + extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STREAM_DRAW); + } + + extGlBindBuffer(GL_ARRAY_BUFFER, 0); + + return (glGetError() == GL_NO_ERROR); +#else + return false; +#endif +} + + +bool COpenGLDriver::updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer) +{ + if (!HWBuffer) + return false; + + if (!FeatureAvailable[IRR_ARB_vertex_buffer_object]) + return false; + +#if defined(GL_ARB_vertex_buffer_object) + const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; + + const void* indices=mb->getIndices(); + u32 indexCount= mb->getIndexCount(); + + GLenum indexSize; + switch (mb->getIndexType()) + { + case EIT_16BIT: + { + indexSize=sizeof(u16); + break; + } + case EIT_32BIT: + { + indexSize=sizeof(u32); + break; + } + default: + { + return false; + } + } + + + //get or create buffer + bool newBuffer=false; + if (!HWBuffer->vbo_indicesID) + { + extGlGenBuffers(1, &HWBuffer->vbo_indicesID); + if (!HWBuffer->vbo_indicesID) + return false; + newBuffer=true; + } + else if (HWBuffer->vbo_indicesSize < indexCount*indexSize) + { + newBuffer=true; + } + + extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID); + + //copy data to graphics card + glGetError(); // clear error storage + if (!newBuffer) + extGlBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexCount * indexSize, indices); + else + { + HWBuffer->vbo_indicesSize = indexCount*indexSize; + + if (HWBuffer->Mapped_Index==scene::EHM_STATIC) + extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW); + else if (HWBuffer->Mapped_Index==scene::EHM_DYNAMIC) + extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_DYNAMIC_DRAW); + else //scene::EHM_STREAM + extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STREAM_DRAW); + } + + extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + return (glGetError() == GL_NO_ERROR); +#else + return false; +#endif +} + + +//! updates hardware buffer if needed +bool COpenGLDriver::updateHardwareBuffer(SHWBufferLink *HWBuffer) +{ + if (!HWBuffer) + return false; + + if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) + { + if (HWBuffer->ChangedID_Vertex != HWBuffer->MeshBuffer->getChangedID_Vertex() + || !((SHWBufferLink_opengl*)HWBuffer)->vbo_verticesID) + { + + HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex(); + + if (!updateVertexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer)) + return false; + } + } + + if (HWBuffer->Mapped_Index!=scene::EHM_NEVER) + { + if (HWBuffer->ChangedID_Index != HWBuffer->MeshBuffer->getChangedID_Index() + || !((SHWBufferLink_opengl*)HWBuffer)->vbo_indicesID) + { + + HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index(); + + if (!updateIndexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer)) + return false; + } + } + + return true; +} + + +//! Create hardware buffer from meshbuffer +COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::IMeshBuffer* mb) +{ +#if defined(GL_ARB_vertex_buffer_object) + if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) + return 0; + + SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb); + + //add to map + HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer); + + HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex(); + HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index(); + HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); + HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); + HWBuffer->LastUsed=0; + HWBuffer->vbo_verticesID=0; + HWBuffer->vbo_indicesID=0; + HWBuffer->vbo_verticesSize=0; + HWBuffer->vbo_indicesSize=0; + + if (!updateHardwareBuffer(HWBuffer)) + { + deleteHardwareBuffer(HWBuffer); + return 0; + } + + return HWBuffer; +#else + return 0; +#endif +} + + +void COpenGLDriver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) +{ + if (!_HWBuffer) + return; + +#if defined(GL_ARB_vertex_buffer_object) + SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer; + if (HWBuffer->vbo_verticesID) + { + extGlDeleteBuffers(1, &HWBuffer->vbo_verticesID); + HWBuffer->vbo_verticesID=0; + } + if (HWBuffer->vbo_indicesID) + { + extGlDeleteBuffers(1, &HWBuffer->vbo_indicesID); + HWBuffer->vbo_indicesID=0; + } +#endif + + CNullDriver::deleteHardwareBuffer(_HWBuffer); +} + + +//! Draw hardware buffer +void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) +{ + if (!_HWBuffer) + return; + + updateHardwareBuffer(_HWBuffer); //check if update is needed + _HWBuffer->LastUsed=0; //reset count + +#if defined(GL_ARB_vertex_buffer_object) + SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer; + + const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; + const void *vertices=mb->getVertices(); + const void *indexList=mb->getIndices(); + + if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) + { + extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID); + vertices=0; + } + + if (HWBuffer->Mapped_Index!=scene::EHM_NEVER) + { + extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID); + indexList=0; + } + + drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); + + if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER) + extGlBindBuffer(GL_ARRAY_BUFFER, 0); + if (HWBuffer->Mapped_Index!=scene::EHM_NEVER) + extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#endif +} + + +//! Create occlusion query. +/** Use node for identification and mesh for occlusion test. */ +void COpenGLDriver::addOcclusionQuery(scene::ISceneNode* node, + const scene::IMesh* mesh) +{ + if (!queryFeature(EVDF_OCCLUSION_QUERY)) + return; + + CNullDriver::addOcclusionQuery(node, mesh); + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if ((index != -1) && (OcclusionQueries[index].UID == 0)) + extGlGenQueries(1, reinterpret_cast(&OcclusionQueries[index].UID)); +} + + +//! Remove occlusion query. +void COpenGLDriver::removeOcclusionQuery(scene::ISceneNode* node) +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + if (OcclusionQueries[index].UID != 0) + extGlDeleteQueries(1, reinterpret_cast(&OcclusionQueries[index].UID)); + CNullDriver::removeOcclusionQuery(node); + } +} + + +//! Run occlusion query. Draws mesh stored in query. +/** If the mesh shall not be rendered visible, use +overrideMaterial to disable the color and depth buffer. */ +void COpenGLDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) +{ + if (!node) + return; + + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + if (OcclusionQueries[index].UID) + extGlBeginQuery( +#ifdef GL_ARB_occlusion_query + GL_SAMPLES_PASSED_ARB, +#else + 0, +#endif + OcclusionQueries[index].UID); + CNullDriver::runOcclusionQuery(node,visible); + if (OcclusionQueries[index].UID) + extGlEndQuery( +#ifdef GL_ARB_occlusion_query + GL_SAMPLES_PASSED_ARB); +#else + 0); +#endif + testGLError(); + } +} + + +//! Update occlusion query. Retrieves results from GPU. +/** If the query shall not block, set the flag to false. +Update might not occur in this case, though */ +void COpenGLDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block) +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + // not yet started + if (OcclusionQueries[index].Run==u32(~0)) + return; + GLint available = block?GL_TRUE:GL_FALSE; + if (!block) + extGlGetQueryObjectiv(OcclusionQueries[index].UID, +#ifdef GL_ARB_occlusion_query + GL_QUERY_RESULT_AVAILABLE_ARB, +#elif defined(GL_NV_occlusion_query) + GL_PIXEL_COUNT_AVAILABLE_NV, +#else + 0, +#endif + &available); + testGLError(); + if (available==GL_TRUE) + { + extGlGetQueryObjectiv(OcclusionQueries[index].UID, +#ifdef GL_ARB_occlusion_query + GL_QUERY_RESULT_ARB, +#elif defined(GL_NV_occlusion_query) + GL_PIXEL_COUNT_NV, +#else + 0, +#endif + &available); + if (queryFeature(EVDF_OCCLUSION_QUERY)) + OcclusionQueries[index].Result = available; + } + testGLError(); + } +} + + +//! Return query result. +/** Return value is the number of visible pixels/fragments. +The value is a safe approximation, i.e. can be larger than the +actual value of pixels. */ +u32 COpenGLDriver::getOcclusionQueryResult(scene::ISceneNode* node) const +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + return OcclusionQueries[index].Result; + else + return ~0; +} + + +// small helper function to create vertex buffer object adress offsets +static inline u8* buffer_offset(const long offset) +{ + return ((u8*)0 + offset); +} + + +//! draws a vertex primitive list +void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) +{ + if (!primitiveCount || !vertexCount) + return; + + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + + if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra]) + getColorBuffer(vertices, vertexCount, vType); + + // draw everything + setRenderStates3DMode(); + + if (MultiTextureExtension) + extGlClientActiveTexture(GL_TEXTURE0_ARB); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_NORMAL_ARRAY); + +//due to missing defines in OSX headers, we have to be more specific with this check +//#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra) +#ifdef GL_BGRA + const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4; +#else + const GLint colorSize=4; +#endif + if (vertices) + { + if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) + { + switch (vType) + { + case EVT_STANDARD: + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast(vertices))[0].Color); + break; + case EVT_2TCOORDS: + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Color); + break; + case EVT_TANGENTS: + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Color); + break; + } + } + else + { + // avoid passing broken pointer to OpenGL + _IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0); + glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); + } + } + + switch (vType) + { + case EVT_STANDARD: + if (vertices) + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].TCoords); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].Pos); + } + else + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex), buffer_offset(12)); + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), 0); + } + + if (MultiTextureExtension && CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].TCoords); + else + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); + } + break; + case EVT_2TCOORDS: + if (vertices) + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].TCoords); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Pos); + } + else + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(12)); + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0)); + } + + + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].TCoords2); + else + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36)); + } + break; + case EVT_TANGENTS: + if (vertices) + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].TCoords); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Pos); + } + else + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(12)); + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); + } + + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Tangent); + else + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(36)); + + extGlClientActiveTexture(GL_TEXTURE2_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Binormal); + else + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48)); + } + break; + } + + renderArray(indexList, primitiveCount, pType, iType); + + if (MultiTextureExtension) + { + if (vType==EVT_TANGENTS) + { + extGlClientActiveTexture(GL_TEXTURE2_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + if ((vType!=EVT_STANDARD) || CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + extGlClientActiveTexture(GL_TEXTURE0_ARB); + } + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +void COpenGLDriver::getColorBuffer(const void* vertices, u32 vertexCount, E_VERTEX_TYPE vType) +{ + // convert colors to gl color format. + vertexCount *= 4; //reused as color component count + ColorBuffer.set_used(vertexCount); + u32 i; + + switch (vType) + { + case EVT_STANDARD: + { + const S3DVertex* p = static_cast(vertices); + for (i=0; iColor.toOpenGLColor(&ColorBuffer[i]); + ++p; + } + } + break; + case EVT_2TCOORDS: + { + const S3DVertex2TCoords* p = static_cast(vertices); + for (i=0; iColor.toOpenGLColor(&ColorBuffer[i]); + ++p; + } + } + break; + case EVT_TANGENTS: + { + const S3DVertexTangents* p = static_cast(vertices); + for (i=0; iColor.toOpenGLColor(&ColorBuffer[i]); + ++p; + } + } + break; + } +} + + +void COpenGLDriver::renderArray(const void* indexList, u32 primitiveCount, + scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) +{ + GLenum indexSize=0; + + switch (iType) + { + case EIT_16BIT: + { + indexSize=GL_UNSIGNED_SHORT; + break; + } + case EIT_32BIT: + { + indexSize=GL_UNSIGNED_INT; + break; + } + } + + switch (pType) + { + case scene::EPT_POINTS: + case scene::EPT_POINT_SPRITES: + { +#ifdef GL_ARB_point_sprite + if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) + glEnable(GL_POINT_SPRITE_ARB); +#endif + + // prepare size and attenuation (where supported) + GLfloat particleSize=Material.Thickness; +// if (AntiAlias) +// particleSize=core::clamp(particleSize, DimSmoothedPoint[0], DimSmoothedPoint[1]); +// else + particleSize=core::clamp(particleSize, DimAliasedPoint[0], DimAliasedPoint[1]); +#if defined(GL_VERSION_1_4) || defined(GL_ARB_point_parameters) || defined(GL_EXT_point_parameters) || defined(GL_SGIS_point_parameters) + const float att[] = {1.0f, 1.0f, 0.0f}; +#if defined(GL_VERSION_1_4) + extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, att); +// extGlPointParameterf(GL_POINT_SIZE_MIN,1.f); + extGlPointParameterf(GL_POINT_SIZE_MAX, particleSize); + extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, 1.0f); +#elif defined(GL_ARB_point_parameters) + extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION_ARB, att); +// extGlPointParameterf(GL_POINT_SIZE_MIN_ARB,1.f); + extGlPointParameterf(GL_POINT_SIZE_MAX_ARB, particleSize); + extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 1.0f); +#elif defined(GL_EXT_point_parameters) + extGlPointParameterfv(GL_DISTANCE_ATTENUATION_EXT, att); +// extGlPointParameterf(GL_POINT_SIZE_MIN_EXT,1.f); + extGlPointParameterf(GL_POINT_SIZE_MAX_EXT, particleSize); + extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1.0f); +#elif defined(GL_SGIS_point_parameters) + extGlPointParameterfv(GL_DISTANCE_ATTENUATION_SGIS, att); +// extGlPointParameterf(GL_POINT_SIZE_MIN_SGIS,1.f); + extGlPointParameterf(GL_POINT_SIZE_MAX_SGIS, particleSize); + extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_SGIS, 1.0f); +#endif +#endif + glPointSize(particleSize); + +#ifdef GL_ARB_point_sprite + if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) + glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_TRUE); +#endif + glDrawArrays(GL_POINTS, 0, primitiveCount); +#ifdef GL_ARB_point_sprite + if (pType==scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_ARB_point_sprite]) + { + glDisable(GL_POINT_SPRITE_ARB); + glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE); + } +#endif + } + break; + case scene::EPT_LINE_STRIP: + glDrawElements(GL_LINE_STRIP, primitiveCount+1, indexSize, indexList); + break; + case scene::EPT_LINE_LOOP: + glDrawElements(GL_LINE_LOOP, primitiveCount, indexSize, indexList); + break; + case scene::EPT_LINES: + glDrawElements(GL_LINES, primitiveCount*2, indexSize, indexList); + break; + case scene::EPT_TRIANGLE_STRIP: + glDrawElements(GL_TRIANGLE_STRIP, primitiveCount+2, indexSize, indexList); + break; + case scene::EPT_TRIANGLE_FAN: + glDrawElements(GL_TRIANGLE_FAN, primitiveCount+2, indexSize, indexList); + break; + case scene::EPT_TRIANGLES: + glDrawElements(GL_TRIANGLES, primitiveCount*3, indexSize, indexList); + break; + case scene::EPT_QUAD_STRIP: + glDrawElements(GL_QUAD_STRIP, primitiveCount*2+2, indexSize, indexList); + break; + case scene::EPT_QUADS: + glDrawElements(GL_QUADS, primitiveCount*4, indexSize, indexList); + break; + case scene::EPT_POLYGON: + glDrawElements(GL_POLYGON, primitiveCount, indexSize, indexList); + break; + } +} + + +//! draws a vertex primitive list in 2d +void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) +{ + if (!primitiveCount || !vertexCount) + return; + + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + + if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra]) + getColorBuffer(vertices, vertexCount, vType); + + // draw everything + this->setActiveTexture(0, Material.getTexture(0)); + if (Material.MaterialType==EMT_ONETEXTURE_BLEND) + { + E_BLEND_FACTOR srcFact; + E_BLEND_FACTOR dstFact; + E_MODULATE_FUNC modulo; + u32 alphaSource; + unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); + setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); + } + else + setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); + + if (MultiTextureExtension) + extGlClientActiveTexture(GL_TEXTURE0_ARB); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + +//due to missing defines in OSX headers, we have to be more specific with this check +//#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra) +#ifdef GL_BGRA + const GLint colorSize=(FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])?GL_BGRA:4; +#else + const GLint colorSize=4; +#endif + if (vertices) + { + if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra]) + { + switch (vType) + { + case EVT_STANDARD: + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(static_cast(vertices))[0].Color); + break; + case EVT_2TCOORDS: + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Color); + break; + case EVT_TANGENTS: + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Color); + break; + } + } + else + { + // avoid passing broken pointer to OpenGL + _IRR_DEBUG_BREAK_IF(ColorBuffer.size()==0); + glColorPointer(colorSize, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); + } + } + + switch (vType) + { + case EVT_STANDARD: + if (vertices) + { + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].TCoords); + glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].Pos); + } + else + { + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); + glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex), 0); + } + + if (MultiTextureExtension && CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].TCoords); + else + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); + } + break; + case EVT_2TCOORDS: + if (vertices) + { + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].TCoords); + glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Pos); + } + else + { + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); + glVertexPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0)); + } + + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].TCoords2); + else + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36)); + } + break; + case EVT_TANGENTS: + if (vertices) + { + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].TCoords); + glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Pos); + } + else + { + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28)); + glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); + } + + break; + } + + renderArray(indexList, primitiveCount, pType, iType); + + if (MultiTextureExtension) + { + if ((vType!=EVT_STANDARD) || CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + extGlClientActiveTexture(GL_TEXTURE0_ARB); + } + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +//! draws a set of 2d images, using a color and the alpha channel of the +//! texture if desired. +void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture, + const core::array >& positions, + const core::array >& sourceRects, + const core::rect* clipRect, + SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + const u32 drawCount = core::min_(positions.size(), sourceRects.size()); + + const core::dimension2d& ss = texture->getOriginalSize(); + const f32 invW = 1.f / static_cast(ss.Width); + const f32 invH = 1.f / static_cast(ss.Height); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + disableTextures(1); + if (!setActiveTexture(0, texture)) + return; + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glBegin(GL_QUADS); + + for (u32 i=0; i targetPos(positions[i]); + core::position2d sourcePos(sourceRects[i].UpperLeftCorner); + // This needs to be signed as it may go negative. + core::dimension2d sourceSize(sourceRects[i].getSize()); + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + continue; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + continue; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + continue; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + continue; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + continue; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + continue; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + continue; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + continue; + } + + // ok, we've clipped everything. + // now draw it. + + const core::rect tcoords( + sourcePos.X * invW, + sourcePos.Y * invH, + (sourcePos.X + sourceSize.Width) * invW, + (sourcePos.Y + sourceSize.Height) * invH); + + const core::rect poss(targetPos, sourceSize); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); + } + glEnd(); +} + + +//! draws a 2d image, using a color and the alpha channel of the texture if +//! desired. The image is drawn at pos, clipped against clipRect (if != 0). +//! Only the subtexture defined by sourceRect is used. +void COpenGLDriver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + if (!sourceRect.isValid()) + return; + + core::position2d targetPos(pos); + core::position2d sourcePos(sourceRect.UpperLeftCorner); + // This needs to be signed as it may go negative. + core::dimension2d sourceSize(sourceRect.getSize()); + if (clipRect) + { + if (targetPos.X < clipRect->UpperLeftCorner.X) + { + sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; + targetPos.X = clipRect->UpperLeftCorner.X; + } + + if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y < clipRect->UpperLeftCorner.Y) + { + sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; + targetPos.Y = clipRect->UpperLeftCorner.Y; + } + + if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; + if (sourceSize.Height <= 0) + return; + } + } + + // clip these coordinates + + if (targetPos.X<0) + { + sourceSize.Width += targetPos.X; + if (sourceSize.Width <= 0) + return; + + sourcePos.X -= targetPos.X; + targetPos.X = 0; + } + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + + if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) + { + sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; + if (sourceSize.Width <= 0) + return; + } + + if (targetPos.Y<0) + { + sourceSize.Height += targetPos.Y; + if (sourceSize.Height <= 0) + return; + + sourcePos.Y -= targetPos.Y; + targetPos.Y = 0; + } + + if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) + { + sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; + if (sourceSize.Height <= 0) + return; + } + + // ok, we've clipped everything. + // now draw it. + + const core::dimension2d& ss = texture->getOriginalSize(); + const f32 invW = 1.f / static_cast(ss.Width); + const f32 invH = 1.f / static_cast(ss.Height); + const core::rect tcoords( + sourcePos.X * invW, + sourcePos.Y * invH, + (sourcePos.X + sourceSize.Width) * invW, + (sourcePos.Y + sourceSize.Height) * invH); + + const core::rect poss(targetPos, sourceSize); + + disableTextures(1); + if (!setActiveTexture(0, texture)) + return; + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glBegin(GL_QUADS); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glEnd(); +} + + +//! The same, but with a four element array of colors, one for each vertex +void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + const core::dimension2d& ss = texture->getOriginalSize(); + const f32 invW = 1.f / static_cast(ss.Width); + const f32 invH = 1.f / static_cast(ss.Height); + const core::rect tcoords( + sourceRect.UpperLeftCorner.X * invW, + sourceRect.UpperLeftCorner.Y * invH, + sourceRect.LowerRightCorner.X * invW, + sourceRect.LowerRightCorner.Y *invH); + + const video::SColor temp[4] = + { + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFF + }; + + const video::SColor* const useColor = colors ? colors : temp; + + disableTextures(1); + setActiveTexture(0, texture); + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || + useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, + true, useAlphaChannelOfTexture); + + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, + clipRect->getWidth(), clipRect->getHeight()); + } + + glBegin(GL_QUADS); + + glColor4ub(useColor[0].getRed(), useColor[0].getGreen(), useColor[0].getBlue(), useColor[0].getAlpha()); + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.UpperLeftCorner.Y)); + + glColor4ub(useColor[3].getRed(), useColor[3].getGreen(), useColor[3].getBlue(), useColor[3].getAlpha()); + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.UpperLeftCorner.Y)); + + glColor4ub(useColor[2].getRed(), useColor[2].getGreen(), useColor[2].getBlue(), useColor[2].getAlpha()); + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(destRect.LowerRightCorner.X), GLfloat(destRect.LowerRightCorner.Y)); + + glColor4ub(useColor[1].getRed(), useColor[1].getGreen(), useColor[1].getBlue(), useColor[1].getAlpha()); + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(destRect.UpperLeftCorner.X), GLfloat(destRect.LowerRightCorner.Y)); + + glEnd(); + + if (clipRect) + glDisable(GL_SCISSOR_TEST); +} + + +//! draws a set of 2d images, using a color and the alpha channel of the +//! texture if desired. The images are drawn beginning at pos and concatenated +//! in one line. All drawings are clipped against clipRect (if != 0). +//! The subtextures are defined by the array of sourceRects and are chosen +//! by the indices given. +void COpenGLDriver::draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (!texture) + return; + + disableTextures(1); + if (!setActiveTexture(0, texture)) + return; + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + if (clipRect) + { + if (!clipRect->isValid()) + return; + + glEnable(GL_SCISSOR_TEST); + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, + clipRect->getWidth(),clipRect->getHeight()); + } + + const core::dimension2d& ss = texture->getOriginalSize(); + core::position2d targetPos(pos); + const f32 invW = 1.f / static_cast(ss.Width); + const f32 invH = 1.f / static_cast(ss.Height); + + for (u32 i=0; i tcoords( + sourceRects[currentIndex].UpperLeftCorner.X * invW, + sourceRects[currentIndex].UpperLeftCorner.Y * invH, + sourceRects[currentIndex].LowerRightCorner.X * invW, + sourceRects[currentIndex].LowerRightCorner.Y * invH); + + const core::rect poss(targetPos, sourceRects[currentIndex].getSize()); + + glBegin(GL_QUADS); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); + + glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); + glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); + + glEnd(); + targetPos.X += sourceRects[currentIndex].getWidth(); + } + if (clipRect) + glDisable(GL_SCISSOR_TEST); +} + + +//! draw a 2d rectangle +void COpenGLDriver::draw2DRectangle(SColor color, const core::rect& position, + const core::rect* clip) +{ + disableTextures(); + setRenderStates2DMode(color.getAlpha() < 255, false, false); + + core::rect pos = position; + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glRectf(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y), + GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y)); +} + + +//! draw an 2d rectangle +void COpenGLDriver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + core::rect pos = position; + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + disableTextures(); + + setRenderStates2DMode(colorLeftUp.getAlpha() < 255 || + colorRightUp.getAlpha() < 255 || + colorLeftDown.getAlpha() < 255 || + colorRightDown.getAlpha() < 255, false, false); + + glBegin(GL_QUADS); + glColor4ub(colorLeftUp.getRed(), colorLeftUp.getGreen(), + colorLeftUp.getBlue(), colorLeftUp.getAlpha()); + glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.UpperLeftCorner.Y)); + + glColor4ub(colorRightUp.getRed(), colorRightUp.getGreen(), + colorRightUp.getBlue(), colorRightUp.getAlpha()); + glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.UpperLeftCorner.Y)); + + glColor4ub(colorRightDown.getRed(), colorRightDown.getGreen(), + colorRightDown.getBlue(), colorRightDown.getAlpha()); + glVertex2f(GLfloat(pos.LowerRightCorner.X), GLfloat(pos.LowerRightCorner.Y)); + + glColor4ub(colorLeftDown.getRed(), colorLeftDown.getGreen(), + colorLeftDown.getBlue(), colorLeftDown.getAlpha()); + glVertex2f(GLfloat(pos.UpperLeftCorner.X), GLfloat(pos.LowerRightCorner.Y)); + + glEnd(); +} + + +//! Draws a 2d line. +void COpenGLDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, SColor color) +{ + if (start==end) + drawPixel(start.X, start.Y, color); + else + { + disableTextures(); + setRenderStates2DMode(color.getAlpha() < 255, false, false); + + glBegin(GL_LINES); + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + GLfloat x=(GLfloat)start.X; + GLfloat y=(GLfloat)start.Y; + if (x>end.X) + x += 0.5f; + if (y>end.Y) + y += 0.5f; + glVertex2f(GLfloat(x), GLfloat(y)); + x=(GLfloat)end.X; + y=(GLfloat)end.Y; + if (x>start.X) + x += 0.5f; + if (y>start.Y) + y += 0.5f; + glVertex2f(GLfloat(x), GLfloat(y)); + glEnd(); + } +} + +//! Draws a pixel +void COpenGLDriver::drawPixel(u32 x, u32 y, const SColor &color) +{ + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) + return; + + disableTextures(); + setRenderStates2DMode(color.getAlpha() < 255, false, false); + + glBegin(GL_POINTS); + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glVertex2i(x, y); + glEnd(); +} + +bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture) +{ + if (stage >= MaxSupportedTextures) + return false; + + if (CurrentTexture[stage]==texture) + return true; + + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB + stage); + + CurrentTexture.set(stage,texture); + + if (!texture) + { + glDisable(GL_TEXTURE_2D); + return true; + } + else + { + if (texture->getDriverType() != EDT_OPENGL) + { + glDisable(GL_TEXTURE_2D); + CurrentTexture.set(stage, 0); + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, + static_cast(texture)->getOpenGLTextureName()); + } + return true; +} + + +//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. +//! Returns whether disabling was successful or not. +bool COpenGLDriver::disableTextures(u32 fromStage) +{ + bool result=true; + for (u32 i=fromStage; i= 0; --i) + { + setActiveTexture(i, material.getTexture(i)); + setTransform ((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), + Material.getTextureMatrix(i)); + } +} + + +//! prints error if an error happened. +bool COpenGLDriver::testGLError() +{ +#ifdef _DEBUG + GLenum g = glGetError(); + switch (g) + { + case GL_NO_ERROR: + return false; + case GL_INVALID_ENUM: + os::Printer::log("GL_INVALID_ENUM", ELL_ERROR); break; + case GL_INVALID_VALUE: + os::Printer::log("GL_INVALID_VALUE", ELL_ERROR); break; + case GL_INVALID_OPERATION: + os::Printer::log("GL_INVALID_OPERATION", ELL_ERROR); break; + case GL_STACK_OVERFLOW: + os::Printer::log("GL_STACK_OVERFLOW", ELL_ERROR); break; + case GL_STACK_UNDERFLOW: + os::Printer::log("GL_STACK_UNDERFLOW", ELL_ERROR); break; + case GL_OUT_OF_MEMORY: + os::Printer::log("GL_OUT_OF_MEMORY", ELL_ERROR); break; + case GL_TABLE_TOO_LARGE: + os::Printer::log("GL_TABLE_TOO_LARGE", ELL_ERROR); break; +#if defined(GL_EXT_framebuffer_object) + case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: + os::Printer::log("GL_INVALID_FRAMEBUFFER_OPERATION", ELL_ERROR); break; +#endif + }; +// _IRR_DEBUG_BREAK_IF(true); + return true; +#else + return false; +#endif +} + + +//! sets the needed renderstates +void COpenGLDriver::setRenderStates3DMode() +{ + if (CurrentRenderMode != ERM_3D) + { + // Reset Texture Stages + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // switch back the matrices + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((Matrices[ETS_VIEW] * Matrices[ETS_WORLD]).pointer()); + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(Matrices[ETS_PROJECTION].pointer()); + + ResetRenderStates = true; +#ifdef GL_EXT_clip_volume_hint + if (FeatureAvailable[IRR_EXT_clip_volume_hint]) + glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_NICEST); +#endif + } + + if (ResetRenderStates || LastMaterial != Material) + { + // unset old material + + if (LastMaterial.MaterialType != Material.MaterialType && + static_cast(LastMaterial.MaterialType) < MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + + // set new material. + if (static_cast(Material.MaterialType) < MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( + Material, LastMaterial, ResetRenderStates, this); + + LastMaterial = Material; + ResetRenderStates = false; + } + + if (static_cast(Material.MaterialType) < MaterialRenderers.size()) + MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, video::EVT_STANDARD); + + CurrentRenderMode = ERM_3D; +} + + +//! Get native wrap mode value +GLint COpenGLDriver::getTextureWrapMode(const u8 clamp) +{ + GLint mode=GL_REPEAT; + switch (clamp) + { + case ETC_REPEAT: + mode=GL_REPEAT; + break; + case ETC_CLAMP: + mode=GL_CLAMP; + break; + case ETC_CLAMP_TO_EDGE: +#ifdef GL_VERSION_1_2 + if (Version>101) + mode=GL_CLAMP_TO_EDGE; + else +#endif +#ifdef GL_SGIS_texture_edge_clamp + if (FeatureAvailable[IRR_SGIS_texture_edge_clamp]) + mode=GL_CLAMP_TO_EDGE_SGIS; + else +#endif + // fallback + mode=GL_CLAMP; + break; + case ETC_CLAMP_TO_BORDER: +#ifdef GL_VERSION_1_3 + if (Version>102) + mode=GL_CLAMP_TO_BORDER; + else +#endif +#ifdef GL_ARB_texture_border_clamp + if (FeatureAvailable[IRR_ARB_texture_border_clamp]) + mode=GL_CLAMP_TO_BORDER_ARB; + else +#endif +#ifdef GL_SGIS_texture_border_clamp + if (FeatureAvailable[IRR_SGIS_texture_border_clamp]) + mode=GL_CLAMP_TO_BORDER_SGIS; + else +#endif + // fallback + mode=GL_CLAMP; + break; + case ETC_MIRROR: +#ifdef GL_VERSION_1_4 + if (Version>103) + mode=GL_MIRRORED_REPEAT; + else +#endif +#ifdef GL_ARB_texture_border_clamp + if (FeatureAvailable[IRR_ARB_texture_mirrored_repeat]) + mode=GL_MIRRORED_REPEAT_ARB; + else +#endif +#ifdef GL_IBM_texture_mirrored_repeat + if (FeatureAvailable[IRR_IBM_texture_mirrored_repeat]) + mode=GL_MIRRORED_REPEAT_IBM; + else +#endif + mode=GL_REPEAT; + break; + case ETC_MIRROR_CLAMP: +#ifdef GL_EXT_texture_mirror_clamp + if (FeatureAvailable[IRR_EXT_texture_mirror_clamp]) + mode=GL_MIRROR_CLAMP_EXT; + else +#endif +#if defined(GL_ATI_texture_mirror_once) + if (FeatureAvailable[IRR_ATI_texture_mirror_once]) + mode=GL_MIRROR_CLAMP_ATI; + else +#endif + mode=GL_CLAMP; + break; + case ETC_MIRROR_CLAMP_TO_EDGE: +#ifdef GL_EXT_texture_mirror_clamp + if (FeatureAvailable[IRR_EXT_texture_mirror_clamp]) + mode=GL_MIRROR_CLAMP_TO_EDGE_EXT; + else +#endif +#if defined(GL_ATI_texture_mirror_once) + if (FeatureAvailable[IRR_ATI_texture_mirror_once]) + mode=GL_MIRROR_CLAMP_TO_EDGE_ATI; + else +#endif + mode=GL_CLAMP; + break; + case ETC_MIRROR_CLAMP_TO_BORDER: +#ifdef GL_EXT_texture_mirror_clamp + if (FeatureAvailable[IRR_EXT_texture_mirror_clamp]) + mode=GL_MIRROR_CLAMP_TO_BORDER_EXT; + else +#endif + mode=GL_CLAMP; + break; + } + return mode; +} + + +void COpenGLDriver::setWrapMode(const SMaterial& material) +{ + // texture address mode + // Has to be checked always because it depends on the textures + for (u32 u=0; u0) + break; // stop loop + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[u].TextureWrapU)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[u].TextureWrapV)); + } +} + + +//! Can be called by an IMaterialRenderer to make its work easier. +void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderStates) +{ + if (resetAllRenderStates || + lastmaterial.ColorMaterial != material.ColorMaterial) + { + switch (material.ColorMaterial) + { + case ECM_NONE: + glDisable(GL_COLOR_MATERIAL); + break; + case ECM_DIFFUSE: + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + break; + case ECM_AMBIENT: + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); + break; + case ECM_EMISSIVE: + glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); + break; + case ECM_SPECULAR: + glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); + break; + case ECM_DIFFUSE_AND_AMBIENT: + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + break; + } + if (material.ColorMaterial != ECM_NONE) + glEnable(GL_COLOR_MATERIAL); + } + + if (resetAllRenderStates || + lastmaterial.AmbientColor != material.AmbientColor || + lastmaterial.DiffuseColor != material.DiffuseColor || + lastmaterial.EmissiveColor != material.EmissiveColor || + lastmaterial.ColorMaterial != material.ColorMaterial) + { + GLfloat color[4]; + + const f32 inv = 1.0f / 255.0f; + + if ((material.ColorMaterial != video::ECM_AMBIENT) && + (material.ColorMaterial != video::ECM_DIFFUSE_AND_AMBIENT)) + { + color[0] = material.AmbientColor.getRed() * inv; + color[1] = material.AmbientColor.getGreen() * inv; + color[2] = material.AmbientColor.getBlue() * inv; + color[3] = material.AmbientColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); + } + + if ((material.ColorMaterial != video::ECM_DIFFUSE) && + (material.ColorMaterial != video::ECM_DIFFUSE_AND_AMBIENT)) + { + color[0] = material.DiffuseColor.getRed() * inv; + color[1] = material.DiffuseColor.getGreen() * inv; + color[2] = material.DiffuseColor.getBlue() * inv; + color[3] = material.DiffuseColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); + } + + if (material.ColorMaterial != video::ECM_EMISSIVE) + { + color[0] = material.EmissiveColor.getRed() * inv; + color[1] = material.EmissiveColor.getGreen() * inv; + color[2] = material.EmissiveColor.getBlue() * inv; + color[3] = material.EmissiveColor.getAlpha() * inv; + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color); + } + } + + if (resetAllRenderStates || + lastmaterial.SpecularColor != material.SpecularColor || + lastmaterial.Shininess != material.Shininess || + lastmaterial.ColorMaterial != material.ColorMaterial) + { + GLfloat color[4]={0.f,0.f,0.f,1.f}; + const f32 inv = 1.0f / 255.0f; + + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material.Shininess); + // disable Specular colors if no shininess is set + if ((material.Shininess != 0.0f) && + (material.ColorMaterial != video::ECM_SPECULAR)) + { +#ifdef GL_EXT_separate_specular_color + if (FeatureAvailable[IRR_EXT_separate_specular_color]) + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); +#endif + color[0] = material.SpecularColor.getRed() * inv; + color[1] = material.SpecularColor.getGreen() * inv; + color[2] = material.SpecularColor.getBlue() * inv; + color[3] = material.SpecularColor.getAlpha() * inv; + } +#ifdef GL_EXT_separate_specular_color + else if (FeatureAvailable[IRR_EXT_separate_specular_color]) + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); +#endif + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); + } + + // Texture filter + // Has to be checked always because it depends on the textures + // Filtering has to be set for each texture layer + for (u32 i=0; i0) + break; + +#ifdef GL_EXT_texture_lod_bias + if (FeatureAvailable[IRR_EXT_texture_lod_bias]) + { + if (material.TextureLayer[i].LODBias) + { + const float tmp = core::clamp(material.TextureLayer[i].LODBias * 0.125f, -MaxTextureLODBias, MaxTextureLODBias); + glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, tmp); + } + else + glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.f); + } +#endif + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); + + if (material.UseMipMaps && CurrentTexture[i]->hasMipMaps()) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR : + material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST : + GL_NEAREST_MIPMAP_NEAREST); + else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST); + +#ifdef GL_EXT_texture_filter_anisotropic + if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic]) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1); +#endif + } + + // fillmode + if (resetAllRenderStates || (lastmaterial.Wireframe != material.Wireframe) || (lastmaterial.PointCloud != material.PointCloud)) + glPolygonMode(GL_FRONT_AND_BACK, material.Wireframe ? GL_LINE : material.PointCloud? GL_POINT : GL_FILL); + + // shademode + if (resetAllRenderStates || (lastmaterial.GouraudShading != material.GouraudShading)) + { + if (material.GouraudShading) + glShadeModel(GL_SMOOTH); + else + glShadeModel(GL_FLAT); + } + + // lighting + if (resetAllRenderStates || (lastmaterial.Lighting != material.Lighting)) + { + if (material.Lighting) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); + } + + // zbuffer + if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer) + { + switch (material.ZBuffer) + { + case ECFN_NEVER: + glDisable(GL_DEPTH_TEST); + break; + case ECFN_LESSEQUAL: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + break; + case ECFN_EQUAL: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_EQUAL); + break; + case ECFN_LESS: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + break; + case ECFN_NOTEQUAL: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_NOTEQUAL); + break; + case ECFN_GREATEREQUAL: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_GEQUAL); + break; + case ECFN_GREATER: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_GREATER); + break; + case ECFN_ALWAYS: + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + break; + } + } + + // zwrite +// if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable) + { + if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) + { + glDepthMask(GL_TRUE); + } + else + glDepthMask(GL_FALSE); + } + + // back face culling + if (resetAllRenderStates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) + { + if ((material.FrontfaceCulling) && (material.BackfaceCulling)) + { + glCullFace(GL_FRONT_AND_BACK); + glEnable(GL_CULL_FACE); + } + else + if (material.BackfaceCulling) + { + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + } + else + if (material.FrontfaceCulling) + { + glCullFace(GL_FRONT); + glEnable(GL_CULL_FACE); + } + else + glDisable(GL_CULL_FACE); + } + + // fog + if (resetAllRenderStates || lastmaterial.FogEnable != material.FogEnable) + { + if (material.FogEnable) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + } + + // normalization + if (resetAllRenderStates || lastmaterial.NormalizeNormals != material.NormalizeNormals) + { + if (material.NormalizeNormals) + glEnable(GL_NORMALIZE); + else + glDisable(GL_NORMALIZE); + } + + // Color Mask + if (resetAllRenderStates || lastmaterial.ColorMask != material.ColorMask) + { + glColorMask( + (material.ColorMask & ECP_RED)?GL_TRUE:GL_FALSE, + (material.ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE, + (material.ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE, + (material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE); + } + + if (queryFeature(EVDF_BLEND_OPERATIONS) && + (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation)) + { + if (material.BlendOperation==EBO_NONE) + glDisable(GL_BLEND); + else + { + glEnable(GL_BLEND); +#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) || defined(GL_VERSION_1_2) + switch (material.BlendOperation) + { + case EBO_SUBTRACT: +#if defined(GL_EXT_blend_subtract) + if (FeatureAvailable[IRR_EXT_blend_subtract] || (Version>=120)) + extGlBlendEquation(GL_FUNC_SUBTRACT_EXT); +#elif defined(GL_VERSION_1_2) + if (Version>=120) + extGlBlendEquation(GL_FUNC_SUBTRACT); +#endif + break; + case EBO_REVSUBTRACT: +#if defined(GL_EXT_blend_subtract) + if (FeatureAvailable[IRR_EXT_blend_subtract] || (Version>=120)) + extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT_EXT); +#elif defined(GL_VERSION_1_2) + if (Version>=120) + extGlBlendEquation(GL_FUNC_REVERSE_SUBTRACT); +#endif + break; + case EBO_MIN: +#if defined(GL_EXT_blend_minmax) + if (FeatureAvailable[IRR_EXT_blend_minmax] || (Version>=120)) + extGlBlendEquation(GL_MIN_EXT); +#elif defined(GL_VERSION_1_2) + if (Version>=120) + extGlBlendEquation(GL_MIN); +#endif + break; + case EBO_MAX: +#if defined(GL_EXT_blend_minmax) + if (FeatureAvailable[IRR_EXT_blend_minmax] || (Version>=120)) + extGlBlendEquation(GL_MAX_EXT); +#elif defined(GL_VERSION_1_2) + if (Version>=120) + extGlBlendEquation(GL_MAX); +#endif + break; + case EBO_MIN_FACTOR: +#if defined(GL_AMD_blend_minmax_factor) + if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) + extGlBlendEquation(GL_FACTOR_MIN_AMD); +#endif + // fallback in case of missing extension +#if defined(GL_VERSION_1_2) +#if defined(GL_AMD_blend_minmax_factor) + else +#endif + if (Version>=120) + extGlBlendEquation(GL_MIN); +#endif + break; + case EBO_MAX_FACTOR: +#if defined(GL_AMD_blend_minmax_factor) + if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) + extGlBlendEquation(GL_FACTOR_MAX_AMD); +#endif + // fallback in case of missing extension +#if defined(GL_VERSION_1_2) +#if defined(GL_AMD_blend_minmax_factor) + else +#endif + if (Version>=120) + extGlBlendEquation(GL_MAX); +#endif + break; + case EBO_MIN_ALPHA: +#if defined(GL_SGIX_blend_alpha_minmax) + if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax]) + extGlBlendEquation(GL_ALPHA_MIN_SGIX); + // fallback in case of missing extension + else + if (FeatureAvailable[IRR_EXT_blend_minmax]) + extGlBlendEquation(GL_MIN_EXT); +#endif + break; + case EBO_MAX_ALPHA: +#if defined(GL_SGIX_blend_alpha_minmax) + if (FeatureAvailable[IRR_SGIX_blend_alpha_minmax]) + extGlBlendEquation(GL_ALPHA_MAX_SGIX); + // fallback in case of missing extension + else + if (FeatureAvailable[IRR_EXT_blend_minmax]) + extGlBlendEquation(GL_MAX_EXT); +#endif + break; + default: +#if defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_logic_op) + extGlBlendEquation(GL_FUNC_ADD_EXT); +#elif defined(GL_VERSION_1_2) + extGlBlendEquation(GL_FUNC_ADD); +#endif + break; + } +#endif + } + } + + // Polygon Offset + if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderStates || + lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || + lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) + { + glDisable(lastmaterial.Wireframe?GL_POLYGON_OFFSET_LINE:lastmaterial.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL); + if (material.PolygonOffsetFactor) + { + glDisable(material.Wireframe?GL_POLYGON_OFFSET_LINE:material.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL); + glEnable(material.Wireframe?GL_POLYGON_OFFSET_LINE:material.PointCloud?GL_POLYGON_OFFSET_POINT:GL_POLYGON_OFFSET_FILL); + } + if (material.PolygonOffsetDirection==EPO_BACK) + glPolygonOffset(1.0f, (GLfloat)material.PolygonOffsetFactor); + else + glPolygonOffset(-1.0f, (GLfloat)-material.PolygonOffsetFactor); + } + + // thickness + if (resetAllRenderStates || lastmaterial.Thickness != material.Thickness) + { + if (AntiAlias) + { +// glPointSize(core::clamp(static_cast(material.Thickness), DimSmoothedPoint[0], DimSmoothedPoint[1])); + // we don't use point smoothing + glPointSize(core::clamp(static_cast(material.Thickness), DimAliasedPoint[0], DimAliasedPoint[1])); + glLineWidth(core::clamp(static_cast(material.Thickness), DimSmoothedLine[0], DimSmoothedLine[1])); + } + else + { + glPointSize(core::clamp(static_cast(material.Thickness), DimAliasedPoint[0], DimAliasedPoint[1])); + glLineWidth(core::clamp(static_cast(material.Thickness), DimAliasedLine[0], DimAliasedLine[1])); + } + } + + // Anti aliasing + if (resetAllRenderStates || lastmaterial.AntiAliasing != material.AntiAliasing) + { + if (FeatureAvailable[IRR_ARB_multisample]) + { + if (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE) + glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); + else if (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE) + glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); + + if ((AntiAlias >= 2) && (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))) + { + glEnable(GL_MULTISAMPLE_ARB); +#ifdef GL_NV_multisample_filter_hint + if (FeatureAvailable[IRR_NV_multisample_filter_hint]) + { + if ((material.AntiAliasing & EAAM_QUALITY) == EAAM_QUALITY) + glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); + else + glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); + } +#endif + } + else + glDisable(GL_MULTISAMPLE_ARB); + } + if ((material.AntiAliasing & EAAM_LINE_SMOOTH) != (lastmaterial.AntiAliasing & EAAM_LINE_SMOOTH)) + { + if (material.AntiAliasing & EAAM_LINE_SMOOTH) + glEnable(GL_LINE_SMOOTH); + else if (lastmaterial.AntiAliasing & EAAM_LINE_SMOOTH) + glDisable(GL_LINE_SMOOTH); + } + if ((material.AntiAliasing & EAAM_POINT_SMOOTH) != (lastmaterial.AntiAliasing & EAAM_POINT_SMOOTH)) + { + if (material.AntiAliasing & EAAM_POINT_SMOOTH) + // often in software, and thus very slow + glEnable(GL_POINT_SMOOTH); + else if (lastmaterial.AntiAliasing & EAAM_POINT_SMOOTH) + glDisable(GL_POINT_SMOOTH); + } + } + + setWrapMode(material); + + // be sure to leave in texture stage 0 + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB); +} + + +//! Enable the 2d override material +void COpenGLDriver::enableMaterial2D(bool enable) +{ + if (!enable) + CurrentRenderMode = ERM_NONE; + CNullDriver::enableMaterial2D(enable); +} + + +//! sets the needed renderstates +void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) +{ + if (CurrentRenderMode != ERM_2D || Transformation3DChanged) + { + // unset last 3d material + if (CurrentRenderMode == ERM_3D) + { + if (static_cast(LastMaterial.MaterialType) < MaterialRenderers.size()) + MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); + } + if (Transformation3DChanged) + { + glMatrixMode(GL_PROJECTION); + + const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); + core::matrix4 m(core::matrix4::EM4CONST_NOTHING); + m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f); + m.setTranslation(core::vector3df(-1,1,0)); + glLoadMatrixf(m.pointer()); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.375f, 0.375f, 0.0f); + + // Make sure we set first texture matrix + if (MultiTextureExtension) + extGlActiveTexture(GL_TEXTURE0_ARB); + + Transformation3DChanged = false; + } + if (!OverrideMaterial2DEnabled) + { + setBasicRenderStates(InitMaterial2D, LastMaterial, true); + LastMaterial = InitMaterial2D; + } + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#ifdef GL_EXT_clip_volume_hint + if (FeatureAvailable[IRR_EXT_clip_volume_hint]) + glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); +#endif + + } + if (OverrideMaterial2DEnabled) + { + OverrideMaterial2D.Lighting=false; + setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); + LastMaterial = OverrideMaterial2D; + } + + // no alphaChannel without texture + alphaChannel &= texture; + + if (alphaChannel || alpha) + { + glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + } + else + { + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + if (texture) + { + if (!OverrideMaterial2DEnabled) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + Material.setTexture(0, const_cast(CurrentTexture[0])); + setTransform(ETS_TEXTURE_0, core::IdentityMatrix); + // Due to the transformation change, the previous line would call a reset each frame + // but we can safely reset the variable as it was false before + Transformation3DChanged=false; + + if (alphaChannel) + { + // if alpha and alpha texture just modulate, otherwise use only the alpha channel + if (alpha) + { + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + { +#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) + if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); + // rgb always modulates + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + // rgb always modulates + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); +#endif + } + else +#endif + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } + else + { + if (alpha) + { +#if defined(GL_ARB_texture_env_combine) || defined(GL_EXT_texture_env_combine) + if (FeatureAvailable[IRR_ARB_texture_env_combine]||FeatureAvailable[IRR_EXT_texture_env_combine]) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); + // rgb always modulates + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); + // rgb always modulates + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); +#endif + } + else +#endif + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } + } + + CurrentRenderMode = ERM_2D; +} + + +//! \return Returns the name of the video driver. +const wchar_t* COpenGLDriver::getName() const +{ + return Name.c_str(); +} + + +//! deletes all dynamic lights there are +void COpenGLDriver::deleteAllDynamicLights() +{ + for (s32 i=0; i= (s32)RequestedLights.size()) + return; + + RequestedLight & requestedLight = RequestedLights[lightIndex]; + + requestedLight.DesireToBeOn = turnOn; + + if(turnOn) + { + if(-1 == requestedLight.HardwareLightIndex) + assignHardwareLight(lightIndex); + } + else + { + if(-1 != requestedLight.HardwareLightIndex) + { + // It's currently assigned, so free up the hardware light + glDisable(requestedLight.HardwareLightIndex); + requestedLight.HardwareLightIndex = -1; + + // Now let the first light that's waiting on a free hardware light grab it + for(u32 requested = 0; requested < RequestedLights.size(); ++requested) + if(RequestedLights[requested].DesireToBeOn + && + -1 == RequestedLights[requested].HardwareLightIndex) + { + assignHardwareLight(requested); + break; + } + } + } +} + + +//! returns the maximal amount of dynamic lights the device can handle +u32 COpenGLDriver::getMaximalDynamicLightAmount() const +{ + return MaxLights; +} + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void COpenGLDriver::setAmbientLight(const SColorf& color) +{ + GLfloat data[4] = {color.r, color.g, color.b, color.a}; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data); +} + + +// this code was sent in by Oliver Klems, thank you! (I modified the glViewport +// method just a bit. +void COpenGLDriver::setViewPort(const core::rect& area) +{ + if (area == ViewPort) + return; + core::rect vp = area; + core::rect rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); + vp.clipAgainst(rendert); + + if (vp.getHeight()>0 && vp.getWidth()>0) + { + glViewport(vp.UpperLeftCorner.X, + getCurrentRenderTargetSize().Height - vp.UpperLeftCorner.Y - vp.getHeight(), + vp.getWidth(), vp.getHeight()); + + ViewPort = vp; + } +} + + +//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do +//! this: First, draw all geometry. Then use this method, to draw the shadow +//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow. +void COpenGLDriver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) +{ + const u32 count=triangles.size(); + if (!StencilBuffer || !count) + return; + + // unset last 3d material + if (CurrentRenderMode == ERM_3D && + static_cast(Material.MaterialType) < MaterialRenderers.size()) + { + MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); + ResetRenderStates = true; + } + + // store current OpenGL state + glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | + GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDepthFunc(GL_LESS); + glDepthMask(GL_FALSE); // no depth buffer writing + if (debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no color buffer drawing + glEnable(GL_STENCIL_TEST); + } + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3,GL_FLOAT,sizeof(core::vector3df),triangles.const_pointer()); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + GLenum incr = GL_INCR; + GLenum decr = GL_DECR; +#ifdef GL_EXT_stencil_wrap + if (FeatureAvailable[IRR_EXT_stencil_wrap]) + { + incr = GL_INCR_WRAP_EXT; + decr = GL_DECR_WRAP_EXT; + } +#endif +#ifdef GL_NV_depth_clamp + if (FeatureAvailable[IRR_NV_depth_clamp]) + glEnable(GL_DEPTH_CLAMP_NV); +#endif + + // The first parts are not correctly working, yet. +#if 0 +#ifdef GL_EXT_stencil_two_side + if (FeatureAvailable[IRR_EXT_stencil_two_side]) + { + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); + glDisable(GL_CULL_FACE); + if (zfail) + { + extGlActiveStencilFace(GL_BACK); + glStencilOp(GL_KEEP, incr, GL_KEEP); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + extGlActiveStencilFace(GL_FRONT); + glStencilOp(GL_KEEP, decr, GL_KEEP); + } + else // zpass + { + extGlActiveStencilFace(GL_BACK); + glStencilOp(GL_KEEP, GL_KEEP, decr); + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + + extGlActiveStencilFace(GL_FRONT); + glStencilOp(GL_KEEP, GL_KEEP, incr); + } + glStencilMask(~0); + glStencilFunc(GL_ALWAYS, 0, ~0); + glDrawArrays(GL_TRIANGLES,0,count); + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); + } + else +#endif + if (FeatureAvailable[IRR_ATI_separate_stencil]) + { + glDisable(GL_CULL_FACE); + if (zfail) + { + extGlStencilOpSeparate(GL_BACK, GL_KEEP, incr, GL_KEEP); + extGlStencilOpSeparate(GL_FRONT, GL_KEEP, decr, GL_KEEP); + } + else // zpass + { + extGlStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, decr); + extGlStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, incr); + } + extGlStencilFuncSeparate(GL_ALWAYS, GL_ALWAYS, 0, ~0); + glStencilMask(~0); + glDrawArrays(GL_TRIANGLES,0,count); + } + else +#endif + { + glEnable(GL_CULL_FACE); + if (zfail) + { + glCullFace(GL_FRONT); + glStencilOp(GL_KEEP, incr, GL_KEEP); + glDrawArrays(GL_TRIANGLES,0,count); + + glCullFace(GL_BACK); + glStencilOp(GL_KEEP, decr, GL_KEEP); + glDrawArrays(GL_TRIANGLES,0,count); + } + else // zpass + { + glCullFace(GL_BACK); + glStencilOp(GL_KEEP, GL_KEEP, incr); + glDrawArrays(GL_TRIANGLES,0,count); + + glCullFace(GL_FRONT); + glStencilOp(GL_KEEP, GL_KEEP, decr); + glDrawArrays(GL_TRIANGLES,0,count); + } + } +#ifdef GL_NV_depth_clamp + if (FeatureAvailable[IRR_NV_depth_clamp]) + glDisable(GL_DEPTH_CLAMP_NV); +#endif + + glDisable(GL_POLYGON_OFFSET_FILL); + glDisableClientState(GL_VERTEX_ARRAY); //not stored on stack + glPopAttrib(); +} + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!StencilBuffer) + return; + + disableTextures(); + + // store attributes + glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT | GL_LIGHTING_BIT); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDepthMask(GL_FALSE); + + glShadeModel(GL_FLAT); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_NOTEQUAL, 0, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + // draw a shadow rectangle covering the entire screen using stencil buffer + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glBegin(GL_QUADS); + + glColor4ub(leftDownEdge.getRed(), leftDownEdge.getGreen(), leftDownEdge.getBlue(), leftDownEdge.getAlpha()); + glVertex3f(-1.f,-1.f,-0.9f); + + glColor4ub(leftUpEdge.getRed(), leftUpEdge.getGreen(), leftUpEdge.getBlue(), leftUpEdge.getAlpha()); + glVertex3f(-1.f, 1.f,-0.9f); + + glColor4ub(rightUpEdge.getRed(), rightUpEdge.getGreen(), rightUpEdge.getBlue(), rightUpEdge.getAlpha()); + glVertex3f(1.f, 1.f,-0.9f); + + glColor4ub(rightDownEdge.getRed(), rightDownEdge.getGreen(), rightDownEdge.getBlue(), rightDownEdge.getAlpha()); + glVertex3f(1.f,-1.f,-0.9f); + + glEnd(); + + clearBuffers(false, false, clearStencilBuffer, 0x0); + + // restore settings + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); +} + + +//! Sets the fog mode. +void COpenGLDriver::setFog(SColor c, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(c, fogType, start, end, density, pixelFog, rangeFog); + + glFogf(GL_FOG_MODE, GLfloat((fogType==EFT_FOG_LINEAR)? GL_LINEAR : (fogType==EFT_FOG_EXP)?GL_EXP:GL_EXP2)); + +#ifdef GL_EXT_fog_coord + if (FeatureAvailable[IRR_EXT_fog_coord]) + glFogi(GL_FOG_COORDINATE_SOURCE, GL_FRAGMENT_DEPTH); +#endif +#ifdef GL_NV_fog_distance + if (FeatureAvailable[IRR_NV_fog_distance]) + { + if (rangeFog) + glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV); + else + glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV); + } +#endif + + if (fogType==EFT_FOG_LINEAR) + { + glFogf(GL_FOG_START, start); + glFogf(GL_FOG_END, end); + } + else + glFogf(GL_FOG_DENSITY, density); + + if (pixelFog) + glHint(GL_FOG_HINT, GL_NICEST); + else + glHint(GL_FOG_HINT, GL_FASTEST); + + SColorf color(c); + GLfloat data[4] = {color.r, color.g, color.b, color.a}; + glFogfv(GL_FOG_COLOR, data); +} + + +//! Draws a 3d line. +void COpenGLDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + setRenderStates3DMode(); + + glBegin(GL_LINES); + glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glVertex3f(start.X, start.Y, start.Z); + + glVertex3f(end.X, end.Y, end.Z); + glEnd(); +} + + +//! Removes a texture from the texture cache and deletes it, freeing lot of memory. +void COpenGLDriver::removeTexture(ITexture* texture) +{ + if (!texture) + return; + + CNullDriver::removeTexture(texture); + // Remove this texture from CurrentTexture as well + CurrentTexture.remove(texture); +} + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void COpenGLDriver::OnResize(const core::dimension2d& size) +{ + CNullDriver::OnResize(size); + glViewport(0, 0, size.Width, size.Height); + Transformation3DChanged = true; +} + + +//! Returns type of video driver +E_DRIVER_TYPE COpenGLDriver::getDriverType() const +{ + return EDT_OPENGL; +} + + +//! returns color format +ECOLOR_FORMAT COpenGLDriver::getColorFormat() const +{ + return ColorFormat; +} + + +//! Sets a vertex shader constant. +void COpenGLDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ +#ifdef GL_ARB_vertex_program + for (s32 i=0; isetPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); + return false; +} + +//! Bool interface for the above. +bool COpenGLDriver::setPixelShaderConstant(const c8* name, const bool* bools, int count) +{ + os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); + return false; +} + +//! Int interface for the above. +bool COpenGLDriver::setPixelShaderConstant(const c8* name, const s32* ints, int count) +{ + os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant()."); + return false; +} + + +//! Adds a new material renderer to the VideoDriver, using pixel and/or +//! vertex shaders to render geometry. +s32 COpenGLDriver::addShaderMaterial(const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, s32 userData) +{ + s32 nr = -1; + COpenGLShaderMaterialRenderer* r = new COpenGLShaderMaterialRenderer( + this, nr, vertexShaderProgram, pixelShaderProgram, + callback, getMaterialRenderer(baseMaterial), userData); + + r->drop(); + return nr; +} + + +//! Adds a new material renderer to the VideoDriver, using GLSL to render geometry. +s32 COpenGLDriver::addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName, + E_GEOMETRY_SHADER_TYPE gsCompileTarget, + scene::E_PRIMITIVE_TYPE inType, + scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut, + IShaderConstantSetCallBack* callback, + E_MATERIAL_TYPE baseMaterial, + s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) +{ + s32 nr = -1; + + #ifdef _IRR_COMPILE_WITH_CG_ + if (shadingLang == EGSL_CG) + { + COpenGLCgMaterialRenderer* r = new COpenGLCgMaterialRenderer( + this, nr, + vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, + pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, + geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, + inType, outType, verticesOut, + callback,getMaterialRenderer(baseMaterial), userData); + + r->drop(); + } + else + #endif + { + COpenGLSLMaterialRenderer* r = new COpenGLSLMaterialRenderer( + this, nr, + vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, + pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, + geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, + inType, outType, verticesOut, + callback,getMaterialRenderer(baseMaterial), userData); + + r->drop(); + } + + return nr; +} + + +//! Returns a pointer to the IVideoDriver interface. (Implementation for +//! IMaterialRendererServices) +IVideoDriver* COpenGLDriver::getVideoDriver() +{ + return this; +} + + +ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, + const ECOLOR_FORMAT format) +{ + //disable mip-mapping + bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); + setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false); + + video::ITexture* rtt = 0; +#if defined(GL_EXT_framebuffer_object) + // if driver supports FrameBufferObjects, use them + if (queryFeature(EVDF_FRAMEBUFFER_OBJECT)) + { + rtt = new COpenGLFBOTexture(size, name, this, format); + if (rtt) + { + bool success = false; + addTexture(rtt); + ITexture* tex = createDepthTexture(rtt); + if (tex) + { + success = static_cast(tex)->attach(rtt); + if ( !success ) + { + removeDepthTexture(tex); + } + tex->drop(); + } + rtt->drop(); + if (!success) + { + removeTexture(rtt); + rtt=0; + } + } + } + else +#endif + { + // the simple texture is only possible for size <= screensize + // we try to find an optimal size with the original constraints + core::dimension2du destSize(core::min_(size.Width,ScreenSize.Width), core::min_(size.Height,ScreenSize.Height)); + destSize = destSize.getOptimalSize((size==size.getOptimalSize()), false, false); + rtt = addTexture(destSize, name, ECF_A8R8G8B8); + if (rtt) + { + static_cast(rtt)->setIsRenderTarget(true); + } + } + + //restore mip-mapping + setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels); + + return rtt; +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 COpenGLDriver::getMaximalPrimitiveCount() const +{ + return 0x7fffffff; +} + + +//! set or reset render target +bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, + bool clearZBuffer, SColor color) +{ + if (target != CurrentTarget) + setRenderTarget(0, false, false, 0x0); + + if (ERT_RENDER_TEXTURE == target) + { + os::Printer::log("For render textures call setRenderTarget with the actual texture as first parameter.", ELL_ERROR); + return false; + } + if (ERT_MULTI_RENDER_TEXTURES == target) + { + os::Printer::log("For multiple render textures call setRenderTarget with the texture array as first parameter.", ELL_ERROR); + return false; + } + + if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target)) + { + if (Params.Doublebuffer) + glDrawBuffer(GL_BACK_RIGHT); + else + glDrawBuffer(GL_FRONT_RIGHT); + } + else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target) + { + if (Params.Doublebuffer) + glDrawBuffer(GL_BACK); + else + glDrawBuffer(GL_FRONT); + } + else if ((target >= ERT_AUX_BUFFER0) && (target-ERT_AUX_BUFFER0 < MaxAuxBuffers)) + { + glDrawBuffer(GL_AUX0+target-ERT_AUX_BUFFER0); + } + else + { + if (Params.Doublebuffer) + glDrawBuffer(GL_BACK_LEFT); + else + glDrawBuffer(GL_FRONT_LEFT); + // exit with false, but also with working color buffer + if (target != ERT_FRAME_BUFFER) + return false; + } + CurrentTarget=target; + clearBuffers(clearTarget, clearZBuffer, false, color); + return true; +} + + +//! set or reset render target +bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + // check for right driver type + + if (texture && texture->getDriverType() != EDT_OPENGL) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + +#if defined(GL_EXT_framebuffer_object) + if (CurrentTarget==ERT_MULTI_RENDER_TEXTURES) + { + for (u32 i=0; iunbindRTT(); + } + + if (texture) + { + // we want to set a new target. so do this. + glViewport(0, 0, texture->getSize().Width, texture->getSize().Height); + RenderTargetTexture = static_cast(texture); + // calls glDrawBuffer as well + RenderTargetTexture->bindRTT(); + CurrentRendertargetSize = texture->getSize(); + CurrentTarget=ERT_RENDER_TEXTURE; + } + else + { + glViewport(0,0,ScreenSize.Width,ScreenSize.Height); + RenderTargetTexture = 0; + CurrentRendertargetSize = core::dimension2d(0,0); + CurrentTarget=ERT_FRAME_BUFFER; + glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT); + } + // we need to update the matrices due to the rendersize change. + Transformation3DChanged=true; + } + + clearBuffers(clearBackBuffer, clearZBuffer, false, color); + + return true; +} + + +//! Sets multiple render targets +bool COpenGLDriver::setRenderTarget(const core::array& targets, + bool clearBackBuffer, bool clearZBuffer, SColor color) +{ + // if simply disabling the MRT via array call + if (targets.size()==0) + return setRenderTarget(0, clearBackBuffer, clearZBuffer, color); + // if disabling old MRT, but enabling new one as well + if ((MRTargets.size()!=0) && (targets != MRTargets)) + setRenderTarget(0, clearBackBuffer, clearZBuffer, color); + // if no change, simply clear buffers + else if (targets == MRTargets) + { + clearBuffers(clearBackBuffer, clearZBuffer, false, color); + return true; + } + + // copy to storage for correct disabling + MRTargets=targets; + + u32 maxMultipleRTTs = core::min_(static_cast(MaxMultipleRenderTargets), targets.size()); + + // determine common size + core::dimension2du rttSize = CurrentRendertargetSize; + if (targets[0].TargetType==ERT_RENDER_TEXTURE) + { + if (!targets[0].RenderTexture) + { + os::Printer::log("Missing render texture for MRT.", ELL_ERROR); + return false; + } + rttSize=targets[0].RenderTexture->getSize(); + } + + for (u32 i = 0; i < maxMultipleRTTs; ++i) + { + // check for right driver type + if (targets[i].TargetType==ERT_RENDER_TEXTURE) + { + if (!targets[i].RenderTexture) + { + maxMultipleRTTs=i; + os::Printer::log("Missing render texture for MRT.", ELL_WARNING); + break; + } + if (targets[i].RenderTexture->getDriverType() != EDT_OPENGL) + { + maxMultipleRTTs=i; + os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING); + break; + } + + // check for valid render target + if (!targets[i].RenderTexture->isRenderTarget() || !static_cast(targets[i].RenderTexture)->isFrameBufferObject()) + { + maxMultipleRTTs=i; + os::Printer::log("Tried to set a non FBO-RTT as render target.", ELL_WARNING); + break; + } + + // check for valid size + if (rttSize != targets[i].RenderTexture->getSize()) + { + maxMultipleRTTs=i; + os::Printer::log("Render target texture has wrong size.", ELL_WARNING); + break; + } + } + } + if (maxMultipleRTTs==0) + { + os::Printer::log("No valid MRTs.", ELL_ERROR); + return false; + } + + // init FBO, if any + for (u32 i=0; i 1) + { + CurrentTarget=ERT_MULTI_RENDER_TEXTURES; + core::array MRTs; + MRTs.set_used(maxMultipleRTTs); + for(u32 i = 0; i < maxMultipleRTTs; i++) + { + if (FeatureAvailable[IRR_EXT_draw_buffers2]) + { + extGlColorMaskIndexed(i, + (targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE, + (targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE, + (targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE, + (targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE); + if (targets[i].BlendOp==EBO_NONE) + extGlDisableIndexed(GL_BLEND, i); + else + extGlEnableIndexed(GL_BLEND, i); + } +#if defined(GL_AMD_draw_buffers_blend) || defined(GL_ARB_draw_buffers_blend) + if (FeatureAvailable[IRR_AMD_draw_buffers_blend] || FeatureAvailable[IRR_ARB_draw_buffers_blend]) + { + extGlBlendFuncIndexed(i, getGLBlend(targets[i].BlendFuncSrc), getGLBlend(targets[i].BlendFuncDst)); + switch(targets[i].BlendOp) + { + case EBO_SUBTRACT: + extGlBlendEquationIndexed(i, GL_FUNC_SUBTRACT); + break; + case EBO_REVSUBTRACT: + extGlBlendEquationIndexed(i, GL_FUNC_REVERSE_SUBTRACT); + break; + case EBO_MIN: + extGlBlendEquationIndexed(i, GL_MIN); + break; + case EBO_MAX: + extGlBlendEquationIndexed(i, GL_MAX); + break; + case EBO_MIN_FACTOR: + case EBO_MIN_ALPHA: +#if defined(GL_AMD_blend_minmax_factor) + if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) + extGlBlendEquationIndexed(i, GL_FACTOR_MIN_AMD); + // fallback in case of missing extension + else +#endif + extGlBlendEquation(GL_MIN); + break; + case EBO_MAX_FACTOR: + case EBO_MAX_ALPHA: +#if defined(GL_AMD_blend_minmax_factor) + if (FeatureAvailable[IRR_AMD_blend_minmax_factor]) + extGlBlendEquationIndexed(i, GL_FACTOR_MAX_AMD); + // fallback in case of missing extension + else +#endif + extGlBlendEquation(GL_MAX); + break; + default: + extGlBlendEquationIndexed(i, GL_FUNC_ADD); + break; + } + } +#endif + if (targets[i].TargetType==ERT_RENDER_TEXTURE) + { + GLenum attachment = GL_NONE; +#ifdef GL_EXT_framebuffer_object + // attach texture to FrameBuffer Object on Color [i] + attachment = GL_COLOR_ATTACHMENT0_EXT+i; + if ((i != 0) && (targets[i].RenderTexture != RenderTargetTexture)) + extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, static_cast(targets[i].RenderTexture)->getOpenGLTextureName(), 0); +#endif + MRTs[i]=attachment; + } + else + { + switch(targets[i].TargetType) + { + case ERT_FRAME_BUFFER: + MRTs[i]=GL_BACK_LEFT; + break; + case ERT_STEREO_BOTH_BUFFERS: + MRTs[i]=GL_BACK; + break; + case ERT_STEREO_RIGHT_BUFFER: + MRTs[i]=GL_BACK_RIGHT; + break; + case ERT_STEREO_LEFT_BUFFER: + MRTs[i]=GL_BACK_LEFT; + break; + default: + MRTs[i]=GL_AUX0+(targets[i].TargetType-ERT_AUX_BUFFER0); + break; + } + } + } + + extGlDrawBuffers(maxMultipleRTTs, MRTs.const_pointer()); + } + + clearBuffers(clearBackBuffer, clearZBuffer, false, color); + return true; +} + + +// returns the current size of the screen or rendertarget +const core::dimension2d& COpenGLDriver::getCurrentRenderTargetSize() const +{ + if (CurrentRendertargetSize.Width == 0) + return ScreenSize; + else + return CurrentRendertargetSize; +} + + +//! Clears the ZBuffer. +void COpenGLDriver::clearZBuffer() +{ + clearBuffers(false, true, false, 0x0); +} + + +//! Returns an image created from the last rendered frame. +IImage* COpenGLDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) +{ + if (target==video::ERT_MULTI_RENDER_TEXTURES || target==video::ERT_RENDER_TEXTURE || target==video::ERT_STEREO_BOTH_BUFFERS) + return 0; + + // allows to read pixels in top-to-bottom order +#ifdef GL_MESA_pack_invert + if (FeatureAvailable[IRR_MESA_pack_invert]) + glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); +#endif + + if (format==video::ECF_UNKNOWN) + format=getColorFormat(); + GLenum fmt; + GLenum type; + switch (format) + { + case ECF_A1R5G5B5: + fmt = GL_BGRA; + type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case ECF_R5G6B5: + fmt = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case ECF_R8G8B8: + fmt = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; + case ECF_A8R8G8B8: + fmt = GL_BGRA; + if (Version > 101) + type = GL_UNSIGNED_INT_8_8_8_8_REV; + else + type = GL_UNSIGNED_BYTE; + break; + case ECF_R16F: + if (FeatureAvailable[IRR_ARB_texture_rg]) + fmt = GL_RED; + else + fmt = GL_LUMINANCE; +#ifdef GL_ARB_half_float_pixel + if (FeatureAvailable[IRR_ARB_half_float_pixel]) + type = GL_HALF_FLOAT_ARB; + else +#endif + { + type = GL_FLOAT; + format = ECF_R32F; + } + break; + case ECF_G16R16F: +#ifdef GL_ARB_texture_rg + if (FeatureAvailable[IRR_ARB_texture_rg]) + fmt = GL_RG; + else +#endif + fmt = GL_LUMINANCE_ALPHA; +#ifdef GL_ARB_half_float_pixel + if (FeatureAvailable[IRR_ARB_half_float_pixel]) + type = GL_HALF_FLOAT_ARB; + else +#endif + { + type = GL_FLOAT; + format = ECF_G32R32F; + } + break; + case ECF_A16B16G16R16F: + fmt = GL_BGRA; +#ifdef GL_ARB_half_float_pixel + if (FeatureAvailable[IRR_ARB_half_float_pixel]) + type = GL_HALF_FLOAT_ARB; + else +#endif + { + type = GL_FLOAT; + format = ECF_A32B32G32R32F; + } + break; + case ECF_R32F: + if (FeatureAvailable[IRR_ARB_texture_rg]) + fmt = GL_RED; + else + fmt = GL_LUMINANCE; + type = GL_FLOAT; + break; + case ECF_G32R32F: +#ifdef GL_ARB_texture_rg + if (FeatureAvailable[IRR_ARB_texture_rg]) + fmt = GL_RG; + else +#endif + fmt = GL_LUMINANCE_ALPHA; + type = GL_FLOAT; + break; + case ECF_A32B32G32R32F: + fmt = GL_BGRA; + type = GL_FLOAT; + break; + default: + fmt = GL_BGRA; + type = GL_UNSIGNED_BYTE; + break; + } + IImage* newImage = createImage(format, ScreenSize); + + u8* pixels = 0; + if (newImage) + pixels = static_cast(newImage->lock()); + if (pixels) + { + GLenum tgt=GL_FRONT; + switch (target) + { + case video::ERT_FRAME_BUFFER: + break; + case video::ERT_STEREO_LEFT_BUFFER: + tgt=GL_FRONT_LEFT; + break; + case video::ERT_STEREO_RIGHT_BUFFER: + tgt=GL_FRONT_RIGHT; + break; + default: + tgt=GL_AUX0+(target-video::ERT_AUX_BUFFER0); + break; + } + glReadBuffer(tgt); + glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, fmt, type, pixels); + testGLError(); + glReadBuffer(GL_BACK); + } + +#ifdef GL_MESA_pack_invert + if (FeatureAvailable[IRR_MESA_pack_invert]) + glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE); + else +#endif + if (pixels) + { + // opengl images are horizontally flipped, so we have to fix that here. + const s32 pitch=newImage->getPitch(); + u8* p2 = pixels + (ScreenSize.Height - 1) * pitch; + u8* tmpBuffer = new u8[pitch]; + for (u32 i=0; i < ScreenSize.Height; i += 2) + { + memcpy(tmpBuffer, pixels, pitch); +// for (u32 j=0; junlock(); + if (testGLError() || !pixels) + { + newImage->drop(); + return 0; + } + } + return newImage; +} + + +//! get depth texture for the given render target texture +ITexture* COpenGLDriver::createDepthTexture(ITexture* texture, bool shared) +{ + if ((texture->getDriverType() != EDT_OPENGL) || (!texture->isRenderTarget())) + return 0; + COpenGLTexture* tex = static_cast(texture); + + if (!tex->isFrameBufferObject()) + return 0; + + if (shared) + { + for (u32 i=0; igetSize()==texture->getSize()) + { + DepthTextures[i]->grab(); + return DepthTextures[i]; + } + } + DepthTextures.push_back(new COpenGLFBODepthTexture(texture->getSize(), "depth1", this)); + return DepthTextures.getLast(); + } + return (new COpenGLFBODepthTexture(texture->getSize(), "depth1", this)); +} + + +void COpenGLDriver::removeDepthTexture(ITexture* texture) +{ + for (u32 i=0; i= MaxUserClipPlanes) + return false; + + UserClipPlanes[index].Plane=plane; + enableClipPlane(index, enable); + return true; +} + + +void COpenGLDriver::uploadClipPlane(u32 index) +{ + // opengl needs an array of doubles for the plane equation + GLdouble clip_plane[4]; + clip_plane[0] = UserClipPlanes[index].Plane.Normal.X; + clip_plane[1] = UserClipPlanes[index].Plane.Normal.Y; + clip_plane[2] = UserClipPlanes[index].Plane.Normal.Z; + clip_plane[3] = UserClipPlanes[index].Plane.D; + glClipPlane(GL_CLIP_PLANE0 + index, clip_plane); +} + + +//! Enable/disable a clipping plane. +void COpenGLDriver::enableClipPlane(u32 index, bool enable) +{ + if (index >= MaxUserClipPlanes) + return; + if (enable) + { + if (!UserClipPlanes[index].Enabled) + { + uploadClipPlane(index); + glEnable(GL_CLIP_PLANE0 + index); + } + } + else + glDisable(GL_CLIP_PLANE0 + index); + + UserClipPlanes[index].Enabled=enable; +} + + +core::dimension2du COpenGLDriver::getMaxTextureSize() const +{ + return core::dimension2du(MaxTextureSize, MaxTextureSize); +} + + +//! Convert E_PRIMITIVE_TYPE to OpenGL equivalent +GLenum COpenGLDriver::primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const +{ + switch (type) + { + case scene::EPT_POINTS: + return GL_POINTS; + case scene::EPT_LINE_STRIP: + return GL_LINE_STRIP; + case scene::EPT_LINE_LOOP: + return GL_LINE_LOOP; + case scene::EPT_LINES: + return GL_LINES; + case scene::EPT_TRIANGLE_STRIP: + return GL_TRIANGLE_STRIP; + case scene::EPT_TRIANGLE_FAN: + return GL_TRIANGLE_FAN; + case scene::EPT_TRIANGLES: + return GL_TRIANGLES; + case scene::EPT_QUAD_STRIP: + return GL_QUAD_STRIP; + case scene::EPT_QUADS: + return GL_QUADS; + case scene::EPT_POLYGON: + return GL_POLYGON; + case scene::EPT_POINT_SPRITES: +#ifdef GL_ARB_point_sprite + return GL_POINT_SPRITE_ARB; +#else + return GL_POINTS; +#endif + } + return GL_TRIANGLES; +} + + +GLenum COpenGLDriver::getGLBlend(E_BLEND_FACTOR factor) const +{ + GLenum r = 0; + switch (factor) + { + case EBF_ZERO: r = GL_ZERO; break; + case EBF_ONE: r = GL_ONE; break; + case EBF_DST_COLOR: r = GL_DST_COLOR; break; + case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break; + case EBF_SRC_COLOR: r = GL_SRC_COLOR; break; + case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break; + case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break; + case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break; + case EBF_DST_ALPHA: r = GL_DST_ALPHA; break; + case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break; + case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break; + } + return r; +} + +GLenum COpenGLDriver::getZBufferBits() const +{ + GLenum bits = 0; + switch (Params.ZBufferBits) + { + case 16: + bits = GL_DEPTH_COMPONENT16; + break; + case 24: + bits = GL_DEPTH_COMPONENT24; + break; + case 32: + bits = GL_DEPTH_COMPONENT32; + break; + default: + bits = GL_DEPTH_COMPONENT; + break; + } + return bits; +} + +#ifdef _IRR_COMPILE_WITH_CG_ +const CGcontext& COpenGLDriver::getCgContext() +{ + return CgContext; +} +#endif + + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_OPENGL_ + +namespace irr +{ +namespace video +{ + + +// ----------------------------------- +// WINDOWS VERSION +// ----------------------------------- +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ +IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceWin32* device) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + COpenGLDriver* ogl = new COpenGLDriver(params, io, device); + if (!ogl->initDriver(device)) + { + ogl->drop(); + ogl = 0; + } + return ogl; +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + +// ----------------------------------- +// MACOSX VERSION +// ----------------------------------- +#if defined(_IRR_COMPILE_WITH_OSX_DEVICE_) +IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceMacOSX *device) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + return new COpenGLDriver(params, io, device); +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_COMPILE_WITH_OSX_DEVICE_ + +// ----------------------------------- +// X11 VERSION +// ----------------------------------- +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ +IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceLinux* device) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + COpenGLDriver* ogl = new COpenGLDriver(params, io, device); + if (!ogl->initDriver(device)) + { + ogl->drop(); + ogl = 0; + } + return ogl; +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_COMPILE_WITH_X11_DEVICE_ + + +// ----------------------------------- +// SDL VERSION +// ----------------------------------- +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, + io::IFileSystem* io, CIrrDeviceSDL* device) +{ +#ifdef _IRR_COMPILE_WITH_OPENGL_ + return new COpenGLDriver(params, io, device); +#else + return 0; +#endif // _IRR_COMPILE_WITH_OPENGL_ +} +#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ + +} // end namespace +} // end namespace + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.h new file mode 100644 index 0000000..693052c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLDriver.h @@ -0,0 +1,613 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef __C_VIDEO_OPEN_GL_H_INCLUDED__ +#define __C_VIDEO_OPEN_GL_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#include "SIrrCreationParameters.h" + +namespace irr +{ + class CIrrDeviceWin32; + class CIrrDeviceLinux; + class CIrrDeviceSDL; + class CIrrDeviceMacOSX; +} + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "CNullDriver.h" +#include "IMaterialRendererServices.h" +// also includes the OpenGL stuff +#include "COpenGLExtensionHandler.h" + +#ifdef _IRR_COMPILE_WITH_CG_ +#include "Cg/cg.h" +#endif + +namespace irr +{ + +namespace video +{ + class COpenGLTexture; + + class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler + { + friend class COpenGLTexture; + public: + + #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device); + //! inits the windows specific parts of the open gl driver + bool initDriver(CIrrDeviceWin32* device); + bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device); + #endif + + #ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceLinux* device); + //! inits the GLX specific parts of the open gl driver + bool initDriver(CIrrDeviceLinux* device); + bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device); + #endif + + #ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceSDL* device); + #endif + + #ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceMacOSX *device); + #endif + + //! generic version which overloads the unimplemented versions + bool changeRenderContext(const SExposedVideoData& videoData, void* device) {return false;} + + //! destructor + virtual ~COpenGLDriver(); + + //! clears the zbuffer + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect* sourceRect=0); + + //! presents the rendered scene on the screen, returns false if failed + virtual bool endScene(); + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + + struct SHWBufferLink_opengl : public SHWBufferLink + { + SHWBufferLink_opengl(const scene::IMeshBuffer *_MeshBuffer): SHWBufferLink(_MeshBuffer), vbo_verticesID(0),vbo_indicesID(0){} + + GLuint vbo_verticesID; //tmp + GLuint vbo_indicesID; //tmp + + GLuint vbo_verticesSize; //tmp + GLuint vbo_indicesSize; //tmp + }; + + //! updates hardware buffer if needed + virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Create hardware buffer from mesh + virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb); + + //! Delete hardware buffer (only some drivers can) + virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Draw hardware buffer + virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer); + + //! Create occlusion query. + /** Use node for identification and mesh for occlusion test. */ + virtual void addOcclusionQuery(scene::ISceneNode* node, + const scene::IMesh* mesh=0); + + //! Remove occlusion query. + virtual void removeOcclusionQuery(scene::ISceneNode* node); + + //! Run occlusion query. Draws mesh stored in query. + /** If the mesh shall not be rendered visible, use + overrideMaterial to disable the color and depth buffer. */ + virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false); + + //! Update occlusion query. Retrieves results from GPU. + /** If the query shall not block, set the flag to false. + Update might not occur in this case, though */ + virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true); + + //! Return query result. + /** Return value is the number of visible pixels/fragments. + The value is a safe approximation, i.e. can be larger then the + actual value of pixels. */ + virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const; + + //! draws a vertex primitive list + virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType); + + //! draws a vertex primitive list in 2d + virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const + { + return FeatureEnabled[feature] && COpenGLExtensionHandler::queryFeature(feature); + } + + //! Sets a material. All 3d drawing functions draw geometry now + //! using this material. + //! \param material: Material to be used from now on. + virtual void setMaterial(const SMaterial& material); + + //! draws a set of 2d images, using a color and the alpha channel of the + //! texture if desired. + void draw2DImageBatch(const video::ITexture* texture, + const core::array >& positions, + const core::array >& sourceRects, + const core::rect* clipRect, + SColor color, + bool useAlphaChannelOfTexture); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! draws a set of 2d images, using a color and the alpha + /** channel of the texture if desired. The images are drawn + beginning at pos and concatenated in one line. All drawings + are clipped against clipRect (if != 0). + The subtextures are defined by the array of sourceRects + and are chosen by the indices given. + \param texture: Texture to be drawn. + \param pos: Upper left 2d destination position where the image will be drawn. + \param sourceRects: Source rectangles of the image. + \param indices: List of indices which choose the actual rectangle used each time. + \param clipRect: Pointer to rectangle on the screen where the image is clipped to. + This pointer can be 0. Then the image is not clipped. + \param color: Color with which the image is colored. + Note that the alpha component is used: If alpha is other than 255, the image will be transparent. + \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is + used to draw the image. */ + virtual void draw2DImage(const video::ITexture* texture, + const core::position2d& pos, + const core::array >& sourceRects, + const core::array& indices, + const core::rect* clipRect=0, + SColor color=SColor(255,255,255,255), + bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a single pixel + virtual void drawPixel(u32 x, u32 y, const SColor & color); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, + SColor color = SColor(255,255,255,255)); + + //! \return Returns the name of the video driver. Example: In case of the Direct3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light, returning an index to the light + //! \param light: the light data to use to create the light + //! \return An index to the light, or -1 if an error occurs + virtual s32 addDynamicLight(const SLight& light); + + //! Turns a dynamic light on or off + //! \param lightIndex: the index returned by addDynamicLight + //! \param turnOn: true to turn the light on, false to turn it off + virtual void turnLightOn(s32 lightIndex, bool turnOn); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do + //! this: First, draw all geometry. Then use this method, to draw the shadow + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible=0); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! Sets the fog mode. + virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! get color format of the current color buffer + virtual ECOLOR_FORMAT getColorFormat() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Can be called by an IMaterialRenderer to make its work easier. + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, + bool resetAllRenderstates); + + //! Sets a vertex shader constant. + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a pixel shader constant. + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + + //! Sets a constant for the vertex shader based on a name. + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); + + //! Sets a constant for the pixel shader based on a name. + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + + //! Bool interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); + + //! Int interface for the above. + virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); + + //! sets the current Texture + //! Returns whether setting was a success or not. + bool setActiveTexture(u32 stage, const video::ITexture* texture); + + //! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled. + //! Returns whether disabling was successful or not. + bool disableTextures(u32 fromStage=0); + + //! Adds a new material renderer to the VideoDriver, using + //! extGLGetObjectParameteriv(shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &status) + //! pixel and/or vertex shaders to render geometry. + virtual s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData); + + //! Adds a new material renderer to the VideoDriver, using GLSL to render geometry. + virtual s32 addHighLevelShaderMaterial( + const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, + s32 userData = 0, + E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT); + + //! Returns a pointer to the IVideoDriver interface. (Implementation for + //! IMaterialRendererServices) + virtual IVideoDriver* getVideoDriver(); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! set or reset render target + virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget, + bool clearZBuffer, SColor color); + + //! set or reset render target texture + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! Sets multiple render targets + virtual bool setRenderTarget(const core::array& texture, + bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0)); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); + + //! checks if an OpenGL error has happend and prints it + //! for performance reasons only available in debug mode + bool testGLError(); + + //! Set/unset a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param plane: The plane itself. + //! \param enable: If true, enable the clipping plane else disable it. + virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); + + //! Enable/disable a clipping plane. + //! There are at least 6 clipping planes available for the user to set at will. + //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. + //! \param enable: If true, enable the clipping plane else disable it. + virtual void enableClipPlane(u32 index, bool enable); + + //! Enable the 2d override material + virtual void enableMaterial2D(bool enable=true); + + //! Returns the graphics card vendor name. + virtual core::stringc getVendorInfo() {return VendorName;} + + //! Returns the maximum texture size supported. + virtual core::dimension2du getMaxTextureSize() const; + + ITexture* createDepthTexture(ITexture* texture, bool shared=true); + void removeDepthTexture(ITexture* texture); + + //! Removes a texture from the texture cache and deletes it, freeing lot of memory. + void removeTexture(ITexture* texture); + + //! Convert E_PRIMITIVE_TYPE to OpenGL equivalent + GLenum primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const; + + //! Convert E_BLEND_FACTOR to OpenGL equivalent + GLenum getGLBlend(E_BLEND_FACTOR factor) const; + + //! Get ZBuffer bits. + GLenum getZBufferBits() const; + + //! Get Cg context + #ifdef _IRR_COMPILE_WITH_CG_ + const CGcontext& getCgContext(); + #endif + + private: + + //! clears the zbuffer and color buffer + void clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color); + + bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer); + bool updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer); + + void uploadClipPlane(u32 index); + + //! inits the parts of the open gl driver used on all platforms + bool genericDriverInit(); + //! returns a device dependent texture from a software surface (IImage) + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData); + + //! creates a transposed matrix in supplied GLfloat array to pass to OpenGL + inline void getGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m); + inline void getGLTextureMatrix(GLfloat gl_matrix[16], const core::matrix4& m); + + //! Set GL pipeline to desired texture wrap modes of the material + void setWrapMode(const SMaterial& material); + + //! get native wrap mode value + GLint getTextureWrapMode(const u8 clamp); + + //! sets the needed renderstates + void setRenderStates3DMode(); + + //! sets the needed renderstates + void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); + + // returns the current size of the screen or rendertarget + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + void createMaterialRenderers(); + + //! Assign a hardware light to the specified requested light, if any + //! free hardware lights exist. + //! \param[in] lightIndex: the index of the requesting light + void assignHardwareLight(u32 lightIndex); + + //! helper function for render setup. + void getColorBuffer(const void* vertices, u32 vertexCount, E_VERTEX_TYPE vType); + + //! helper function doing the actual rendering. + void renderArray(const void* indexList, u32 primitiveCount, + scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType); + + core::stringw Name; + core::matrix4 Matrices[ETS_COUNT]; + core::array ColorBuffer; + + //! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. + enum E_RENDER_MODE + { + ERM_NONE = 0, // no render state has been set yet. + ERM_2D, // 2d drawing rendermode + ERM_3D // 3d rendering mode + }; + + E_RENDER_MODE CurrentRenderMode; + //! bool to make all renderstates reset if set to true. + bool ResetRenderStates; + bool Transformation3DChanged; + u8 AntiAlias; + + SMaterial Material, LastMaterial; + COpenGLTexture* RenderTargetTexture; + core::array MRTargets; + class STextureStageCache + { + const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; + public: + STextureStageCache() + { + for (u32 i=0; igrab(); + CurrentTexture[stage]=tex; + if (oldTexture) + oldTexture->drop(); + } + } + + const ITexture* operator[](int stage) const + { + if ((u32)stage= 0; --i) + { + if (CurrentTexture[i] == tex) + { + tex->drop(); + CurrentTexture[i] = 0; + } + } + } + + void clear() + { + // Drop all the CurrentTexture handles + for (u32 i=0; idrop(); + CurrentTexture[i] = 0; + } + } + } + }; + STextureStageCache CurrentTexture; + core::array DepthTextures; + struct SUserClipPlane + { + SUserClipPlane() : Enabled(false) {} + core::plane3df Plane; + bool Enabled; + }; + core::array UserClipPlanes; + + core::dimension2d CurrentRendertargetSize; + + core::stringc VendorName; + + core::matrix4 TextureFlipMatrix; + + //! Color buffer format + ECOLOR_FORMAT ColorFormat; + + //! Render target type for render operations + E_RENDER_TARGET CurrentTarget; + + SIrrlichtCreationParameters Params; + + //! All the lights that have been requested; a hardware limited + //! number of them will be used at once. + struct RequestedLight + { + RequestedLight(SLight const & lightData) + : LightData(lightData), HardwareLightIndex(-1), DesireToBeOn(true) { } + + SLight LightData; + s32 HardwareLightIndex; // GL_LIGHT0 - GL_LIGHT7 + bool DesireToBeOn; + }; + core::array RequestedLights; + + #ifdef _IRR_WINDOWS_API_ + HDC HDc; // Private GDI Device Context + HWND Window; + #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + CIrrDeviceWin32 *Win32Device; + #endif + #endif + #ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + GLXDrawable Drawable; + Display* X11Display; + CIrrDeviceLinux *X11Device; + #endif + #ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + CIrrDeviceMacOSX *OSXDevice; + #endif + #ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + CIrrDeviceSDL *SDLDevice; + #endif + #ifdef _IRR_COMPILE_WITH_CG_ + CGcontext CgContext; + #endif + + E_DEVICE_TYPE DeviceType; + }; + +} // end namespace video +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_OPENGL_ +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.cpp new file mode 100644 index 0000000..ae64ffd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.cpp @@ -0,0 +1,804 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLExtensionHandler.h" +#include "irrString.h" +#include "SMaterial.h" // for MATERIAL_MAX_TEXTURES +#include "fast_atof.h" + +namespace irr +{ +namespace video +{ + +COpenGLExtensionHandler::COpenGLExtensionHandler() : + StencilBuffer(false), MultiTextureExtension(false), + TextureCompressionExtension(false), + MaxSupportedTextures(1), MaxTextureUnits(1), MaxLights(1), + MaxAnisotropy(1), MaxUserClipPlanes(0), MaxAuxBuffers(0), + MaxMultipleRenderTargets(1), MaxIndices(65535), + MaxTextureSize(1), MaxGeometryVerticesOut(0), + MaxTextureLODBias(0.f), Version(0), ShaderLanguageVersion(0), + OcclusionQuerySupport(false) +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + ,pGlActiveTextureARB(0), pGlClientActiveTextureARB(0), + pGlGenProgramsARB(0), pGlGenProgramsNV(0), + pGlBindProgramARB(0), pGlBindProgramNV(0), + pGlDeleteProgramsARB(0), pGlDeleteProgramsNV(0), + pGlProgramStringARB(0), pGlLoadProgramNV(0), + pGlProgramLocalParameter4fvARB(0), + pGlCreateShaderObjectARB(0), pGlShaderSourceARB(0), + pGlCompileShaderARB(0), pGlCreateProgramObjectARB(0), pGlAttachObjectARB(0), + pGlLinkProgramARB(0), pGlUseProgramObjectARB(0), pGlDeleteObjectARB(0), + pGlCreateProgram(0), pGlUseProgram(0), + pGlDeleteProgram(0), pGlDeleteShader(0), + pGlGetAttachedObjectsARB(0), pGlGetAttachedShaders(0), + pGlCreateShader(0), pGlShaderSource(0), pGlCompileShader(0), + pGlAttachShader(0), pGlLinkProgram(0), + pGlGetInfoLogARB(0), pGlGetShaderInfoLog(0), pGlGetProgramInfoLog(0), + pGlGetObjectParameterivARB(0), pGlGetShaderiv(0), pGlGetProgramiv(0), + pGlGetUniformLocationARB(0), pGlGetUniformLocation(0), + pGlUniform1fvARB(0), pGlUniform2fvARB(0), pGlUniform3fvARB(0), pGlUniform4fvARB(0), + pGlUniform1ivARB(0), pGlUniform2ivARB(0), pGlUniform3ivARB(0), pGlUniform4ivARB(0), + pGlUniformMatrix2fvARB(0), pGlUniformMatrix3fvARB(0), pGlUniformMatrix4fvARB(0), + pGlGetActiveUniformARB(0), pGlGetActiveUniform(0), + pGlPointParameterfARB(0), pGlPointParameterfvARB(0), + pGlStencilFuncSeparate(0), pGlStencilOpSeparate(0), + pGlStencilFuncSeparateATI(0), pGlStencilOpSeparateATI(0), + pGlCompressedTexImage2D(0), + // ARB framebuffer object + pGlBindFramebuffer(0), pGlDeleteFramebuffers(0), pGlGenFramebuffers(0), + pGlCheckFramebufferStatus(0), pGlFramebufferTexture2D(0), + pGlBindRenderbuffer(0), pGlDeleteRenderbuffers(0), pGlGenRenderbuffers(0), + pGlRenderbufferStorage(0), pGlFramebufferRenderbuffer(0), pGlGenerateMipmap(0), + // EXT framebuffer object + pGlBindFramebufferEXT(0), pGlDeleteFramebuffersEXT(0), pGlGenFramebuffersEXT(0), + pGlCheckFramebufferStatusEXT(0), pGlFramebufferTexture2DEXT(0), + pGlBindRenderbufferEXT(0), pGlDeleteRenderbuffersEXT(0), pGlGenRenderbuffersEXT(0), + pGlRenderbufferStorageEXT(0), pGlFramebufferRenderbufferEXT(0), pGlGenerateMipmapEXT(0), + // MRTs + pGlDrawBuffersARB(0), pGlDrawBuffersATI(0), + pGlGenBuffersARB(0), pGlBindBufferARB(0), pGlBufferDataARB(0), pGlDeleteBuffersARB(0), + pGlBufferSubDataARB(0), pGlGetBufferSubDataARB(0), pGlMapBufferARB(0), pGlUnmapBufferARB(0), + pGlIsBufferARB(0), pGlGetBufferParameterivARB(0), pGlGetBufferPointervARB(0), + pGlProvokingVertexARB(0), pGlProvokingVertexEXT(0), + pGlColorMaskIndexedEXT(0), pGlEnableIndexedEXT(0), pGlDisableIndexedEXT(0), + pGlBlendFuncIndexedAMD(0), pGlBlendFunciARB(0), + pGlBlendEquationIndexedAMD(0), pGlBlendEquationiARB(0), + pGlProgramParameteriARB(0), pGlProgramParameteriEXT(0), + pGlGenQueriesARB(0), pGlDeleteQueriesARB(0), pGlIsQueryARB(0), + pGlBeginQueryARB(0), pGlEndQueryARB(0), pGlGetQueryivARB(0), + pGlGetQueryObjectivARB(0), pGlGetQueryObjectuivARB(0), + pGlGenOcclusionQueriesNV(0), pGlDeleteOcclusionQueriesNV(0), + pGlIsOcclusionQueryNV(0), pGlBeginOcclusionQueryNV(0), + pGlEndOcclusionQueryNV(0), pGlGetOcclusionQueryivNV(0), + pGlGetOcclusionQueryuivNV(0), + pGlBlendEquationEXT(0), pGlBlendEquation(0) +#if defined(GLX_SGI_swap_control) + ,pGlxSwapIntervalSGI(0) +#endif +#if defined(GLX_EXT_swap_control) + ,pGlxSwapIntervalEXT(0) +#endif +#if defined(WGL_EXT_swap_control) + ,pWglSwapIntervalEXT(0) +#endif +#if defined(GLX_MESA_swap_control) + ,pGlxSwapIntervalMESA(0) +#endif +#endif // _IRR_OPENGL_USE_EXTPOINTER_ +{ + for (u32 i=0; i(glGetString(GL_VERSION))); + Version = static_cast(core::floor32(ogl_ver)*100+core::round32(core::fract(ogl_ver)*10.0f)); + if ( Version >= 102) + os::Printer::log("OpenGL driver version is 1.2 or better.", ELL_INFORMATION); + else + os::Printer::log("OpenGL driver version is not 1.2 or better.", ELL_WARNING); + + { + const char* t = reinterpret_cast(glGetString(GL_EXTENSIONS)); + size_t len = 0; + c8 *str = 0; + if (t) + { + len = strlen(t); + str = new c8[len+1]; + } + c8* p = str; + + for (size_t i=0; i(t[i]); + + if (str[i] == ' ') + { + str[i] = 0; + for (u32 j=0; j(x)) +#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && !defined(_IRR_COMPILE_WITH_X11_DEVICE_) + #define IRR_OGL_LOAD_EXTENSION(x) SDL_GL_GetProcAddress(reinterpret_cast(x)) +#else + // Accessing the correct function is quite complex + // All libraries should support the ARB version, however + // since GLX 1.4 the non-ARB version is the official one + // So we have to check the runtime environment and + // choose the proper symbol + // In case you still have problems please enable the + // next line by uncommenting it + // #define _IRR_GETPROCADDRESS_WORKAROUND_ + + #ifndef _IRR_GETPROCADDRESS_WORKAROUND_ + __GLXextFuncPtr (*IRR_OGL_LOAD_EXTENSION_FUNCP)(const GLubyte*)=0; + #ifdef GLX_VERSION_1_4 + int major=0,minor=0; + if (glXGetCurrentDisplay()) + glXQueryVersion(glXGetCurrentDisplay(), &major, &minor); + if ((major>1) || (minor>3)) + IRR_OGL_LOAD_EXTENSION_FUNCP=glXGetProcAddress; + else + #endif + IRR_OGL_LOAD_EXTENSION_FUNCP=glXGetProcAddressARB; + #define IRR_OGL_LOAD_EXTENSION(X) IRR_OGL_LOAD_EXTENSION_FUNCP(reinterpret_cast(X)) + #else + #define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddressARB(reinterpret_cast(X)) + #endif // workaround +#endif // Windows, SDL, or Linux + + // get multitexturing function pointers + pGlActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION("glActiveTextureARB"); + pGlClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION("glClientActiveTextureARB"); + + // get fragment and vertex program function pointers + pGlGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) IRR_OGL_LOAD_EXTENSION("glGenProgramsARB"); + pGlGenProgramsNV = (PFNGLGENPROGRAMSNVPROC) IRR_OGL_LOAD_EXTENSION("glGenProgramsNV"); + pGlBindProgramARB = (PFNGLBINDPROGRAMARBPROC) IRR_OGL_LOAD_EXTENSION("glBindProgramARB"); + pGlBindProgramNV = (PFNGLBINDPROGRAMNVPROC) IRR_OGL_LOAD_EXTENSION("glBindProgramNV"); + pGlProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramStringARB"); + pGlLoadProgramNV = (PFNGLLOADPROGRAMNVPROC) IRR_OGL_LOAD_EXTENSION("glLoadProgramNV"); + pGlDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteProgramsARB"); + pGlDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC) IRR_OGL_LOAD_EXTENSION("glDeleteProgramsNV"); + pGlProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramLocalParameter4fvARB"); + pGlCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glCreateShaderObjectARB"); + pGlCreateShader = (PFNGLCREATESHADERPROC) IRR_OGL_LOAD_EXTENSION("glCreateShader"); + pGlShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) IRR_OGL_LOAD_EXTENSION("glShaderSourceARB"); + pGlShaderSource = (PFNGLSHADERSOURCEPROC) IRR_OGL_LOAD_EXTENSION("glShaderSource"); + pGlCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) IRR_OGL_LOAD_EXTENSION("glCompileShaderARB"); + pGlCompileShader = (PFNGLCOMPILESHADERPROC) IRR_OGL_LOAD_EXTENSION("glCompileShader"); + pGlCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glCreateProgramObjectARB"); + pGlCreateProgram = (PFNGLCREATEPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glCreateProgram"); + pGlAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glAttachObjectARB"); + pGlAttachShader = (PFNGLATTACHSHADERPROC) IRR_OGL_LOAD_EXTENSION("glAttachShader"); + pGlLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) IRR_OGL_LOAD_EXTENSION("glLinkProgramARB"); + pGlLinkProgram = (PFNGLLINKPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glLinkProgram"); + pGlUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glUseProgramObjectARB"); + pGlUseProgram = (PFNGLUSEPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glUseProgram"); + pGlDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteObjectARB"); + pGlDeleteProgram = (PFNGLDELETEPROGRAMPROC) IRR_OGL_LOAD_EXTENSION("glDeleteProgram"); + pGlDeleteShader = (PFNGLDELETESHADERPROC) IRR_OGL_LOAD_EXTENSION("glDeleteShader"); + pGlGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) IRR_OGL_LOAD_EXTENSION("glGetAttachedShaders"); + pGlGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) IRR_OGL_LOAD_EXTENSION("glGetAttachedObjectsARB"); + pGlGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) IRR_OGL_LOAD_EXTENSION("glGetInfoLogARB"); + pGlGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); + pGlGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); + pGlGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetObjectParameterivARB"); + pGlGetShaderiv = (PFNGLGETSHADERIVPROC) IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); + pGlGetProgramiv = (PFNGLGETPROGRAMIVPROC) IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); + pGlGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) IRR_OGL_LOAD_EXTENSION("glGetUniformLocationARB"); + pGlGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); + pGlUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform1fvARB"); + pGlUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform2fvARB"); + pGlUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform3fvARB"); + pGlUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform4fvARB"); + pGlUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform1ivARB"); + pGlUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform2ivARB"); + pGlUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform3ivARB"); + pGlUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniform4ivARB"); + pGlUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix2fvARB"); + pGlUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix3fvARB"); + pGlUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fvARB"); + pGlGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) IRR_OGL_LOAD_EXTENSION("glGetActiveUniformARB"); + pGlGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) IRR_OGL_LOAD_EXTENSION("glGetActiveUniform"); + + // get point parameter extension + pGlPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC) IRR_OGL_LOAD_EXTENSION("glPointParameterfARB"); + pGlPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) IRR_OGL_LOAD_EXTENSION("glPointParameterfvARB"); + + // get stencil extension + pGlStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) IRR_OGL_LOAD_EXTENSION("glStencilFuncSeparate"); + pGlStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) IRR_OGL_LOAD_EXTENSION("glStencilOpSeparate"); + pGlStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) IRR_OGL_LOAD_EXTENSION("glStencilFuncSeparateATI"); + pGlStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC) IRR_OGL_LOAD_EXTENSION("glStencilOpSeparateATI"); + + // compressed textures + pGlCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D"); + + // ARB FrameBufferObjects + pGlBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebuffer"); + pGlDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffers"); + pGlGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glGenFramebuffers"); + pGlCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus"); + pGlFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2D"); + pGlBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glBindRenderbuffer"); + pGlDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glDeleteRenderbuffers"); + pGlGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) IRR_OGL_LOAD_EXTENSION("glGenRenderbuffers"); + pGlRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorage"); + pGlFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferRenderbuffer"); + pGlGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) IRR_OGL_LOAD_EXTENSION("glGenerateMipmap"); + + // EXT FrameBufferObjects + pGlBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glBindFramebufferEXT"); + pGlDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glDeleteFramebuffersEXT"); + pGlGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenFramebuffersEXT"); + pGlCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatusEXT"); + pGlFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2DEXT"); + pGlBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glBindRenderbufferEXT"); + pGlDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glDeleteRenderbuffersEXT"); + pGlGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenRenderbuffersEXT"); + pGlRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) IRR_OGL_LOAD_EXTENSION("glRenderbufferStorageEXT"); + pGlFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) IRR_OGL_LOAD_EXTENSION("glFramebufferRenderbufferEXT"); + pGlGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) IRR_OGL_LOAD_EXTENSION("glGenerateMipmapEXT"); + pGlDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION("glDrawBuffersARB"); + pGlDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC) IRR_OGL_LOAD_EXTENSION("glDrawBuffersATI"); + + // get vertex buffer extension + pGlGenBuffersARB = (PFNGLGENBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION("glGenBuffersARB"); + pGlBindBufferARB = (PFNGLBINDBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glBindBufferARB"); + pGlBufferDataARB = (PFNGLBUFFERDATAARBPROC) IRR_OGL_LOAD_EXTENSION("glBufferDataARB"); + pGlDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteBuffersARB"); + pGlBufferSubDataARB= (PFNGLBUFFERSUBDATAARBPROC) IRR_OGL_LOAD_EXTENSION("glBufferSubDataARB"); + pGlGetBufferSubDataARB= (PFNGLGETBUFFERSUBDATAARBPROC)IRR_OGL_LOAD_EXTENSION("glGetBufferSubDataARB"); + pGlMapBufferARB= (PFNGLMAPBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glMapBufferARB"); + pGlUnmapBufferARB= (PFNGLUNMAPBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glUnmapBufferARB"); + pGlIsBufferARB= (PFNGLISBUFFERARBPROC) IRR_OGL_LOAD_EXTENSION("glIsBufferARB"); + pGlGetBufferParameterivARB= (PFNGLGETBUFFERPARAMETERIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetBufferParameterivARB"); + pGlGetBufferPointervARB= (PFNGLGETBUFFERPOINTERVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetBufferPointervARB"); + pGlProvokingVertexARB= (PFNGLPROVOKINGVERTEXPROC) IRR_OGL_LOAD_EXTENSION("glProvokingVertex"); + pGlProvokingVertexEXT= (PFNGLPROVOKINGVERTEXEXTPROC) IRR_OGL_LOAD_EXTENSION("glProvokingVertexEXT"); + pGlColorMaskIndexedEXT= (PFNGLCOLORMASKINDEXEDEXTPROC) IRR_OGL_LOAD_EXTENSION("glColorMaskIndexedEXT"); + pGlEnableIndexedEXT= (PFNGLENABLEINDEXEDEXTPROC) IRR_OGL_LOAD_EXTENSION("glEnableIndexedEXT"); + pGlDisableIndexedEXT= (PFNGLDISABLEINDEXEDEXTPROC) IRR_OGL_LOAD_EXTENSION("glDisableIndexedEXT"); + pGlBlendFuncIndexedAMD= (PFNGLBLENDFUNCINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendFuncIndexedAMD"); + pGlBlendFunciARB= (PFNGLBLENDFUNCIPROC) IRR_OGL_LOAD_EXTENSION("glBlendFunciARB"); + pGlBlendEquationIndexedAMD= (PFNGLBLENDEQUATIONINDEXEDAMDPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationIndexedAMD"); + pGlBlendEquationiARB= (PFNGLBLENDEQUATIONIPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationiARB"); + pGlProgramParameteriARB= (PFNGLPROGRAMPARAMETERIARBPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteriARB"); + pGlProgramParameteriEXT= (PFNGLPROGRAMPARAMETERIEXTPROC) IRR_OGL_LOAD_EXTENSION("glProgramParameteriEXT"); + + // occlusion query + pGlGenQueriesARB = (PFNGLGENQUERIESARBPROC) IRR_OGL_LOAD_EXTENSION("glGenQueriesARB"); + pGlDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC) IRR_OGL_LOAD_EXTENSION("glDeleteQueriesARB"); + pGlIsQueryARB = (PFNGLISQUERYARBPROC) IRR_OGL_LOAD_EXTENSION("glIsQueryARB"); + pGlBeginQueryARB = (PFNGLBEGINQUERYARBPROC) IRR_OGL_LOAD_EXTENSION("glBeginQueryARB"); + pGlEndQueryARB = (PFNGLENDQUERYARBPROC) IRR_OGL_LOAD_EXTENSION("glEndQueryARB"); + pGlGetQueryivARB = (PFNGLGETQUERYIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetQueryivARB"); + pGlGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetQueryObjectivARB"); + pGlGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC) IRR_OGL_LOAD_EXTENSION("glGetQueryObjectuivARB"); + pGlGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC) IRR_OGL_LOAD_EXTENSION("glGenOcclusionQueriesNV"); + pGlDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC) IRR_OGL_LOAD_EXTENSION("glDeleteOcclusionQueriesNV"); + pGlIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC) IRR_OGL_LOAD_EXTENSION("glIsOcclusionQueryNV"); + pGlBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC) IRR_OGL_LOAD_EXTENSION("glBeginOcclusionQueryNV"); + pGlEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC) IRR_OGL_LOAD_EXTENSION("glEndOcclusionQueryNV"); + pGlGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC) IRR_OGL_LOAD_EXTENSION("glGetOcclusionQueryivNV"); + pGlGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC) IRR_OGL_LOAD_EXTENSION("glGetOcclusionQueryuivNV"); + + // blend equation + pGlBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquationEXT"); + pGlBlendEquation = (PFNGLBLENDEQUATIONPROC) IRR_OGL_LOAD_EXTENSION("glBlendEquation"); + + // get vsync extension + #if defined(WGL_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + pWglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) IRR_OGL_LOAD_EXTENSION("wglSwapIntervalEXT"); + #endif + #if defined(GLX_SGI_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + pGlxSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalSGI"); + #endif + #if defined(GLX_EXT_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + pGlxSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalEXT"); + #endif + #if defined(GLX_MESA_swap_control) && !defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + pGlxSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)IRR_OGL_LOAD_EXTENSION("glXSwapIntervalMESA"); + #endif +#endif // use extension pointer + + GLint num=0; + // set some properties +#if defined(GL_ARB_multitexture) || defined(GL_VERSION_1_3) + if (Version>102 || FeatureAvailable[IRR_ARB_multitexture]) + { +#if defined(GL_MAX_TEXTURE_UNITS) + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &num); +#elif defined(GL_MAX_TEXTURE_UNITS_ARB) + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num); +#endif + MaxSupportedTextures=static_cast(num); + } +#endif +#if defined(GL_ARB_vertex_shader) || defined(GL_VERSION_2_0) + if (Version>=200 || FeatureAvailable[IRR_ARB_vertex_shader]) + { + num=0; +#if defined(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &num); +#elif defined(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB) + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &num); +#endif + MaxSupportedTextures=core::max_(MaxSupportedTextures,static_cast(num)); + } +#endif + glGetIntegerv(GL_MAX_LIGHTS, &num); + MaxLights=static_cast(num); +#ifdef GL_EXT_texture_filter_anisotropic + if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic]) + { + glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &num); + MaxAnisotropy=static_cast(num); + } +#endif +#ifdef GL_VERSION_1_2 + if (Version>101) + { + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &num); + MaxIndices=num; + } +#endif + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &num); + MaxTextureSize=static_cast(num); + if (queryFeature(EVDF_GEOMETRY_SHADER)) + { +#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_shader4) + glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &num); + MaxGeometryVerticesOut=static_cast(num); +#elif defined(GL_NV_geometry_program4) + extGlGetProgramiv(GEOMETRY_PROGRAM_NV, GL_MAX_PROGRAM_OUTPUT_VERTICES_NV, &num); + MaxGeometryVerticesOut=static_cast(num); +#endif + } +#ifdef GL_EXT_texture_lod_bias + if (FeatureAvailable[IRR_EXT_texture_lod_bias]) + glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &MaxTextureLODBias); +#endif + glGetIntegerv(GL_MAX_CLIP_PLANES, &num); + MaxUserClipPlanes=static_cast(num); + glGetIntegerv(GL_AUX_BUFFERS, &num); + MaxAuxBuffers=static_cast(num); +#ifdef GL_ARB_draw_buffers + if (FeatureAvailable[IRR_ARB_draw_buffers]) + { + glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &num); + MaxMultipleRenderTargets = static_cast(num); + } +#endif +#if defined(GL_ATI_draw_buffers) +#ifdef GL_ARB_draw_buffers + else +#endif + if (FeatureAvailable[IRR_ATI_draw_buffers]) + { + glGetIntegerv(GL_MAX_DRAW_BUFFERS_ATI, &num); + MaxMultipleRenderTargets = static_cast(num); + } +#endif + glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine); + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, DimAliasedPoint); + glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, DimSmoothedLine); + glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, DimSmoothedPoint); +#if defined(GL_ARB_shading_language_100) || defined (GL_VERSION_2_0) + if (FeatureAvailable[IRR_ARB_shading_language_100] || Version>=200) + { + glGetError(); // clean error buffer +#ifdef GL_SHADING_LANGUAGE_VERSION + const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); +#else + const GLubyte* shaderVersion = glGetString(GL_SHADING_LANGUAGE_VERSION_ARB); +#endif + if (glGetError() == GL_INVALID_ENUM) + ShaderLanguageVersion = 100; + else + { + const f32 sl_ver = core::fast_atof(reinterpret_cast(shaderVersion)); + ShaderLanguageVersion = static_cast(core::floor32(sl_ver)*100+core::round32(core::fract(sl_ver)*10.0f)); + } + } +#endif + +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (!pGlActiveTextureARB || !pGlClientActiveTextureARB) + { + MultiTextureExtension = false; + os::Printer::log("Failed to load OpenGL's multitexture extension, proceeding without.", ELL_WARNING); + } + else +#endif + MaxTextureUnits = core::min_(MaxSupportedTextures, static_cast(MATERIAL_MAX_TEXTURES)); + if (MaxTextureUnits < 2) + { + MultiTextureExtension = false; + os::Printer::log("Warning: OpenGL device only has one texture unit. Disabling multitexturing.", ELL_WARNING); + } + +#ifdef GL_ARB_occlusion_query + if (FeatureAvailable[IRR_ARB_occlusion_query]) + { + extGlGetQueryiv(GL_SAMPLES_PASSED_ARB,GL_QUERY_COUNTER_BITS_ARB, + &num); + OcclusionQuerySupport=(num>0); + } + else +#endif +#ifdef GL_NV_occlusion_query + if (FeatureAvailable[IRR_NV_occlusion_query]) + { + glGetIntegerv(GL_PIXEL_COUNTER_BITS_NV, &num); + OcclusionQuerySupport=(num>0); + } + else +#endif + OcclusionQuerySupport=false; + +#ifdef _DEBUG + if (FeatureAvailable[IRR_NVX_gpu_memory_info]) + { + // undocumented flags, so use the RAW values + GLint val; + glGetIntegerv(0x9047, &val); + os::Printer::log("Dedicated video memory (kB)", core::stringc(val)); + glGetIntegerv(0x9048, &val); + os::Printer::log("Total video memory (kB)", core::stringc(val)); + glGetIntegerv(0x9049, &val); + os::Printer::log("Available video memory (kB)", core::stringc(val)); + } +#ifdef GL_ATI_meminfo + if (FeatureAvailable[IRR_ATI_meminfo]) + { + GLint val[4]; + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, val); + os::Printer::log("Free texture memory (kB)", core::stringc(val[0])); + glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, val); + os::Printer::log("Free VBO memory (kB)", core::stringc(val[0])); + glGetIntegerv(GL_RENDERBUFFER_FREE_MEMORY_ATI, val); + os::Printer::log("Free render buffer memory (kB)", core::stringc(val[0])); + } +#endif +#endif +} + +bool COpenGLExtensionHandler::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { + case EVDF_RENDER_TO_TARGET: + return true; + case EVDF_HARDWARE_TL: + return true; // we cannot tell other things + case EVDF_MULTITEXTURE: + return MultiTextureExtension; + case EVDF_BILINEAR_FILTER: + return true; + case EVDF_MIP_MAP: + return true; + case EVDF_MIP_MAP_AUTO_UPDATE: + return FeatureAvailable[IRR_SGIS_generate_mipmap] || FeatureAvailable[IRR_EXT_framebuffer_object] || FeatureAvailable[IRR_ARB_framebuffer_object]; + case EVDF_STENCIL_BUFFER: + return StencilBuffer; + case EVDF_VERTEX_SHADER_1_1: + case EVDF_ARB_VERTEX_PROGRAM_1: + return FeatureAvailable[IRR_ARB_vertex_program] || FeatureAvailable[IRR_NV_vertex_program1_1]; + case EVDF_PIXEL_SHADER_1_1: + case EVDF_PIXEL_SHADER_1_2: + case EVDF_ARB_FRAGMENT_PROGRAM_1: + return FeatureAvailable[IRR_ARB_fragment_program] || FeatureAvailable[IRR_NV_fragment_program]; + case EVDF_PIXEL_SHADER_2_0: + case EVDF_VERTEX_SHADER_2_0: + case EVDF_ARB_GLSL: + return (FeatureAvailable[IRR_ARB_shading_language_100]||Version>=200); + case EVDF_TEXTURE_NSQUARE: + return true; // non-square is always supported + case EVDF_TEXTURE_NPOT: + // Some ATI cards seem to have only SW support in OpenGL 2.0 + // drivers if the extension is not exposed, so we skip this + // extra test for now! + // return (FeatureAvailable[IRR_ARB_texture_non_power_of_two]||Version>=200); + return (FeatureAvailable[IRR_ARB_texture_non_power_of_two]); + case EVDF_FRAMEBUFFER_OBJECT: + return FeatureAvailable[IRR_EXT_framebuffer_object] || FeatureAvailable[IRR_ARB_framebuffer_object]; + case EVDF_VERTEX_BUFFER_OBJECT: + return FeatureAvailable[IRR_ARB_vertex_buffer_object]; + case EVDF_COLOR_MASK: + return true; + case EVDF_ALPHA_TO_COVERAGE: + return FeatureAvailable[IRR_ARB_multisample]; + case EVDF_GEOMETRY_SHADER: + return FeatureAvailable[IRR_ARB_geometry_shader4] || FeatureAvailable[IRR_EXT_geometry_shader4] || FeatureAvailable[IRR_NV_geometry_program4] || FeatureAvailable[IRR_NV_geometry_shader4]; + case EVDF_MULTIPLE_RENDER_TARGETS: + return FeatureAvailable[IRR_ARB_draw_buffers] || FeatureAvailable[IRR_ATI_draw_buffers]; + case EVDF_MRT_BLEND: + case EVDF_MRT_COLOR_MASK: + return FeatureAvailable[IRR_EXT_draw_buffers2]; + case EVDF_MRT_BLEND_FUNC: + return FeatureAvailable[IRR_ARB_draw_buffers_blend] || FeatureAvailable[IRR_AMD_draw_buffers_blend]; + case EVDF_OCCLUSION_QUERY: + return FeatureAvailable[IRR_ARB_occlusion_query] && OcclusionQuerySupport; + case EVDF_POLYGON_OFFSET: + // both features supported with OpenGL 1.1 + return Version>=110; + case EVDF_BLEND_OPERATIONS: + return (Version>=120) || FeatureAvailable[IRR_EXT_blend_minmax] || + FeatureAvailable[IRR_EXT_blend_subtract] || FeatureAvailable[IRR_EXT_blend_logic_op]; + case EVDF_TEXTURE_MATRIX: +#ifdef _IRR_COMPILE_WITH_CG_ + // available iff. define is present + case EVDF_CG: +#endif + return true; + default: + return false; + }; +} + + +} +} + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.h new file mode 100644 index 0000000..1b77bad --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLExtensionHandler.h @@ -0,0 +1,2586 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef __C_OPEN_GL_FEATURE_MAP_H_INCLUDED__ +#define __C_OPEN_GL_FEATURE_MAP_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "EDriverFeatures.h" +#include "irrTypes.h" +#include "os.h" + +#if defined(_IRR_WINDOWS_API_) + // include windows headers for HWND + #define WIN32_LEAN_AND_MEAN + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #endif + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #endif + #include "wglext.h" + + #ifdef _MSC_VER + #pragma comment(lib, "OpenGL32.lib") + #endif + +#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #endif + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #endif +#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) && !defined(_IRR_COMPILE_WITH_X11_DEVICE_) + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #define GLX_GLXEXT_LEGACY 1 + #else + #define GL_GLEXT_PROTOTYPES 1 + #define GLX_GLXEXT_PROTOTYPES 1 + #endif + #define NO_SDL_GLEXT + #include + #include + #include "glext.h" +#else + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 + #define GLX_GLXEXT_LEGACY 1 + #else + #define GL_GLEXT_PROTOTYPES 1 + #define GLX_GLXEXT_PROTOTYPES 1 + #endif + #include + #include + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" + #undef GLX_ARB_get_proc_address // avoid problems with local glxext.h + #include "glxext.h" + #endif +#endif + +#ifndef GL_ARB_shader_objects +/* GL types for program/shader text and shader object handles */ +typedef char GLcharARB; +typedef unsigned int GLhandleARB; +#endif + +#ifndef GL_VERSION_2_0 +/* GL type for program/shader text */ +typedef char GLchar; +#endif + + +namespace irr +{ +namespace video +{ + + +static const char* const OpenGLFeatureStrings[] = { + "GL_3DFX_multisample", + "GL_3DFX_tbuffer", + "GL_3DFX_texture_compression_FXT1", + "GL_AMD_blend_minmax_factor", + "GL_AMD_conservative_depth", + "GL_AMD_debug_output", + "GL_AMD_depth_clamp_separate", + "GL_AMD_draw_buffers_blend", + "GL_AMD_multi_draw_indirect", + "GL_AMD_name_gen_delete", + "GL_AMD_performance_monitor", + "GL_AMD_sample_positions", + "GL_AMD_seamless_cubemap_per_texture", + "GL_AMD_shader_stencil_export", + "GL_AMD_texture_texture4", + "GL_AMD_transform_feedback3_lines_triangles", + "GL_AMD_vertex_shader_tesselator", + "GL_APPLE_aux_depth_stencil", + "GL_APPLE_client_storage", + "GL_APPLE_element_array", + "GL_APPLE_fence", + "GL_APPLE_float_pixels", + "GL_APPLE_flush_buffer_range", + "GL_APPLE_object_purgeable", + "GL_APPLE_rgb_422", + "GL_APPLE_row_bytes", + "GL_APPLE_specular_vector", + "GL_APPLE_texture_range", + "GL_APPLE_transform_hint", + "GL_APPLE_vertex_array_object", + "GL_APPLE_vertex_array_range", + "GL_APPLE_vertex_program_evaluators", + "GL_APPLE_ycbcr_422", + "GL_ARB_base_instance", + "GL_ARB_blend_func_extended", + "GL_ARB_cl_event", + "GL_ARB_color_buffer_float", + "GL_ARB_compatibility", + "GL_ARB_compressed_texture_pixel_storage", + "GL_ARB_conservative_depth", + "GL_ARB_copy_buffer", + "GL_ARB_debug_output", + "GL_ARB_depth_buffer_float", + "GL_ARB_depth_clamp", + "GL_ARB_depth_texture", + "GL_ARB_draw_buffers", + "GL_ARB_draw_buffers_blend", + "GL_ARB_draw_elements_base_vertex", + "GL_ARB_draw_indirect", + "GL_ARB_draw_instanced", + "GL_ARB_ES2_compatibility", + "GL_ARB_explicit_attrib_location", + "GL_ARB_fragment_coord_conventions", + "GL_ARB_fragment_program", + "GL_ARB_fragment_program_shadow", + "GL_ARB_fragment_shader", + "GL_ARB_framebuffer_object", + "GL_ARB_framebuffer_sRGB", + "GL_ARB_get_program_binary", + "GL_ARB_geometry_shader4", + "GL_ARB_gpu_shader5", + "GL_ARB_gpu_shader_fp64", + "GL_ARB_half_float_pixel", + "GL_ARB_half_float_vertex", + "GL_ARB_imaging", + "GL_ARB_instanced_arrays", + "GL_ARB_internalformat_query", + "GL_ARB_map_buffer_alignment", + "GL_ARB_map_buffer_range", + "GL_ARB_matrix_palette", + "GL_ARB_multisample", + "GL_ARB_multitexture", + "GL_ARB_occlusion_query", + "GL_ARB_occlusion_query2", + "GL_ARB_pixel_buffer_object", + "GL_ARB_point_parameters", + "GL_ARB_point_sprite", + "GL_ARB_provoking_vertex", + "GL_ARB_robustness", + "GL_ARB_sample_shading", + "GL_ARB_sampler_objects", + "GL_ARB_seamless_cube_map", + "GL_ARB_separate_shader_objects", + "GL_ARB_shader_atomic_counters", + "GL_ARB_shader_bit_encoding", + "GL_ARB_shader_image_load_store", + "GL_ARB_shader_objects", + "GL_ARB_shader_precision", + "GL_ARB_shader_stencil_export", + "GL_ARB_shader_subroutine", + "GL_ARB_shader_texture_lod", + "GL_ARB_shading_language_100", + "GL_ARB_shading_language_420pack", + "GL_ARB_shading_language_include", + "GL_ARB_shading_language_packing", + "GL_ARB_shadow", + "GL_ARB_shadow_ambient", + "GL_ARB_sync", + "GL_ARB_tessellation_shader", + "GL_ARB_texture_border_clamp", + "GL_ARB_texture_buffer_object", + "GL_ARB_texture_buffer_object_rgb32", + "GL_ARB_texture_compression", + "GL_ARB_texture_compression_bptc", + "GL_ARB_texture_compression_rgtc", + "GL_ARB_texture_cube_map", + "GL_ARB_texture_cube_map_array", + "GL_ARB_texture_env_add", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_crossbar", + "GL_ARB_texture_env_dot3", + "GL_ARB_texture_float", + "GL_ARB_texture_gather", + "GL_ARB_texture_mirrored_repeat", + "GL_ARB_texture_multisample", + "GL_ARB_texture_non_power_of_two", + "GL_ARB_texture_query_lod", + "GL_ARB_texture_rectangle", + "GL_ARB_texture_rg", + "GL_ARB_texture_rgb10_a2ui", + "GL_ARB_texture_storage", + "GL_ARB_texture_swizzle", + "GL_ARB_timer_query", + "GL_ARB_transform_feedback2", + "GL_ARB_transform_feedback3", + "GL_ARB_transform_feedback_instanced", + "GL_ARB_transpose_matrix", + "GL_ARB_uniform_buffer_object", + "GL_ARB_vertex_array_bgra", + "GL_ARB_vertex_array_object", + "GL_ARB_vertex_attrib_64bit", + "GL_ARB_vertex_blend", + "GL_ARB_vertex_buffer_object", + "GL_ARB_vertex_program", + "GL_ARB_vertex_shader", + "GL_ARB_vertex_type_2_10_10_10_rev", + "GL_ARB_viewport_array", + "GL_ARB_window_pos", + "GL_ATI_draw_buffers", + "GL_ATI_element_array", + "GL_ATI_envmap_bumpmap", + "GL_ATI_fragment_shader", + "GL_ATI_map_object_buffer", + "GL_ATI_meminfo", + "GL_ATI_pixel_format_float", + "GL_ATI_pn_triangles", + "GL_ATI_separate_stencil", + "GL_ATI_text_fragment_shader", + "GL_ATI_texture_env_combine3", + "GL_ATI_texture_float", + "GL_ATI_texture_mirror_once", + "GL_ATI_vertex_array_object", + "GL_ATI_vertex_attrib_array_object", + "GL_ATI_vertex_streams", + "GL_EXT_422_pixels", + "GL_EXT_abgr", + "GL_EXT_bgra", + "GL_EXT_bindable_uniform", + "GL_EXT_blend_color", + "GL_EXT_blend_equation_separate", + "GL_EXT_blend_func_separate", + "GL_EXT_blend_logic_op", + "GL_EXT_blend_minmax", + "GL_EXT_blend_subtract", + "GL_EXT_clip_volume_hint", + "GL_EXT_cmyka", + "GL_EXT_color_subtable", + "GL_EXT_compiled_vertex_array", + "GL_EXT_convolution", + "GL_EXT_coordinate_frame", + "GL_EXT_copy_texture", + "GL_EXT_cull_vertex", + "GL_EXT_depth_bounds_test", + "GL_EXT_direct_state_access", + "GL_EXT_draw_buffers2", + "GL_EXT_draw_instanced", + "GL_EXT_draw_range_elements", + "GL_EXT_fog_coord", + "GL_EXT_framebuffer_blit", + "GL_EXT_framebuffer_multisample", + "GL_EXT_framebuffer_multisample_blit_scaled", + "GL_EXT_framebuffer_object", + "GL_EXT_framebuffer_sRGB", + "GL_EXT_geometry_shader4", + "GL_EXT_gpu_program_parameters", + "GL_EXT_gpu_shader4", + "GL_EXT_histogram", + "GL_EXT_index_array_formats", + "GL_EXT_index_func", + "GL_EXT_index_material", + "GL_EXT_index_texture", + "GL_EXT_light_texture", + "GL_EXT_misc_attribute", + "GL_EXT_multi_draw_arrays", + "GL_EXT_multisample", + "GL_EXT_packed_depth_stencil", + "GL_EXT_packed_float", + "GL_EXT_packed_pixels", + "GL_EXT_paletted_texture", + "GL_EXT_pixel_buffer_object", + "GL_EXT_pixel_transform", + "GL_EXT_pixel_transform_color_table", + "GL_EXT_point_parameters", + "GL_EXT_polygon_offset", + "GL_EXT_provoking_vertex", + "GL_EXT_rescale_normal", + "GL_EXT_secondary_color", + "GL_EXT_separate_shader_objects", + "GL_EXT_separate_specular_color", + "GL_EXT_shader_image_load_store", + "GL_EXT_shadow_funcs", + "GL_EXT_shared_texture_palette", + "GL_EXT_stencil_clear_tag", + "GL_EXT_stencil_two_side", + "GL_EXT_stencil_wrap", + "GL_EXT_subtexture", + "GL_EXT_texture", + "GL_EXT_texture3D", + "GL_EXT_texture_array", + "GL_EXT_texture_buffer_object", + "GL_EXT_texture_compression_latc", + "GL_EXT_texture_compression_rgtc", + "GL_EXT_texture_compression_s3tc", + "GL_EXT_texture_cube_map", + "GL_EXT_texture_env_add", + "GL_EXT_texture_env_combine", + "GL_EXT_texture_env_dot3", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_texture_integer", + "GL_EXT_texture_lod_bias", + "GL_EXT_texture_mirror_clamp", + "GL_EXT_texture_object", + "GL_EXT_texture_perturb_normal", + "GL_EXT_texture_shared_exponent", + "GL_EXT_texture_snorm", + "GL_EXT_texture_sRGB", + "GL_EXT_texture_sRGB_decode", + "GL_EXT_texture_swizzle", + "GL_EXT_timer_query", + "GL_EXT_transform_feedback", + "GL_EXT_vertex_array", + "GL_EXT_vertex_array_bgra", + "GL_EXT_vertex_attrib_64bit", + "GL_EXT_vertex_shader", + "GL_EXT_vertex_weighting", + "GL_EXT_x11_sync_object", + "GL_FfdMaskSGIX", + "GL_GREMEDY_frame_terminator", + "GL_GREMEDY_string_marker", + "GL_HP_convolution_border_modes", + "GL_HP_image_transform", + "GL_HP_occlusion_test", + "GL_HP_texture_lighting", + "GL_IBM_cull_vertex", + "GL_IBM_multimode_draw_arrays", + "GL_IBM_rasterpos_clip", + "GL_IBM_texture_mirrored_repeat", + "GL_IBM_vertex_array_lists", + "GL_INGR_blend_func_separate", + "GL_INGR_color_clamp", + "GL_INGR_interlace_read", + "GL_INGR_palette_buffer", + "GL_INTEL_parallel_arrays", + "GL_INTEL_texture_scissor", + "GL_MESA_pack_invert", + "GL_MESA_resize_buffers", + "GL_MESA_window_pos", + "GL_MESAX_texture_stack", + "GL_MESA_ycbcr_texture", + "GL_NV_blend_square", + "GL_NV_conditional_render", + "GL_NV_copy_depth_to_color", + "GL_NV_copy_image", + "GL_NV_depth_buffer_float", + "GL_NV_depth_clamp", + "GL_NV_evaluators", + "GL_NV_explicit_multisample", + "GL_NV_fence", + "GL_NV_float_buffer", + "GL_NV_fog_distance", + "GL_NV_fragment_program", + "GL_NV_fragment_program2", + "GL_NV_fragment_program4", + "GL_NV_fragment_program_option", + "GL_NV_framebuffer_multisample_coverage", + "GL_NV_geometry_program4", + "GL_NV_geometry_shader4", + "GL_NV_gpu_program4", + "GL_NV_gpu_program5", + "GL_NV_gpu_shader5", + "GL_NV_half_float", + "GL_NV_light_max_exponent", + "GL_NV_multisample_coverage", + "GL_NV_multisample_filter_hint", + "GL_NV_occlusion_query", + "GL_NV_packed_depth_stencil", + "GL_NV_parameter_buffer_object", + "GL_NV_parameter_buffer_object2", + "GL_NV_pixel_data_range", + "GL_NV_point_sprite", + "GL_NV_present_video", + "GL_NV_primitive_restart", + "GL_NV_register_combiners", + "GL_NV_register_combiners2", + "GL_NV_shader_buffer_load", + "GL_NV_shader_buffer_store", + "GL_NV_tessellation_program5", + "GL_NV_texgen_emboss", + "GL_NV_texgen_reflection", + "GL_NV_texture_barrier", + "GL_NV_texture_compression_vtc", + "GL_NV_texture_env_combine4", + "GL_NV_texture_expand_normal", + "GL_NV_texture_multisample", + "GL_NV_texture_rectangle", + "GL_NV_texture_shader", + "GL_NV_texture_shader2", + "GL_NV_texture_shader3", + "GL_NV_transform_feedback", + "GL_NV_transform_feedback2", + "GL_NV_vdpau_interop", + "GL_NV_vertex_array_range", + "GL_NV_vertex_array_range2", + "GL_NV_vertex_attrib_integer_64bit", + "GL_NV_vertex_buffer_unified_memory", + "GL_NV_vertex_program", + "GL_NV_vertex_program1_1", + "GL_NV_vertex_program2", + "GL_NV_vertex_program2_option", + "GL_NV_vertex_program3", + "GL_NV_vertex_program4", + "GL_NV_video_capture", + "GL_OES_read_format", + "GL_OML_interlace", + "GL_OML_resample", + "GL_OML_subsample", + "GL_PGI_misc_hints", + "GL_PGI_vertex_hints", + "GL_REND_screen_coordinates", + "GL_S3_s3tc", + "GL_SGI_color_matrix", + "GL_SGI_color_table", + "GL_SGI_depth_pass_instrument", + "GL_SGIS_detail_texture", + "GL_SGIS_fog_function", + "GL_SGIS_generate_mipmap", + "GL_SGIS_multisample", + "GL_SGIS_pixel_texture", + "GL_SGIS_point_line_texgen", + "GL_SGIS_point_parameters", + "GL_SGIS_sharpen_texture", + "GL_SGIS_texture4D", + "GL_SGIS_texture_border_clamp", + "GL_SGIS_texture_color_mask", + "GL_SGIS_texture_edge_clamp", + "GL_SGIS_texture_filter4", + "GL_SGIS_texture_lod", + "GL_SGIS_texture_select", + "GL_SGI_texture_color_table", + "GL_SGIX_async", + "GL_SGIX_async_histogram", + "GL_SGIX_async_pixel", + "GL_SGIX_blend_alpha_minmax", + "GL_SGIX_calligraphic_fragment", + "GL_SGIX_clipmap", + "GL_SGIX_convolution_accuracy", + "GL_SGIX_depth_pass_instrument", + "GL_SGIX_depth_texture", + "GL_SGIX_flush_raster", + "GL_SGIX_fog_offset", + "GL_SGIX_fog_scale", + "GL_SGIX_fragment_lighting", + "GL_SGIX_framezoom", + "GL_SGIX_igloo_interface", + "GL_SGIX_impact_pixel_texture", + "GL_SGIX_instruments", + "GL_SGIX_interlace", + "GL_SGIX_ir_instrument1", + "GL_SGIX_list_priority", + "GL_SGIX_pixel_texture", + "GL_SGIX_pixel_tiles", + "GL_SGIX_polynomial_ffd", + "GL_SGIX_reference_plane", + "GL_SGIX_resample", + "GL_SGIX_scalebias_hint", + "GL_SGIX_shadow", + "GL_SGIX_shadow_ambient", + "GL_SGIX_sprite", + "GL_SGIX_subsample", + "GL_SGIX_tag_sample_buffer", + "GL_SGIX_texture_add_env", + "GL_SGIX_texture_coordinate_clamp", + "GL_SGIX_texture_lod_bias", + "GL_SGIX_texture_multi_buffer", + "GL_SGIX_texture_scale_bias", + "GL_SGIX_texture_select", + "GL_SGIX_vertex_preclip", + "GL_SGIX_ycrcb", + "GL_SGIX_ycrcba", + "GL_SGIX_ycrcb_subsample", + "GL_SUN_convolution_border_modes", + "GL_SUN_global_alpha", + "GL_SUN_mesh_array", + "GL_SUN_slice_accum", + "GL_SUN_triangle_list", + "GL_SUN_vertex", + "GL_SUNX_constant_data", + "GL_WIN_phong_shading", + "GL_WIN_specular_fog", + // unofficial stuff + "GL_NVX_gpu_memory_info" +}; + + +class COpenGLExtensionHandler +{ + public: + enum EOpenGLFeatures { + IRR_3DFX_multisample = 0, + IRR_3DFX_tbuffer, + IRR_3DFX_texture_compression_FXT1, + IRR_AMD_blend_minmax_factor, + IRR_AMD_conservative_depth, + IRR_AMD_debug_output, + IRR_AMD_depth_clamp_separate, + IRR_AMD_draw_buffers_blend, + IRR_AMD_multi_draw_indirect, + IRR_AMD_name_gen_delete, + IRR_AMD_performance_monitor, + IRR_AMD_sample_positions, + IRR_AMD_seamless_cubemap_per_texture, + IRR_AMD_shader_stencil_export, + IRR_AMD_texture_texture4, + IRR_AMD_transform_feedback3_lines_triangles, + IRR_AMD_vertex_shader_tesselator, + IRR_APPLE_aux_depth_stencil, + IRR_APPLE_client_storage, + IRR_APPLE_element_array, + IRR_APPLE_fence, + IRR_APPLE_float_pixels, + IRR_APPLE_flush_buffer_range, + IRR_APPLE_object_purgeable, + IRR_APPLE_rgb_422, + IRR_APPLE_row_bytes, + IRR_APPLE_specular_vector, + IRR_APPLE_texture_range, + IRR_APPLE_transform_hint, + IRR_APPLE_vertex_array_object, + IRR_APPLE_vertex_array_range, + IRR_APPLE_vertex_program_evaluators, + IRR_APPLE_ycbcr_422, + IRR_ARB_base_instance, + IRR_ARB_blend_func_extended, + IRR_ARB_cl_event, + IRR_ARB_color_buffer_float, + IRR_ARB_compatibility, + IRR_ARB_compressed_texture_pixel_storage, + IRR_ARB_conservative_depth, + IRR_ARB_copy_buffer, + IRR_ARB_debug_output, + IRR_ARB_depth_buffer_float, + IRR_ARB_depth_clamp, + IRR_ARB_depth_texture, + IRR_ARB_draw_buffers, + IRR_ARB_draw_buffers_blend, + IRR_ARB_draw_elements_base_vertex, + IRR_ARB_draw_indirect, + IRR_ARB_draw_instanced, + IRR_ARB_ES2_compatibility, + IRR_ARB_explicit_attrib_location, + IRR_ARB_fragment_coord_conventions, + IRR_ARB_fragment_program, + IRR_ARB_fragment_program_shadow, + IRR_ARB_fragment_shader, + IRR_ARB_framebuffer_object, + IRR_ARB_framebuffer_sRGB, + IRR_ARB_geometry_shader4, + IRR_ARB_get_program_binary, + IRR_ARB_gpu_shader5, + IRR_ARB_gpu_shader_fp64, + IRR_ARB_half_float_pixel, + IRR_ARB_half_float_vertex, + IRR_ARB_imaging, + IRR_ARB_instanced_arrays, + IRR_ARB_internalformat_query, + IRR_ARB_map_buffer_alignment, + IRR_ARB_map_buffer_range, + IRR_ARB_matrix_palette, + IRR_ARB_multisample, + IRR_ARB_multitexture, + IRR_ARB_occlusion_query, + IRR_ARB_occlusion_query2, + IRR_ARB_pixel_buffer_object, + IRR_ARB_point_parameters, + IRR_ARB_point_sprite, + IRR_ARB_provoking_vertex, + IRR_ARB_robustness, + IRR_ARB_sample_shading, + IRR_ARB_sampler_objects, + IRR_ARB_seamless_cube_map, + IRR_ARB_separate_shader_objects, + IRR_ARB_shader_atomic_counters, + IRR_ARB_shader_bit_encoding, + IRR_ARB_shader_image_load_store, + IRR_ARB_shader_objects, + IRR_ARB_shader_precision, + IRR_ARB_shader_stencil_export, + IRR_ARB_shader_subroutine, + IRR_ARB_shader_texture_lod, + IRR_ARB_shading_language_100, + IRR_ARB_shading_language_420pack, + IRR_ARB_shading_language_include, + IRR_ARB_shading_language_packing, + IRR_ARB_shadow, + IRR_ARB_shadow_ambient, + IRR_ARB_sync, + IRR_ARB_tessellation_shader, + IRR_ARB_texture_border_clamp, + IRR_ARB_texture_buffer_object, + IRR_ARB_texture_buffer_object_rgb32, + IRR_ARB_texture_compression, + IRR_ARB_texture_compression_bptc, + IRR_ARB_texture_compression_rgtc, + IRR_ARB_texture_cube_map, + IRR_ARB_texture_cube_map_array, + IRR_ARB_texture_env_add, + IRR_ARB_texture_env_combine, + IRR_ARB_texture_env_crossbar, + IRR_ARB_texture_env_dot3, + IRR_ARB_texture_float, + IRR_ARB_texture_gather, + IRR_ARB_texture_mirrored_repeat, + IRR_ARB_texture_multisample, + IRR_ARB_texture_non_power_of_two, + IRR_ARB_texture_query_lod, + IRR_ARB_texture_rectangle, + IRR_ARB_texture_rg, + IRR_ARB_texture_rgb10_a2ui, + IRR_ARB_texture_storage, + IRR_ARB_texture_swizzle, + IRR_ARB_timer_query, + IRR_ARB_transform_feedback2, + IRR_ARB_transform_feedback3, + IRR_ARB_transform_feedback_instanced, + IRR_ARB_transpose_matrix, + IRR_ARB_uniform_buffer_object, + IRR_ARB_vertex_array_bgra, + IRR_ARB_vertex_array_object, + IRR_ARB_vertex_attrib_64bit, + IRR_ARB_vertex_blend, + IRR_ARB_vertex_buffer_object, + IRR_ARB_vertex_program, + IRR_ARB_vertex_shader, + IRR_ARB_vertex_type_2_10_10_10_rev, + IRR_ARB_viewport_array, + IRR_ARB_window_pos, + IRR_ATI_draw_buffers, + IRR_ATI_element_array, + IRR_ATI_envmap_bumpmap, + IRR_ATI_fragment_shader, + IRR_ATI_map_object_buffer, + IRR_ATI_meminfo, + IRR_ATI_pixel_format_float, + IRR_ATI_pn_triangles, + IRR_ATI_separate_stencil, + IRR_ATI_text_fragment_shader, + IRR_ATI_texture_env_combine3, + IRR_ATI_texture_float, + IRR_ATI_texture_mirror_once, + IRR_ATI_vertex_array_object, + IRR_ATI_vertex_attrib_array_object, + IRR_ATI_vertex_streams, + IRR_EXT_422_pixels, + IRR_EXT_abgr, + IRR_EXT_bgra, + IRR_EXT_bindable_uniform, + IRR_EXT_blend_color, + IRR_EXT_blend_equation_separate, + IRR_EXT_blend_func_separate, + IRR_EXT_blend_logic_op, + IRR_EXT_blend_minmax, + IRR_EXT_blend_subtract, + IRR_EXT_clip_volume_hint, + IRR_EXT_cmyka, + IRR_EXT_color_subtable, + IRR_EXT_compiled_vertex_array, + IRR_EXT_convolution, + IRR_EXT_coordinate_frame, + IRR_EXT_copy_texture, + IRR_EXT_cull_vertex, + IRR_EXT_depth_bounds_test, + IRR_EXT_direct_state_access, + IRR_EXT_draw_buffers2, + IRR_EXT_draw_instanced, + IRR_EXT_draw_range_elements, + IRR_EXT_fog_coord, + IRR_EXT_framebuffer_blit, + IRR_EXT_framebuffer_multisample, + IRR_EXT_framebuffer_multisample_blit_scaled, + IRR_EXT_framebuffer_object, + IRR_EXT_framebuffer_sRGB, + IRR_EXT_geometry_shader4, + IRR_EXT_gpu_program_parameters, + IRR_EXT_gpu_shader4, + IRR_EXT_histogram, + IRR_EXT_index_array_formats, + IRR_EXT_index_func, + IRR_EXT_index_material, + IRR_EXT_index_texture, + IRR_EXT_light_texture, + IRR_EXT_misc_attribute, + IRR_EXT_multi_draw_arrays, + IRR_EXT_multisample, + IRR_EXT_packed_depth_stencil, + IRR_EXT_packed_float, + IRR_EXT_packed_pixels, + IRR_EXT_paletted_texture, + IRR_EXT_pixel_buffer_object, + IRR_EXT_pixel_transform, + IRR_EXT_pixel_transform_color_table, + IRR_EXT_point_parameters, + IRR_EXT_polygon_offset, + IRR_EXT_provoking_vertex, + IRR_EXT_rescale_normal, + IRR_EXT_secondary_color, + IRR_EXT_separate_shader_objects, + IRR_EXT_separate_specular_color, + IRR_EXT_shader_image_load_store, + IRR_EXT_shadow_funcs, + IRR_EXT_shared_texture_palette, + IRR_EXT_stencil_clear_tag, + IRR_EXT_stencil_two_side, + IRR_EXT_stencil_wrap, + IRR_EXT_subtexture, + IRR_EXT_texture, + IRR_EXT_texture3D, + IRR_EXT_texture_array, + IRR_EXT_texture_buffer_object, + IRR_EXT_texture_compression_latc, + IRR_EXT_texture_compression_rgtc, + IRR_EXT_texture_compression_s3tc, + IRR_EXT_texture_cube_map, + IRR_EXT_texture_env_add, + IRR_EXT_texture_env_combine, + IRR_EXT_texture_env_dot3, + IRR_EXT_texture_filter_anisotropic, + IRR_EXT_texture_integer, + IRR_EXT_texture_lod_bias, + IRR_EXT_texture_mirror_clamp, + IRR_EXT_texture_object, + IRR_EXT_texture_perturb_normal, + IRR_EXT_texture_shared_exponent, + IRR_EXT_texture_snorm, + IRR_EXT_texture_sRGB, + IRR_EXT_texture_sRGB_decode, + IRR_EXT_texture_swizzle, + IRR_EXT_timer_query, + IRR_EXT_transform_feedback, + IRR_EXT_vertex_array, + IRR_EXT_vertex_array_bgra, + IRR_EXT_vertex_attrib_64bit, + IRR_EXT_vertex_shader, + IRR_EXT_vertex_weighting, + IRR_EXT_x11_sync_object, + IRR_FfdMaskSGIX, + IRR_GREMEDY_frame_terminator, + IRR_GREMEDY_string_marker, + IRR_HP_convolution_border_modes, + IRR_HP_image_transform, + IRR_HP_occlusion_test, + IRR_HP_texture_lighting, + IRR_IBM_cull_vertex, + IRR_IBM_multimode_draw_arrays, + IRR_IBM_rasterpos_clip, + IRR_IBM_texture_mirrored_repeat, + IRR_IBM_vertex_array_lists, + IRR_INGR_blend_func_separate, + IRR_INGR_color_clamp, + IRR_INGR_interlace_read, + IRR_INGR_palette_buffer, + IRR_INTEL_parallel_arrays, + IRR_INTEL_texture_scissor, + IRR_MESA_pack_invert, + IRR_MESA_resize_buffers, + IRR_MESA_window_pos, + IRR_MESAX_texture_stack, + IRR_MESA_ycbcr_texture, + IRR_NV_blend_square, + IRR_NV_conditional_render, + IRR_NV_copy_depth_to_color, + IRR_NV_copy_image, + IRR_NV_depth_buffer_float, + IRR_NV_depth_clamp, + IRR_NV_evaluators, + IRR_NV_explicit_multisample, + IRR_NV_fence, + IRR_NV_float_buffer, + IRR_NV_fog_distance, + IRR_NV_fragment_program, + IRR_NV_fragment_program2, + IRR_NV_fragment_program4, + IRR_NV_fragment_program_option, + IRR_NV_framebuffer_multisample_coverage, + IRR_NV_geometry_program4, + IRR_NV_geometry_shader4, + IRR_NV_gpu_program4, + IRR_NV_gpu_program5, + IRR_NV_gpu_shader5, + IRR_NV_half_float, + IRR_NV_light_max_exponent, + IRR_NV_multisample_coverage, + IRR_NV_multisample_filter_hint, + IRR_NV_occlusion_query, + IRR_NV_packed_depth_stencil, + IRR_NV_parameter_buffer_object, + IRR_NV_parameter_buffer_object2, + IRR_NV_pixel_data_range, + IRR_NV_point_sprite, + IRR_NV_present_video, + IRR_NV_primitive_restart, + IRR_NV_register_combiners, + IRR_NV_register_combiners2, + IRR_NV_shader_buffer_load, + IRR_NV_shader_buffer_store, + IRR_NV_tessellation_program5, + IRR_NV_texgen_emboss, + IRR_NV_texgen_reflection, + IRR_NV_texture_barrier, + IRR_NV_texture_compression_vtc, + IRR_NV_texture_env_combine4, + IRR_NV_texture_expand_normal, + IRR_NV_texture_multisample, + IRR_NV_texture_rectangle, + IRR_NV_texture_shader, + IRR_NV_texture_shader2, + IRR_NV_texture_shader3, + IRR_NV_transform_feedback, + IRR_NV_transform_feedback2, + IRR_NV_vdpau_interop, + IRR_NV_vertex_array_range, + IRR_NV_vertex_array_range2, + IRR_NV_vertex_attrib_integer_64bit, + IRR_NV_vertex_buffer_unified_memory, + IRR_NV_vertex_program, + IRR_NV_vertex_program1_1, + IRR_NV_vertex_program2, + IRR_NV_vertex_program2_option, + IRR_NV_vertex_program3, + IRR_NV_vertex_program4, + IRR_NV_video_capture, + IRR_OES_read_format, + IRR_OML_interlace, + IRR_OML_resample, + IRR_OML_subsample, + IRR_PGI_misc_hints, + IRR_PGI_vertex_hints, + IRR_REND_screen_coordinates, + IRR_S3_s3tc, + IRR_SGI_color_matrix, + IRR_SGI_color_table, + IRR_SGI_depth_pass_instrument, + IRR_SGIS_detail_texture, + IRR_SGIS_fog_function, + IRR_SGIS_generate_mipmap, + IRR_SGIS_multisample, + IRR_SGIS_pixel_texture, + IRR_SGIS_point_line_texgen, + IRR_SGIS_point_parameters, + IRR_SGIS_sharpen_texture, + IRR_SGIS_texture4D, + IRR_SGIS_texture_border_clamp, + IRR_SGIS_texture_color_mask, + IRR_SGIS_texture_edge_clamp, + IRR_SGIS_texture_filter4, + IRR_SGIS_texture_lod, + IRR_SGIS_texture_select, + IRR_SGI_texture_color_table, + IRR_SGIX_async, + IRR_SGIX_async_histogram, + IRR_SGIX_async_pixel, + IRR_SGIX_blend_alpha_minmax, + IRR_SGIX_calligraphic_fragment, + IRR_SGIX_clipmap, + IRR_SGIX_convolution_accuracy, + IRR_SGIX_depth_pass_instrument, + IRR_SGIX_depth_texture, + IRR_SGIX_flush_raster, + IRR_SGIX_fog_offset, + IRR_SGIX_fog_scale, + IRR_SGIX_fragment_lighting, + IRR_SGIX_framezoom, + IRR_SGIX_igloo_interface, + IRR_SGIX_impact_pixel_texture, + IRR_SGIX_instruments, + IRR_SGIX_interlace, + IRR_SGIX_ir_instrument1, + IRR_SGIX_list_priority, + IRR_SGIX_pixel_texture, + IRR_SGIX_pixel_tiles, + IRR_SGIX_polynomial_ffd, + IRR_SGIX_reference_plane, + IRR_SGIX_resample, + IRR_SGIX_scalebias_hint, + IRR_SGIX_shadow, + IRR_SGIX_shadow_ambient, + IRR_SGIX_sprite, + IRR_SGIX_subsample, + IRR_SGIX_tag_sample_buffer, + IRR_SGIX_texture_add_env, + IRR_SGIX_texture_coordinate_clamp, + IRR_SGIX_texture_lod_bias, + IRR_SGIX_texture_multi_buffer, + IRR_SGIX_texture_scale_bias, + IRR_SGIX_texture_select, + IRR_SGIX_vertex_preclip, + IRR_SGIX_ycrcb, + IRR_SGIX_ycrcba, + IRR_SGIX_ycrcb_subsample, + IRR_SUN_convolution_border_modes, + IRR_SUN_global_alpha, + IRR_SUN_mesh_array, + IRR_SUN_slice_accum, + IRR_SUN_triangle_list, + IRR_SUN_vertex, + IRR_SUNX_constant_data, + IRR_WIN_phong_shading, + IRR_WIN_specular_fog, + IRR_NVX_gpu_memory_info, + IRR_OpenGL_Feature_Count + }; + + + // constructor + COpenGLExtensionHandler(); + + // deferred initialization + void initExtensions(bool stencilBuffer); + + //! queries the features of the driver, returns true if feature is available + bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! queries the features of the driver, returns true if feature is available + bool queryOpenGLFeature(EOpenGLFeatures feature) const + { + return FeatureAvailable[feature]; + } + + //! show all features with availablity + void dump() const; + + void dumpFramebufferFormats() const; + + // Some variables for properties + bool StencilBuffer; + bool MultiTextureExtension; + bool TextureCompressionExtension; + + // Some non-boolean properties + //! Maxmimum texture layers supported by the fixed pipeline + u8 MaxSupportedTextures; + //! Maxmimum texture layers supported by the engine + u8 MaxTextureUnits; + //! Maximum hardware lights supported + u8 MaxLights; + //! Maximal Anisotropy + u8 MaxAnisotropy; + //! Number of user clipplanes + u8 MaxUserClipPlanes; + //! Number of auxiliary buffers + u8 MaxAuxBuffers; + //! Number of rendertargets available as MRTs + u8 MaxMultipleRenderTargets; + //! Optimal number of indices per meshbuffer + u32 MaxIndices; + //! Maximal texture dimension + u32 MaxTextureSize; + //! Maximal vertices handled by geometry shaders + u32 MaxGeometryVerticesOut; + //! Maximal LOD Bias + f32 MaxTextureLODBias; + //! Minimal and maximal supported thickness for lines without smoothing + GLfloat DimAliasedLine[2]; + //! Minimal and maximal supported thickness for points without smoothing + GLfloat DimAliasedPoint[2]; + //! Minimal and maximal supported thickness for lines with smoothing + GLfloat DimSmoothedLine[2]; + //! Minimal and maximal supported thickness for points with smoothing + GLfloat DimSmoothedPoint[2]; + + //! OpenGL version as Integer: 100*Major+Minor, i.e. 2.1 becomes 201 + u16 Version; + //! GLSL version as Integer: 100*Major+Minor + u16 ShaderLanguageVersion; + + bool OcclusionQuerySupport; + + // public access to the (loaded) extensions. + // general functions + void extGlActiveTexture(GLenum texture); + void extGlClientActiveTexture(GLenum texture); + void extGlPointParameterf(GLint loc, GLfloat f); + void extGlPointParameterfv(GLint loc, const GLfloat *v); + void extGlStencilFuncSeparate (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); + void extGlStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); + void extGlCompressedTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void* data); + + // shader programming + void extGlGenPrograms(GLsizei n, GLuint *programs); + void extGlBindProgram(GLenum target, GLuint program); + void extGlProgramString(GLenum target, GLenum format, GLsizei len, const GLvoid *string); + void extGlLoadProgram(GLenum target, GLuint id, GLsizei len, const GLubyte *string); + void extGlDeletePrograms(GLsizei n, const GLuint *programs); + void extGlProgramLocalParameter4fv(GLenum, GLuint, const GLfloat *); + GLhandleARB extGlCreateShaderObject(GLenum shaderType); + GLuint extGlCreateShader(GLenum shaderType); + // note: Due to the type confusion between shader_objects and OpenGL 2.0 + // we have to add the ARB extension for proper method definitions in case + // that handleARB and uint are the same type + void extGlShaderSourceARB(GLhandleARB shader, GLsizei numOfStrings, const char **strings, const GLint *lenOfStrings); + void extGlShaderSource(GLuint shader, GLsizei numOfStrings, const char **strings, const GLint *lenOfStrings); + // note: Due to the type confusion between shader_objects and OpenGL 2.0 + // we have to add the ARB extension for proper method definitions in case + // that handleARB and uint are the same type + void extGlCompileShaderARB(GLhandleARB shader); + void extGlCompileShader(GLuint shader); + GLhandleARB extGlCreateProgramObject(void); + GLuint extGlCreateProgram(void); + void extGlAttachObject(GLhandleARB program, GLhandleARB shader); + void extGlAttachShader(GLuint program, GLuint shader); + void extGlLinkProgramARB(GLhandleARB program); + // note: Due to the type confusion between shader_objects and OpenGL 2.0 + // we have to add the ARB extension for proper method definitions in case + // that handleARB and uint are the same type + void extGlLinkProgram(GLuint program); + void extGlUseProgramObject(GLhandleARB prog); + void extGlUseProgram(GLuint prog); + void extGlDeleteObject(GLhandleARB object); + void extGlDeleteProgram(GLuint object); + void extGlDeleteShader(GLuint shader); + void extGlGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); + void extGlGetAttachedObjects(GLhandleARB program, GLsizei maxcount, GLsizei* count, GLhandleARB* shaders); + void extGlGetInfoLog(GLhandleARB object, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); + void extGlGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog); + void extGlGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog); + void extGlGetObjectParameteriv(GLhandleARB object, GLenum type, GLint *param); + void extGlGetShaderiv(GLuint shader, GLenum type, GLint *param); + void extGlGetProgramiv(GLuint program, GLenum type, GLint *param); + GLint extGlGetUniformLocationARB(GLhandleARB program, const char *name); + GLint extGlGetUniformLocation(GLuint program, const char *name); + void extGlUniform1fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniform2fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniform3fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniform4fv(GLint loc, GLsizei count, const GLfloat *v); + void extGlUniform1bv(GLint loc, GLsizei count, const bool *v); + void extGlUniform2bv(GLint loc, GLsizei count, const bool *v); + void extGlUniform3bv(GLint loc, GLsizei count, const bool *v); + void extGlUniform4bv(GLint loc, GLsizei count, const bool *v); + void extGlUniform1iv(GLint loc, GLsizei count, const GLint *v); + void extGlUniform2iv(GLint loc, GLsizei count, const GLint *v); + void extGlUniform3iv(GLint loc, GLsizei count, const GLint *v); + void extGlUniform4iv(GLint loc, GLsizei count, const GLint *v); + void extGlUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v); + void extGlUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v); + void extGlUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v); + void extGlGetActiveUniformARB(GLhandleARB program, GLuint index, GLsizei maxlength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); + void extGlGetActiveUniform(GLuint program, GLuint index, GLsizei maxlength, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + + // framebuffer objects + void extGlBindFramebuffer(GLenum target, GLuint framebuffer); + void extGlDeleteFramebuffers(GLsizei n, const GLuint *framebuffers); + void extGlGenFramebuffers(GLsizei n, GLuint *framebuffers); + GLenum extGlCheckFramebufferStatus(GLenum target); + void extGlFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + void extGlBindRenderbuffer(GLenum target, GLuint renderbuffer); + void extGlDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers); + void extGlGenRenderbuffers(GLsizei n, GLuint *renderbuffers); + void extGlRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + void extGlFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + void extGlGenerateMipmap(GLenum target); + void extGlActiveStencilFace(GLenum face); + void extGlDrawBuffers(GLsizei n, const GLenum *bufs); + + // vertex buffer object + void extGlGenBuffers(GLsizei n, GLuint *buffers); + void extGlBindBuffer(GLenum target, GLuint buffer); + void extGlBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); + void extGlDeleteBuffers(GLsizei n, const GLuint *buffers); + void extGlBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); + void extGlGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); + void *extGlMapBuffer (GLenum target, GLenum access); + GLboolean extGlUnmapBuffer (GLenum target); + GLboolean extGlIsBuffer (GLuint buffer); + void extGlGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); + void extGlGetBufferPointerv (GLenum target, GLenum pname, GLvoid **params); + void extGlProvokingVertex(GLenum mode); + void extGlColorMaskIndexed(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + void extGlEnableIndexed(GLenum target, GLuint index); + void extGlDisableIndexed(GLenum target, GLuint index); + void extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst); + void extGlBlendEquationIndexed(GLuint buf, GLenum mode); + void extGlProgramParameteri(GLuint program, GLenum pname, GLint value); + + // occlusion query + void extGlGenQueries(GLsizei n, GLuint *ids); + void extGlDeleteQueries(GLsizei n, const GLuint *ids); + GLboolean extGlIsQuery(GLuint id); + void extGlBeginQuery(GLenum target, GLuint id); + void extGlEndQuery(GLenum target); + void extGlGetQueryiv(GLenum target, GLenum pname, GLint *params); + void extGlGetQueryObjectiv(GLuint id, GLenum pname, GLint *params); + void extGlGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); + + // generic vsync setting method for several extensions + void extGlSwapInterval(int interval); + + // blend operations + void extGlBlendEquation(GLenum mode); + + // the global feature array + bool FeatureAvailable[IRR_OpenGL_Feature_Count]; + + protected: + #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + PFNGLACTIVETEXTUREARBPROC pGlActiveTextureARB; + PFNGLCLIENTACTIVETEXTUREARBPROC pGlClientActiveTextureARB; + PFNGLGENPROGRAMSARBPROC pGlGenProgramsARB; + PFNGLGENPROGRAMSNVPROC pGlGenProgramsNV; + PFNGLBINDPROGRAMARBPROC pGlBindProgramARB; + PFNGLBINDPROGRAMNVPROC pGlBindProgramNV; + PFNGLDELETEPROGRAMSARBPROC pGlDeleteProgramsARB; + PFNGLDELETEPROGRAMSNVPROC pGlDeleteProgramsNV; + PFNGLPROGRAMSTRINGARBPROC pGlProgramStringARB; + PFNGLLOADPROGRAMNVPROC pGlLoadProgramNV; + PFNGLPROGRAMLOCALPARAMETER4FVARBPROC pGlProgramLocalParameter4fvARB; + PFNGLCREATESHADEROBJECTARBPROC pGlCreateShaderObjectARB; + PFNGLSHADERSOURCEARBPROC pGlShaderSourceARB; + PFNGLCOMPILESHADERARBPROC pGlCompileShaderARB; + PFNGLCREATEPROGRAMOBJECTARBPROC pGlCreateProgramObjectARB; + PFNGLATTACHOBJECTARBPROC pGlAttachObjectARB; + PFNGLLINKPROGRAMARBPROC pGlLinkProgramARB; + PFNGLUSEPROGRAMOBJECTARBPROC pGlUseProgramObjectARB; + PFNGLDELETEOBJECTARBPROC pGlDeleteObjectARB; + PFNGLCREATEPROGRAMPROC pGlCreateProgram; + PFNGLUSEPROGRAMPROC pGlUseProgram; + PFNGLDELETEPROGRAMPROC pGlDeleteProgram; + PFNGLDELETESHADERPROC pGlDeleteShader; + PFNGLGETATTACHEDOBJECTSARBPROC pGlGetAttachedObjectsARB; + PFNGLGETATTACHEDSHADERSPROC pGlGetAttachedShaders; + PFNGLCREATESHADERPROC pGlCreateShader; + PFNGLSHADERSOURCEPROC pGlShaderSource; + PFNGLCOMPILESHADERPROC pGlCompileShader; + PFNGLATTACHSHADERPROC pGlAttachShader; + PFNGLLINKPROGRAMPROC pGlLinkProgram; + PFNGLGETINFOLOGARBPROC pGlGetInfoLogARB; + PFNGLGETSHADERINFOLOGPROC pGlGetShaderInfoLog; + PFNGLGETPROGRAMINFOLOGPROC pGlGetProgramInfoLog; + PFNGLGETOBJECTPARAMETERIVARBPROC pGlGetObjectParameterivARB; + PFNGLGETSHADERIVPROC pGlGetShaderiv; + PFNGLGETSHADERIVPROC pGlGetProgramiv; + PFNGLGETUNIFORMLOCATIONARBPROC pGlGetUniformLocationARB; + PFNGLGETUNIFORMLOCATIONPROC pGlGetUniformLocation; + PFNGLUNIFORM1FVARBPROC pGlUniform1fvARB; + PFNGLUNIFORM2FVARBPROC pGlUniform2fvARB; + PFNGLUNIFORM3FVARBPROC pGlUniform3fvARB; + PFNGLUNIFORM4FVARBPROC pGlUniform4fvARB; + PFNGLUNIFORM1IVARBPROC pGlUniform1ivARB; + PFNGLUNIFORM2IVARBPROC pGlUniform2ivARB; + PFNGLUNIFORM3IVARBPROC pGlUniform3ivARB; + PFNGLUNIFORM4IVARBPROC pGlUniform4ivARB; + PFNGLUNIFORMMATRIX2FVARBPROC pGlUniformMatrix2fvARB; + PFNGLUNIFORMMATRIX3FVARBPROC pGlUniformMatrix3fvARB; + PFNGLUNIFORMMATRIX4FVARBPROC pGlUniformMatrix4fvARB; + PFNGLGETACTIVEUNIFORMARBPROC pGlGetActiveUniformARB; + PFNGLGETACTIVEUNIFORMPROC pGlGetActiveUniform; + PFNGLPOINTPARAMETERFARBPROC pGlPointParameterfARB; + PFNGLPOINTPARAMETERFVARBPROC pGlPointParameterfvARB; + PFNGLSTENCILFUNCSEPARATEPROC pGlStencilFuncSeparate; + PFNGLSTENCILOPSEPARATEPROC pGlStencilOpSeparate; + PFNGLSTENCILFUNCSEPARATEATIPROC pGlStencilFuncSeparateATI; + PFNGLSTENCILOPSEPARATEATIPROC pGlStencilOpSeparateATI; + PFNGLCOMPRESSEDTEXIMAGE2DPROC pGlCompressedTexImage2D; + // ARB framebuffer object + PFNGLBINDFRAMEBUFFERPROC pGlBindFramebuffer; + PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers; + PFNGLGENFRAMEBUFFERSPROC pGlGenFramebuffers; + PFNGLCHECKFRAMEBUFFERSTATUSPROC pGlCheckFramebufferStatus; + PFNGLFRAMEBUFFERTEXTURE2DPROC pGlFramebufferTexture2D; + PFNGLBINDRENDERBUFFERPROC pGlBindRenderbuffer; + PFNGLDELETERENDERBUFFERSPROC pGlDeleteRenderbuffers; + PFNGLGENRENDERBUFFERSPROC pGlGenRenderbuffers; + PFNGLRENDERBUFFERSTORAGEPROC pGlRenderbufferStorage; + PFNGLFRAMEBUFFERRENDERBUFFERPROC pGlFramebufferRenderbuffer; + PFNGLGENERATEMIPMAPPROC pGlGenerateMipmap; + // EXT framebuffer object + PFNGLBINDFRAMEBUFFEREXTPROC pGlBindFramebufferEXT; + PFNGLDELETEFRAMEBUFFERSEXTPROC pGlDeleteFramebuffersEXT; + PFNGLGENFRAMEBUFFERSEXTPROC pGlGenFramebuffersEXT; + PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pGlCheckFramebufferStatusEXT; + PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pGlFramebufferTexture2DEXT; + PFNGLBINDRENDERBUFFEREXTPROC pGlBindRenderbufferEXT; + PFNGLDELETERENDERBUFFERSEXTPROC pGlDeleteRenderbuffersEXT; + PFNGLGENRENDERBUFFERSEXTPROC pGlGenRenderbuffersEXT; + PFNGLRENDERBUFFERSTORAGEEXTPROC pGlRenderbufferStorageEXT; + PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC pGlFramebufferRenderbufferEXT; + PFNGLGENERATEMIPMAPEXTPROC pGlGenerateMipmapEXT; + PFNGLACTIVESTENCILFACEEXTPROC pGlActiveStencilFaceEXT; + PFNGLDRAWBUFFERSARBPROC pGlDrawBuffersARB; + PFNGLDRAWBUFFERSATIPROC pGlDrawBuffersATI; + PFNGLGENBUFFERSARBPROC pGlGenBuffersARB; + PFNGLBINDBUFFERARBPROC pGlBindBufferARB; + PFNGLBUFFERDATAARBPROC pGlBufferDataARB; + PFNGLDELETEBUFFERSARBPROC pGlDeleteBuffersARB; + PFNGLBUFFERSUBDATAARBPROC pGlBufferSubDataARB; + PFNGLGETBUFFERSUBDATAARBPROC pGlGetBufferSubDataARB; + PFNGLMAPBUFFERARBPROC pGlMapBufferARB; + PFNGLUNMAPBUFFERARBPROC pGlUnmapBufferARB; + PFNGLISBUFFERARBPROC pGlIsBufferARB; + PFNGLGETBUFFERPARAMETERIVARBPROC pGlGetBufferParameterivARB; + PFNGLGETBUFFERPOINTERVARBPROC pGlGetBufferPointervARB; + PFNGLPROVOKINGVERTEXPROC pGlProvokingVertexARB; + PFNGLPROVOKINGVERTEXEXTPROC pGlProvokingVertexEXT; + PFNGLCOLORMASKINDEXEDEXTPROC pGlColorMaskIndexedEXT; + PFNGLENABLEINDEXEDEXTPROC pGlEnableIndexedEXT; + PFNGLDISABLEINDEXEDEXTPROC pGlDisableIndexedEXT; + PFNGLBLENDFUNCINDEXEDAMDPROC pGlBlendFuncIndexedAMD; + PFNGLBLENDFUNCIPROC pGlBlendFunciARB; + PFNGLBLENDEQUATIONINDEXEDAMDPROC pGlBlendEquationIndexedAMD; + PFNGLBLENDEQUATIONIPROC pGlBlendEquationiARB; + PFNGLPROGRAMPARAMETERIARBPROC pGlProgramParameteriARB; + PFNGLPROGRAMPARAMETERIEXTPROC pGlProgramParameteriEXT; + PFNGLGENQUERIESARBPROC pGlGenQueriesARB; + PFNGLDELETEQUERIESARBPROC pGlDeleteQueriesARB; + PFNGLISQUERYARBPROC pGlIsQueryARB; + PFNGLBEGINQUERYARBPROC pGlBeginQueryARB; + PFNGLENDQUERYARBPROC pGlEndQueryARB; + PFNGLGETQUERYIVARBPROC pGlGetQueryivARB; + PFNGLGETQUERYOBJECTIVARBPROC pGlGetQueryObjectivARB; + PFNGLGETQUERYOBJECTUIVARBPROC pGlGetQueryObjectuivARB; + PFNGLGENOCCLUSIONQUERIESNVPROC pGlGenOcclusionQueriesNV; + PFNGLDELETEOCCLUSIONQUERIESNVPROC pGlDeleteOcclusionQueriesNV; + PFNGLISOCCLUSIONQUERYNVPROC pGlIsOcclusionQueryNV; + PFNGLBEGINOCCLUSIONQUERYNVPROC pGlBeginOcclusionQueryNV; + PFNGLENDOCCLUSIONQUERYNVPROC pGlEndOcclusionQueryNV; + PFNGLGETOCCLUSIONQUERYIVNVPROC pGlGetOcclusionQueryivNV; + PFNGLGETOCCLUSIONQUERYUIVNVPROC pGlGetOcclusionQueryuivNV; + PFNGLBLENDEQUATIONEXTPROC pGlBlendEquationEXT; + PFNGLBLENDEQUATIONPROC pGlBlendEquation; + #if defined(WGL_EXT_swap_control) + PFNWGLSWAPINTERVALEXTPROC pWglSwapIntervalEXT; + #endif + #if defined(GLX_SGI_swap_control) + PFNGLXSWAPINTERVALSGIPROC pGlxSwapIntervalSGI; + #endif + #if defined(GLX_EXT_swap_control) + PFNGLXSWAPINTERVALEXTPROC pGlxSwapIntervalEXT; + #endif + #if defined(GLX_MESA_swap_control) + PFNGLXSWAPINTERVALMESAPROC pGlxSwapIntervalMESA; + #endif + #endif +}; + +inline void COpenGLExtensionHandler::extGlActiveTexture(GLenum texture) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (MultiTextureExtension && pGlActiveTextureARB) + pGlActiveTextureARB(texture); +#else + if (MultiTextureExtension) +#ifdef GL_ARB_multitexture + glActiveTextureARB(texture); +#else + glActiveTexture(texture); +#endif +#endif +} + +inline void COpenGLExtensionHandler::extGlClientActiveTexture(GLenum texture) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (MultiTextureExtension && pGlClientActiveTextureARB) + pGlClientActiveTextureARB(texture); +#else + if (MultiTextureExtension) + glClientActiveTextureARB(texture); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenPrograms(GLsizei n, GLuint *programs) +{ + if (programs) + memset(programs,0,n*sizeof(GLuint)); +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenProgramsARB) + pGlGenProgramsARB(n, programs); + else if (pGlGenProgramsNV) + pGlGenProgramsNV(n, programs); +#elif defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + glGenProgramsARB(n,programs); +#elif defined(GL_NV_vertex_program) || defined(GL_NV_fragment_program) + glGenProgramsNV(n,programs); +#else + os::Printer::log("glGenPrograms not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindProgram(GLenum target, GLuint program) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindProgramARB) + pGlBindProgramARB(target, program); + else if (pGlBindProgramNV) + pGlBindProgramNV(target, program); +#elif defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + glBindProgramARB(target, program); +#elif defined(GL_NV_vertex_program) || defined(GL_NV_fragment_program) + glBindProgramNV(target, program); +#else + os::Printer::log("glBindProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlProgramString(GLenum target, GLenum format, GLsizei len, const GLvoid *string) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlProgramStringARB) + pGlProgramStringARB(target, format, len, string); +#elif defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + glProgramStringARB(target,format,len,string); +#else + os::Printer::log("glProgramString not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlLoadProgram(GLenum target, GLuint id, GLsizei len, const GLubyte *string) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlLoadProgramNV) + pGlLoadProgramNV(target, id, len, string); +#elif defined(GL_NV_vertex_program) || defined(GL_NV_fragment_program) + glLoadProgramNV(target,id,len,string); +#else + os::Printer::log("glLoadProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeletePrograms(GLsizei n, const GLuint *programs) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteProgramsARB) + pGlDeleteProgramsARB(n, programs); + else if (pGlDeleteProgramsNV) + pGlDeleteProgramsNV(n, programs); +#elif defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + glDeleteProgramsARB(n,programs); +#elif defined(GL_NV_vertex_program) || defined(GL_NV_fragment_program) + glDeleteProgramsNV(n,programs); +#else + os::Printer::log("glDeletePrograms not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlProgramLocalParameter4fv(GLenum n, GLuint i, const GLfloat *f) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlProgramLocalParameter4fvARB) + pGlProgramLocalParameter4fvARB(n,i,f); +#elif defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + glProgramLocalParameter4fvARB(n,i,f); +#else + os::Printer::log("glProgramLocalParameter4fv not supported", ELL_ERROR); +#endif +} + +inline GLhandleARB COpenGLExtensionHandler::extGlCreateShaderObject(GLenum shaderType) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCreateShaderObjectARB) + return pGlCreateShaderObjectARB(shaderType); +#elif defined(GL_ARB_shader_objects) + return glCreateShaderObjectARB(shaderType); +#else + os::Printer::log("glCreateShaderObject not supported", ELL_ERROR); +#endif + return 0; +} + +inline GLuint COpenGLExtensionHandler::extGlCreateShader(GLenum shaderType) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCreateShader) + return pGlCreateShader(shaderType); +#elif defined(GL_VERSION_2_0) + return glCreateShader(shaderType); +#else + os::Printer::log("glCreateShader not supported", ELL_ERROR); +#endif + return 0; +} + +inline void COpenGLExtensionHandler::extGlShaderSourceARB(GLhandleARB shader, GLsizei numOfStrings, const char **strings, const GLint *lenOfStrings) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlShaderSourceARB) + pGlShaderSourceARB(shader, numOfStrings, strings, lenOfStrings); +#elif defined(GL_ARB_shader_objects) + glShaderSourceARB(shader, numOfStrings, strings, (GLint *)lenOfStrings); +#else + os::Printer::log("glShaderSource not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlShaderSource(GLuint shader, GLsizei numOfStrings, const char **strings, const GLint *lenOfStrings) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlShaderSource) + pGlShaderSource(shader, numOfStrings, strings, lenOfStrings); +#elif defined(GL_VERSION_2_0) + glShaderSource(shader, numOfStrings, strings, (GLint *)lenOfStrings); +#else + os::Printer::log("glShaderSource not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlCompileShaderARB(GLhandleARB shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCompileShaderARB) + pGlCompileShaderARB(shader); +#elif defined(GL_ARB_shader_objects) + glCompileShaderARB(shader); +#else + os::Printer::log("glCompileShader not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlCompileShader(GLuint shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCompileShader) + pGlCompileShader(shader); +#elif defined(GL_VERSION_2_0) + glCompileShader(shader); +#else + os::Printer::log("glCompileShader not supported", ELL_ERROR); +#endif +} + +inline GLhandleARB COpenGLExtensionHandler::extGlCreateProgramObject(void) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCreateProgramObjectARB) + return pGlCreateProgramObjectARB(); +#elif defined(GL_ARB_shader_objects) + return glCreateProgramObjectARB(); +#else + os::Printer::log("glCreateProgramObject not supported", ELL_ERROR); +#endif + return 0; +} + +inline GLuint COpenGLExtensionHandler::extGlCreateProgram(void) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCreateProgram) + return pGlCreateProgram(); +#elif defined(GL_VERSION_2_0) + return glCreateProgram(); +#else + os::Printer::log("glCreateProgram not supported", ELL_ERROR); +#endif + return 0; +} + +inline void COpenGLExtensionHandler::extGlAttachObject(GLhandleARB program, GLhandleARB shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlAttachObjectARB) + pGlAttachObjectARB(program, shader); +#elif defined(GL_ARB_shader_objects) + glAttachObjectARB(program, shader); +#else + os::Printer::log("glAttachObject not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlAttachShader(GLuint program, GLuint shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlAttachShader) + pGlAttachShader(program, shader); +#elif defined(GL_VERSION_2_0) + glAttachShader(program, shader); +#else + os::Printer::log("glAttachShader not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlLinkProgramARB(GLhandleARB program) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlLinkProgramARB) + pGlLinkProgramARB(program); +#elif defined(GL_ARB_shader_objects) + glLinkProgramARB(program); +#else + os::Printer::log("glLinkProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlLinkProgram(GLuint program) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlLinkProgram) + pGlLinkProgram(program); +#elif defined(GL_VERSION_2_0) + glLinkProgram(program); +#else + os::Printer::log("glLinkProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUseProgramObject(GLhandleARB prog) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUseProgramObjectARB) + pGlUseProgramObjectARB(prog); +#elif defined(GL_ARB_shader_objects) + glUseProgramObjectARB(prog); +#else + os::Printer::log("glUseProgramObject not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUseProgram(GLuint prog) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUseProgram) + pGlUseProgram(prog); +#elif defined(GL_VERSION_2_0) + glUseProgram(prog); +#else + os::Printer::log("glUseProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteObject(GLhandleARB object) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteObjectARB) + pGlDeleteObjectARB(object); +#elif defined(GL_ARB_shader_objects) + glDeleteObjectARB(object); +#else + os::Printer::log("glDeleteObject not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteProgram(GLuint object) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteProgram) + pGlDeleteProgram(object); +#elif defined(GL_VERSION_2_0) + glDeleteProgram(object); +#else + os::Printer::log("glDeleteProgram not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteShader(GLuint shader) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteShader) + pGlDeleteShader(shader); +#elif defined(GL_VERSION_2_0) + glDeleteShader(shader); +#else + os::Printer::log("glDeleteShader not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetAttachedObjects(GLhandleARB program, GLsizei maxcount, GLsizei* count, GLhandleARB* shaders) +{ + if (count) + *count=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetAttachedObjectsARB) + pGlGetAttachedObjectsARB(program, maxcount, count, shaders); +#elif defined(GL_ARB_shader_objects) + glGetAttachedObjectsARB(program, maxcount, count, shaders); +#else + os::Printer::log("glGetAttachedObjects not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +{ + if (count) + *count=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetAttachedShaders) + pGlGetAttachedShaders(program, maxcount, count, shaders); +#elif defined(GL_VERSION_2_0) + glGetAttachedShaders(program, maxcount, count, shaders); +#else + os::Printer::log("glGetAttachedShaders not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetInfoLog(GLhandleARB object, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) +{ + if (length) + *length=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetInfoLogARB) + pGlGetInfoLogARB(object, maxLength, length, infoLog); +#elif defined(GL_ARB_shader_objects) + glGetInfoLogARB(object, maxLength, length, infoLog); +#else + os::Printer::log("glGetInfoLog not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog) +{ + if (length) + *length=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetShaderInfoLog) + pGlGetShaderInfoLog(shader, maxLength, length, infoLog); +#elif defined(GL_VERSION_2_0) + glGetShaderInfoLog(shader, maxLength, length, infoLog); +#else + os::Printer::log("glGetShaderInfoLog not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog) +{ + if (length) + *length=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetProgramInfoLog) + pGlGetProgramInfoLog(program, maxLength, length, infoLog); +#elif defined(GL_VERSION_2_0) + glGetProgramInfoLog(program, maxLength, length, infoLog); +#else + os::Printer::log("glGetProgramInfoLog not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetObjectParameteriv(GLhandleARB object, GLenum type, GLint *param) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetObjectParameterivARB) + pGlGetObjectParameterivARB(object, type, param); +#elif defined(GL_ARB_shader_objects) + glGetObjectParameterivARB(object, type, param); +#else + os::Printer::log("glGetObjectParameteriv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetShaderiv(GLuint shader, GLenum type, GLint *param) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetShaderiv) + pGlGetShaderiv(shader, type, param); +#elif defined(GL_VERSION_2_0) + glGetShaderiv(shader, type, param); +#else + os::Printer::log("glGetShaderiv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetProgramiv(GLuint program, GLenum type, GLint *param) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetProgramiv) + pGlGetProgramiv(program, type, param); +#elif defined(GL_VERSION_2_0) + glGetProgramiv(program, type, param); +#else + os::Printer::log("glGetProgramiv not supported", ELL_ERROR); +#endif +} + +inline GLint COpenGLExtensionHandler::extGlGetUniformLocationARB(GLhandleARB program, const char *name) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetUniformLocationARB) + return pGlGetUniformLocationARB(program, name); +#elif defined(GL_ARB_shader_objects) + return glGetUniformLocationARB(program, name); +#else + os::Printer::log("glGetUniformLocation not supported", ELL_ERROR); +#endif + return 0; +} + +inline GLint COpenGLExtensionHandler::extGlGetUniformLocation(GLuint program, const char *name) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetUniformLocation) + return pGlGetUniformLocation(program, name); +#elif defined(GL_VERSION_2_0) + return glGetUniformLocation(program, name); +#else + os::Printer::log("glGetUniformLocation not supported", ELL_ERROR); +#endif + return 0; +} + +inline void COpenGLExtensionHandler::extGlUniform1fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform1fvARB) + pGlUniform1fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform1fvARB(loc, count, v); +#else + os::Printer::log("glUniform1fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform2fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform2fvARB) + pGlUniform2fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform2fvARB(loc, count, v); +#else + os::Printer::log("glUniform2fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform3fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform3fvARB) + pGlUniform3fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform3fvARB(loc, count, v); +#else + os::Printer::log("glUniform3fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform4fv(GLint loc, GLsizei count, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform4fvARB) + pGlUniform4fvARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform4fvARB(loc, count, v); +#else + os::Printer::log("glUniform4fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform1iv(GLint loc, GLsizei count, const GLint *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform1ivARB) + pGlUniform1ivARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform1ivARB(loc, count, v); +#else + os::Printer::log("glUniform1iv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform2iv(GLint loc, GLsizei count, const GLint *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform2ivARB) + pGlUniform2ivARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform2ivARB(loc, count, v); +#else + os::Printer::log("glUniform2iv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform3iv(GLint loc, GLsizei count, const GLint *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform3ivARB) + pGlUniform3ivARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform3ivARB(loc, count, v); +#else + os::Printer::log("glUniform3iv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniform4iv(GLint loc, GLsizei count, const GLint *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniform4ivARB) + pGlUniform4ivARB(loc, count, v); +#elif defined(GL_ARB_shader_objects) + glUniform4ivARB(loc, count, v); +#else + os::Printer::log("glUniform4iv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniformMatrix2fvARB) + pGlUniformMatrix2fvARB(loc, count, transpose, v); +#elif defined(GL_ARB_shader_objects) + glUniformMatrix2fvARB(loc, count, transpose, v); +#else + os::Printer::log("glUniformMatrix2fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniformMatrix3fvARB) + pGlUniformMatrix3fvARB(loc, count, transpose, v); +#elif defined(GL_ARB_shader_objects) + glUniformMatrix3fvARB(loc, count, transpose, v); +#else + os::Printer::log("glUniformMatrix3fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUniformMatrix4fvARB) + pGlUniformMatrix4fvARB(loc, count, transpose, v); +#elif defined(GL_ARB_shader_objects) + glUniformMatrix4fvARB(loc, count, transpose, v); +#else + os::Printer::log("glUniformMatrix4fv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetActiveUniformARB(GLhandleARB program, + GLuint index, GLsizei maxlength, GLsizei *length, + GLint *size, GLenum *type, GLcharARB *name) +{ + if (length) + *length=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetActiveUniformARB) + pGlGetActiveUniformARB(program, index, maxlength, length, size, type, name); +#elif defined(GL_ARB_shader_objects) + glGetActiveUniformARB(program, index, maxlength, length, size, type, name); +#else + os::Printer::log("glGetActiveUniform not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetActiveUniform(GLuint program, + GLuint index, GLsizei maxlength, GLsizei *length, + GLint *size, GLenum *type, GLchar *name) +{ + if (length) + *length=0; +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetActiveUniform) + pGlGetActiveUniform(program, index, maxlength, length, size, type, name); +#elif defined(GL_VERSION_2_0) + glGetActiveUniform(program, index, maxlength, length, size, type, name); +#else + os::Printer::log("glGetActiveUniform not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlPointParameterf(GLint loc, GLfloat f) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlPointParameterfARB) + pGlPointParameterfARB(loc, f); +#elif defined(GL_ARB_point_parameters) + glPointParameterfARB(loc, f); +#else + os::Printer::log("glPointParameterf not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlPointParameterfv(GLint loc, const GLfloat *v) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlPointParameterfvARB) + pGlPointParameterfvARB(loc, v); +#elif defined(GL_ARB_point_parameters) + glPointParameterfvARB(loc, v); +#else + os::Printer::log("glPointParameterfv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlStencilFuncSeparate (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlStencilFuncSeparate) + pGlStencilFuncSeparate(frontfunc, backfunc, ref, mask); + else if (pGlStencilFuncSeparateATI) + pGlStencilFuncSeparateATI(frontfunc, backfunc, ref, mask); +#elif defined(GL_VERSION_2_0) + glStencilFuncSeparate(frontfunc, backfunc, ref, mask); +#elif defined(GL_ATI_separate_stencil) + glStencilFuncSeparateATI(frontfunc, backfunc, ref, mask); +#else + os::Printer::log("glStencilFuncSeparate not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlStencilOpSeparate) + pGlStencilOpSeparate(face, fail, zfail, zpass); + else if (pGlStencilOpSeparateATI) + pGlStencilOpSeparateATI(face, fail, zfail, zpass); +#elif defined(GL_VERSION_2_0) + glStencilOpSeparate(face, fail, zfail, zpass); +#elif defined(GL_ATI_separate_stencil) + glStencilOpSeparateATI(face, fail, zfail, zpass); +#else + os::Printer::log("glStencilOpSeparate not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, const void* data) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCompressedTexImage2D) + pGlCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); +#elif defined(GL_ARB_texture_compression) + glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); +#else + os::Printer::log("glCompressedTexImage2D not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindFramebuffer(GLenum target, GLuint framebuffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindFramebuffer) + pGlBindFramebuffer(target, framebuffer); + else if (pGlBindFramebufferEXT) + pGlBindFramebufferEXT(target, framebuffer); +#elif defined(GL_ARB_framebuffer_object) + glBindFramebuffer(target, framebuffer); +#elif defined(GL_EXT_framebuffer_object) + glBindFramebufferEXT(target, framebuffer); +#else + os::Printer::log("glBindFramebuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteFramebuffers) + pGlDeleteFramebuffers(n, framebuffers); + else if (pGlDeleteFramebuffersEXT) + pGlDeleteFramebuffersEXT(n, framebuffers); +#elif defined(GL_ARB_framebuffer_object) + glDeleteFramebuffers(n, framebuffers); +#elif defined(GL_EXT_framebuffer_object) + glDeleteFramebuffersEXT(n, framebuffers); +#else + os::Printer::log("glDeleteFramebuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenFramebuffers(GLsizei n, GLuint *framebuffers) +{ + if (framebuffers) + memset(framebuffers,0,n*sizeof(GLuint)); +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenFramebuffers) + pGlGenFramebuffers(n, framebuffers); + else if (pGlGenFramebuffersEXT) + pGlGenFramebuffersEXT(n, framebuffers); +#elif defined(GL_ARB_framebuffer_object) + glGenFramebuffers(n, framebuffers); +#elif defined(GL_EXT_framebuffer_object) + glGenFramebuffersEXT(n, framebuffers); +#else + os::Printer::log("glGenFramebuffers not supported", ELL_ERROR); +#endif +} + +inline GLenum COpenGLExtensionHandler::extGlCheckFramebufferStatus(GLenum target) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlCheckFramebufferStatus) + return pGlCheckFramebufferStatus(target); + else if (pGlCheckFramebufferStatusEXT) + return pGlCheckFramebufferStatusEXT(target); + else + return 0; +#elif defined(GL_ARB_framebuffer_object) + return glCheckFramebufferStatus(target); +#elif defined(GL_EXT_framebuffer_object) + return glCheckFramebufferStatusEXT(target); +#else + os::Printer::log("glCheckFramebufferStatus not supported", ELL_ERROR); + return 0; +#endif +} + +inline void COpenGLExtensionHandler::extGlFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlFramebufferTexture2D) + pGlFramebufferTexture2D(target, attachment, textarget, texture, level); + else if (pGlFramebufferTexture2DEXT) + pGlFramebufferTexture2DEXT(target, attachment, textarget, texture, level); +#elif defined(GL_ARB_framebuffer_object) + glFramebufferTexture2D(target, attachment, textarget, texture, level); +#elif defined(GL_EXT_framebuffer_object) + glFramebufferTexture2DEXT(target, attachment, textarget, texture, level); +#else + os::Printer::log("glFramebufferTexture2D not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindRenderbuffer(GLenum target, GLuint renderbuffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindRenderbuffer) + pGlBindRenderbuffer(target, renderbuffer); + else if (pGlBindRenderbufferEXT) + pGlBindRenderbufferEXT(target, renderbuffer); +#elif defined(GL_ARB_framebuffer_object) + glBindRenderbuffer(target, renderbuffer); +#elif defined(GL_EXT_framebuffer_object) + glBindRenderbufferEXT(target, renderbuffer); +#else + os::Printer::log("glBindRenderbuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteRenderbuffers) + pGlDeleteRenderbuffers(n, renderbuffers); + else if (pGlDeleteRenderbuffersEXT) + pGlDeleteRenderbuffersEXT(n, renderbuffers); +#elif defined(GL_ARB_framebuffer_object) + glDeleteRenderbuffers(n, renderbuffers); +#elif defined(GL_EXT_framebuffer_object) + glDeleteRenderbuffersEXT(n, renderbuffers); +#else + os::Printer::log("glDeleteRenderbuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ + if (renderbuffers) + memset(renderbuffers,0,n*sizeof(GLuint)); +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenRenderbuffers) + pGlGenRenderbuffers(n, renderbuffers); + else if (pGlGenRenderbuffersEXT) + pGlGenRenderbuffersEXT(n, renderbuffers); +#elif defined(GL_ARB_framebuffer_object) + glGenRenderbuffers(n, renderbuffers); +#elif defined(GL_EXT_framebuffer_object) + glGenRenderbuffersEXT(n, renderbuffers); +#else + os::Printer::log("glGenRenderbuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlRenderbufferStorage) + pGlRenderbufferStorage(target, internalformat, width, height); + else if (pGlRenderbufferStorageEXT) + pGlRenderbufferStorageEXT(target, internalformat, width, height); +#elif defined(GL_ARB_framebuffer_object) + glRenderbufferStorage(target, internalformat, width, height); +#elif defined(GL_EXT_framebuffer_object) + glRenderbufferStorageEXT(target, internalformat, width, height); +#else + os::Printer::log("glRenderbufferStorage not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlFramebufferRenderbuffer) + pGlFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + else if (pGlFramebufferRenderbufferEXT) + pGlFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); +#elif defined(GL_ARB_framebuffer_object) + glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); +#elif defined(GL_EXT_framebuffer_object) + glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); +#else + os::Printer::log("glFramebufferRenderbuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenerateMipmap(GLenum target) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenerateMipmap) + pGlGenerateMipmap(target); + else if (pGlGenerateMipmapEXT) + pGlGenerateMipmapEXT(target); +#elif defined(GL_ARB_framebuffer_object) + glGenerateMipmap(target); +#elif defined(GL_EXT_framebuffer_object) + glGenerateMipmapEXT(target); +#else + os::Printer::log("glGenerateMipmap not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlActiveStencilFace(GLenum face) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlActiveStencilFaceEXT) + pGlActiveStencilFaceEXT(face); +#elif defined(GL_EXT_stencil_two_side) + glActiveStencilFaceEXT(face); +#else + os::Printer::log("glActiveStencilFace not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDrawBuffers(GLsizei n, const GLenum *bufs) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDrawBuffersARB) + pGlDrawBuffersARB(n, bufs); + else if (pGlDrawBuffersATI) + pGlDrawBuffersATI(n, bufs); +#elif defined(GL_ARB_draw_buffers) + glDrawBuffersARB(n, bufs); +#elif defined(GL_ATI_draw_buffers) + glDrawBuffersATI(n, bufs); +#else + os::Printer::log("glDrawBuffers not supported", ELL_ERROR); +#endif +} + + +inline void COpenGLExtensionHandler::extGlGenBuffers(GLsizei n, GLuint *buffers) +{ + if (buffers) + memset(buffers,0,n*sizeof(GLuint)); +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenBuffersARB) + pGlGenBuffersARB(n, buffers); +#elif defined(GL_ARB_vertex_buffer_object) + glGenBuffers(n, buffers); +#else + os::Printer::log("glGenBuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBindBuffer(GLenum target, GLuint buffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBindBufferARB) + pGlBindBufferARB(target, buffer); +#elif defined(GL_ARB_vertex_buffer_object) + glBindBuffer(target, buffer); +#else + os::Printer::log("glBindBuffer not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBufferDataARB) + pGlBufferDataARB(target, size, data, usage); +#elif defined(GL_ARB_vertex_buffer_object) + glBufferData(target, size, data, usage); +#else + os::Printer::log("glBufferData not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteBuffers(GLsizei n, const GLuint *buffers) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteBuffersARB) + pGlDeleteBuffersARB(n, buffers); +#elif defined(GL_ARB_vertex_buffer_object) + glDeleteBuffers(n, buffers); +#else + os::Printer::log("glDeleteBuffers not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBufferSubDataARB) + pGlBufferSubDataARB(target, offset, size, data); +#elif defined(GL_ARB_vertex_buffer_object) + glBufferSubData(target, offset, size, data); +#else + os::Printer::log("glBufferSubData not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetBufferSubDataARB) + pGlGetBufferSubDataARB(target, offset, size, data); +#elif defined(GL_ARB_vertex_buffer_object) + glGetBufferSubData(target, offset, size, data); +#else + os::Printer::log("glGetBufferSubData not supported", ELL_ERROR); +#endif +} + +inline void *COpenGLExtensionHandler::extGlMapBuffer(GLenum target, GLenum access) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlMapBufferARB) + return pGlMapBufferARB(target, access); + return 0; +#elif defined(GL_ARB_vertex_buffer_object) + return glMapBuffer(target, access); +#else + os::Printer::log("glMapBuffer not supported", ELL_ERROR); + return 0; +#endif +} + +inline GLboolean COpenGLExtensionHandler::extGlUnmapBuffer(GLenum target) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlUnmapBufferARB) + return pGlUnmapBufferARB(target); + return false; +#elif defined(GL_ARB_vertex_buffer_object) + return glUnmapBuffer(target); +#else + os::Printer::log("glUnmapBuffer not supported", ELL_ERROR); + return false; +#endif +} + +inline GLboolean COpenGLExtensionHandler::extGlIsBuffer(GLuint buffer) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlIsBufferARB) + return pGlIsBufferARB(buffer); + return false; +#elif defined(GL_ARB_vertex_buffer_object) + return glIsBuffer(buffer); +#else + os::Printer::log("glDeleteBuffers not supported", ELL_ERROR); + return false; +#endif +} + +inline void COpenGLExtensionHandler::extGlGetBufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetBufferParameterivARB) + pGlGetBufferParameterivARB(target, pname, params); +#elif defined(GL_ARB_vertex_buffer_object) + glGetBufferParameteriv(target, pname, params); +#else + os::Printer::log("glGetBufferParameteriv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetBufferPointerv(GLenum target, GLenum pname, GLvoid **params) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetBufferPointervARB) + pGlGetBufferPointervARB(target, pname, params); +#elif defined(GL_ARB_vertex_buffer_object) + glGetBufferPointerv(target, pname, params); +#else + os::Printer::log("glGetBufferPointerv not supported", ELL_ERROR); +#endif +} + + +inline void COpenGLExtensionHandler::extGlProvokingVertex(GLenum mode) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (FeatureAvailable[IRR_ARB_provoking_vertex] && pGlProvokingVertexARB) + pGlProvokingVertexARB(mode); + else if (FeatureAvailable[IRR_EXT_provoking_vertex] && pGlProvokingVertexEXT) + pGlProvokingVertexEXT(mode); +#elif defined(GL_ARB_provoking_vertex) + glProvokingVertex(mode); +#elif defined(GL_EXT_provoking_vertex) + glProvokingVertexEXT(mode); +#else + os::Printer::log("glProvokingVertex not supported", ELL_ERROR); +#endif +} + + +inline void COpenGLExtensionHandler::extGlColorMaskIndexed(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (FeatureAvailable[IRR_EXT_draw_buffers2] && pGlColorMaskIndexedEXT) + pGlColorMaskIndexedEXT(buf, r, g, b, a); +#elif defined(GL_EXT_draw_buffers2) + glColorMaskIndexedEXT(buf, r, g, b, a); +#else + os::Printer::log("glColorMaskIndexed not supported", ELL_ERROR); +#endif +} + + +inline void COpenGLExtensionHandler::extGlEnableIndexed(GLenum target, GLuint index) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (FeatureAvailable[IRR_EXT_draw_buffers2] && pGlEnableIndexedEXT) + pGlEnableIndexedEXT(target, index); +#elif defined(GL_EXT_draw_buffers2) + glEnableIndexedEXT(target, index); +#else + os::Printer::log("glEnableIndexed not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDisableIndexed(GLenum target, GLuint index) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (FeatureAvailable[IRR_EXT_draw_buffers2] && pGlDisableIndexedEXT) + pGlDisableIndexedEXT(target, index); +#elif defined(GL_EXT_draw_buffers2) + glDisableIndexedEXT(target, index); +#else + os::Printer::log("glDisableIndexed not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (FeatureAvailable[IRR_ARB_draw_buffers_blend] && pGlBlendFunciARB) + pGlBlendFunciARB(buf, src, dst); + else if (FeatureAvailable[IRR_AMD_draw_buffers_blend] && pGlBlendFuncIndexedAMD) + pGlBlendFuncIndexedAMD(buf, src, dst); +#elif defined(GL_ARB_draw_buffers_blend) + glBlendFunciARB(buf, src, dst); +#elif defined(GL_AMD_draw_buffers_blend) + glBlendFuncIndexedAMD(buf, src, dst); +#else + os::Printer::log("glBlendFuncIndexed not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlBlendEquationIndexed(GLuint buf, GLenum mode) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (FeatureAvailable[IRR_ARB_draw_buffers_blend] && pGlBlendEquationiARB) + pGlBlendEquationiARB(buf, mode); + else if (FeatureAvailable[IRR_AMD_draw_buffers_blend] && pGlBlendEquationIndexedAMD) + pGlBlendEquationIndexedAMD(buf, mode); +#elif defined(GL_ARB_draw_buffers_blend) + glBlendEquationiARB(buf, mode); +#elif defined(GL_AMD_draw_buffers_blend) + glBlendEquationIndexedAMD(buf, mode); +#else + os::Printer::log("glBlendEquationIndexed not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlProgramParameteri(GLuint program, GLenum pname, GLint value) +{ +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + if (queryFeature(EVDF_GEOMETRY_SHADER)) + { + if (pGlProgramParameteriARB) + pGlProgramParameteriARB(program, pname, value); + else if (pGlProgramParameteriEXT) + pGlProgramParameteriEXT(program, pname, value); + } +#elif defined(GL_ARB_geometry_shader4) + glProgramParameteriARB(program, pname, value); +#elif defined(GL_EXT_geometry_shader4) + glProgramParameteriEXT(program, pname, value); +#elif defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4) + glProgramParameteriNV(program, pname, value); +#else + os::Printer::log("glProgramParameteri not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGenQueries(GLsizei n, GLuint *ids) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGenQueriesARB) + pGlGenQueriesARB(n, ids); + else if (pGlGenOcclusionQueriesNV) + pGlGenOcclusionQueriesNV(n, ids); +#elif defined(GL_ARB_occlusion_query) + glGenQueriesARB(n, ids); +#elif defined(GL_NV_occlusion_query) + glGenOcclusionQueriesNV(n, ids); +#else + os::Printer::log("glGenQueries not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlDeleteQueries(GLsizei n, const GLuint *ids) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDeleteQueriesARB) + pGlDeleteQueriesARB(n, ids); + else if (pGlDeleteOcclusionQueriesNV) + pGlDeleteOcclusionQueriesNV(n, ids); +#elif defined(GL_ARB_occlusion_query) + glDeleteQueriesARB(n, ids); +#elif defined(GL_NV_occlusion_query) + glDeleteOcclusionQueriesNV(n, ids); +#else + os::Printer::log("glDeleteQueries not supported", ELL_ERROR); +#endif +} + +inline GLboolean COpenGLExtensionHandler::extGlIsQuery(GLuint id) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlIsQueryARB) + return pGlIsQueryARB(id); + else if (pGlIsOcclusionQueryNV) + return pGlIsOcclusionQueryNV(id); + return false; +#elif defined(GL_ARB_occlusion_query) + return glIsQueryARB(id); +#elif defined(GL_NV_occlusion_query) + return glIsOcclusionQueryNV(id); +#else + return false; +#endif +} + +inline void COpenGLExtensionHandler::extGlBeginQuery(GLenum target, GLuint id) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBeginQueryARB) + pGlBeginQueryARB(target, id); + else if (pGlBeginOcclusionQueryNV) + pGlBeginOcclusionQueryNV(id); +#elif defined(GL_ARB_occlusion_query) + glBeginQueryARB(target, id); +#elif defined(GL_NV_occlusion_query) + glBeginOcclusionQueryNV(id); +#else + os::Printer::log("glBeginQuery not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlEndQuery(GLenum target) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlEndQueryARB) + pGlEndQueryARB(target); + else if (pGlEndOcclusionQueryNV) + pGlEndOcclusionQueryNV(); +#elif defined(GL_ARB_occlusion_query) + glEndQueryARB(target); +#elif defined(GL_NV_occlusion_query) + glEndOcclusionQueryNV(); +#else + os::Printer::log("glEndQuery not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetQueryiv(GLenum target, GLenum pname, GLint *params) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetQueryivARB) + pGlGetQueryivARB(target, pname, params); +#elif defined(GL_ARB_occlusion_query) + glGetQueryivARB(target, pname, params); +#else + os::Printer::log("glGetQueryivARB not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetQueryObjectivARB) + pGlGetQueryObjectivARB(id, pname, params); + else if (pGlGetOcclusionQueryivNV) + pGlGetOcclusionQueryivNV(id, pname, params); +#elif defined(GL_ARB_occlusion_query) + glGetQueryObjectivARB(id, pname, params); +#elif defined(GL_NV_occlusion_query) + glGetOcclusionQueryivNV(id, pname, params); +#else + os::Printer::log("glGetQueryObjectiv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlGetQueryObjectuivARB) + pGlGetQueryObjectuivARB(id, pname, params); + else if (pGlGetOcclusionQueryuivNV) + pGlGetOcclusionQueryuivNV(id, pname, params); +#elif defined(GL_ARB_occlusion_query) + glGetQueryObjectuivARB(id, pname, params); +#elif defined(GL_NV_occlusion_query) + glGetOcclusionQueryuivNV(id, pname, params); +#else + os::Printer::log("glGetQueryObjectuiv not supported", ELL_ERROR); +#endif +} + +inline void COpenGLExtensionHandler::extGlSwapInterval(int interval) +{ + // we have wglext, so try to use that +#if defined(_IRR_WINDOWS_API_) && defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) +#ifdef WGL_EXT_swap_control + if (pWglSwapIntervalEXT) + pWglSwapIntervalEXT(interval); +#endif +#endif +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + //TODO: Check GLX_EXT_swap_control and GLX_MESA_swap_control +#ifdef GLX_SGI_swap_control + // does not work with interval==0 +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (interval && pGlxSwapIntervalSGI) + pGlxSwapIntervalSGI(interval); +#else + if (interval) + glXSwapIntervalSGI(interval); +#endif +#elif defined(GLX_EXT_swap_control) +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + Display *dpy = glXGetCurrentDisplay(); + GLXDrawable drawable = glXGetCurrentDrawable(); + + if (pGlxSwapIntervalEXT) + pGlxSwapIntervalEXT(dpy, drawable, interval); +#else + pGlXSwapIntervalEXT(dpy, drawable, interval); +#endif +#elif defined(GLX_MESA_swap_control) +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlxSwapIntervalMESA) + pGlxSwapIntervalMESA(interval); +#else + pGlXSwapIntervalMESA(interval); +#endif +#endif +#endif +} + +inline void COpenGLExtensionHandler::extGlBlendEquation(GLenum mode) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlBlendEquation) + pGlBlendEquation(mode); + else if (pGlBlendEquationEXT) + pGlBlendEquationEXT(mode); +#elif defined(GL_EXT_blend_minmax) || defined(GL_EXT_blend_subtract) || defined(GL_EXT_blend_logic_op) + glBlendEquationEXT(mode); +#elif defined(GL_VERSION_1_2) + glBlendEquation(mode); +#else + os::Printer::log("glBlendEquation not supported", ELL_ERROR); +#endif +} + + +} +} + +#endif + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLMaterialRenderer.h new file mode 100644 index 0000000..ea84a54 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLMaterialRenderer.h @@ -0,0 +1,756 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLDriver.h" +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +//! Base class for all internal OpenGL material renderers +class COpenGLMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + COpenGLMaterialRenderer(video::COpenGLDriver* driver) : Driver(driver) + { + } + +protected: + + video::COpenGLDriver* Driver; +}; + + +//! Solid material renderer +class COpenGLMaterialRenderer_SOLID : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_SOLID(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (resetAllRenderstates || (material.MaterialType != lastMaterial.MaterialType)) + { + // thanks to Murphy, the following line removed some + // bugs with several OpenGL implementations. + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } +}; + + +//! Generic Texture Blend +class COpenGLMaterialRenderer_ONETEXTURE_BLEND : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_ONETEXTURE_BLEND(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + +// if (material.MaterialType != lastMaterial.MaterialType || +// material.MaterialTypeParam != lastMaterial.MaterialTypeParam || +// resetAllRenderstates) + { + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + u32 alphaSource; + unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam); + +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (f32) modulate ); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, (f32) modulate ); +#endif + + glBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact)); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + glEnable(GL_BLEND); + + if ( textureBlendFunc_hasAlpha(srcFact) || textureBlendFunc_hasAlpha(dstFact) ) + { + if (alphaSource==EAS_VERTEX_COLOR) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); +#endif + } + else if (alphaSource==EAS_TEXTURE) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); +#endif + } + else + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_TEXTURE); +#endif + } + } + } + } + + virtual void OnUnsetMaterial() + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); +#endif + + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + //! Returns if the material is transparent. + /** Is not always transparent, but mostly. */ + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Solid 2 layer material renderer +class COpenGLMaterialRenderer_SOLID_2_LAYER : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_SOLID_2_LAYER(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA); +#endif + } + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR); +#endif + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + } +}; + + +//! Transparent add color material renderer +class COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_ADD_COLOR(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates) + { + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_BLEND); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent vertex alpha material renderer +class COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PRIMARY_COLOR_EXT ); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); +#endif + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + } + + virtual void OnUnsetMaterial() + { + // default values + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE ); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE ); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE ); +#endif + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates + || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); +#endif + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + + glAlphaFunc(GL_GREATER, material.MaterialTypeParam); + } + } + + virtual void OnUnsetMaterial() + { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE ); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE ); +#endif + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + + +//! Transparent alpha channel material renderer +class COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5f); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_ALPHA_TEST); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return false; // this material is not really transparent because it does no blending. + } +}; + + +//! material renderer for all kinds of lightmaps +class COpenGLMaterialRenderer_LIGHTMAP : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_LIGHTMAP(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + // diffuse map + + switch (material.MaterialType) + { + case EMT_LIGHTMAP_LIGHTING: + case EMT_LIGHTMAP_LIGHTING_M2: + case EMT_LIGHTMAP_LIGHTING_M4: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case EMT_LIGHTMAP_ADD: + case EMT_LIGHTMAP: + case EMT_LIGHTMAP_M2: + case EMT_LIGHTMAP_M4: + default: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + } + + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + // lightmap + + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); +#ifdef GL_ARB_texture_env_combine + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + + if (material.MaterialType == EMT_LIGHTMAP_ADD) + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD); + else + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + + if (material.MaterialType == EMT_LIGHTMAP_ADD) + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD); + else + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT); +#endif + + switch (material.MaterialType) + { + case EMT_LIGHTMAP_M4: + case EMT_LIGHTMAP_LIGHTING_M4: +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 4.0f); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 4.0f); +#endif + break; + case EMT_LIGHTMAP_M2: + case EMT_LIGHTMAP_LIGHTING_M2: +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0f); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f); +#endif + break; + default: +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f); +#endif + } + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); +#ifdef GL_ARB_texture_env_combine + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.f ); +#else + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.f ); +#endif + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } +}; + + + +//! detail map material renderer +class COpenGLMaterialRenderer_DETAIL_MAP : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_DETAIL_MAP(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + // diffuse map is default modulated + + // detail map on second layer + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); +#ifdef GL_ARB_texture_env_combine + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD_SIGNED_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); +#endif + } + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + } +}; + + +//! sphere map material renderer +class COpenGLMaterialRenderer_SPHERE_MAP : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_SPHERE_MAP(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(1); + // texture needs to be flipped for OpenGL + core::matrix4 tmp = Driver->getTransform(ETS_TEXTURE_0); + tmp[5]*=-1; + Driver->setTransform(ETS_TEXTURE_0, tmp); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + } + } + + virtual void OnUnsetMaterial() + { + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + } +}; + + +//! reflection 2 layer material renderer +class COpenGLMaterialRenderer_REFLECTION_2_LAYER : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_REFLECTION_2_LAYER(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); +#ifdef GL_ARB_texture_env_combine + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); +#endif + } + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + } +}; + + +//! reflection 2 layer material renderer +class COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public COpenGLMaterialRenderer +{ +public: + + COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(video::COpenGLDriver* d) + : COpenGLMaterialRenderer(d) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + Driver->disableTextures(2); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { +#ifdef GL_ARB_texture_env_combine + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB); +#endif + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); +#ifdef GL_ARB_texture_env_combine + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); +#else + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB); +#endif + } + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + } + + virtual void OnUnsetMaterial() + { + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE1_ARB); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + if (Driver->queryFeature(EVDF_MULTITEXTURE)) + { + Driver->extGlActiveTexture(GL_TEXTURE0_ARB); + } + glDisable(GL_BLEND); + } + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } +}; + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.cpp new file mode 100644 index 0000000..875fe63 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.cpp @@ -0,0 +1,291 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLNormalMapRenderer.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" +#include "COpenGLDriver.h" + +namespace irr +{ +namespace video +{ + +// Irrlicht Engine OpenGL render path normal map vertex shader +// I guess it could be optimized a lot, because I wrote it in D3D ASM and +// transferred it 1:1 to OpenGL +const char OPENGL_NORMAL_MAP_VSH[] = + "!!ARBvp1.0\n"\ + "#input\n"\ + "# 0-3: transposed world matrix;\n"\ + "#;12: Light01 position \n"\ + "#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\ + "#;14: Light02 position \n"\ + "#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\ + "\n"\ + "ATTRIB InPos = vertex.position;\n"\ + "ATTRIB InColor = vertex.color;\n"\ + "ATTRIB InNormal = vertex.normal;\n"\ + "ATTRIB InTexCoord = vertex.texcoord[0];\n"\ + "ATTRIB InTangent = vertex.texcoord[1];\n"\ + "ATTRIB InBinormal = vertex.texcoord[2];\n"\ + "\n"\ + "#output\n"\ + "OUTPUT OutPos = result.position;\n"\ + "OUTPUT OutLightColor1 = result.color.primary;\n"\ + "OUTPUT OutLightColor2 = result.color.secondary;\n"\ + "OUTPUT OutTexCoord = result.texcoord[0];\n"\ + "OUTPUT OutLightVector1 = result.texcoord[1];\n"\ + "OUTPUT OutLightVector2 = result.texcoord[2];\n"\ + "\n"\ + "PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\ + "TEMP Temp;\n"\ + "TEMP TempColor;\n"\ + "TEMP TempLightVector1;\n"\ + "TEMP TempLightVector2;\n"\ + "TEMP TempTransLightV1;\n"\ + "TEMP TempTransLightV2;\n"\ + "\n"\ + "# transform position to clip space \n"\ + "DP4 OutPos.x, MVP[0], InPos;\n"\ + "DP4 OutPos.y, MVP[1], InPos;\n"\ + "DP4 Temp.z, MVP[2], InPos;\n"\ + "DP4 OutPos.w, MVP[3], InPos;\n"\ + "MOV OutPos.z, Temp.z;\n"\ + "MOV result.fogcoord.x, Temp.z;\n"\ + "\n"\ + "# vertex - lightpositions \n"\ + "SUB TempLightVector1, program.local[12], InPos; \n"\ + "SUB TempLightVector2, program.local[14], InPos; \n"\ + "\n"\ + "# transform the light vector 1 with U, V, W \n"\ + "DP3 TempTransLightV1.x, InTangent, TempLightVector1; \n"\ + "DP3 TempTransLightV1.y, InBinormal, TempLightVector1; \n"\ + "DP3 TempTransLightV1.z, InNormal, TempLightVector1; \n"\ + "\n"\ + "# transform the light vector 2 with U, V, W \n"\ + "DP3 TempTransLightV2.x, InTangent, TempLightVector2; \n"\ + "DP3 TempTransLightV2.y, InBinormal, TempLightVector2; \n"\ + "DP3 TempTransLightV2.z, InNormal, TempLightVector2; \n"\ + "\n"\ + "# normalize light vector 1 \n"\ + "DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\ + "RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\ + "MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\ + "\n"\ + "# normalize light vector 2 \n"\ + "DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\ + "RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\ + "MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\ + "\n"\ + "\n"\ + "# move light vectors out\n"\ + "MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "\n"\ + "# calculate attenuation of light 1\n"\ + "MOV TempLightVector1.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\ + "MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w; \n"\ + "RSQ TempLightVector1, TempLightVector1.x; \n"\ + "MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# calculate attenuation of light 2\n"\ + "MOV TempLightVector2.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\ + "MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w; \n"\ + "RSQ TempLightVector2, TempLightVector2.x; \n"\ + "MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# move out texture coordinates and original alpha value\n"\ + "MOV OutTexCoord, InTexCoord; \n"\ + "MOV OutLightColor1.w, InColor.w; \n"\ + "\n"\ + "END\n"; + +// Irrlicht Engine OpenGL render path normal map pixel shader +// I guess it could be optimized a bit, because I wrote it in D3D ASM and +// transfered it 1:1 to OpenGL +const char OPENGL_NORMAL_MAP_PSH[] = + "!!ARBfp1.0\n"\ + "#_IRR_FOG_MODE_\n"\ + "\n"\ + "#Input\n"\ + "ATTRIB inTexCoord = fragment.texcoord[0]; \n"\ + "ATTRIB light1Vector = fragment.texcoord[1]; \n"\ + "ATTRIB light2Vector = fragment.texcoord[2]; \n"\ + "ATTRIB light1Color = fragment.color.primary; \n"\ + "ATTRIB light2Color = fragment.color.secondary; \n"\ + "\n"\ + "#Output\n"\ + "OUTPUT outColor = result.color;\n"\ + "TEMP temp;\n"\ + "TEMP temp2;\n"\ + "TEMP colorMapColor;\n"\ + "TEMP normalMapColor;\n"\ + "\n"\ + "# fetch color and normal map; \n"\ + "TXP colorMapColor, inTexCoord, texture[0], 2D; \n"\ + "TXP normalMapColor, inTexCoord, texture[1], 2D; \n"\ + "\n"\ + "# calculate color of light1; \n"\ + "MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp, normalMapColor, temp; \n"\ + "MUL temp, light1Color, temp; \n"\ + "\n"\ + "# calculate color of light2; \n"\ + "MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp2, normalMapColor, temp2; \n"\ + "MAD temp, light2Color, temp2, temp; \n"\ + "\n"\ + "# luminance * base color; \n"\ + "MUL outColor, temp, colorMapColor; \n"\ + "MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\ + "\n"\ + "END\n"; + +//! Constructor +COpenGLNormalMapRenderer::COpenGLNormalMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true) +{ + + #ifdef _DEBUG + setDebugName("COpenGLNormalMapRenderer"); + #endif + + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basically, this thing simply compiles the hardcoded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) || + !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); + + if (renderer) + { + // use the already compiled shaders + video::COpenGLNormalMapRenderer* nmr = reinterpret_cast(renderer); + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, OPENGL_NORMAL_MAP_VSH, OPENGL_NORMAL_MAP_PSH, EVT_TANGENTS); + } + + // fallback if compilation has failed + if (-1==outMaterialTypeNr) + outMaterialTypeNr = driver->addMaterialRenderer(this); +} + + +//! Destructor +COpenGLNormalMapRenderer::~COpenGLNormalMapRenderer() +{ + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader.clear(); + } +} + + +//! Returns the render capability of the material. +s32 COpenGLNormalMapRenderer::getRenderCapability() const +{ + if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) && + Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + return 0; + + return 1; +} + + +//! Called by the engine when the vertex and/or pixel shader constants for an +//! material renderer should be set. +void COpenGLNormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) +{ + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed(); + services->setVertexShaderConstant(tWorld.pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + core::matrix4 tr(worldViewProj.getTransposed()); + services->setVertexShaderConstant(tr.pointer(), 8, 4); + + // here we fetch the fixed function lights from the driver + // and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + // Load the inverse world matrix. + core::matrix4 invWorldMat; + driver->getTransform(video::ETS_WORLD).getInverse(invWorldMat); + + for (u32 i=0; i<2; ++i) + { + video::SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + // Transform the light by the inverse world matrix to get it into object space. + invWorldMat.transformVect(light.Position); + + services->setVertexShaderConstant( + reinterpret_cast(&light.Position), 12+(i*2), 1); + + services->setVertexShaderConstant( + reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } +} + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.h new file mode 100644 index 0000000..304802d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLNormalMapRenderer.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_NORMAL_MAP_RENDERER_H_INCLUDED__ +#define __C_OPENGL_NORMAL_MAP_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Class for rendering normal maps with OpenGL +class COpenGLNormalMapRenderer : public COpenGLShaderMaterialRenderer, public IShaderConstantSetCallBack +{ +public: + + //! Constructor + COpenGLNormalMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + //! Destructor + ~COpenGLNormalMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + +protected: + + bool CompiledShaders; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.cpp new file mode 100644 index 0000000..15eae29 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.cpp @@ -0,0 +1,354 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLParallaxMapRenderer.h" +#include "COpenGLDriver.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +// Irrlicht Engine OpenGL render path parallax map vertex shader +// I guess it could be optimized a lot, because I wrote it in D3D ASM and +// transferred it 1:1 to OpenGL +const char OPENGL_PARALLAX_MAP_VSH[] = + "!!ARBvp1.0\n"\ + "#input\n"\ + "# 0-3: transposed world matrix;\n"\ + "#;12: Light01 position \n"\ + "#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\ + "#;14: Light02 position \n"\ + "#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\ + "#;16: Eye position \n"\ + "\n"\ + "ATTRIB InPos = vertex.position;\n"\ + "ATTRIB InColor = vertex.color;\n"\ + "ATTRIB InNormal = vertex.normal;\n"\ + "ATTRIB InTexCoord = vertex.texcoord[0];\n"\ + "ATTRIB InTangent = vertex.texcoord[1];\n"\ + "ATTRIB InBinormal = vertex.texcoord[2];\n"\ + "\n"\ + "#output\n"\ + "OUTPUT OutPos = result.position;\n"\ + "OUTPUT OutLightColor1 = result.color.primary;\n"\ + "OUTPUT OutLightColor2 = result.color.secondary;\n"\ + "OUTPUT OutTexCoord = result.texcoord[0];\n"\ + "OUTPUT OutLightVector1 = result.texcoord[1];\n"\ + "OUTPUT OutLightVector2 = result.texcoord[2];\n"\ + "OUTPUT OutEyeVector = result.texcoord[3];\n"\ + "\n"\ + "PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\ + "TEMP Temp;\n"\ + "TEMP TempColor;\n"\ + "TEMP TempLightVector1;\n"\ + "TEMP TempLightVector2;\n"\ + "TEMP TempEyeVector;\n"\ + "TEMP TempTransLightV1;\n"\ + "TEMP TempTransLightV2;\n"\ + "\n"\ + "# transform position to clip space \n"\ + "DP4 OutPos.x, MVP[0], InPos;\n"\ + "DP4 OutPos.y, MVP[1], InPos;\n"\ + "DP4 Temp.z, MVP[2], InPos;\n"\ + "DP4 OutPos.w, MVP[3], InPos;\n"\ + "MOV OutPos.z, Temp.z;\n"\ + "MOV result.fogcoord.x, Temp.z;\n"\ + "\n"\ + "# vertex - lightpositions \n"\ + "SUB TempLightVector1, program.local[12], InPos; \n"\ + "SUB TempLightVector2, program.local[14], InPos; \n"\ + "\n"\ + "# eye vector \n"\ + "SUB Temp, program.local[16], InPos; \n"\ + "\n"\ + "# transform the light vector 1 with U, V, W \n"\ + "DP3 TempTransLightV1.x, InTangent, TempLightVector1; \n"\ + "DP3 TempTransLightV1.y, InBinormal, TempLightVector1; \n"\ + "DP3 TempTransLightV1.z, InNormal, TempLightVector1; \n"\ + "\n"\ + "# transform the light vector 2 with U, V, W \n"\ + "DP3 TempTransLightV2.x, InTangent, TempLightVector2; \n"\ + "DP3 TempTransLightV2.y, InBinormal, TempLightVector2; \n"\ + "DP3 TempTransLightV2.z, InNormal, TempLightVector2; \n"\ + "\n"\ + "# transform the eye vector with U, V, W \n"\ + "DP3 TempEyeVector.x, InTangent, Temp; \n"\ + "DP3 TempEyeVector.y, InBinormal, Temp; \n"\ + "DP3 TempEyeVector.z, InNormal, Temp; \n"\ + "\n"\ + "# normalize light vector 1 \n"\ + "DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\ + "RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\ + "MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\ + "\n"\ + "# normalize light vector 2 \n"\ + "DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\ + "RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\ + "MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\ + "\n"\ + "# normalize eye vector \n"\ + "DP3 TempEyeVector.w, TempEyeVector, TempEyeVector; \n"\ + "RSQ TempEyeVector.w, TempEyeVector.w; \n"\ + "MUL TempEyeVector, TempEyeVector, TempEyeVector.w;\n"\ + "MUL TempEyeVector, TempEyeVector, {1,-1,-1,1}; # flip x \n"\ + "\n"\ + "\n"\ + "# move light and eye vectors out\n"\ + "MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "MAD OutEyeVector, TempEyeVector, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\ + "\n"\ + "# calculate attenuation of light 1\n"\ + "MOV TempLightVector1.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\ + "MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w; \n"\ + "RSQ TempLightVector1, TempLightVector1.x; \n"\ + "MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# calculate attenuation of light 2\n"\ + "MOV TempLightVector2.w, {0,0,0,0}; \n"\ + "DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\ + "MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w; \n"\ + "RSQ TempLightVector2, TempLightVector2.x; \n"\ + "MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\ + "\n"\ + "# move out texture coordinates and original alpha value\n"\ + "MOV OutTexCoord, InTexCoord; \n"\ + "MOV OutLightColor1.w, InColor.w; \n"\ + "\n"\ + "END\n"; + +// Irrlicht Engine OpenGL render path parallax map pixel shader +// I guess it could be optimized a bit, because I wrote it in D3D ASM and +// transfered it 1:1 to OpenGL +const char OPENGL_PARALLAX_MAP_PSH[] = + "!!ARBfp1.0\n"\ + "#_IRR_FOG_MODE_\n"\ + "\n"\ + "#Input\n"\ + "ATTRIB inTexCoord = fragment.texcoord[0]; \n"\ + "ATTRIB light1Vector = fragment.texcoord[1]; \n"\ + "ATTRIB light2Vector = fragment.texcoord[2]; \n"\ + "ATTRIB eyeVector = fragment.texcoord[3]; \n"\ + "ATTRIB light1Color = fragment.color.primary; \n"\ + "ATTRIB light2Color = fragment.color.secondary; \n"\ + "\n"\ + "#Output\n"\ + "OUTPUT outColor = result.color;\n"\ + "TEMP temp;\n"\ + "TEMP temp2;\n"\ + "TEMP colorMapColor;\n"\ + "TEMP normalMapColor;\n"\ + "\n"\ + "PARAM height_scale = program.local[0]; \n"\ + "# fetch color and normal map; \n"\ + "TXP normalMapColor, inTexCoord, texture[1], 2D; \n"\ + "MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "\n"\ + "\n"\ + "# extract eye vector (so substract 0.5f and multiply by 2)\n"\ + "MAD temp, eyeVector, {2,2,2,2}, {-1,-1,-1,-1};\n"\ + "\n"\ + "# height = height * scale \n"\ + "MUL normalMapColor, normalMapColor, height_scale;\n"\ + "\n"\ + "# calculate new texture coord: height * eye + oldTexCoord\n"\ + "MAD temp, temp, normalMapColor.wwww, inTexCoord;\n"\ + "\n"\ + "# fetch new textures \n"\ + "TXP colorMapColor, temp, texture[0], 2D; \n"\ + "TXP normalMapColor, temp, texture[1], 2D; \n"\ + "\n"\ + "# calculate color of light1; \n"\ + "MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp, normalMapColor, temp; \n"\ + "MUL temp, light1Color, temp; \n"\ + "\n"\ + "# calculate color of light2; \n"\ + "MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\ + "DP3_SAT temp2, normalMapColor, temp2; \n"\ + "MAD temp, light2Color, temp2, temp; \n"\ + "\n"\ + "# luminance * base color; \n"\ + "MUL outColor, temp, colorMapColor; \n"\ + "MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\ + "\n"\ + "END\n"; + +//! Constructor +COpenGLParallaxMapRenderer::COpenGLParallaxMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) + : COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true) +{ + + #ifdef _DEBUG + setDebugName("COpenGLParallaxMapRenderer"); + #endif + + // set this as callback. We could have done this in + // the initialization list, but some compilers don't like it. + + CallBack = this; + + // basically, this simply compiles the hard coded shaders if the + // hardware is able to do them, otherwise it maps to the base material + + if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) || + !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + { + // this hardware is not able to do shaders. Fall back to + // base material. + outMaterialTypeNr = driver->addMaterialRenderer(this); + return; + } + + // check if already compiled normal map shaders are there. + + video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); + + if (renderer) + { + // use the already compiled shaders + video::COpenGLParallaxMapRenderer* nmr = reinterpret_cast(renderer); + CompiledShaders = false; + + VertexShader = nmr->VertexShader; + PixelShader = nmr->PixelShader; + + outMaterialTypeNr = driver->addMaterialRenderer(this); + } + else + { + // compile shaders on our own + init(outMaterialTypeNr, OPENGL_PARALLAX_MAP_VSH, OPENGL_PARALLAX_MAP_PSH, EVT_TANGENTS); + } + + // fallback if compilation has failed + if (-1==outMaterialTypeNr) + outMaterialTypeNr = driver->addMaterialRenderer(this); +} + + +//! Destructor +COpenGLParallaxMapRenderer::~COpenGLParallaxMapRenderer() +{ + if (CallBack == this) + CallBack = 0; + + if (!CompiledShaders) + { + // prevent this from deleting shaders we did not create + VertexShader = 0; + PixelShader.clear(); + } +} + + +void COpenGLParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + COpenGLShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, + resetAllRenderstates, services); + + CurrentScale = material.MaterialTypeParam; +} + + + +//! Returns the render capability of the material. +s32 COpenGLParallaxMapRenderer::getRenderCapability() const +{ + if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) && + Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) + return 0; + + return 1; +} + + +//! Called by the engine when the vertex and/or pixel shader constants for an +//! material renderer should be set. +void COpenGLParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) +{ + video::IVideoDriver* driver = services->getVideoDriver(); + + // set transposed world matrix + const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed(); + services->setVertexShaderConstant(tWorld.pointer(), 0, 4); + + // set transposed worldViewProj matrix + core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); + worldViewProj *= driver->getTransform(video::ETS_VIEW); + worldViewProj *= driver->getTransform(video::ETS_WORLD); + core::matrix4 tr(worldViewProj.getTransposed()); + services->setVertexShaderConstant(tr.pointer(), 8, 4); + + // here we fetch the fixed function lights from the driver + // and set them as constants + + u32 cnt = driver->getDynamicLightCount(); + + // Load the inverse world matrix. + core::matrix4 invWorldMat; + driver->getTransform(video::ETS_WORLD).getInverse(invWorldMat); + + for (u32 i=0; i<2; ++i) + { + video::SLight light; + + if (igetDynamicLight(i); + else + { + light.DiffuseColor.set(0,0,0); // make light dark + light.Radius = 1.0f; + } + + light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation + + // Transform the light by the inverse world matrix to get it into object space. + invWorldMat.transformVect(light.Position); + + services->setVertexShaderConstant( + reinterpret_cast(&light.Position), 12+(i*2), 1); + + services->setVertexShaderConstant( + reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); + } + + // Obtain the view position by transforming 0,0,0 by the inverse view matrix + // and then multiply this by the inverse world matrix. + core::vector3df viewPos(0.0f, 0.0f, 0.0f); + core::matrix4 inverseView; + driver->getTransform(video::ETS_VIEW).getInverse(inverseView); + inverseView.transformVect(viewPos); + invWorldMat.transformVect(viewPos); + services->setVertexShaderConstant(reinterpret_cast(&viewPos.X), 16, 1); + + // set scale factor + f32 factor = 0.02f; // default value + if (CurrentScale != 0.0f) + factor = CurrentScale; + + f32 c6[] = {factor, factor, factor, factor}; + services->setPixelShaderConstant(c6, 0, 1); +} + + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.h new file mode 100644 index 0000000..bfee487 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLParallaxMapRenderer.h @@ -0,0 +1,55 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_PARALLAX_MAP_RENDERER_H_INCLUDED__ +#define __C_OPENGL_PARALLAX_MAP_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLShaderMaterialRenderer.h" +#include "IShaderConstantSetCallBack.h" + +namespace irr +{ +namespace video +{ + +//! Class for rendering normal maps with OpenGL +class COpenGLParallaxMapRenderer : public COpenGLShaderMaterialRenderer, public IShaderConstantSetCallBack +{ +public: + + //! Constructor + COpenGLParallaxMapRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); + + //! Destructor + ~COpenGLParallaxMapRenderer(); + + //! Called by the engine when the vertex and/or pixel shader constants for an + //! material renderer should be set. + virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); + + //! Returns the render capability of the material. + virtual s32 getRenderCapability() const; + + virtual void OnSetMaterial(const SMaterial& material) { } + virtual void OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services); + +protected: + + bool CompiledShaders; + f32 CurrentScale; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.cpp new file mode 100644 index 0000000..af47c0e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.cpp @@ -0,0 +1,693 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// This file was originally written by William Finlayson. I (Nikolaus +// Gebhardt) did some minor modifications and changes to it and integrated it +// into Irrlicht. Thanks a lot to William for his work on this and that he gave +// me his permission to add it into Irrlicht using the zlib license. + +// After Irrlicht 0.12, Michael Zoech did some improvements to this renderer, I +// merged this into Irrlicht 0.14, thanks to him for his work. + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLSLMaterialRenderer.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IMaterialRendererServices.h" +#include "IVideoDriver.h" +#include "os.h" +#include "COpenGLDriver.h" + +namespace irr +{ +namespace video +{ + + +//! Constructor +COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* vertexShaderEntryPointName, + E_VERTEX_SHADER_TYPE vsCompileTarget, + const c8* pixelShaderProgram, + const c8* pixelShaderEntryPointName, + E_PIXEL_SHADER_TYPE psCompileTarget, + const c8* geometryShaderProgram, + const c8* geometryShaderEntryPointName, + E_GEOMETRY_SHADER_TYPE gsCompileTarget, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut, + IShaderConstantSetCallBack* callback, + video::IMaterialRenderer* baseMaterial, + s32 userData) + : Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + Program(0), Program2(0), UserData(userData) +{ + #ifdef _DEBUG + setDebugName("COpenGLSLMaterialRenderer"); + #endif + + //entry points must always be main, and the compile target isn't selectable + //it is fine to ignore what has been asked for, as the compiler should spot anything wrong + //just check that GLSL is available + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + if (!Driver->queryFeature(EVDF_ARB_GLSL)) + return; + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, geometryShaderProgram); +} + + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData) +: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + Program(0), Program2(0), UserData(userData) +{ + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + +//! Destructor +COpenGLSLMaterialRenderer::~COpenGLSLMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (Program) + { + GLhandleARB shaders[8]; + GLint count; + Driver->extGlGetAttachedObjects(Program, 8, &count, shaders); + // avoid bugs in some drivers, which return larger numbers + count=core::min_(count,8); + for (GLint i=0; iextGlDeleteObject(shaders[i]); + Driver->extGlDeleteObject(Program); + Program = 0; + } + + if (Program2) + { + GLuint shaders[8]; + GLint count; + Driver->extGlGetAttachedShaders(Program2, 8, &count, shaders); + // avoid bugs in some drivers, which return larger numbers + count=core::min_(count,8); + for (GLint i=0; iextGlDeleteShader(shaders[i]); + Driver->extGlDeleteProgram(Program2); + Program2 = 0; + } + + UniformInfo.clear(); + + if (BaseMaterial) + BaseMaterial->drop(); +} + + +void COpenGLSLMaterialRenderer::init(s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + const c8* geometryShaderProgram, + scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, + u32 verticesOut) +{ + outMaterialTypeNr = -1; + + if (!createProgram()) + return; + +#if defined(GL_ARB_vertex_shader) && defined (GL_ARB_fragment_shader) + if (vertexShaderProgram) + if (!createShader(GL_VERTEX_SHADER_ARB, vertexShaderProgram)) + return; + + if (pixelShaderProgram) + if (!createShader(GL_FRAGMENT_SHADER_ARB, pixelShaderProgram)) + return; +#endif + +#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_program4) || defined(GL_NV_geometry_shader4) + if (geometryShaderProgram && Driver->queryFeature(EVDF_GEOMETRY_SHADER)) + { + if (!createShader(GL_GEOMETRY_SHADER_EXT, geometryShaderProgram)) + return; +#if defined(GL_ARB_geometry_shader4) || defined(GL_EXT_geometry_shader4) || defined(GL_NV_geometry_shader4) + if (Program2) // Geometry shaders are supported only in OGL2.x+ drivers. + { + Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_INPUT_TYPE_EXT, Driver->primitiveTypeToGL(inType)); + Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_OUTPUT_TYPE_EXT, Driver->primitiveTypeToGL(outType)); + if (verticesOut==0) + Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_VERTICES_OUT_EXT, Driver->MaxGeometryVerticesOut); + else + Driver->extGlProgramParameteri(Program2, GL_GEOMETRY_VERTICES_OUT_EXT, core::min_(verticesOut, Driver->MaxGeometryVerticesOut)); + } +#elif defined(GL_NV_geometry_program4) + if (verticesOut==0) + Driver->extGlProgramVertexLimit(GL_GEOMETRY_PROGRAM_NV, Driver->MaxGeometryVerticesOut); + else + Driver->extGlProgramVertexLimit(GL_GEOMETRY_PROGRAM_NV, core::min_(verticesOut, Driver->MaxGeometryVerticesOut)); +#endif + } +#endif + + if (!linkProgram()) + return; + + // register myself as new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + +bool COpenGLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, + E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (Program||Program2)) + CallBack->OnSetConstants(this, UserData); + + return true; +} + + +void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material, + const video::SMaterial& lastMaterial, + bool resetAllRenderstates, + video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (Program2) + Driver->extGlUseProgram(Program2); + else if (Program) + Driver->extGlUseProgramObject(Program); + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, this); + } + + //let callback know used material + if (CallBack) + CallBack->OnSetMaterial(material); + + for (u32 i=0; isetActiveTexture(i, material.getTexture(i)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +void COpenGLSLMaterialRenderer::OnUnsetMaterial() +{ + if (Program) + Driver->extGlUseProgramObject(0); + if (Program2) + Driver->extGlUseProgram(0); + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + + +//! Returns if the material is transparent. +bool COpenGLSLMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + + +bool COpenGLSLMaterialRenderer::createProgram() +{ + if (Driver->Version>=200) + Program2 = Driver->extGlCreateProgram(); + else + Program = Driver->extGlCreateProgramObject(); + return true; +} + + +bool COpenGLSLMaterialRenderer::createShader(GLenum shaderType, const char* shader) +{ + if (Program2) + { + GLuint shaderHandle = Driver->extGlCreateShader(shaderType); + Driver->extGlShaderSource(shaderHandle, 1, &shader, NULL); + Driver->extGlCompileShader(shaderHandle); + + GLint status = 0; + +#ifdef GL_VERSION_2_0 + Driver->extGlGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &status); +#endif + + if (status != GL_TRUE) + { + os::Printer::log("GLSL shader failed to compile", ELL_ERROR); + // check error message and log it + GLint maxLength=0; + GLint length; +#ifdef GL_VERSION_2_0 + Driver->extGlGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, + &maxLength); +#endif + if (maxLength) + { + GLchar *infoLog = new GLchar[maxLength]; + Driver->extGlGetShaderInfoLog(shaderHandle, maxLength, &length, infoLog); + os::Printer::log(reinterpret_cast(infoLog), ELL_ERROR); + delete [] infoLog; + } + + return false; + } + + Driver->extGlAttachShader(Program2, shaderHandle); + } + else + { + GLhandleARB shaderHandle = Driver->extGlCreateShaderObject(shaderType); + + Driver->extGlShaderSourceARB(shaderHandle, 1, &shader, NULL); + Driver->extGlCompileShaderARB(shaderHandle); + + GLint status = 0; + +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &status); +#endif + + if (!status) + { + os::Printer::log("GLSL shader failed to compile", ELL_ERROR); + // check error message and log it + GLint maxLength=0; + GLsizei length; +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(shaderHandle, + GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); +#endif + if (maxLength) + { + GLcharARB *infoLog = new GLcharARB[maxLength]; + Driver->extGlGetInfoLog(shaderHandle, maxLength, &length, infoLog); + os::Printer::log(reinterpret_cast(infoLog), ELL_ERROR); + delete [] infoLog; + } + + return false; + } + + Driver->extGlAttachObject(Program, shaderHandle); + } + return true; +} + + +bool COpenGLSLMaterialRenderer::linkProgram() +{ + if (Program2) + { + Driver->extGlLinkProgram(Program2); + + GLint status = 0; + +#ifdef GL_VERSION_2_0 + Driver->extGlGetProgramiv(Program2, GL_LINK_STATUS, &status); +#endif + + if (!status) + { + os::Printer::log("GLSL shader program failed to link", ELL_ERROR); + // check error message and log it + GLint maxLength=0; + GLsizei length; +#ifdef GL_VERSION_2_0 + Driver->extGlGetProgramiv(Program2, GL_INFO_LOG_LENGTH, &maxLength); +#endif + if (maxLength) + { + GLchar *infoLog = new GLchar[maxLength]; + Driver->extGlGetProgramInfoLog(Program2, maxLength, &length, infoLog); + os::Printer::log(reinterpret_cast(infoLog), ELL_ERROR); + delete [] infoLog; + } + + return false; + } + + // get uniforms information + + GLint num = 0; +#ifdef GL_VERSION_2_0 + Driver->extGlGetProgramiv(Program2, GL_ACTIVE_UNIFORMS, &num); +#endif + + if (num == 0) + { + // no uniforms + return true; + } + + GLint maxlen = 0; +#ifdef GL_VERSION_2_0 + Driver->extGlGetProgramiv(Program2, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen); +#endif + + if (maxlen == 0) + { + os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR); + return false; + } + + // seems that some implementations use an extra null terminator + ++maxlen; + c8 *buf = new c8[maxlen]; + + UniformInfo.clear(); + UniformInfo.reallocate(num); + + for (GLint i=0; i < num; ++i) + { + SUniformInfo ui; + memset(buf, 0, maxlen); + + GLint size; + Driver->extGlGetActiveUniform(Program2, i, maxlen, 0, &size, &ui.type, reinterpret_cast(buf)); + ui.name = buf; + + UniformInfo.push_back(ui); + } + + delete [] buf; + } + else + { + Driver->extGlLinkProgramARB(Program); + + GLint status = 0; + +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_LINK_STATUS_ARB, &status); +#endif + + if (!status) + { + os::Printer::log("GLSL shader program failed to link", ELL_ERROR); + // check error message and log it + GLint maxLength=0; + GLsizei length; +#ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, + GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); +#endif + if (maxLength) + { + GLcharARB *infoLog = new GLcharARB[maxLength]; + Driver->extGlGetInfoLog(Program, maxLength, &length, infoLog); + os::Printer::log(reinterpret_cast(infoLog), ELL_ERROR); + delete [] infoLog; + } + + return false; + } + + // get uniforms information + + GLint num = 0; + #ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &num); + #endif + + if (num == 0) + { + // no uniforms + return true; + } + + GLint maxlen = 0; + #ifdef GL_ARB_shader_objects + Driver->extGlGetObjectParameteriv(Program, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &maxlen); + #endif + + if (maxlen == 0) + { + os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR); + return false; + } + + // seems that some implementations use an extra null terminator + ++maxlen; + c8 *buf = new c8[maxlen]; + + UniformInfo.clear(); + UniformInfo.reallocate(num); + + for (int i=0; i < num; ++i) + { + SUniformInfo ui; + memset(buf, 0, maxlen); + + GLint size; + Driver->extGlGetActiveUniformARB(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast(buf)); + ui.name = buf; + + UniformInfo.push_back(ui); + } + + delete [] buf; + } + + return true; +} + + +void COpenGLSLMaterialRenderer::setBasicRenderStates(const SMaterial& material, + const SMaterial& lastMaterial, + bool resetAllRenderstates) +{ + // forward + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +bool COpenGLSLMaterialRenderer::setVertexShaderConstant(const c8* name, const f32* floats, int count) +{ + return setPixelShaderConstant(name, floats, count); +} + +bool COpenGLSLMaterialRenderer::setVertexShaderConstant(const c8* name, const bool* bools, int count) +{ + return setPixelShaderConstant(name, bools, count); +} + +bool COpenGLSLMaterialRenderer::setVertexShaderConstant(const c8* name, const s32* ints, int count) +{ + return setPixelShaderConstant(name, ints, count); +} + +void COpenGLSLMaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING); +} + +bool COpenGLSLMaterialRenderer::setPixelShaderConstant(const c8* name, const f32* floats, int count) +{ + u32 i; + const u32 num = UniformInfo.size(); + + for (i=0; i < num; ++i) + { + if (UniformInfo[i].name == name) + break; + } + + if (i == num) + return false; + +#if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects) + GLint Location=0; + if (Program2) + Location=Driver->extGlGetUniformLocation(Program2,name); + else + Location=Driver->extGlGetUniformLocationARB(Program,name); + + bool status = true; + + switch (UniformInfo[i].type) + { + case GL_FLOAT: + Driver->extGlUniform1fv(Location, count, floats); + break; + case GL_FLOAT_VEC2: + Driver->extGlUniform2fv(Location, count/2, floats); + break; + case GL_FLOAT_VEC3: + Driver->extGlUniform3fv(Location, count/3, floats); + break; + case GL_FLOAT_VEC4: + Driver->extGlUniform4fv(Location, count/4, floats); + break; + case GL_FLOAT_MAT2: + Driver->extGlUniformMatrix2fv(Location, count/4, false, floats); + break; + case GL_FLOAT_MAT3: + Driver->extGlUniformMatrix3fv(Location, count/9, false, floats); + break; + case GL_FLOAT_MAT4: + Driver->extGlUniformMatrix4fv(Location, count/16, false, floats); + break; + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + { + const GLint id = static_cast(*floats); + Driver->extGlUniform1iv(Location, 1, &id); + } + break; + default: + status = false; + break; + } + return status; +#else + return false; +#endif +} + +bool COpenGLSLMaterialRenderer::setPixelShaderConstant(const c8* name, const bool* bools, int count) +{ + u32 i; + const u32 num = UniformInfo.size(); + + for (i=0; i < num; ++i) + { + if (UniformInfo[i].name == name) + break; + } + + if (i == num) + return false; + +#if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects) + GLint Location=0; + if (Program2) + Location=Driver->extGlGetUniformLocation(Program2,name); + else + Location=Driver->extGlGetUniformLocationARB(Program,name); + + bool status = true; + + switch (UniformInfo[i].type) + { + case GL_BOOL: + Driver->extGlUniform1iv(Location, count, (GLint*)bools); + break; + case GL_BOOL_VEC2: + Driver->extGlUniform2iv(Location, count/2, (GLint*)bools); + break; + case GL_BOOL_VEC3: + Driver->extGlUniform3iv(Location, count/3, (GLint*)bools); + break; + case GL_BOOL_VEC4: + Driver->extGlUniform4iv(Location, count/4, (GLint*)bools); + break; + default: + status = false; + break; + } + return status; +#else + return false; +#endif +} + +bool COpenGLSLMaterialRenderer::setPixelShaderConstant(const c8* name, const s32* ints, int count) +{ + u32 i; + const u32 num = UniformInfo.size(); + + for (i=0; i < num; ++i) + { + if (UniformInfo[i].name == name) + break; + } + + if (i == num) + return false; + +#if defined(GL_VERSION_2_0)||defined(GL_ARB_shader_objects) + GLint Location=0; + if (Program2) + Location=Driver->extGlGetUniformLocation(Program2,name); + else + Location=Driver->extGlGetUniformLocationARB(Program,name); + + bool status = true; + + switch (UniformInfo[i].type) + { + case GL_INT: + Driver->extGlUniform1iv(Location, count, ints); + break; + case GL_INT_VEC2: + Driver->extGlUniform2iv(Location, count/2, ints); + break; + case GL_INT_VEC3: + Driver->extGlUniform3iv(Location, count/3, ints); + break; + case GL_INT_VEC4: + Driver->extGlUniform4iv(Location, count/4, ints); + break; + case GL_SAMPLER_1D: + case GL_SAMPLER_2D: + case GL_SAMPLER_3D: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D_SHADOW: + Driver->extGlUniform1iv(Location, 1, ints); + break; + default: + status = false; + break; + } + return status; +#else + return false; +#endif +} + +void COpenGLSLMaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) +{ + os::Printer::log("Cannot set constant, use high level shader call.", ELL_WARNING); +} + +IVideoDriver* COpenGLSLMaterialRenderer::getVideoDriver() +{ + return Driver; +} + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.h new file mode 100644 index 0000000..ff71150 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLSLMaterialRenderer.h @@ -0,0 +1,141 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_SHADER_LANGUAGE_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_SHADER_LANGUAGE_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#ifdef _IRR_WINDOWS_API_ + #define WIN32_LEAN_AND_MEAN + #include + #include + #include "glext.h" +#else +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 +#else + #define GL_GLEXT_PROTOTYPES 1 +#endif +#if defined(_IRR_OSX_PLATFORM_) + #include +#else + #include +#endif +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #include "glext.h" +#endif +#endif + + +#include "IMaterialRenderer.h" +#include "IMaterialRendererServices.h" +#include "IGPUProgrammingServices.h" +#include "irrArray.h" +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +class IShaderConstantSetCallBack; + +//! Class for using GLSL shaders with OpenGL +//! Please note: This renderer implements its own IMaterialRendererServices +class COpenGLSLMaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices +{ +public: + + //! Constructor + COpenGLSLMaterialRenderer( + COpenGLDriver* driver, + s32& outMaterialTypeNr, + const c8* vertexShaderProgram = 0, + const c8* vertexShaderEntryPointName = 0, + E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1, + const c8* pixelShaderProgram = 0, + const c8* pixelShaderEntryPointName = 0, + E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1, + const c8* geometryShaderProgram = 0, + const c8* geometryShaderEntryPointName = "main", + E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, + scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, + u32 verticesOut = 0, + IShaderConstantSetCallBack* callback = 0, + IMaterialRenderer* baseMaterial = 0, + s32 userData = 0); + + //! Destructor + virtual ~COpenGLSLMaterialRenderer(); + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + virtual void OnUnsetMaterial(); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + + // implementations for the render services + virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates); + virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); + virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); + virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); + virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); + virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); + virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); + virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); + virtual IVideoDriver* getVideoDriver(); + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + COpenGLSLMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, + s32 userData=0); + + void init(s32& outMaterialTypeNr, + const c8* vertexShaderProgram, + const c8* pixelShaderProgram, + const c8* geometryShaderProgram, + scene::E_PRIMITIVE_TYPE inType=scene::EPT_TRIANGLES, + scene::E_PRIMITIVE_TYPE outType=scene::EPT_TRIANGLE_STRIP, + u32 verticesOut=0); + + bool createProgram(); + bool createShader(GLenum shaderType, const char* shader); + bool linkProgram(); + + COpenGLDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + struct SUniformInfo + { + core::stringc name; + GLenum type; + }; + + GLhandleARB Program; + GLuint Program2; + core::array UniformInfo; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif // compile with OpenGL +#endif // if included + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.cpp new file mode 100644 index 0000000..8921a51 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.cpp @@ -0,0 +1,339 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "COpenGLShaderMaterialRenderer.h" +#include "IGPUProgrammingServices.h" +#include "IShaderConstantSetCallBack.h" +#include "IVideoDriver.h" +#include "os.h" +#include "COpenGLDriver.h" + +namespace irr +{ +namespace video +{ + + +//! Constructor +COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) + : Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), UserData(userData) +{ + #ifdef _DEBUG + setDebugName("COpenGLShaderMaterialRenderer"); + #endif + + PixelShader.set_used(4); + for (u32 i=0; i<4; ++i) + { + PixelShader[i]=0; + } + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); + + init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, EVT_STANDARD); +} + + +//! constructor only for use by derived classes who want to +//! create a fall back material for example. +COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData) +: Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), + VertexShader(0), UserData(userData) +{ + PixelShader.set_used(4); + for (u32 i=0; i<4; ++i) + { + PixelShader[i]=0; + } + + if (BaseMaterial) + BaseMaterial->grab(); + + if (CallBack) + CallBack->grab(); +} + + +//! Destructor +COpenGLShaderMaterialRenderer::~COpenGLShaderMaterialRenderer() +{ + if (CallBack) + CallBack->drop(); + + if (VertexShader) + Driver->extGlDeletePrograms(1, &VertexShader); + + for (u32 i=0; iextGlDeletePrograms(1, &PixelShader[i]); + + if (BaseMaterial) + BaseMaterial->drop(); +} + + +void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr, + const c8* vertexShaderProgram, const c8* pixelShaderProgram, + E_VERTEX_TYPE type) +{ + outMaterialTypeNr = -1; + + bool success; + + // create vertex shader + success=createVertexShader(vertexShaderProgram); + + // create pixel shader + if (!createPixelShader(pixelShaderProgram) || !success) + return; + + // register as a new material + outMaterialTypeNr = Driver->addMaterialRenderer(this); +} + + +bool COpenGLShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) +{ + // call callback to set shader constants + if (CallBack && (VertexShader || PixelShader[0])) + CallBack->OnSetConstants(service, UserData); + + return true; +} + + +void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, + bool resetAllRenderstates, video::IMaterialRendererServices* services) +{ + if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) + { + if (VertexShader) + { + // set new vertex shader +#ifdef GL_ARB_vertex_program + Driver->extGlBindProgram(GL_VERTEX_PROGRAM_ARB, VertexShader); + glEnable(GL_VERTEX_PROGRAM_ARB); +#elif defined(GL_NV_vertex_program) + Driver->extGlBindProgram(GL_VERTEX_PROGRAM_NV, VertexShader); + glEnable(GL_VERTEX_PROGRAM_NV); +#endif + } + + // set new pixel shader + if (PixelShader[0]) + { + GLuint nextShader=PixelShader[0]; + if (material.FogEnable) + { + GLint curFogMode; + glGetIntegerv(GL_FOG_MODE, &curFogMode); +// if (Driver->LinearFog && PixelShader[1]) + if (curFogMode==GL_LINEAR && PixelShader[1]) + nextShader=PixelShader[1]; +// else if (!Driver->LinearFog && PixelShader[2]) + else if (curFogMode==GL_EXP && PixelShader[2]) + nextShader=PixelShader[2]; + else if (curFogMode==GL_EXP2 && PixelShader[3]) + nextShader=PixelShader[3]; + } +#ifdef GL_ARB_fragment_program + Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_ARB, nextShader); + glEnable(GL_FRAGMENT_PROGRAM_ARB); +#elif defined(GL_NV_fragment_program) + Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_NV, nextShader); + glEnable(GL_FRAGMENT_PROGRAM_NV); +#endif + } + + if (BaseMaterial) + BaseMaterial->OnSetMaterial(material, material, true, services); + } + + //let callback know used material + if (CallBack) + CallBack->OnSetMaterial(material); + + for (u32 i=0; isetActiveTexture(i, material.getTexture(i)); + Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); +} + + +void COpenGLShaderMaterialRenderer::OnUnsetMaterial() +{ + // disable vertex shader +#ifdef GL_ARB_vertex_program + if (VertexShader) + glDisable(GL_VERTEX_PROGRAM_ARB); +#elif defined(GL_NV_vertex_program) + if (VertexShader) + glDisable(GL_VERTEX_PROGRAM_NV); +#endif + +#ifdef GL_ARB_fragment_program + if (PixelShader[0]) + glDisable(GL_FRAGMENT_PROGRAM_ARB); +#elif defined(GL_NV_fragment_program) + if (PixelShader[0]) + glDisable(GL_FRAGMENT_PROGRAM_NV); +#endif + + if (BaseMaterial) + BaseMaterial->OnUnsetMaterial(); +} + + +//! Returns if the material is transparent. +bool COpenGLShaderMaterialRenderer::isTransparent() const +{ + return BaseMaterial ? BaseMaterial->isTransparent() : false; +} + + +// This method needs a properly cleaned error state before the checked instruction is called +bool COpenGLShaderMaterialRenderer::checkError(const irr::c8* type) +{ +#if defined(GL_ARB_vertex_program) || defined(GL_NV_vertex_program) || defined(GL_ARB_fragment_program) || defined(GL_NV_fragment_program) + GLenum g = glGetError(); + if (g == GL_NO_ERROR) + return false; + + core::stringc errString = type; + errString += " compilation failed"; + + errString += " at position "; + GLint errPos=-1; +#if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos ); +#else + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); +#endif + errString += core::stringc(s32(errPos)); + errString += ":\n"; +#if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program) + errString += reinterpret_cast(glGetString(GL_PROGRAM_ERROR_STRING_ARB)); +#else + errString += reinterpret_cast(glGetString(GL_PROGRAM_ERROR_STRING_NV)); +#endif +#else + core::stringc errString("Shaders not supported."); +#endif + os::Printer::log(errString.c_str(), ELL_ERROR); + return true; +} + + +bool COpenGLShaderMaterialRenderer::createPixelShader(const c8* pxsh) +{ + if (!pxsh) + return true; + + const core::stringc inshdr(pxsh); + core::stringc shdr; + const s32 pos = inshdr.find("#_IRR_FOG_MODE_"); + const u32 numShaders = (-1 != pos)?4:1; + + for (u32 i=0; iextGlGenPrograms(1, &PixelShader[i]); +#ifdef GL_ARB_fragment_program + Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_ARB, PixelShader[i]); +#elif defined GL_NV_fragment_program + Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_NV, PixelShader[i]); +#endif + + // clear error buffer + while(glGetError() != GL_NO_ERROR) + {} + +#ifdef GL_ARB_fragment_program + // compile + Driver->extGlProgramString(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + shdr.size(), shdr.c_str()); +#elif defined GL_NV_fragment_program + Driver->extGlLoadProgram(GL_FRAGMENT_PROGRAM_NV, PixelShader[i], + shdr.size(), shdr.c_str()); +#endif + + if (checkError("Pixel shader")) + { + Driver->extGlDeletePrograms(1, &PixelShader[i]); + PixelShader[i]=0; + + return false; + } + } + + return true; +} + + +bool COpenGLShaderMaterialRenderer::createVertexShader(const c8* vtxsh) +{ + if (!vtxsh) + return true; + + Driver->extGlGenPrograms(1, &VertexShader); +#ifdef GL_ARB_vertex_program + Driver->extGlBindProgram(GL_VERTEX_PROGRAM_ARB, VertexShader); +#elif defined GL_NV_vertex_program + Driver->extGlBindProgram(GL_VERTEX_PROGRAM_NV, VertexShader); +#endif + + // clear error buffer + while(glGetError() != GL_NO_ERROR) + {} + + // compile +#ifdef GL_ARB_vertex_program + Driver->extGlProgramString(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + (GLsizei)strlen(vtxsh), vtxsh); +#elif defined GL_NV_vertex_program + Driver->extGlLoadProgram(GL_VERTEX_PROGRAM_NV, VertexShader, + (GLsizei)strlen(vtxsh), vtxsh); +#endif + + if (checkError("Vertex shader")) + { + Driver->extGlDeletePrograms(1, &VertexShader); + VertexShader=0; + + return false; + } + + return true; +} + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.h new file mode 100644 index 0000000..6f5f580 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLShaderMaterialRenderer.h @@ -0,0 +1,97 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPENGL_SHADER_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_OPENGL_SHADER_MATERIAL_RENDERER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 +#else + #define GL_GLEXT_PROTOTYPES 1 +#endif +#ifdef _IRR_WINDOWS_API_ + #define WIN32_LEAN_AND_MEAN + #include + #include +#elif defined(_IRR_OSX_PLATFORM_) + #include +#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + #define NO_SDL_GLEXT + #include + #include +#else + #include +#endif + +#include "IMaterialRenderer.h" + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +class IShaderConstantSetCallBack; +class IMaterialRenderer; + +//! Class for using vertex and pixel shaders with OpenGL +class COpenGLShaderMaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + COpenGLShaderMaterialRenderer(COpenGLDriver* driver, + s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, + IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); + + //! Destructor + virtual ~COpenGLShaderMaterialRenderer(); + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services); + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); + + virtual void OnUnsetMaterial(); + + //! Returns if the material is transparent. + virtual bool isTransparent() const; + +protected: + + //! constructor only for use by derived classes who want to + //! create a fall back material for example. + COpenGLShaderMaterialRenderer(COpenGLDriver* driver, + IShaderConstantSetCallBack* callback, + IMaterialRenderer* baseMaterial, s32 userData=0); + + // must not be called more than once! + void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, + const c8* pixelShaderProgram, E_VERTEX_TYPE type); + + bool createPixelShader(const c8* pxsh); + bool createVertexShader(const c8* vtxsh); + bool checkError(const irr::c8* type); + + COpenGLDriver* Driver; + IShaderConstantSetCallBack* CallBack; + IMaterialRenderer* BaseMaterial; + + GLuint VertexShader; + // We have 4 values here, [0] is the non-fog version, the other three are + // ARB_fog_linear, ARB_fog_exp, and ARB_fog_exp2 in that order + core::array PixelShader; + s32 UserData; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.cpp new file mode 100644 index 0000000..3cc41c0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.cpp @@ -0,0 +1,963 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#include "irrTypes.h" +#include "COpenGLTexture.h" +#include "COpenGLDriver.h" +#include "os.h" +#include "CColorConverter.h" + +#include "irrString.h" + +namespace irr +{ +namespace video +{ + +//! constructor for usual textures +COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mipmapData, COpenGLDriver* driver) + : ITexture(name), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0), + TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), + PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true), + IsRenderTarget(false), AutomaticMipmapUpdate(false), + ReadOnlyLock(false), KeepImage(true) +{ + #ifdef _DEBUG + setDebugName("COpenGLTexture"); + #endif + + HasMipMaps = Driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS); + getImageValues(origImage); + + glGenTextures(1, &TextureName); + + if (ImageSize==TextureSize) + { + Image = Driver->createImage(ColorFormat, ImageSize); + origImage->copyTo(Image); + } + else + { + Image = Driver->createImage(ColorFormat, TextureSize); + // scale texture + origImage->copyToScaling(Image); + } + uploadTexture(true, mipmapData); + if (!KeepImage) + { + Image->drop(); + Image=0; + } +} + + +//! constructor for basic setup (only for derived classes) +COpenGLTexture::COpenGLTexture(const io::path& name, COpenGLDriver* driver) + : ITexture(name), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0), + TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT), + PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), HasMipMaps(true), + MipmapLegacyMode(true), IsRenderTarget(false), AutomaticMipmapUpdate(false), + ReadOnlyLock(false), KeepImage(true) +{ + #ifdef _DEBUG + setDebugName("COpenGLTexture"); + #endif +} + + +//! destructor +COpenGLTexture::~COpenGLTexture() +{ + if (TextureName) + glDeleteTextures(1, &TextureName); + if (Image) + Image->drop(); +} + + +//! Choose best matching color format, based on texture creation flags +ECOLOR_FORMAT COpenGLTexture::getBestColorFormat(ECOLOR_FORMAT format) +{ + ECOLOR_FORMAT destFormat = ECF_A8R8G8B8; + switch (format) + { + case ECF_A1R5G5B5: + if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT)) + destFormat = ECF_A1R5G5B5; + break; + case ECF_R5G6B5: + if (!Driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT)) + destFormat = ECF_A1R5G5B5; + break; + case ECF_A8R8G8B8: + if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) || + Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + destFormat = ECF_A1R5G5B5; + break; + case ECF_R8G8B8: + if (Driver->getTextureCreationFlag(ETCF_ALWAYS_16_BIT) || + Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + destFormat = ECF_A1R5G5B5; + default: + break; + } + if (Driver->getTextureCreationFlag(ETCF_NO_ALPHA_CHANNEL)) + { + switch (destFormat) + { + case ECF_A1R5G5B5: + destFormat = ECF_R5G6B5; + break; + case ECF_A8R8G8B8: + destFormat = ECF_R8G8B8; + break; + default: + break; + } + } + return destFormat; +} + + +//! Get opengl values for the GPU texture storage +GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT format, + GLint& filtering, + GLenum& colorformat, + GLenum& type) +{ + // default + filtering = GL_LINEAR; + colorformat = GL_RGBA; + type = GL_UNSIGNED_BYTE; + GLenum internalformat = GL_RGBA; + + switch(format) + { + case ECF_A1R5G5B5: + colorformat=GL_BGRA_EXT; + type=GL_UNSIGNED_SHORT_1_5_5_5_REV; + internalformat = GL_RGBA; + break; + case ECF_R5G6B5: + colorformat=GL_RGB; + type=GL_UNSIGNED_SHORT_5_6_5; + internalformat = GL_RGB; + break; + case ECF_R8G8B8: + colorformat=GL_BGR; + type=GL_UNSIGNED_BYTE; + internalformat = GL_RGB; + break; + case ECF_A8R8G8B8: + colorformat=GL_BGRA_EXT; + if (Driver->Version > 101) + type=GL_UNSIGNED_INT_8_8_8_8_REV; + internalformat = GL_RGBA; + break; + // Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski. + case ECF_R16F: + { +#ifdef GL_ARB_texture_rg + filtering = GL_NEAREST; + colorformat = GL_RED; + type = GL_FLOAT; + + internalformat = GL_R16F; +#else + ColorFormat = ECF_A8R8G8B8; + internalformat = GL_RGB8; +#endif + } + break; + case ECF_G16R16F: + { +#ifdef GL_ARB_texture_rg + filtering = GL_NEAREST; + colorformat = GL_RG; + type = GL_FLOAT; + + internalformat = GL_RG16F; +#else + ColorFormat = ECF_A8R8G8B8; + internalformat = GL_RGB8; +#endif + } + break; + case ECF_A16B16G16R16F: + { +#ifdef GL_ARB_texture_rg + filtering = GL_NEAREST; + colorformat = GL_RGBA; + type = GL_FLOAT; + + internalformat = GL_RGBA16F_ARB; +#else + ColorFormat = ECF_A8R8G8B8; + internalformat = GL_RGBA8; +#endif + } + break; + case ECF_R32F: + { +#ifdef GL_ARB_texture_rg + filtering = GL_NEAREST; + colorformat = GL_RED; + type = GL_FLOAT; + + internalformat = GL_R32F; +#else + ColorFormat = ECF_A8R8G8B8; + internalformat = GL_RGB8; +#endif + } + break; + case ECF_G32R32F: + { +#ifdef GL_ARB_texture_rg + filtering = GL_NEAREST; + colorformat = GL_RG; + type = GL_FLOAT; + + internalformat = GL_RG32F; +#else + ColorFormat = ECF_A8R8G8B8; + internalformat = GL_RGB8; +#endif + } + break; + case ECF_A32B32G32R32F: + { +#ifdef GL_ARB_texture_float + filtering = GL_NEAREST; + colorformat = GL_RGBA; + type = GL_FLOAT; + + internalformat = GL_RGBA32F_ARB; +#else + ColorFormat = ECF_A8R8G8B8; + internalformat = GL_RGBA8; +#endif + } + break; + default: + { + os::Printer::log("Unsupported texture format", ELL_ERROR); + internalformat = GL_RGBA8; + } + } +#if defined(GL_ARB_framebuffer_sRGB) || defined(GL_EXT_framebuffer_sRGB) + if (Driver->Params.HandleSRGB) + { + if (internalformat==GL_RGBA) + internalformat=GL_SRGB_ALPHA_EXT; + else if (internalformat==GL_RGB) + internalformat=GL_SRGB_EXT; + } +#endif + return internalformat; +} + + +// prepare values ImageSize, TextureSize, and ColorFormat based on image +void COpenGLTexture::getImageValues(IImage* image) +{ + if (!image) + { + os::Printer::log("No image for OpenGL texture.", ELL_ERROR); + return; + } + + ImageSize = image->getDimension(); + + if ( !ImageSize.Width || !ImageSize.Height) + { + os::Printer::log("Invalid size of image for OpenGL Texture.", ELL_ERROR); + return; + } + + const f32 ratio = (f32)ImageSize.Width/(f32)ImageSize.Height; + if ((ImageSize.Width>Driver->MaxTextureSize) && (ratio >= 1.0f)) + { + ImageSize.Width = Driver->MaxTextureSize; + ImageSize.Height = (u32)(Driver->MaxTextureSize/ratio); + } + else if (ImageSize.Height>Driver->MaxTextureSize) + { + ImageSize.Height = Driver->MaxTextureSize; + ImageSize.Width = (u32)(Driver->MaxTextureSize*ratio); + } + TextureSize=ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT)); + + ColorFormat = getBestColorFormat(image->getColorFormat()); +} + + +//! copies the the texture into an open gl texture. +void COpenGLTexture::uploadTexture(bool newTexture, void* mipmapData, u32 level) +{ + // check which image needs to be uploaded + IImage* image = level?MipImage:Image; + if (!image) + { + os::Printer::log("No image for OpenGL texture to upload", ELL_ERROR); + return; + } + + // get correct opengl color data values + GLenum oldInternalFormat = InternalFormat; + GLint filtering; + InternalFormat = getOpenGLFormatAndParametersFromColorFormat(ColorFormat, filtering, PixelFormat, PixelType); + // make sure we don't change the internal format of existing images + if (!newTexture) + InternalFormat=oldInternalFormat; + + Driver->setActiveTexture(0, this); + if (Driver->testGLError()) + os::Printer::log("Could not bind Texture", ELL_ERROR); + + // mipmap handling for main texture + if (!level && newTexture) + { +#ifndef DISABLE_MIPMAPPING +#ifdef GL_SGIS_generate_mipmap + // auto generate if possible and no mipmap data is given + if (HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + { + if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED)) + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST); + else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY)) + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); + else + glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_DONT_CARE); + + AutomaticMipmapUpdate=true; + + if (!Driver->queryFeature(EVDF_FRAMEBUFFER_OBJECT)) + { + glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ); + MipmapLegacyMode=true; + } + else + MipmapLegacyMode=false; + } + else +#endif + { + // Either generate manually due to missing capability + // or use predefined mipmap data + AutomaticMipmapUpdate=false; + regenerateMipMapLevels(mipmapData); + } + if (HasMipMaps) // might have changed in regenerateMipMapLevels + { + // enable bilinear mipmap filter + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else +#else + HasMipMaps=false; + os::Printer::log("Did not create OpenGL texture mip maps.", ELL_INFORMATION); +#endif + { + // enable bilinear filter without mipmaps + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + } + + // now get image data and upload to GPU + void* source = image->lock(); + if (newTexture) + glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width, + image->getDimension().Height, 0, PixelFormat, PixelType, source); + else + glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width, + image->getDimension().Height, PixelFormat, PixelType, source); + image->unlock(); + + if (!MipmapLegacyMode && AutomaticMipmapUpdate) + { + glEnable(GL_TEXTURE_2D); + Driver->extGlGenerateMipmap(GL_TEXTURE_2D); + } + + if (Driver->testGLError()) + os::Printer::log("Could not glTexImage2D", ELL_ERROR); +} + + +//! lock function +void* COpenGLTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) +{ + // store info about which image is locked + IImage* image = (mipmapLevel==0)?Image:MipImage; + ReadOnlyLock |= (mode==ETLM_READ_ONLY); + MipLevelStored = mipmapLevel; + if (!ReadOnlyLock && mipmapLevel) + { +#ifdef GL_SGIS_generate_mipmap + if (Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) + { + // do not automatically generate and update mipmaps + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); + } +#endif + AutomaticMipmapUpdate=false; + } + + // if data not available or might have changed on GPU download it + if (!image || IsRenderTarget) + { + // prepare the data storage if necessary + if (!image) + { + if (mipmapLevel) + { + u32 i=0; + u32 width = TextureSize.Width; + u32 height = TextureSize.Height; + do + { + if (width>1) + width>>=1; + if (height>1) + height>>=1; + ++i; + } + while (i != mipmapLevel); + MipImage = image = Driver->createImage(ECF_A8R8G8B8, core::dimension2du(width,height)); + } + else + Image = image = Driver->createImage(ECF_A8R8G8B8, ImageSize); + ColorFormat = ECF_A8R8G8B8; + } + if (!image) + return 0; + + if (mode != ETLM_WRITE_ONLY) + { + u8* pixels = static_cast(image->lock()); + if (!pixels) + return 0; + + // we need to keep the correct texture bound later on + GLint tmpTexture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmpTexture); + glBindTexture(GL_TEXTURE_2D, TextureName); + + // we need to flip textures vertical + // however, it seems that this does not hold for mipmap + // textures, for unknown reasons. + + // allows to read pixels in top-to-bottom order +#ifdef GL_MESA_pack_invert + if (!mipmapLevel && Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert)) + glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE); +#endif + + // download GPU data as ARGB8 to pixels; + glGetTexImage(GL_TEXTURE_2D, mipmapLevel, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); + + if (!mipmapLevel) + { +#ifdef GL_MESA_pack_invert + if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_MESA_pack_invert)) + glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE); + else +#endif + { + // opengl images are horizontally flipped, so we have to fix that here. + const s32 pitch=image->getPitch(); + u8* p2 = pixels + (image->getDimension().Height - 1) * pitch; + u8* tmpBuffer = new u8[pitch]; + for (u32 i=0; i < image->getDimension().Height; i += 2) + { + memcpy(tmpBuffer, pixels, pitch); + memcpy(pixels, p2, pitch); + memcpy(p2, tmpBuffer, pitch); + pixels += pitch; + p2 -= pitch; + } + delete [] tmpBuffer; + } + } + image->unlock(); + + //reset old bound texture + glBindTexture(GL_TEXTURE_2D, tmpTexture); + } + } + return image->lock(); +} + + +//! unlock function +void COpenGLTexture::unlock() +{ + // test if miplevel or main texture was locked + IImage* image = MipImage?MipImage:Image; + if (!image) + return; + // unlock image to see changes + image->unlock(); + // copy texture data to GPU + if (!ReadOnlyLock) + uploadTexture(false, 0, MipLevelStored); + ReadOnlyLock = false; + // cleanup local image + if (MipImage) + { + MipImage->drop(); + MipImage=0; + } + else if (!KeepImage) + { + Image->drop(); + Image=0; + } + // update information + if (Image) + ColorFormat=Image->getColorFormat(); + else + ColorFormat=ECF_A8R8G8B8; +} + + +//! Returns size of the original image. +const core::dimension2d& COpenGLTexture::getOriginalSize() const +{ + return ImageSize; +} + + +//! Returns size of the texture. +const core::dimension2d& COpenGLTexture::getSize() const +{ + return TextureSize; +} + + +//! returns driver type of texture, i.e. the driver, which created the texture +E_DRIVER_TYPE COpenGLTexture::getDriverType() const +{ + return EDT_OPENGL; +} + + +//! returns color format of texture +ECOLOR_FORMAT COpenGLTexture::getColorFormat() const +{ + return ColorFormat; +} + + +//! returns pitch of texture (in bytes) +u32 COpenGLTexture::getPitch() const +{ + if (Image) + return Image->getPitch(); + else + return 0; +} + + +//! return open gl texture name +GLuint COpenGLTexture::getOpenGLTextureName() const +{ + return TextureName; +} + + +//! Returns whether this texture has mipmaps +bool COpenGLTexture::hasMipMaps() const +{ + return HasMipMaps; +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void COpenGLTexture::regenerateMipMapLevels(void* mipmapData) +{ + if (AutomaticMipmapUpdate || !HasMipMaps || !Image) + return; + if ((Image->getDimension().Width==1) && (Image->getDimension().Height==1)) + return; + + // Manually create mipmaps or use prepared version + u32 width=Image->getDimension().Width; + u32 height=Image->getDimension().Height; + u32 i=0; + u8* target = static_cast(mipmapData); + do + { + if (width>1) + width>>=1; + if (height>1) + height>>=1; + ++i; + if (!target) + target = new u8[width*height*Image->getBytesPerPixel()]; + // create scaled version if no mipdata available + if (!mipmapData) + Image->copyToScaling(target, width, height, Image->getColorFormat()); + glTexImage2D(GL_TEXTURE_2D, i, InternalFormat, width, height, + 0, PixelFormat, PixelType, target); + // get next prepared mipmap data if available + if (mipmapData) + { + mipmapData = static_cast(mipmapData)+width*height*Image->getBytesPerPixel(); + target = static_cast(mipmapData); + } + } + while (width!=1 || height!=1); + // cleanup + if (!mipmapData) + delete [] target; +} + + +bool COpenGLTexture::isRenderTarget() const +{ + return IsRenderTarget; +} + + +void COpenGLTexture::setIsRenderTarget(bool isTarget) +{ + IsRenderTarget = isTarget; +} + + +bool COpenGLTexture::isFrameBufferObject() const +{ + return false; +} + + +//! Bind Render Target Texture +void COpenGLTexture::bindRTT() +{ +} + + +//! Unbind Render Target Texture +void COpenGLTexture::unbindRTT() +{ + Driver->setActiveTexture(0, this); + + // Copy Our ViewPort To The Texture + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSize().Width, getSize().Height); +} + + +/* FBO Textures */ + +// helper function for render to texture +static bool checkFBOStatus(COpenGLDriver* Driver); + +//! RTT ColorFrameBuffer constructor +COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d& size, + const io::path& name, COpenGLDriver* driver, + ECOLOR_FORMAT format) + : COpenGLTexture(name, driver), DepthTexture(0), ColorFrameBuffer(0) +{ + #ifdef _DEBUG + setDebugName("COpenGLTexture_FBO"); + #endif + + ImageSize = size; + TextureSize = size; + + if (ECF_UNKNOWN == format) + format = getBestColorFormat(driver->getColorFormat()); + + ColorFormat = format; + + GLint FilteringType; + InternalFormat = getOpenGLFormatAndParametersFromColorFormat(format, FilteringType, PixelFormat, PixelType); + + HasMipMaps = false; + IsRenderTarget = true; + +#ifdef GL_EXT_framebuffer_object + // generate frame buffer + Driver->extGlGenFramebuffers(1, &ColorFrameBuffer); + bindRTT(); + + // generate color texture + glGenTextures(1, &TextureName); + Driver->setActiveTexture(0, this); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width, + ImageSize.Height, 0, PixelFormat, PixelType, 0); +#ifdef _DEBUG + driver->testGLError(); +#endif + + // attach color texture to frame buffer + Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + TextureName, + 0); +#ifdef _DEBUG + checkFBOStatus(Driver); +#endif + +#endif + unbindRTT(); +} + + +//! destructor +COpenGLFBOTexture::~COpenGLFBOTexture() +{ + if (DepthTexture) + if (DepthTexture->drop()) + Driver->removeDepthTexture(DepthTexture); + if (ColorFrameBuffer) + Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer); +} + + +bool COpenGLFBOTexture::isFrameBufferObject() const +{ + return true; +} + + +//! Bind Render Target Texture +void COpenGLFBOTexture::bindRTT() +{ +#ifdef GL_EXT_framebuffer_object + if (ColorFrameBuffer != 0) + Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer); + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); +#endif +} + + +//! Unbind Render Target Texture +void COpenGLFBOTexture::unbindRTT() +{ +#ifdef GL_EXT_framebuffer_object + if (ColorFrameBuffer != 0) + Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); +#endif +} + + +/* FBO Depth Textures */ + +//! RTT DepthBuffer constructor +COpenGLFBODepthTexture::COpenGLFBODepthTexture( + const core::dimension2d& size, + const io::path& name, + COpenGLDriver* driver, + bool useStencil) + : COpenGLTexture(name, driver), DepthRenderBuffer(0), + StencilRenderBuffer(0), UseStencil(useStencil) +{ +#ifdef _DEBUG + setDebugName("COpenGLTextureFBO_Depth"); +#endif + + ImageSize = size; + TextureSize = size; + InternalFormat = GL_RGBA; + PixelFormat = GL_RGBA; + PixelType = GL_UNSIGNED_BYTE; + HasMipMaps = false; + + if (useStencil) + { + glGenTextures(1, &DepthRenderBuffer); + glBindTexture(GL_TEXTURE_2D, DepthRenderBuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#ifdef GL_EXT_packed_depth_stencil + if (Driver->queryOpenGLFeature(COpenGLExtensionHandler::IRR_EXT_packed_depth_stencil)) + { + // generate packed depth stencil texture + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_EXT, ImageSize.Width, + ImageSize.Height, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0); + StencilRenderBuffer = DepthRenderBuffer; // stencil is packed with depth + } + else // generate separate stencil and depth textures +#endif + { + // generate depth texture + glTexImage2D(GL_TEXTURE_2D, 0, Driver->getZBufferBits(), ImageSize.Width, + ImageSize.Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); + + // generate stencil texture + glGenTextures(1, &StencilRenderBuffer); + glBindTexture(GL_TEXTURE_2D, StencilRenderBuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX, ImageSize.Width, + ImageSize.Height, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 0); + } + } +#ifdef GL_EXT_framebuffer_object + else + { + // generate depth buffer + Driver->extGlGenRenderbuffers(1, &DepthRenderBuffer); + Driver->extGlBindRenderbuffer(GL_RENDERBUFFER_EXT, DepthRenderBuffer); + Driver->extGlRenderbufferStorage(GL_RENDERBUFFER_EXT, + Driver->getZBufferBits(), ImageSize.Width, + ImageSize.Height); + } +#endif +} + + +//! destructor +COpenGLFBODepthTexture::~COpenGLFBODepthTexture() +{ + if (DepthRenderBuffer && UseStencil) + glDeleteTextures(1, &DepthRenderBuffer); + else + Driver->extGlDeleteRenderbuffers(1, &DepthRenderBuffer); + if (StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer) + glDeleteTextures(1, &StencilRenderBuffer); +} + + +//combine depth texture and rtt +bool COpenGLFBODepthTexture::attach(ITexture* renderTex) +{ + if (!renderTex) + return false; + video::COpenGLFBOTexture* rtt = static_cast(renderTex); + rtt->bindRTT(); +#ifdef GL_EXT_framebuffer_object + if (UseStencil) + { + // attach stencil texture to stencil buffer + Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_TEXTURE_2D, + StencilRenderBuffer, + 0); + + // attach depth texture to depth buffer + Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_TEXTURE_2D, + DepthRenderBuffer, + 0); + } + else + { + // attach depth renderbuffer to depth buffer + Driver->extGlFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + DepthRenderBuffer); + } +#endif + // check the status + if (!checkFBOStatus(Driver)) + { + os::Printer::log("FBO incomplete"); + return false; + } + rtt->DepthTexture=this; + grab(); // grab the depth buffer, not the RTT + rtt->unbindRTT(); + return true; +} + + +//! Bind Render Target Texture +void COpenGLFBODepthTexture::bindRTT() +{ +} + + +//! Unbind Render Target Texture +void COpenGLFBODepthTexture::unbindRTT() +{ +} + + +bool checkFBOStatus(COpenGLDriver* Driver) +{ +#ifdef GL_EXT_framebuffer_object + GLenum status = Driver->extGlCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + + switch (status) + { + //Our FBO is perfect, return true + case GL_FRAMEBUFFER_COMPLETE_EXT: + return true; + + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + os::Printer::log("FBO has invalid read buffer", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + os::Printer::log("FBO has invalid draw buffer", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + os::Printer::log("FBO has one or several incomplete image attachments", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + os::Printer::log("FBO has one or several image attachments with different internal formats", ELL_ERROR); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + os::Printer::log("FBO has one or several image attachments with different dimensions", ELL_ERROR); + break; + +// not part of fbo_object anymore, but won't harm as it is just a return value +#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT + case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: + os::Printer::log("FBO has a duplicate image attachment", ELL_ERROR); + break; +#endif + + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + os::Printer::log("FBO missing an image attachment", ELL_ERROR); + break; + +#ifdef GL_EXT_framebuffer_multisample + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: + os::Printer::log("FBO wrong multisample setup", ELL_ERROR); + break; +#endif + + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + os::Printer::log("FBO format unsupported", ELL_ERROR); + break; + + default: + break; + } +#endif + os::Printer::log("FBO error", ELL_ERROR); +// _IRR_DEBUG_BREAK_IF(true); + return false; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_OPENGL_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.h b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.h new file mode 100644 index 0000000..1fd4ca2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/COpenGLTexture.h @@ -0,0 +1,205 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OPEN_GL_TEXTURE_H_INCLUDED__ +#define __C_OPEN_GL_TEXTURE_H_INCLUDED__ + +#include "ITexture.h" +#include "IImage.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_OPENGL_ + +#if defined(_IRR_OPENGL_USE_EXTPOINTER_) + #define GL_GLEXT_LEGACY 1 +#else + #define GL_GLEXT_PROTOTYPES 1 +#endif +#ifdef _IRR_WINDOWS_API_ + // include windows headers for HWND + #define WIN32_LEAN_AND_MEAN + #include + #include +#ifdef _MSC_VER + #pragma comment(lib, "OpenGL32.lib") +#endif +#elif defined(_IRR_OSX_PLATFORM_) + #include +#elif defined(_IRR_COMPILE_WITH_SDL_DEVICE_) + #define NO_SDL_GLEXT + #include + #include +#else + #if defined(_IRR_OSX_PLATFORM_) + #include + #else + #include + #endif +#endif + + +namespace irr +{ +namespace video +{ + +class COpenGLDriver; +//! OpenGL texture. +class COpenGLTexture : public ITexture +{ +public: + + //! constructor + COpenGLTexture(IImage* surface, const io::path& name, void* mipmapData=0, COpenGLDriver* driver=0); + + //! destructor + virtual ~COpenGLTexture(); + + //! lock function + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture (image). + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns size of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns driver type of texture (=the driver, that created it) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! return open gl texture name + GLuint getOpenGLTextureName() const; + + //! return whether this texture has mipmaps + virtual bool hasMipMaps() const; + + //! Regenerates the mip map levels of the texture. + /** Useful after locking and modifying the texture + \param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image. If not set the mipmaps are derived from the main image. */ + virtual void regenerateMipMapLevels(void* mipmapData=0); + + //! Is it a render target? + virtual bool isRenderTarget() const; + + //! Is it a FrameBufferObject? + virtual bool isFrameBufferObject() const; + + //! Bind RenderTargetTexture + virtual void bindRTT(); + + //! Unbind RenderTargetTexture + virtual void unbindRTT(); + + //! sets whether this texture is intended to be used as a render target. + void setIsRenderTarget(bool isTarget); + +protected: + + //! protected constructor with basic setup, no GL texture name created, for derived classes + COpenGLTexture(const io::path& name, COpenGLDriver* driver); + + //! get the desired color format based on texture creation flags and the input format. + ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format); + + //! Get the OpenGL color format parameters based on the given Irrlicht color format + GLint getOpenGLFormatAndParametersFromColorFormat( + ECOLOR_FORMAT format, GLint& filtering, GLenum& colorformat, GLenum& type); + + //! get important numbers of the image and hw texture + void getImageValues(IImage* image); + + //! copies the texture into an OpenGL texture. + /** \param newTexture True if method is called for a newly created texture for the first time. Otherwise call with false to improve memory handling. + \param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image. + \param mipLevel If set to non-zero, only that specific miplevel is updated, using the MipImage member. */ + void uploadTexture(bool newTexture=false, void* mipmapData=0, u32 mipLevel=0); + + core::dimension2d ImageSize; + core::dimension2d TextureSize; + ECOLOR_FORMAT ColorFormat; + COpenGLDriver* Driver; + IImage* Image; + IImage* MipImage; + + GLuint TextureName; + GLint InternalFormat; + GLenum PixelFormat; + GLenum PixelType; + + u8 MipLevelStored; + bool HasMipMaps; + bool MipmapLegacyMode; + bool IsRenderTarget; + bool AutomaticMipmapUpdate; + bool ReadOnlyLock; + bool KeepImage; +}; + +//! OpenGL FBO texture. +class COpenGLFBOTexture : public COpenGLTexture +{ +public: + + //! FrameBufferObject constructor + COpenGLFBOTexture(const core::dimension2d& size, const io::path& name, + COpenGLDriver* driver = 0, ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! destructor + virtual ~COpenGLFBOTexture(); + + //! Is it a FrameBufferObject? + virtual bool isFrameBufferObject() const; + + //! Bind RenderTargetTexture + virtual void bindRTT(); + + //! Unbind RenderTargetTexture + virtual void unbindRTT(); + + ITexture* DepthTexture; +protected: + GLuint ColorFrameBuffer; +}; + + +//! OpenGL FBO depth texture. +class COpenGLFBODepthTexture : public COpenGLTexture +{ +public: + //! FrameBufferObject depth constructor + COpenGLFBODepthTexture(const core::dimension2d& size, const io::path& name, COpenGLDriver* driver=0, bool useStencil=false); + + //! destructor + virtual ~COpenGLFBODepthTexture(); + + //! Bind RenderTargetTexture + virtual void bindRTT(); + + //! Unbind RenderTargetTexture + virtual void unbindRTT(); + + bool attach(ITexture*); + +protected: + GLuint DepthRenderBuffer; + GLuint StencilRenderBuffer; + bool UseStencil; +}; + + +} // end namespace video +} // end namespace irr + +#endif +#endif // _IRR_COMPILE_WITH_OPENGL_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.cpp new file mode 100644 index 0000000..1ef4946 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.cpp @@ -0,0 +1,817 @@ +// Copyright (C) 2009-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_PLY_LOADER_ + +#include "CPLYMeshFileLoader.h" +#include "IMeshManipulator.h" +#include "SMesh.h" +#include "CDynamicMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "fast_atof.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +// input buffer must be at least twice as long as the longest line in the file +#define PLY_INPUT_BUFFER_SIZE 51200 // file is loaded in 50k chunks + +// constructor +CPLYMeshFileLoader::CPLYMeshFileLoader(scene::ISceneManager* smgr) +: SceneManager(smgr), File(0), Buffer(0) +{ +} + + +CPLYMeshFileLoader::~CPLYMeshFileLoader() +{ + // delete the buffer in case we didn't earlier + // (we do, but this could be disabled to increase the speed of loading hundreds of meshes) + if (Buffer) + { + delete [] Buffer; + Buffer = 0; + } + + // Destroy the element list if it exists + for (u32 i=0; igrab(); + + // attempt to allocate the buffer and fill with data + if (!allocateBuffer()) + { + File->drop(); + File = 0; + return 0; + } + + // start with empty mesh + SAnimatedMesh* animMesh = 0; + u32 vertCount=0; + + // Currently only supports ASCII meshes + if (strcmp(getNextLine(), "ply")) + { + os::Printer::log("Not a valid PLY file", file->getFileName().c_str(), ELL_ERROR); + } + else + { + // cut the next line out + getNextLine(); + // grab the word from this line + c8 *word = getNextWord(); + + // ignore comments + while (strcmp(word, "comment") == 0) + { + getNextLine(); + word = getNextWord(); + } + + bool readingHeader = true; + bool continueReading = true; + IsBinaryFile = false; + IsWrongEndian= false; + + do + { + if (strcmp(word, "format") == 0) + { + word = getNextWord(); + + if (strcmp(word, "binary_little_endian") == 0) + { + IsBinaryFile = true; +#ifdef __BIG_ENDIAN__ + IsWrongEndian = true; +#endif + + } + else if (strcmp(word, "binary_big_endian") == 0) + { + IsBinaryFile = true; +#ifndef __BIG_ENDIAN__ + IsWrongEndian = true; +#endif + } + else if (strcmp(word, "ascii")) + { + // abort if this isn't an ascii or a binary mesh + os::Printer::log("Unsupported PLY mesh format", word, ELL_ERROR); + continueReading = false; + } + + if (continueReading) + { + word = getNextWord(); + if (strcmp(word, "1.0")) + { + os::Printer::log("Unsupported PLY mesh version", word, ELL_WARNING); + } + } + } + else if (strcmp(word, "property") == 0) + { + word = getNextWord(); + + if (!ElementList.size()) + { + os::Printer::log("PLY property found before element", word, ELL_WARNING); + } + else + { + // get element + SPLYElement* el = ElementList[ElementList.size()-1]; + + // fill property struct + SPLYProperty prop; + prop.Type = getPropertyType(word); + el->KnownSize += prop.size(); + + if (prop.Type == EPLYPT_LIST) + { + el->IsFixedWidth = false; + + word = getNextWord(); + + prop.Data.List.CountType = getPropertyType(word); + if (IsBinaryFile && prop.Data.List.CountType == EPLYPT_UNKNOWN) + { + os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR); + continueReading = false; + } + else + { + word = getNextWord(); + prop.Data.List.ItemType = getPropertyType(word); + if (IsBinaryFile && prop.Data.List.ItemType == EPLYPT_UNKNOWN) + { + os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR); + continueReading = false; + } + } + } + else if (IsBinaryFile && prop.Type == EPLYPT_UNKNOWN) + { + os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR); + continueReading = false; + } + + prop.Name = getNextWord(); + + // add property to element + el->Properties.push_back(prop); + } + } + else if (strcmp(word, "element") == 0) + { + SPLYElement* el = new SPLYElement; + el->Name = getNextWord(); + el->Count = atoi(getNextWord()); + el->IsFixedWidth = true; + el->KnownSize = 0; + ElementList.push_back(el); + + if (el->Name == "vertex") + vertCount = el->Count; + + } + else if (strcmp(word, "end_header") == 0) + { + readingHeader = false; + if (IsBinaryFile) + { + StartPointer = LineEndPointer + 1; + } + } + else if (strcmp(word, "comment") == 0) + { + // ignore line + } + else + { + os::Printer::log("Unknown item in PLY file", word, ELL_WARNING); + } + + if (readingHeader && continueReading) + { + getNextLine(); + word = getNextWord(); + } + } + while (readingHeader && continueReading); + + // now to read the actual data from the file + if (continueReading) + { + // create a mesh buffer + CDynamicMeshBuffer *mb = new CDynamicMeshBuffer(video::EVT_STANDARD, vertCount > 65565 ? video::EIT_32BIT : video::EIT_16BIT); + mb->getVertexBuffer().reallocate(vertCount); + mb->getIndexBuffer().reallocate(vertCount); + mb->setHardwareMappingHint(EHM_STATIC); + + bool hasNormals=true; + // loop through each of the elements + for (u32 i=0; iName == "vertex") + { + // loop through vertex properties + for (u32 j=0; j < ElementList[i]->Count; ++j) + hasNormals &= readVertex(*ElementList[i], mb); + } + else if (ElementList[i]->Name == "face") + { + // read faces + for (u32 j=0; j < ElementList[i]->Count; ++j) + readFace(*ElementList[i], mb); + } + else + { + // skip these elements + for (u32 j=0; j < ElementList[i]->Count; ++j) + skipElement(*ElementList[i]); + } + } + mb->recalculateBoundingBox(); + if (!hasNormals) + SceneManager->getMeshManipulator()->recalculateNormals(mb); + SMesh* m = new SMesh(); + m->addMeshBuffer(mb); + m->recalculateBoundingBox(); + mb->drop(); + animMesh = new SAnimatedMesh(); + animMesh->addMesh(m); + animMesh->recalculateBoundingBox(); + m->drop(); + } + } + + + // free the buffer + delete [] Buffer; + Buffer = 0; + File->drop(); + File = 0; + + // if we managed to create a mesh, return it + return animMesh; +} + + +bool CPLYMeshFileLoader::readVertex(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb) +{ + if (!IsBinaryFile) + getNextLine(); + + video::S3DVertex vert; + vert.Color.set(255,255,255,255); + vert.TCoords.X = 0.0f; + vert.TCoords.Y = 0.0f; + vert.Normal.X = 0.0f; + vert.Normal.Y = 1.0f; + vert.Normal.Z = 0.0f; + + bool result=false; + for (u32 i=0; i < Element.Properties.size(); ++i) + { + E_PLY_PROPERTY_TYPE t = Element.Properties[i].Type; + + if (Element.Properties[i].Name == "x") + vert.Pos.X = getFloat(t); + else if (Element.Properties[i].Name == "y") + vert.Pos.Z = getFloat(t); + else if (Element.Properties[i].Name == "z") + vert.Pos.Y = getFloat(t); + else if (Element.Properties[i].Name == "nx") + { + vert.Normal.X = getFloat(t); + result=true; + } + else if (Element.Properties[i].Name == "ny") + { + vert.Normal.Z = getFloat(t); + result=true; + } + else if (Element.Properties[i].Name == "nz") + { + vert.Normal.Y = getFloat(t); + result=true; + } + else if (Element.Properties[i].Name == "u") + vert.TCoords.X = getFloat(t); + else if (Element.Properties[i].Name == "v") + vert.TCoords.Y = getFloat(t); + else if (Element.Properties[i].Name == "red") + { + u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t); + vert.Color.setRed(value); + } + else if (Element.Properties[i].Name == "green") + { + u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t); + vert.Color.setGreen(value); + } + else if (Element.Properties[i].Name == "blue") + { + u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t); + vert.Color.setBlue(value); + } + else if (Element.Properties[i].Name == "alpha") + { + u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t); + vert.Color.setAlpha(value); + } + else + skipProperty(Element.Properties[i]); + } + + mb->getVertexBuffer().push_back(vert); + + return result; +} + + +bool CPLYMeshFileLoader::readFace(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb) +{ + if (!IsBinaryFile) + getNextLine(); + + for (u32 i=0; i < Element.Properties.size(); ++i) + { + if ( (Element.Properties[i].Name == "vertex_indices" || + Element.Properties[i].Name == "vertex_index") && Element.Properties[i].Type == EPLYPT_LIST) + { + // get count + s32 count = getInt(Element.Properties[i].Data.List.CountType); + u32 a = getInt(Element.Properties[i].Data.List.ItemType), + b = getInt(Element.Properties[i].Data.List.ItemType), + c = getInt(Element.Properties[i].Data.List.ItemType); + s32 j = 3; + + mb->getIndexBuffer().push_back(a); + mb->getIndexBuffer().push_back(c); + mb->getIndexBuffer().push_back(b); + + for (; j < count; ++j) + { + b = c; + c = getInt(Element.Properties[i].Data.List.ItemType); + mb->getIndexBuffer().push_back(a); + mb->getIndexBuffer().push_back(c); + mb->getIndexBuffer().push_back(b); + } + } + else if (Element.Properties[i].Name == "intensity") + { + // todo: face intensity + skipProperty(Element.Properties[i]); + } + else + skipProperty(Element.Properties[i]); + } + return true; +} + + +// skips an element and all properties. return false on EOF +void CPLYMeshFileLoader::skipElement(const SPLYElement &Element) +{ + if (IsBinaryFile) + if (Element.IsFixedWidth) + moveForward(Element.KnownSize); + else + for (u32 i=0; i < Element.Properties.size(); ++i) + skipProperty(Element.Properties[i]); + else + getNextLine(); +} + + +void CPLYMeshFileLoader::skipProperty(const SPLYProperty &Property) +{ + if (Property.Type == EPLYPT_LIST) + { + s32 count = getInt(Property.Data.List.CountType); + + for (s32 i=0; i < count; ++i) + getInt(Property.Data.List.CountType); + } + else + { + if (IsBinaryFile) + moveForward(Property.size()); + else + getNextWord(); + } +} + + +bool CPLYMeshFileLoader::allocateBuffer() +{ + // Destroy the element list if it exists + for (u32 i=0; igetPos() == File->getSize()) + { + EndOfFile = true; + } + else + { + // read data from the file + u32 count = File->read(EndPointer, PLY_INPUT_BUFFER_SIZE - length); + + // increment the end pointer by the number of bytes read + EndPointer = EndPointer + count; + + // if we didn't completely fill the buffer + if (count != PLY_INPUT_BUFFER_SIZE - length) + { + // blank the rest of the memory + memset(EndPointer, 0, Buffer + PLY_INPUT_BUFFER_SIZE - EndPointer); + + // end of file + EndOfFile = true; + } + } +} + + +// skips x bytes in the file, getting more data if required +void CPLYMeshFileLoader::moveForward(u32 bytes) +{ + if (StartPointer + bytes >= EndPointer) + fillBuffer(); + if (StartPointer + bytes < EndPointer) + StartPointer += bytes; + else + StartPointer = EndPointer; +} + + +E_PLY_PROPERTY_TYPE CPLYMeshFileLoader::getPropertyType(const c8* typeString) const +{ + if (strcmp(typeString, "char") == 0 || + strcmp(typeString, "uchar") == 0 || + strcmp(typeString, "int8") == 0 || + strcmp(typeString, "uint8") == 0) + { + return EPLYPT_INT8; + } + else if (strcmp(typeString, "uint") == 0 || + strcmp(typeString, "int16") == 0 || + strcmp(typeString, "uint16") == 0 || + strcmp(typeString, "short") == 0 || + strcmp(typeString, "ushort") == 0) + { + return EPLYPT_INT16; + } + else if (strcmp(typeString, "int") == 0 || + strcmp(typeString, "long") == 0 || + strcmp(typeString, "ulong") == 0 || + strcmp(typeString, "int32") == 0 || + strcmp(typeString, "uint32") == 0) + { + return EPLYPT_INT32; + } + else if (strcmp(typeString, "float") == 0 || + strcmp(typeString, "float32") == 0) + { + return EPLYPT_FLOAT32; + } + else if (strcmp(typeString, "float64") == 0 || + strcmp(typeString, "double") == 0) + { + return EPLYPT_FLOAT64; + } + else if ( strcmp(typeString, "list") == 0 ) + { + return EPLYPT_LIST; + } + else + { + // unsupported type. + // cannot be loaded in binary mode + return EPLYPT_UNKNOWN; + } +} + + +// Split the string data into a line in place by terminating it instead of copying. +c8* CPLYMeshFileLoader::getNextLine() +{ + // move the start pointer along + StartPointer = LineEndPointer + 1; + + // crlf split across buffer move + if (*StartPointer == '\n') + { + *StartPointer = '\0'; + ++StartPointer; + } + + // begin at the start of the next line + c8* pos = StartPointer; + while (pos < EndPointer && *pos && *pos != '\r' && *pos != '\n') + ++pos; + + if ( pos < EndPointer && ( *(pos+1) == '\r' || *(pos+1) == '\n') ) + { + *pos = '\0'; + ++pos; + } + + // we have reached the end of the buffer + if (pos >= EndPointer) + { + // get data from the file + if (!EndOfFile) + { + fillBuffer(); + // reset line end pointer + LineEndPointer = StartPointer - 1; + + if (StartPointer != EndPointer) + return getNextLine(); + else + return Buffer; + } + else + { + // EOF + StartPointer = EndPointer-1; + *StartPointer = '\0'; + return StartPointer; + } + } + else + { + // null terminate the string in place + *pos = '\0'; + LineEndPointer = pos; + WordLength = -1; + // return pointer to the start of the line + return StartPointer; + } +} + + +// null terminate the next word on the previous line and move the next word pointer along +// since we already have a full line in the buffer, we never need to retrieve more data +c8* CPLYMeshFileLoader::getNextWord() +{ + // move the start pointer along + StartPointer += WordLength + 1; + + if (StartPointer == LineEndPointer) + { + WordLength = -1; // + return LineEndPointer; + } + // begin at the start of the next word + c8* pos = StartPointer; + while (*pos && pos < LineEndPointer && pos < EndPointer && *pos != ' ' && *pos != '\t') + ++pos; + + while(*pos && pos < LineEndPointer && pos < EndPointer && (*pos == ' ' || *pos == '\t') ) + { + // null terminate the string in place + *pos = '\0'; + ++pos; + } + --pos; + WordLength = (s32)(pos-StartPointer); + // return pointer to the start of the word + return StartPointer; +} + + +// read the next float from the file and move the start pointer along +f32 CPLYMeshFileLoader::getFloat(E_PLY_PROPERTY_TYPE t) +{ + f32 retVal = 0.0f; + + if (IsBinaryFile) + { + if (EndPointer - StartPointer < 8) + fillBuffer(); + + if (EndPointer - StartPointer > 0) + { + switch (t) + { + case EPLYPT_INT8: + retVal = *StartPointer; + StartPointer++; + break; + case EPLYPT_INT16: + if (IsWrongEndian) + retVal = os::Byteswap::byteswap(*(reinterpret_cast(StartPointer))); + else + retVal = *(reinterpret_cast(StartPointer)); + StartPointer += 2; + break; + case EPLYPT_INT32: + if (IsWrongEndian) + retVal = f32(os::Byteswap::byteswap(*(reinterpret_cast(StartPointer)))); + else + retVal = f32(*(reinterpret_cast(StartPointer))); + StartPointer += 4; + break; + case EPLYPT_FLOAT32: + if (IsWrongEndian) + retVal = os::Byteswap::byteswap(*(reinterpret_cast(StartPointer))); + else + retVal = *(reinterpret_cast(StartPointer)); + StartPointer += 4; + break; + case EPLYPT_FLOAT64: + // todo: byteswap 64-bit + retVal = f32(*(reinterpret_cast(StartPointer))); + StartPointer += 8; + break; + case EPLYPT_LIST: + case EPLYPT_UNKNOWN: + default: + retVal = 0.0f; + StartPointer++; // ouch! + } + } + else + retVal = 0.0f; + } + else + { + c8* word = getNextWord(); + switch (t) + { + case EPLYPT_INT8: + case EPLYPT_INT16: + case EPLYPT_INT32: + retVal = f32(atoi(word)); + break; + case EPLYPT_FLOAT32: + case EPLYPT_FLOAT64: + retVal = f32(atof(word)); + break; + case EPLYPT_LIST: + case EPLYPT_UNKNOWN: + default: + retVal = 0.0f; + } + } + return retVal; +} + + +// read the next int from the file and move the start pointer along +u32 CPLYMeshFileLoader::getInt(E_PLY_PROPERTY_TYPE t) +{ + u32 retVal = 0; + + if (IsBinaryFile) + { + if (!EndOfFile && EndPointer - StartPointer < 8) + fillBuffer(); + + if (EndPointer - StartPointer) + { + switch (t) + { + case EPLYPT_INT8: + retVal = *StartPointer; + StartPointer++; + break; + case EPLYPT_INT16: + if (IsWrongEndian) + retVal = os::Byteswap::byteswap(*(reinterpret_cast(StartPointer))); + else + retVal = *(reinterpret_cast(StartPointer)); + StartPointer += 2; + break; + case EPLYPT_INT32: + if (IsWrongEndian) + retVal = os::Byteswap::byteswap(*(reinterpret_cast(StartPointer))); + else + retVal = *(reinterpret_cast(StartPointer)); + StartPointer += 4; + break; + case EPLYPT_FLOAT32: + if (IsWrongEndian) + retVal = (u32)os::Byteswap::byteswap(*(reinterpret_cast(StartPointer))); + else + retVal = (u32)(*(reinterpret_cast(StartPointer))); + StartPointer += 4; + break; + case EPLYPT_FLOAT64: + // todo: byteswap 64-bit + retVal = (u32)(*(reinterpret_cast(StartPointer))); + StartPointer += 8; + break; + case EPLYPT_LIST: + case EPLYPT_UNKNOWN: + default: + retVal = 0; + StartPointer++; // ouch! + } + } + else + retVal = 0; + } + else + { + c8* word = getNextWord(); + switch (t) + { + case EPLYPT_INT8: + case EPLYPT_INT16: + case EPLYPT_INT32: + retVal = atoi(word); + break; + case EPLYPT_FLOAT32: + case EPLYPT_FLOAT64: + retVal = u32(atof(word)); + break; + case EPLYPT_LIST: + case EPLYPT_UNKNOWN: + default: + retVal = 0; + } + } + return retVal; +} + + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_PLY_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.h new file mode 100644 index 0000000..d916863 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshFileLoader.h @@ -0,0 +1,148 @@ +// Copyright (C) 2009-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PLY_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_PLY_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "ISceneManager.h" +#include "CDynamicMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +enum E_PLY_PROPERTY_TYPE +{ + EPLYPT_INT8 = 0, + EPLYPT_INT16, + EPLYPT_INT32, + EPLYPT_FLOAT32, + EPLYPT_FLOAT64, + EPLYPT_LIST, + EPLYPT_UNKNOWN +}; + +//! Meshloader capable of loading obj meshes. +class CPLYMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CPLYMeshFileLoader(scene::ISceneManager* smgr); + + //! Destructor + virtual ~CPLYMeshFileLoader(); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".ply") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + struct SPLYProperty + { + core::stringc Name; + E_PLY_PROPERTY_TYPE Type; + union + { + u8 Int8; + u16 Int16; + u32 Int32; + f32 Float32; + f64 Double; + struct SPLYListProperty + { + E_PLY_PROPERTY_TYPE CountType; + E_PLY_PROPERTY_TYPE ItemType; + } List; + + } Data; + + inline u32 size() const + { + switch(Type) + { + case EPLYPT_INT8: + return 1; + case EPLYPT_INT16: + return 2; + case EPLYPT_INT32: + case EPLYPT_FLOAT32: + return 4; + case EPLYPT_FLOAT64: + return 8; + case EPLYPT_LIST: + case EPLYPT_UNKNOWN: + default: + return 0; + } + } + + inline bool isFloat() const + { + switch(Type) + { + case EPLYPT_FLOAT32: + case EPLYPT_FLOAT64: + return true; + case EPLYPT_INT8: + case EPLYPT_INT16: + case EPLYPT_INT32: + case EPLYPT_LIST: + case EPLYPT_UNKNOWN: + default: + return false; + } + } + }; + + struct SPLYElement + { + // name of the element. We only want "vertex" and "face" elements + // but we have to parse the others anyway. + core::stringc Name; + // The number of elements in the file + u32 Count; + // Properties of this element + core::array Properties; + // in binary files, true if this is a fixed size + bool IsFixedWidth; + // known size in bytes, 0 if unknown + u32 KnownSize; + }; + + bool allocateBuffer(); + c8* getNextLine(); + c8* getNextWord(); + void fillBuffer(); + E_PLY_PROPERTY_TYPE getPropertyType(const c8* typeString) const; + + bool readVertex(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb); + bool readFace(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb); + void skipElement(const SPLYElement &Element); + void skipProperty(const SPLYProperty &Property); + f32 getFloat(E_PLY_PROPERTY_TYPE t); + u32 getInt(E_PLY_PROPERTY_TYPE t); + void moveForward(u32 bytes); + + core::array ElementList; + + scene::ISceneManager* SceneManager; + io::IReadFile *File; + c8 *Buffer; + bool IsBinaryFile, IsWrongEndian, EndOfFile; + s32 LineLength, WordLength; + c8 *StartPointer, *EndPointer, *LineEndPointer; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.cpp new file mode 100644 index 0000000..c9f05c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.cpp @@ -0,0 +1,183 @@ +// Copyright (C) 2008-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_PLY_WRITER_ + +#include "CPLYMeshWriter.h" +#include "os.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IWriteFile.h" + +namespace irr +{ +namespace scene +{ + +CPLYMeshWriter::CPLYMeshWriter() +{ + #ifdef _DEBUG + setDebugName("CPLYMeshWriter"); + #endif +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CPLYMeshWriter::getType() const +{ + return EMWT_PLY; +} + +//! writes a mesh +bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file || !mesh) + return false; + + os::Printer::log("Writing mesh", file->getFileName()); + + // write PLY header + core::stringc header = + "ply\n" + "format ascii 1.0\n" + "comment Irrlicht Engine "; + header += IRRLICHT_SDK_VERSION; + + // get vertex and triangle counts + u32 VertexCount = 0; + u32 TriangleCount = 0; + + for (u32 i=0; i < mesh->getMeshBufferCount(); ++i) + { + VertexCount += mesh->getMeshBuffer(i)->getVertexCount(); + TriangleCount += mesh->getMeshBuffer(i)->getIndexCount() / 3; + } + + // vertex definition + header += "\nelement vertex "; + header += VertexCount; + + header += "\n" + "property float x\n" + "property float y\n" + "property float z\n" + "property float nx\n" + "property float ny\n" + "property float nz\n"; + // todo: writer flags for extended (r,g,b,u,v) and non-standard (alpha,u1,uv,tx,ty,tz) properties + // "property uchar red\n" + // "property uchar green\n" + // "property uchar blue\n" + // "property uchar alpha\n" + // "property float u\n" + // "property float v\n"; + // "property float u1\n + // "property float v1\n" + // "property float tx\n" + // "property float ty\n" + // "property float tz\n" + + // face definition + + header += "element face "; + header += TriangleCount; + header += "\n" + "property list uchar int vertex_indices\n" + "end_header\n"; + + // write header + file->write(header.c_str(), header.size()); + + // write vertices + + c8 outLine[1024]; + + for (u32 i=0; i < mesh->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = mesh->getMeshBuffer(i); + for (u32 j=0; j < mb->getVertexCount(); ++j) + { + const core::vector3df& pos = mb->getPosition(j); + const core::vector3df& n = mb->getNormal(j); +// const core::vector2df& tc = mb->getTCoords(j); + + u8 *buf = (u8*)mb->getVertices(); + switch(mb->getVertexType()) + { + case video::EVT_STANDARD: + buf += sizeof(video::S3DVertex)*j; + break; + case video::EVT_2TCOORDS: + buf += sizeof(video::S3DVertex2TCoords)*j; + break; + case video::EVT_TANGENTS: + buf += sizeof(video::S3DVertexTangents)*j; + break; + } +// video::SColor &col = ( (video::S3DVertex*)buf )->Color; + + // x y z nx ny nz red green blue alpha u v [u1 v1 | tx ty tz]\n + snprintf(outLine, 1024, + "%f %f %f %f %f %f\n",// %u %u %u %u %f %f\n", + pos.X, pos.Z, pos.Y, // Y and Z are flipped + n.X, n.Z, n.Y); + /*col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha(), + tc.X, tc.Y);*/ + + // write the line + file->write(outLine, strlen(outLine)); + } + } + + // index of the first vertex in the current mesh buffer + u32 StartOffset = 0; + + // write triangles + for (u32 i=0; i < mesh->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = mesh->getMeshBuffer(i); + for (u32 j=0; j < mb->getIndexCount(); j+=3) + { + // y and z are flipped so triangles are reversed + u32 a=StartOffset, + b=StartOffset, + c=StartOffset; + + switch(mb->getIndexType()) + { + case video::EIT_16BIT: + a += mb->getIndices()[j+0]; + c += mb->getIndices()[j+1]; + b += mb->getIndices()[j+2]; + break; + case video::EIT_32BIT: + a += ((u32*)mb->getIndices()) [j+0]; + c += ((u32*)mb->getIndices()) [j+0]; + b += ((u32*)mb->getIndices()) [j+0]; + break; + } + + // count a b c\n + snprintf(outLine, 1024, "3 %u %u %u\n", a, b, c); + // write the line + file->write(outLine, strlen(outLine)); + } + + // increment offset + StartOffset += mb->getVertexCount(); + } + + // all done! + + + return true; +} + +} // end namespace +} // end namespace + +#endif // _IRR_COMPILE_WITH_PLY_WRITER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.h new file mode 100644 index 0000000..79c2450 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPLYMeshWriter.h @@ -0,0 +1,35 @@ +// Copyright (C) 2009-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_PLY_MESH_WRITER_H_INCLUDED__ +#define __IRR_PLY_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" + +namespace irr +{ + +namespace scene +{ + class IMeshBuffer; + + //! class to write PLY mesh files + class CPLYMeshWriter : public IMeshWriter + { + public: + + CPLYMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + }; + +} // end namespace +} // end namespace + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp new file mode 100644 index 0000000..7b96842 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp @@ -0,0 +1,196 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code contributed by skreamz + +#include "CPakReader.h" + +#ifdef __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ + +#include "os.h" +#include "coreutil.h" + +namespace irr +{ +namespace io +{ + +namespace +{ + +inline bool isHeaderValid(const SPAKFileHeader& header) +{ + const c8* tag = header.tag; + return tag[0] == 'P' && + tag[1] == 'A' && + tag[2] == 'C' && + tag[3] == 'K'; +} + +} // end namespace + +//! Constructor +CArchiveLoaderPAK::CArchiveLoaderPAK( io::IFileSystem* fs) +: FileSystem(fs) +{ +#ifdef _DEBUG + setDebugName("CArchiveLoaderPAK"); +#endif +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CArchiveLoaderPAK::isALoadableFileFormat(const io::path& filename) const +{ + return core::hasFileExtension(filename, "pak"); +} + +//! Check to see if the loader can create archives of this type. +bool CArchiveLoaderPAK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const +{ + return fileType == EFAT_PAK; +} + +//! Creates an archive from the filename +/** \param file File handle to check. +\return Pointer to newly created archive, or 0 upon error. */ +IFileArchive* CArchiveLoaderPAK::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + archive = createArchive(file, ignoreCase, ignorePaths); + file->drop (); + } + + return archive; +} + +//! creates/loads an archive from the file. +//! \return Pointer to the created archive. Returns 0 if loading failed. +IFileArchive* CArchiveLoaderPAK::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + if ( file ) + { + file->seek ( 0 ); + archive = new CPakReader(file, ignoreCase, ignorePaths); + } + return archive; +} + + +//! Check if the file might be loaded by this class +/** Check might look into the file. +\param file File handle to check. +\return True if file seems to be loadable. */ +bool CArchiveLoaderPAK::isALoadableFileFormat(io::IReadFile* file) const +{ + SPAKFileHeader header; + + file->read(&header, sizeof(header)); + + return isHeaderValid(header); +} + + +/*! + PAK Reader +*/ +CPakReader::CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths) +: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file) +{ +#ifdef _DEBUG + setDebugName("CPakReader"); +#endif + + if (File) + { + File->grab(); + scanLocalHeader(); + sort(); + } +} + + +CPakReader::~CPakReader() +{ + if (File) + File->drop(); +} + + +const IFileList* CPakReader::getFileList() const +{ + return this; +} + +bool CPakReader::scanLocalHeader() +{ + SPAKFileHeader header; + + // Read and validate the header + File->read(&header, sizeof(header)); + if (!isHeaderValid(header)) + return false; + + // Seek to the table of contents +#ifdef __BIG_ENDIAN__ + header.offset = os::Byteswap::byteswap(header.offset); + header.length = os::Byteswap::byteswap(header.length); +#endif + File->seek(header.offset); + + const int numberOfFiles = header.length / sizeof(SPAKFileEntry); + + // Loop through each entry in the table of contents + for(int i = 0; i < numberOfFiles; i++) + { + // read an entry + SPAKFileEntry entry; + File->read(&entry, sizeof(entry)); + +#ifdef _DEBUG + os::Printer::log(entry.name); +#endif + +#ifdef __BIG_ENDIAN__ + entry.offset = os::Byteswap::byteswap(entry.offset); + entry.length = os::Byteswap::byteswap(entry.length); +#endif + + addItem(io::path(entry.name), entry.offset, entry.length, false ); + } + return true; +} + + +//! opens a file by file name +IReadFile* CPakReader::createAndOpenFile(const io::path& filename) +{ + s32 index = findFile(filename, false); + + if (index != -1) + return createAndOpenFile(index); + + return 0; +} + + +//! opens a file by index +IReadFile* CPakReader::createAndOpenFile(u32 index) +{ + if (index >= Files.size() ) + return 0; + + const SFileListEntry &entry = Files[index]; + return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size ); +} + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.h new file mode 100644 index 0000000..1a8dbdd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.h @@ -0,0 +1,125 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PAK_READER_H_INCLUDED__ +#define __C_PAK_READER_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ + +#include "IReferenceCounted.h" +#include "IReadFile.h" +#include "irrArray.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "CFileList.h" + +namespace irr +{ +namespace io +{ + //! File header containing location and size of the table of contents + struct SPAKFileHeader + { + // Don't change the order of these fields! They must match the order stored on disk. + c8 tag[4]; + u32 offset; + u32 length; + }; + + //! An entry in the PAK file's table of contents. + struct SPAKFileEntry + { + // Don't change the order of these fields! They must match the order stored on disk. + c8 name[56]; + u32 offset; + u32 length; + }; + + //! Archiveloader capable of loading PAK Archives + class CArchiveLoaderPAK : public IArchiveLoader + { + public: + + //! Constructor + CArchiveLoaderPAK(io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".zip") + virtual bool isALoadableFileFormat(const io::path& filename) const; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const; + + //! Creates an archive from the filename + /** \param file File handle to check. + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const; + + //! creates/loads an archive from the file. + //! \return Pointer to the created archive. Returns 0 if loading failed. + virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const; + + //! Returns the type of archive created by this loader + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_PAK; } + + private: + io::IFileSystem* FileSystem; + }; + + + //! reads from pak + class CPakReader : public virtual IFileArchive, virtual CFileList + { + public: + + CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths); + virtual ~CPakReader(); + + // file archive methods + + //! return the id of the file Archive + virtual const io::path& getArchiveName() const + { + return File->getFileName(); + } + + //! opens a file by file name + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! opens a file by index + virtual IReadFile* createAndOpenFile(u32 index); + + //! returns the list of files + virtual const IFileList* getFileList() const; + + //! get the class Type + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_PAK; } + + private: + + //! scans for a local header, returns false if the header is invalid + bool scanLocalHeader(); + + IReadFile* File; + + }; + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_ + +#endif // __C_PAK_READER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp new file mode 100644 index 0000000..1f295e7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp @@ -0,0 +1,200 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleAnimatedMeshSceneNodeEmitter.h" +#include "IAnimatedMeshSceneNode.h" +#include "IMesh.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleAnimatedMeshSceneNodeEmitter::CParticleAnimatedMeshSceneNodeEmitter( + IAnimatedMeshSceneNode* node, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, const core::dimension2df& maxStartSize ) + : Node(0), AnimatedMesh(0), BaseMesh(0), TotalVertices(0), MBCount(0), MBNumber(mbNumber), + Direction(direction), NormalDirectionModifier(normalDirectionModifier), + MinParticlesPerSecond(minParticlesPerSecond), MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + MaxStartSize(maxStartSize), MinStartSize(minStartSize), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees), + EveryMeshVertex(everyMeshVertex), UseNormalDirection(useNormalDirection) +{ + #ifdef _DEBUG + setDebugName("CParticleAnimatedMeshSceneNodeEmitter"); + #endif + setAnimatedMeshSceneNode(node); +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleAnimatedMeshSceneNodeEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + const f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond * 2) + amount = MaxParticlesPerSecond * 2; + + // Get Mesh for this frame + IMesh* frameMesh = AnimatedMesh->getMesh( core::floor32(Node->getFrameNr()), + 255, Node->getStartFrame(), Node->getEndFrame() ); + for(u32 i=0; igetMeshBufferCount(); ++j ) + { + for( u32 k=0; kgetMeshBuffer(j)->getVertexCount(); ++k ) + { + p.pos = frameMesh->getMeshBuffer(j)->getPosition(k); + if( UseNormalDirection ) + p.vector = frameMesh->getMeshBuffer(j)->getNormal(k) / + NormalDirectionModifier; + else + p.vector = Direction; + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = p.vector; + tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); + p.vector = tgt; + } + + p.endTime = now + MinLifeTime; + if (MaxLifeTime != MinLifeTime) + p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); + + if (MinStartColor==MaxStartColor) + p.color=MinStartColor; + else + p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); + + p.startColor = p.color; + p.startVector = p.vector; + + if (MinStartSize==MaxStartSize) + p.startSize = MinStartSize; + else + p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); + p.size = p.startSize; + + Particles.push_back(p); + } + } + } + else + { + s32 randomMB = 0; + if( MBNumber < 0 ) + randomMB = os::Randomizer::rand() % MBCount; + else + randomMB = MBNumber; + + u32 vertexNumber = frameMesh->getMeshBuffer(randomMB)->getVertexCount(); + if (!vertexNumber) + continue; + vertexNumber = os::Randomizer::rand() % vertexNumber; + + p.pos = frameMesh->getMeshBuffer(randomMB)->getPosition(vertexNumber); + if( UseNormalDirection ) + p.vector = frameMesh->getMeshBuffer(randomMB)->getNormal(vertexNumber) / + NormalDirectionModifier; + else + p.vector = Direction; + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = Direction; + tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); + p.vector = tgt; + } + + p.endTime = now + MinLifeTime; + if (MaxLifeTime != MinLifeTime) + p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); + + if (MinStartColor==MaxStartColor) + p.color=MinStartColor; + else + p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); + + p.startColor = p.color; + p.startVector = p.vector; + + if (MinStartSize==MaxStartSize) + p.startSize = MinStartSize; + else + p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); + p.size = p.startSize; + + Particles.push_back(p); + } + } + + outArray = Particles.pointer(); + + return Particles.size(); + } + + return 0; +} + + +//! Set Mesh to emit particles from +void CParticleAnimatedMeshSceneNodeEmitter::setAnimatedMeshSceneNode( IAnimatedMeshSceneNode* node ) +{ + Node = node; + AnimatedMesh = 0; + BaseMesh = 0; + TotalVertices = 0; + VertexPerMeshBufferList.clear(); + if ( !node ) + { + return; + } + + AnimatedMesh = node->getMesh(); + BaseMesh = AnimatedMesh->getMesh(0); + + MBCount = BaseMesh->getMeshBufferCount(); + VertexPerMeshBufferList.reallocate(MBCount); + for( u32 i = 0; i < MBCount; ++i ) + { + VertexPerMeshBufferList.push_back( BaseMesh->getMeshBuffer(i)->getVertexCount() ); + TotalVertices += BaseMesh->getMeshBuffer(i)->getVertexCount(); + } +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h new file mode 100644 index 0000000..7ca573d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.h @@ -0,0 +1,161 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + +#include "IParticleAnimatedMeshSceneNodeEmitter.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! An animated mesh emitter +class CParticleAnimatedMeshSceneNodeEmitter : public IParticleAnimatedMeshSceneNodeEmitter +{ +public: + + //! constructor + CParticleAnimatedMeshSceneNodeEmitter( + IAnimatedMeshSceneNode* node, + bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,-1.0f), + f32 normalDirectionModifier = 100.0f, + s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, + u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set Mesh to emit particles from + virtual void setAnimatedMeshSceneNode( IAnimatedMeshSceneNode* node ); + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection ) { UseNormalDirection = useNormalDirection; } + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) { NormalDirectionModifier = normalDirectionModifier; } + + //! Sets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual void setEveryMeshVertex( bool everyMeshVertex ) { EveryMeshVertex = everyMeshVertex; } + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; } + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; } + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Get Mesh we're emitting particles from + virtual const IAnimatedMeshSceneNode* getAnimatedMeshSceneNode() const { return Node; } + + //! Get whether to use vertex normal for direciton, or direction specified + virtual bool isUsingNormalDirection() const { return UseNormalDirection; } + + //! Get direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const { return NormalDirectionModifier; } + + //! Gets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual bool getEveryMeshVertex() const { return EveryMeshVertex; } + + //! Get the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Get the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Get the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Get the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Get the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Get the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + +private: + + IAnimatedMeshSceneNode* Node; + IAnimatedMesh* AnimatedMesh; + const IMesh* BaseMesh; + s32 TotalVertices; + u32 MBCount; + s32 MBNumber; + core::array VertexPerMeshBufferList; + + core::array Particles; + core::vector3df Direction; + f32 NormalDirectionModifier; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + core::dimension2df MaxStartSize, MinStartSize; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; + + bool EveryMeshVertex; + bool UseNormalDirection; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_PARTICLE_ANIMATED_MESH_SCENE_NODE_EMITTER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.cpp new file mode 100644 index 0000000..83887c9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleAttractionAffector.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleAttractionAffector::CParticleAttractionAffector( + const core::vector3df& point, f32 speed, bool attract, + bool affectX, bool affectY, bool affectZ ) + : Point(point), Speed(speed), AffectX(affectX), AffectY(affectY), + AffectZ(affectZ), Attract(attract), LastTime(0) +{ + #ifdef _DEBUG + setDebugName("CParticleAttractionAffector"); + #endif +} + + +//! Affects an array of particles. +void CParticleAttractionAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if( LastTime == 0 ) + { + LastTime = now; + return; + } + + f32 timeDelta = ( now - LastTime ) / 1000.0f; + LastTime = now; + + if( !Enabled ) + return; + + for(u32 i=0; iaddVector3d("Point", Point); + out->addFloat("Speed", Speed); + out->addBool("AffectX", AffectX); + out->addBool("AffectY", AffectY); + out->addBool("AffectZ", AffectZ); + out->addBool("Attract", Attract); +} + +//! Reads attributes of the object. +void CParticleAttractionAffector::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Point = in->getAttributeAsVector3d("Point"); + Speed = in->getAttributeAsFloat("Speed"); + AffectX = in->getAttributeAsBool("AffectX"); + AffectY = in->getAttributeAsBool("AffectY"); + AffectZ = in->getAttributeAsBool("AffectZ"); + Attract = in->getAttributeAsBool("Attract"); +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.h new file mode 100644 index 0000000..0221cdf --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleAttractionAffector.h @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ +#define __C_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ + +#include "IParticleAttractionAffector.h" + +namespace irr +{ +namespace scene +{ + +//! Particle Affector for attracting particles to a point +class CParticleAttractionAffector : public IParticleAttractionAffector +{ +public: + + CParticleAttractionAffector( + const core::vector3df& point = core::vector3df(), f32 speed = 1.0f, + bool attract = true, bool affectX = true, + bool affectY = true, bool affectZ = true ); + + //! Affects a particle. + virtual void affect(u32 now, SParticle* particlearray, u32 count); + + //! Set the point that particles will attract to + virtual void setPoint( const core::vector3df& point ) { Point = point; } + + //! Set the speed, in game units per second that the particles will attract to + //! the specified point + virtual void setSpeed( f32 speed ) { Speed = speed; } + + //! Set whether or not the particles are attracting or detracting + virtual void setAttract( bool attract ) { Attract = attract; } + + //! Set whether or not this will affect particles in the X direction + virtual void setAffectX( bool affect ) { AffectX = affect; } + + //! Set whether or not this will affect particles in the Y direction + virtual void setAffectY( bool affect ) { AffectY = affect; } + + //! Set whether or not this will affect particles in the Z direction + virtual void setAffectZ( bool affect ) { AffectZ = affect; } + + //! Get the point that particles are attracted to + virtual const core::vector3df& getPoint() const { return Point; } + + //! Get the speed that points attract to the specified point + virtual f32 getSpeed() const { return Speed; } + + //! Get whether or not the particles are attracting or detracting + virtual bool getAttract() const { return Attract; } + + //! Get whether or not the particles X position are affected + virtual bool getAffectX() const { return AffectX; } + + //! Get whether or not the particles Y position are affected + virtual bool getAffectY() const { return AffectY; } + + //! Get whether or not the particles Z position are affected + virtual bool getAffectZ() const { return AffectZ; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::vector3df Point; + f32 Speed; + bool AffectX; + bool AffectY; + bool AffectZ; + bool Attract; + u32 LastTime; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_PARTICLE_ATTRACTION_AFFECTOR_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.cpp new file mode 100644 index 0000000..9728f6f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.cpp @@ -0,0 +1,188 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleBoxEmitter.h" +#include "os.h" +#include "IAttributes.h" +#include "irrMath.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleBoxEmitter::CParticleBoxEmitter( + const core::aabbox3df& box, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + video::SColor minStartColor, video::SColor maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, const core::dimension2df& maxStartSize) + : Box(box), Direction(direction), + MaxStartSize(maxStartSize), MinStartSize(minStartSize), + MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees) +{ + #ifdef _DEBUG + setDebugName("CParticleBoxEmitter"); + #endif +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleBoxEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + const f32 everyWhatMillisecond = 1000.0f / perSecond; + + if (Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + const core::vector3df& extent = Box.getExtent(); + + if (amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for (u32 i=0; iaddVector3d("Box", b); + out->addVector3d("Direction", Direction); + out->addFloat("MinStartSizeWidth", MinStartSize.Width); + out->addFloat("MinStartSizeHeight", MinStartSize.Height); + out->addFloat("MaxStartSizeWidth", MaxStartSize.Width); + out->addFloat("MaxStartSizeHeight", MaxStartSize.Height); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); +} + + +//! Reads attributes of the object. +void CParticleBoxEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + // read data and correct input values here + + core::vector3df b = in->getAttributeAsVector3d("Box"); + + if (b.X <= 0) + b.X = 1.0f; + if (b.Y <= 0) + b.Y = 1.0f; + if (b.Z <= 0) + b.Z = 1.0f; + + Box.MinEdge.X = -b.X; + Box.MinEdge.Y = -b.Y; + Box.MinEdge.Z = -b.Z; + Box.MaxEdge.X = b.X; + Box.MaxEdge.Y = b.Y; + Box.MaxEdge.Z = b.Z; + + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + int idx = -1; + idx = in->findAttribute("MinStartSizeWidth"); + if ( idx >= 0 ) + MinStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MinStartSizeHeight"); + if ( idx >= 0 ) + MinStartSize.Height = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeWidth"); + if ( idx >= 0 ) + MaxStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeHeight"); + if ( idx >= 0 ) + MaxStartSize.Height = in->getAttributeAsFloat(idx); + + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); + + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); + +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.h new file mode 100644 index 0000000..e9190a9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleBoxEmitter.h @@ -0,0 +1,133 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_BOX_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_BOX_EMITTER_H_INCLUDED__ + +#include "IParticleBoxEmitter.h" +#include "irrArray.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace scene +{ + +//! A default box emitter +class CParticleBoxEmitter : public IParticleBoxEmitter +{ +public: + + //! constructor + CParticleBoxEmitter( + const core::aabbox3df& box, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + video::SColor minStartColor = video::SColor(255,0,0,0), + video::SColor maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set direction the emitter emits particles. + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set minimum number of particles emitted per second. + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles emitted per second. + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum start color. + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum start color. + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; }; + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; }; + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Set box from which the particles are emitted. + virtual void setBox( const core::aabbox3df& box ) { Box = box; } + + //! Gets direction the emitter emits particles. + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Gets minimum number of particles emitted per second. + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Gets maximum number of particles emitted per second. + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Gets minimum start color. + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Gets maximum start color. + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Gets the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Gets the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + + //! Get box from which the particles are emitted. + virtual const core::aabbox3df& getBox() const { return Box; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::array Particles; + core::aabbox3df Box; + core::vector3df Direction; + core::dimension2df MaxStartSize, MinStartSize; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.cpp new file mode 100644 index 0000000..a2078f9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.cpp @@ -0,0 +1,187 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleCylinderEmitter.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleCylinderEmitter::CParticleCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) + : Center(center), Normal(normal), Direction(direction), + MaxStartSize(maxStartSize), MinStartSize(minStartSize), + MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Radius(radius), Length(length), Time(0), Emitted(0), + MaxAngleDegrees(maxAngleDegrees), OutlineOnly(outlineOnly) +{ + #ifdef _DEBUG + setDebugName("CParticleCylinderEmitter"); + #endif +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleCylinderEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + const f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; iaddVector3d("Center", Center); + out->addVector3d("Normal", Normal); + out->addVector3d("Direction", Direction); + out->addFloat("MinStartSizeWidth", MinStartSize.Width); + out->addFloat("MinStartSizeHeight", MinStartSize.Height); + out->addFloat("MaxStartSizeWidth", MaxStartSize.Width); + out->addFloat("MaxStartSizeHeight", MaxStartSize.Height); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addFloat("Radius", Radius); + out->addFloat("Length", Length); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); + out->addBool("OutlineOnly", OutlineOnly); +} + +//! Reads attributes of the object. +void CParticleCylinderEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Center = in->getAttributeAsVector3d("Center"); + Normal = in->getAttributeAsVector3d("Normal"); + if (Normal.getLength() == 0) + Normal.set(0,1.f,0); + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + int idx = -1; + idx = in->findAttribute("MinStartSizeWidth"); + if ( idx >= 0 ) + MinStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MinStartSizeHeight"); + if ( idx >= 0 ) + MinStartSize.Height = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeWidth"); + if ( idx >= 0 ) + MaxStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeHeight"); + if ( idx >= 0 ) + MaxStartSize.Height = in->getAttributeAsFloat(idx); + + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); + + Radius = in->getAttributeAsFloat("Radius"); + Length = in->getAttributeAsFloat("Length"); + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); + OutlineOnly = in->getAttributeAsBool("OutlineOnly"); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.h new file mode 100644 index 0000000..3b0fe41 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleCylinderEmitter.h @@ -0,0 +1,164 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_CYLINDER_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_CYLINDER_EMITTER_H_INCLUDED__ + +#include "IParticleCylinderEmitter.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! A default box emitter +class CParticleCylinderEmitter : public IParticleCylinderEmitter +{ +public: + + //! constructor + CParticleCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly = false, const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set the center of the radius for the cylinder, at one end of the cylinder + virtual void setCenter( const core::vector3df& center ) { Center = center; } + + //! Set the normal of the cylinder + virtual void setNormal( const core::vector3df& normal ) { Normal = normal; } + + //! Set the radius of the cylinder + virtual void setRadius( f32 radius ) { Radius = radius; } + + //! Set the length of the cylinder + virtual void setLength( f32 length ) { Length = length; } + + //! Set whether or not to draw points inside the cylinder + virtual void setOutlineOnly( bool outlineOnly ) { OutlineOnly = outlineOnly; } + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set direction the emitter emits particles + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set direction the emitter emits particles + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set direction the emitter emits particles + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set direction the emitter emits particles + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; } + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; } + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Get the center of the cylinder + virtual const core::vector3df& getCenter() const { return Center; } + + //! Get the normal of the cylinder + virtual const core::vector3df& getNormal() const { return Normal; } + + //! Get the radius of the cylinder + virtual f32 getRadius() const { return Radius; } + + //! Get the center of the cylinder + virtual f32 getLength() const { return Length; } + + //! Get whether or not to draw points inside the cylinder + virtual bool getOutlineOnly() const { return OutlineOnly; } + + //! Gets direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Gets direction the emitter emits particles + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Gets direction the emitter emits particles + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Gets direction the emitter emits particles + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Gets direction the emitter emits particles + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Gets the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Gets the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::array Particles; + + core::vector3df Center; + core::vector3df Normal; + core::vector3df Direction; + core::dimension2df MaxStartSize, MinStartSize; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + f32 Radius; + f32 Length; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; + + bool OutlineOnly; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.cpp new file mode 100644 index 0000000..b14d830 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleFadeOutAffector.h" +#include "IAttributes.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleFadeOutAffector::CParticleFadeOutAffector( + const video::SColor& targetColor, u32 fadeOutTime) + : IParticleFadeOutAffector(), TargetColor(targetColor) +{ + + #ifdef _DEBUG + setDebugName("CParticleFadeOutAffector"); + #endif + + FadeOutTime = fadeOutTime ? static_cast(fadeOutTime) : 1.0f; +} + + +//! Affects an array of particles. +void CParticleFadeOutAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if (!Enabled) + return; + f32 d; + + for (u32 i=0; iaddColor("TargetColor", TargetColor); + out->addFloat("FadeOutTime", FadeOutTime); +} + +//! Reads attributes of the object. +//! Implement this to set the attributes of your scene node animator for +//! scripting languages, editors, debuggers or xml deserialization purposes. +//! \param startIndex: start index where to start reading attributes. +//! \return: returns last index of an attribute read by this affector +void CParticleFadeOutAffector::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + TargetColor = in->getAttributeAsColor("TargetColor"); + FadeOutTime = in->getAttributeAsFloat("FadeOutTime"); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.h new file mode 100644 index 0000000..b39d559 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleFadeOutAffector.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ +#define __C_PARTICLE_FADE_OUT_AFFECTOR_H_INCLUDED__ + +#include "IParticleFadeOutAffector.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + +//! Particle Affector for fading out a color +class CParticleFadeOutAffector : public IParticleFadeOutAffector +{ +public: + + CParticleFadeOutAffector(const video::SColor& targetColor, u32 fadeOutTime); + + //! Affects a particle. + virtual void affect(u32 now, SParticle* particlearray, u32 count); + + //! Sets the targetColor, i.e. the color the particles will interpolate + //! to over time. + virtual void setTargetColor( const video::SColor& targetColor ) { TargetColor = targetColor; } + + //! Sets the amount of time it takes for each particle to fade out. + virtual void setFadeOutTime( u32 fadeOutTime ) { FadeOutTime = fadeOutTime ? static_cast(fadeOutTime) : 1.0f; } + + //! Sets the targetColor, i.e. the color the particles will interpolate + //! to over time. + virtual const video::SColor& getTargetColor() const { return TargetColor; } + + //! Sets the amount of time it takes for each particle to fade out. + virtual u32 getFadeOutTime() const { return static_cast(FadeOutTime); } + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \return: returns last index of an attribute read by this affector + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + video::SColor TargetColor; + f32 FadeOutTime; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.cpp new file mode 100644 index 0000000..450a5df --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleGravityAffector.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleGravityAffector::CParticleGravityAffector( + const core::vector3df& gravity, u32 timeForceLost) + : IParticleGravityAffector(), TimeForceLost(static_cast(timeForceLost)), Gravity(gravity) +{ + #ifdef _DEBUG + setDebugName("CParticleGravityAffector"); + #endif +} + + +//! Affects an array of particles. +void CParticleGravityAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if (!Enabled) + return; + f32 d; + + for (u32 i=0; i 1.0f) + d = 1.0f; + if (d < 0.0f) + d = 0.0f; + d = 1.0f - d; + + particlearray[i].vector = particlearray[i].startVector.getInterpolated(Gravity, d); + } +} + +//! Writes attributes of the object. +void CParticleGravityAffector::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Gravity", Gravity); + out->addFloat("TimeForceLost", TimeForceLost); +} + + +//! Reads attributes of the object. +void CParticleGravityAffector::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Gravity = in->getAttributeAsVector3d("Gravity"); + TimeForceLost = in->getAttributeAsFloat("TimeForceLost"); +} + + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.h new file mode 100644 index 0000000..5491b51 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleGravityAffector.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ +#define __C_PARTICLE_GRAVITY_AFFECTOR_H_INCLUDED__ + +#include "IParticleGravityAffector.h" +#include "SColor.h" + +namespace irr +{ +namespace scene +{ + +//! Particle Affector for affecting direction of particle +class CParticleGravityAffector : public IParticleGravityAffector +{ +public: + + CParticleGravityAffector( + const core::vector3df& gravity = core::vector3df(0.0f,-0.03f,0.0f), + u32 timeForceLost = 1000); + + //! Affects a particle. + virtual void affect(u32 now, SParticle* particlearray, u32 count); + + //! Set the time in milliseconds when the gravity force is totally + //! lost and the particle does not move any more. + virtual void setTimeForceLost( f32 timeForceLost ) { TimeForceLost = timeForceLost; } + + //! Set the direction and force of gravity. + virtual void setGravity( const core::vector3df& gravity ) { Gravity = gravity; } + + //! Set the time in milliseconds when the gravity force is totally + //! lost and the particle does not move any more. + virtual f32 getTimeForceLost() const { return TimeForceLost; } + + //! Set the direction and force of gravity. + virtual const core::vector3df& getGravity() const { return Gravity; } + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \return: returns last index of an attribute read by this affector + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + f32 TimeForceLost; + core::vector3df Gravity; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.cpp new file mode 100644 index 0000000..74d5af1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.cpp @@ -0,0 +1,190 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CParticleMeshEmitter.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleMeshEmitter::CParticleMeshEmitter( + IMesh* mesh, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) + : Mesh(0), TotalVertices(0), MBCount(0), MBNumber(mbNumber), + NormalDirectionModifier(normalDirectionModifier), Direction(direction), + MaxStartSize(maxStartSize), MinStartSize(minStartSize), + MinParticlesPerSecond(minParticlesPerSecond), MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees), + EveryMeshVertex(everyMeshVertex), UseNormalDirection(useNormalDirection) +{ + #ifdef _DEBUG + setDebugName("CParticleMeshEmitter"); + #endif + setMesh(mesh); +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleMeshEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + const f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond * 2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; igetMeshBufferCount(); ++j ) + { + for( u32 k=0; kgetMeshBuffer(j)->getVertexCount(); ++k ) + { + p.pos = Mesh->getMeshBuffer(j)->getPosition(k); + if( UseNormalDirection ) + p.vector = Mesh->getMeshBuffer(j)->getNormal(k) / + NormalDirectionModifier; + else + p.vector = Direction; + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = p.vector; + tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); + p.vector = tgt; + } + + p.endTime = now + MinLifeTime; + if (MaxLifeTime != MinLifeTime) + p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); + + if (MinStartColor==MaxStartColor) + p.color=MinStartColor; + else + p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); + + p.startColor = p.color; + p.startVector = p.vector; + + if (MinStartSize==MaxStartSize) + p.startSize = MinStartSize; + else + p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); + p.size = p.startSize; + + Particles.push_back(p); + } + } + } + else + { + const s32 randomMB = (MBNumber < 0) ? (os::Randomizer::rand() % MBCount) : MBNumber; + + u32 vertexNumber = Mesh->getMeshBuffer(randomMB)->getVertexCount(); + if (!vertexNumber) + continue; + vertexNumber = os::Randomizer::rand() % vertexNumber; + + p.pos = Mesh->getMeshBuffer(randomMB)->getPosition(vertexNumber); + if( UseNormalDirection ) + p.vector = Mesh->getMeshBuffer(randomMB)->getNormal(vertexNumber) / + NormalDirectionModifier; + else + p.vector = Direction; + + p.startTime = now; + + if( MaxAngleDegrees ) + { + core::vector3df tgt = Direction; + tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); + p.vector = tgt; + } + + p.endTime = now + MinLifeTime; + if (MaxLifeTime != MinLifeTime) + p.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); + + if (MinStartColor==MaxStartColor) + p.color=MinStartColor; + else + p.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); + + p.startColor = p.color; + p.startVector = p.vector; + + if (MinStartSize==MaxStartSize) + p.startSize = MinStartSize; + else + p.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); + p.size = p.startSize; + + Particles.push_back(p); + } + } + + outArray = Particles.pointer(); + + return Particles.size(); + } + + return 0; +} + + +//! Set Mesh to emit particles from +void CParticleMeshEmitter::setMesh(IMesh* mesh) +{ + Mesh = mesh; + + TotalVertices = 0; + MBCount = 0; + VertexPerMeshBufferList.clear(); + + if ( !Mesh ) + return; + + MBCount = Mesh->getMeshBufferCount(); + VertexPerMeshBufferList.reallocate(MBCount); + for( u32 i = 0; i < MBCount; ++i ) + { + VertexPerMeshBufferList.push_back( Mesh->getMeshBuffer(i)->getVertexCount() ); + TotalVertices += Mesh->getMeshBuffer(i)->getVertexCount(); + } +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.h new file mode 100644 index 0000000..af00031 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleMeshEmitter.h @@ -0,0 +1,160 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_MESH_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_MESH_EMITTER_H_INCLUDED__ + +#include "IParticleMeshEmitter.h" +#include "irrArray.h" +#include "aabbox3d.h" +#include "IMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +//! A default box emitter +class CParticleMeshEmitter : public IParticleMeshEmitter +{ +public: + + //! constructor + CParticleMeshEmitter( + IMesh* mesh, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.0f,0.0f), + f32 normalDirectionModifier = 100.0f, + s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, + u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set Mesh to emit particles from + virtual void setMesh( IMesh* mesh ); + + //! Set whether to use vertex normal for direction, or direction specified + virtual void setUseNormalDirection( bool useNormalDirection ) { UseNormalDirection = useNormalDirection; } + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set the amount that the normal is divided by for getting a particles direction + virtual void setNormalDirectionModifier( f32 normalDirectionModifier ) { NormalDirectionModifier = normalDirectionModifier; } + + //! Sets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual void setEveryMeshVertex( bool everyMeshVertex ) { EveryMeshVertex = everyMeshVertex; } + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; } + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; } + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Set maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Get Mesh we're emitting particles from + virtual const IMesh* getMesh() const { return Mesh; } + + //! Get whether to use vertex normal for direciton, or direction specified + virtual bool isUsingNormalDirection() const { return UseNormalDirection; } + + //! Get direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Get the amount that the normal is divided by for getting a particles direction + virtual f32 getNormalDirectionModifier() const { return NormalDirectionModifier; } + + //! Gets whether to emit min<->max particles for every vertex per second, or to pick + //! min<->max vertices every second + virtual bool getEveryMeshVertex() const { return EveryMeshVertex; } + + //! Get the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Get the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Get the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Get the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Gets the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Gets the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Get maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + +private: + + const IMesh* Mesh; + core::array VertexPerMeshBufferList; + s32 TotalVertices; + u32 MBCount; + s32 MBNumber; + + f32 NormalDirectionModifier; + core::array Particles; + core::vector3df Direction; + core::dimension2df MaxStartSize, MinStartSize; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; + + bool EveryMeshVertex; + bool UseNormalDirection; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_PARTICLE_MESH_EMITTER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.cpp new file mode 100644 index 0000000..34dc51d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.cpp @@ -0,0 +1,147 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticlePointEmitter.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticlePointEmitter::CParticlePointEmitter( + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, video::SColor minStartColor, + video::SColor maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize) + : Direction(direction), + MinStartSize(minStartSize), MaxStartSize(maxStartSize), + MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + MaxAngleDegrees(maxAngleDegrees), Time(0), Emitted(0) +{ + #ifdef _DEBUG + setDebugName("CParticlePointEmitter"); + #endif +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticlePointEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + const f32 everyWhatMillisecond = 1000.0f / perSecond; + + if (Time > everyWhatMillisecond) + { + Time = 0; + Particle.startTime = now; + Particle.vector = Direction; + + if (MaxAngleDegrees) + { + core::vector3df tgt = Direction; + tgt.rotateXYBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateYZBy(os::Randomizer::frand() * MaxAngleDegrees); + tgt.rotateXZBy(os::Randomizer::frand() * MaxAngleDegrees); + Particle.vector = tgt; + } + + Particle.endTime = now + MinLifeTime; + if (MaxLifeTime != MinLifeTime) + Particle.endTime += os::Randomizer::rand() % (MaxLifeTime - MinLifeTime); + + if (MinStartColor==MaxStartColor) + Particle.color=MinStartColor; + else + Particle.color = MinStartColor.getInterpolated(MaxStartColor, os::Randomizer::frand()); + + Particle.startColor = Particle.color; + Particle.startVector = Particle.vector; + + if (MinStartSize==MaxStartSize) + Particle.startSize = MinStartSize; + else + Particle.startSize = MinStartSize.getInterpolated(MaxStartSize, os::Randomizer::frand()); + Particle.size = Particle.startSize; + + outArray = &Particle; + return 1; + } + + return 0; +} + + +//! Writes attributes of the object. +void CParticlePointEmitter::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Direction", Direction); + out->addFloat("MinStartSizeWidth", MinStartSize.Width); + out->addFloat("MinStartSizeHeight", MinStartSize.Height); + out->addFloat("MaxStartSizeWidth", MaxStartSize.Width); + out->addFloat("MaxStartSizeHeight", MaxStartSize.Height); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); +} + +//! Reads attributes of the object. +void CParticlePointEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + int idx = -1; + idx = in->findAttribute("MinStartSizeWidth"); + if ( idx >= 0 ) + MinStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MinStartSizeHeight"); + if ( idx >= 0 ) + MinStartSize.Height = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeWidth"); + if ( idx >= 0 ) + MaxStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeHeight"); + if ( idx >= 0 ) + MaxStartSize.Height = in->getAttributeAsFloat(idx); + + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); + + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.h new file mode 100644 index 0000000..c83232c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticlePointEmitter.h @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_POINT_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_POINT_EMITTER_H_INCLUDED__ + +#include "IParticleEmitter.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! A default point emitter +class CParticlePointEmitter : public IParticlePointEmitter +{ +public: + + //! constructor + CParticlePointEmitter( + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + video::SColor minStartColor = video::SColor(255,0,0,0), + video::SColor maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set direction the emitter emits particles. + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set minimum number of particles emitted per second. + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles emitted per second. + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum start color. + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum start color. + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; } + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; } + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Set maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Gets direction the emitter emits particles. + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Gets minimum number of particles emitted per second. + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Gets maximum number of particles emitted per second. + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Gets minimum start color. + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Gets maximum start color. + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Gets the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Gets the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Get maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + SParticle Particle; + core::vector3df Direction; + core::dimension2df MinStartSize, MaxStartSize; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + s32 MaxAngleDegrees; + + u32 Time; + u32 Emitted; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.cpp new file mode 100644 index 0000000..5f398cd --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.cpp @@ -0,0 +1,177 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleRingEmitter.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleRingEmitter::CParticleRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, const video::SColor& minStartColor, + const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) + : Center(center), Radius(radius), RingThickness(ringThickness), + Direction(direction), + MaxStartSize(maxStartSize), MinStartSize(minStartSize), + MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees) +{ + #ifdef _DEBUG + setDebugName("CParticleRingEmitter"); + #endif +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleRingEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; iaddVector3d("Center", Center); + out->addFloat("Radius", Radius); + out->addFloat("RingThickness", RingThickness); + + out->addVector3d("Direction", Direction); + out->addFloat("MinStartSizeWidth", MinStartSize.Width); + out->addFloat("MinStartSizeHeight", MinStartSize.Height); + out->addFloat("MaxStartSizeWidth", MaxStartSize.Width); + out->addFloat("MaxStartSizeHeight", MaxStartSize.Height); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); +} + +//! Reads attributes of the object. +void CParticleRingEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Center = in->getAttributeAsVector3d("Center"); + Radius = in->getAttributeAsFloat("Radius"); + RingThickness = in->getAttributeAsFloat("RingThickness"); + + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + int idx = -1; + idx = in->findAttribute("MinStartSizeWidth"); + if ( idx >= 0 ) + MinStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MinStartSizeHeight"); + if ( idx >= 0 ) + MinStartSize.Height = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeWidth"); + if ( idx >= 0 ) + MaxStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeHeight"); + if ( idx >= 0 ) + MaxStartSize.Height = in->getAttributeAsFloat(idx); + + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); + + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.h new file mode 100644 index 0000000..b6c9f13 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRingEmitter.h @@ -0,0 +1,148 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_RING_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_RING_EMITTER_H_INCLUDED__ + +#include "IParticleRingEmitter.h" +#include "irrArray.h" + +namespace irr +{ +namespace scene +{ + +//! A ring emitter +class CParticleRingEmitter : public IParticleRingEmitter +{ +public: + + //! constructor + CParticleRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) + ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set minimum number of particles the emitter emits per second + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles the emitter emits per second + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum starting color for particles + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum starting color for particles + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; } + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; } + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Set maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Set the center of the ring + virtual void setCenter( const core::vector3df& center ) { Center = center; } + + //! Set the radius of the ring + virtual void setRadius( f32 radius ) { Radius = radius; } + + //! Set the thickness of the ring + virtual void setRingThickness( f32 ringThickness ) { RingThickness = ringThickness; } + + //! Gets direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Gets the minimum number of particles the emitter emits per second + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Gets the maximum number of particles the emitter emits per second + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Gets the minimum starting color for particles + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Gets the maximum starting color for particles + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Gets the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Gets the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Get maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + + //! Get the center of the ring + virtual const core::vector3df& getCenter() const { return Center; } + + //! Get the radius of the ring + virtual f32 getRadius() const { return Radius; } + + //! Get the thickness of the ring + virtual f32 getRingThickness() const { return RingThickness; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::array Particles; + + core::vector3df Center; + f32 Radius; + f32 RingThickness; + + core::vector3df Direction; + core::dimension2df MaxStartSize, MinStartSize; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.cpp new file mode 100644 index 0000000..e59854a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.cpp @@ -0,0 +1,67 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleRotationAffector.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleRotationAffector::CParticleRotationAffector( const core::vector3df& speed, const core::vector3df& pivotPoint ) + : PivotPoint(pivotPoint), Speed(speed), LastTime(0) +{ + #ifdef _DEBUG + setDebugName("CParticleRotationAffector"); + #endif +} + + +//! Affects an array of particles. +void CParticleRotationAffector::affect(u32 now, SParticle* particlearray, u32 count) +{ + if( LastTime == 0 ) + { + LastTime = now; + return; + } + + f32 timeDelta = ( now - LastTime ) / 1000.0f; + LastTime = now; + + if( !Enabled ) + return; + + for(u32 i=0; iaddVector3d("PivotPoint", PivotPoint); + out->addVector3d("Speed", Speed); +} + +//! Reads attributes of the object. +void CParticleRotationAffector::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + PivotPoint = in->getAttributeAsVector3d("PivotPoint"); + Speed = in->getAttributeAsVector3d("Speed"); +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.h new file mode 100644 index 0000000..8db5752 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleRotationAffector.h @@ -0,0 +1,56 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ +#define __C_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ + +#include "IParticleRotationAffector.h" + +namespace irr +{ +namespace scene +{ + +//! Particle Affector for rotating particles about a point +class CParticleRotationAffector : public IParticleRotationAffector +{ +public: + + CParticleRotationAffector( const core::vector3df& speed = core::vector3df(5.0f, 5.0f, 5.0f), + const core::vector3df& point = core::vector3df() ); + + //! Affects a particle. + virtual void affect(u32 now, SParticle* particlearray, u32 count); + + //! Set the point that particles will attract to + virtual void setPivotPoint( const core::vector3df& point ) { PivotPoint = point; } + + //! Set the speed in degrees per second + virtual void setSpeed( const core::vector3df& speed ) { Speed = speed; } + + //! Get the point that particles are attracted to + virtual const core::vector3df& getPivotPoint() const { return PivotPoint; } + + //! Get the speed in degrees per second + virtual const core::vector3df& getSpeed() const { return Speed; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::vector3df PivotPoint; + core::vector3df Speed; + u32 LastTime; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_PARTICLE_ROTATION_AFFECTOR_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.cpp new file mode 100644 index 0000000..1817bcf --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2010-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleScaleAffector.h" +#include "IAttributes.h" + +namespace irr +{ + namespace scene + { + CParticleScaleAffector::CParticleScaleAffector(const core::dimension2df& scaleTo) + : ScaleTo(scaleTo) + { + #ifdef _DEBUG + setDebugName("CParticleScaleAffector"); + #endif + } + + + void CParticleScaleAffector::affect (u32 now, SParticle *particlearray, u32 count) + { + for(u32 i=0;iaddFloat("ScaleToWidth", ScaleTo.Width); + out->addFloat("ScaleToHeight", ScaleTo.Height); + } + + + void CParticleScaleAffector::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) + { + ScaleTo.Width = in->getAttributeAsFloat("ScaleToWidth"); + ScaleTo.Height = in->getAttributeAsFloat("ScaleToHeight"); + } + + + E_PARTICLE_AFFECTOR_TYPE CParticleScaleAffector::getType() const + { + return scene::EPAT_SCALE; + } + } +} + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.h new file mode 100644 index 0000000..8bd4c42 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleScaleAffector.h @@ -0,0 +1,44 @@ +// Copyright (C) 2010-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef C_PARTICLE_SCALE_AFFECTOR_H +#define C_PARTICLE_SCALE_AFFECTOR_H + +#include + +namespace irr +{ + namespace scene + { + class CParticleScaleAffector : public IParticleAffector + { + public: + CParticleScaleAffector(const core::dimension2df& scaleTo = core::dimension2df(1.0f, 1.0f)); + + virtual void affect(u32 now, SParticle *particlearray, u32 count); + + //! Writes attributes of the object. + //! Implement this to expose the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml serialization purposes. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + //! Implement this to set the attributes of your scene node animator for + //! scripting languages, editors, debuggers or xml deserialization purposes. + //! \param startIndex: start index where to start reading attributes. + //! \return: returns last index of an attribute read by this affector + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + //! Get emitter type + virtual E_PARTICLE_AFFECTOR_TYPE getType() const; + + protected: + core::dimension2df ScaleTo; + }; + } +} + + +#endif // C_PARTICLE_SCALE_AFFECTOR_H + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.cpp new file mode 100644 index 0000000..42e4e52 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.cpp @@ -0,0 +1,175 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CParticleSphereEmitter.h" +#include "os.h" +#include "IAttributes.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleSphereEmitter::CParticleSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, const video::SColor& minStartColor, + const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) + : Center(center), Radius(radius), Direction(direction), + MinStartSize(minStartSize), MaxStartSize(maxStartSize), + MinParticlesPerSecond(minParticlesPerSecond), + MaxParticlesPerSecond(maxParticlesPerSecond), + MinStartColor(minStartColor), MaxStartColor(maxStartColor), + MinLifeTime(lifeTimeMin), MaxLifeTime(lifeTimeMax), + Time(0), Emitted(0), MaxAngleDegrees(maxAngleDegrees) +{ + #ifdef _DEBUG + setDebugName("CParticleSphereEmitter"); + #endif + +} + + +//! Prepares an array with new particles to emitt into the system +//! and returns how much new particles there are. +s32 CParticleSphereEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) +{ + Time += timeSinceLastCall; + + const u32 pps = (MaxParticlesPerSecond - MinParticlesPerSecond); + const f32 perSecond = pps ? ((f32)MinParticlesPerSecond + os::Randomizer::frand() * pps) : MinParticlesPerSecond; + const f32 everyWhatMillisecond = 1000.0f / perSecond; + + if(Time > everyWhatMillisecond) + { + Particles.set_used(0); + u32 amount = (u32)((Time / everyWhatMillisecond) + 0.5f); + Time = 0; + SParticle p; + + if(amount > MaxParticlesPerSecond*2) + amount = MaxParticlesPerSecond * 2; + + for(u32 i=0; iaddVector3d("Center", Direction); + out->addFloat("Radius", Radius); + + out->addVector3d("Direction", Direction); + out->addFloat("MinStartSizeWidth", MinStartSize.Width); + out->addFloat("MinStartSizeHeight", MinStartSize.Height); + out->addFloat("MaxStartSizeWidth", MaxStartSize.Width); + out->addFloat("MaxStartSizeHeight", MaxStartSize.Height); + out->addInt("MinParticlesPerSecond", MinParticlesPerSecond); + out->addInt("MaxParticlesPerSecond", MaxParticlesPerSecond); + out->addColor("MinStartColor", MinStartColor); + out->addColor("MaxStartColor", MaxStartColor); + out->addInt("MinLifeTime", MinLifeTime); + out->addInt("MaxLifeTime", MaxLifeTime); + out->addInt("MaxAngleDegrees", MaxAngleDegrees); +} + +//! Reads attributes of the object. +void CParticleSphereEmitter::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Center = in->getAttributeAsVector3d("Center"); + Radius = in->getAttributeAsFloat("Radius"); + + Direction = in->getAttributeAsVector3d("Direction"); + if (Direction.getLength() == 0) + Direction.set(0,0.01f,0); + + int idx = -1; + idx = in->findAttribute("MinStartSizeWidth"); + if ( idx >= 0 ) + MinStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MinStartSizeHeight"); + if ( idx >= 0 ) + MinStartSize.Height = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeWidth"); + if ( idx >= 0 ) + MaxStartSize.Width = in->getAttributeAsFloat(idx); + idx = in->findAttribute("MaxStartSizeHeight"); + if ( idx >= 0 ) + MaxStartSize.Height = in->getAttributeAsFloat(idx); + MinParticlesPerSecond = in->getAttributeAsInt("MinParticlesPerSecond"); + MaxParticlesPerSecond = in->getAttributeAsInt("MaxParticlesPerSecond"); + + MinParticlesPerSecond = core::max_(1u, MinParticlesPerSecond); + MaxParticlesPerSecond = core::max_(MaxParticlesPerSecond, 1u); + MaxParticlesPerSecond = core::min_(MaxParticlesPerSecond, 200u); + MinParticlesPerSecond = core::min_(MinParticlesPerSecond, MaxParticlesPerSecond); + + MinStartColor = in->getAttributeAsColor("MinStartColor"); + MaxStartColor = in->getAttributeAsColor("MaxStartColor"); + MinLifeTime = in->getAttributeAsInt("MinLifeTime"); + MaxLifeTime = in->getAttributeAsInt("MaxLifeTime"); + MinLifeTime = core::max_(0u, MinLifeTime); + MaxLifeTime = core::max_(MaxLifeTime, MinLifeTime); + MinLifeTime = core::min_(MinLifeTime, MaxLifeTime); + + MaxAngleDegrees = in->getAttributeAsInt("MaxAngleDegrees"); +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.h new file mode 100644 index 0000000..59736ec --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSphereEmitter.h @@ -0,0 +1,141 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_SPHERE_EMITTER_H_INCLUDED__ +#define __C_PARTICLE_SPHERE_EMITTER_H_INCLUDED__ + +#include "IParticleSphereEmitter.h" +#include "irrArray.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace scene +{ + +//! A default box emitter +class CParticleSphereEmitter : public IParticleSphereEmitter +{ +public: + + //! constructor + CParticleSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 20, + u32 maxParticlesPerSecond = 40, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, + u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Prepares an array with new particles to emitt into the system + //! and returns how much new particles there are. + virtual s32 emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray); + + //! Set direction the emitter emits particles + virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; } + + //! Set minimum number of particles per second. + virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; } + + //! Set maximum number of particles per second. + virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; } + + //! Set minimum start color + virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; } + + //! Set maximum start color + virtual void setMaxStartColor( const video::SColor& color ) { MaxStartColor = color; } + + //! Set the maximum starting size for particles + virtual void setMaxStartSize( const core::dimension2df& size ) { MaxStartSize = size; } + + //! Set the minimum starting size for particles + virtual void setMinStartSize( const core::dimension2df& size ) { MinStartSize = size; } + + //! Set the minimum particle life-time in milliseconds + virtual void setMinLifeTime( u32 lifeTimeMin ) { MinLifeTime = lifeTimeMin; } + + //! Set the maximum particle life-time in milliseconds + virtual void setMaxLifeTime( u32 lifeTimeMax ) { MaxLifeTime = lifeTimeMax; } + + //! Set maximal random derivation from the direction + virtual void setMaxAngleDegrees( s32 maxAngleDegrees ) { MaxAngleDegrees = maxAngleDegrees; } + + //! Set the center of the sphere for particle emissions + virtual void setCenter( const core::vector3df& center ) { Center = center; } + + //! Set the radius of the sphere for particle emissions + virtual void setRadius( f32 radius ) { Radius = radius; } + + //! Gets direction the emitter emits particles + virtual const core::vector3df& getDirection() const { return Direction; } + + //! Get minimum number of particles per second. + virtual u32 getMinParticlesPerSecond() const { return MinParticlesPerSecond; } + + //! Get maximum number of particles per second. + virtual u32 getMaxParticlesPerSecond() const { return MaxParticlesPerSecond; } + + //! Get minimum start color + virtual const video::SColor& getMinStartColor() const { return MinStartColor; } + + //! Get maximum start color + virtual const video::SColor& getMaxStartColor() const { return MaxStartColor; } + + //! Gets the maximum starting size for particles + virtual const core::dimension2df& getMaxStartSize() const { return MaxStartSize; } + + //! Gets the minimum starting size for particles + virtual const core::dimension2df& getMinStartSize() const { return MinStartSize; } + + //! Get the minimum particle life-time in milliseconds + virtual u32 getMinLifeTime() const { return MinLifeTime; } + + //! Get the maximum particle life-time in milliseconds + virtual u32 getMaxLifeTime() const { return MaxLifeTime; } + + //! Get maximal random derivation from the direction + virtual s32 getMaxAngleDegrees() const { return MaxAngleDegrees; } + + //! Get the center of the sphere for particle emissions + virtual const core::vector3df& getCenter() const { return Center; } + + //! Get the radius of the sphere for particle emissions + virtual f32 getRadius() const { return Radius; } + + //! Writes attributes of the object. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the object. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + +private: + + core::array Particles; + + core::vector3df Center; + f32 Radius; + core::vector3df Direction; + + core::dimension2df MinStartSize, MaxStartSize; + u32 MinParticlesPerSecond, MaxParticlesPerSecond; + video::SColor MinStartColor, MaxStartColor; + u32 MinLifeTime, MaxLifeTime; + + u32 Time; + u32 Emitted; + s32 MaxAngleDegrees; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp new file mode 100644 index 0000000..54bfcc7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.cpp @@ -0,0 +1,721 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CParticleSystemSceneNode.h" +#include "os.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "IVideoDriver.h" + +#include "CParticleAnimatedMeshSceneNodeEmitter.h" +#include "CParticleBoxEmitter.h" +#include "CParticleCylinderEmitter.h" +#include "CParticleMeshEmitter.h" +#include "CParticlePointEmitter.h" +#include "CParticleRingEmitter.h" +#include "CParticleSphereEmitter.h" +#include "CParticleAttractionAffector.h" +#include "CParticleFadeOutAffector.h" +#include "CParticleGravityAffector.h" +#include "CParticleRotationAffector.h" +#include "CParticleScaleAffector.h" +#include "SViewFrustum.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter, + ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) + : IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale), + Emitter(0), ParticleSize(core::dimension2d(5.0f, 5.0f)), LastEmitTime(0), + MaxParticles(0xffff), Buffer(0), ParticlesAreGlobal(true) +{ + #ifdef _DEBUG + setDebugName("CParticleSystemSceneNode"); + #endif + + Buffer = new SMeshBuffer(); + if (createDefaultEmitter) + { + IParticleEmitter* e = createBoxEmitter(); + setEmitter(e); + e->drop(); + } +} + + +//! destructor +CParticleSystemSceneNode::~CParticleSystemSceneNode() +{ + if (Emitter) + Emitter->drop(); + if (Buffer) + Buffer->drop(); + + removeAllAffectors(); +} + + +//! Gets the particle emitter, which creates the particles. +IParticleEmitter* CParticleSystemSceneNode::getEmitter() +{ + return Emitter; +} + + +//! Sets the particle emitter, which creates the particles. +void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter) +{ + if (emitter == Emitter) + return; + if (Emitter) + Emitter->drop(); + + Emitter = emitter; + + if (Emitter) + Emitter->grab(); +} + + +//! Adds new particle effector to the particle system. +void CParticleSystemSceneNode::addAffector(IParticleAffector* affector) +{ + affector->grab(); + AffectorList.push_back(affector); +} + +//! Get a list of all particle affectors. +const core::list& CParticleSystemSceneNode::getAffectors() const +{ + return AffectorList; +} + +//! Removes all particle affectors in the particle system. +void CParticleSystemSceneNode::removeAllAffectors() +{ + core::list::Iterator it = AffectorList.begin(); + while (it != AffectorList.end()) + { + (*it)->drop(); + it = AffectorList.erase(it); + } +} + + +//! Returns the material based on the zero based index i. +video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i) +{ + return Buffer->Material; +} + + +//! Returns amount of materials used by this scene node. +u32 CParticleSystemSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Creates a particle emitter for an animated mesh scene node +IParticleAnimatedMeshSceneNodeEmitter* +CParticleSystemSceneNode::createAnimatedMeshSceneNodeEmitter( + scene::IAnimatedMeshSceneNode* node, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) +{ + return new CParticleAnimatedMeshSceneNodeEmitter( node, + useNormalDirection, direction, normalDirectionModifier, + mbNumber, everyMeshVertex, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a box particle emitter. +IParticleBoxEmitter* CParticleSystemSceneNode::createBoxEmitter( + const core::aabbox3df& box, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees, const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) +{ + return new CParticleBoxEmitter(box, direction, minParticlesPerSecond, + maxParticlesPerSecond, minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a particle emitter for emitting from a cylinder +IParticleCylinderEmitter* CParticleSystemSceneNode::createCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) +{ + return new CParticleCylinderEmitter( center, radius, normal, length, + outlineOnly, direction, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a mesh particle emitter. +IParticleMeshEmitter* CParticleSystemSceneNode::createMeshEmitter( + scene::IMesh* mesh, bool useNormalDirection, + const core::vector3df& direction, f32 normalDirectionModifier, + s32 mbNumber, bool everyMeshVertex, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize) +{ + return new CParticleMeshEmitter( mesh, useNormalDirection, direction, + normalDirectionModifier, mbNumber, everyMeshVertex, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a point particle emitter. +IParticlePointEmitter* CParticleSystemSceneNode::createPointEmitter( + const core::vector3df& direction, u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, const video::SColor& minStartColor, + const video::SColor& maxStartColor, u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees, const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) +{ + return new CParticlePointEmitter(direction, minParticlesPerSecond, + maxParticlesPerSecond, minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a ring particle emitter. +IParticleRingEmitter* CParticleSystemSceneNode::createRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, s32 maxAngleDegrees, + const core::dimension2df& minStartSize, const core::dimension2df& maxStartSize ) +{ + return new CParticleRingEmitter( center, radius, ringThickness, direction, + minParticlesPerSecond, maxParticlesPerSecond, minStartColor, + maxStartColor, lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a sphere particle emitter. +IParticleSphereEmitter* CParticleSystemSceneNode::createSphereEmitter( + const core::vector3df& center, f32 radius, const core::vector3df& direction, + u32 minParticlesPerSecond, u32 maxParticlesPerSecond, + const video::SColor& minStartColor, const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees, const core::dimension2df& minStartSize, + const core::dimension2df& maxStartSize ) +{ + return new CParticleSphereEmitter(center, radius, direction, + minParticlesPerSecond, maxParticlesPerSecond, + minStartColor, maxStartColor, + lifeTimeMin, lifeTimeMax, maxAngleDegrees, + minStartSize, maxStartSize ); +} + + +//! Creates a point attraction affector. This affector modifies the positions of the +//! particles and attracts them to a specified point at a specified speed per second. +IParticleAttractionAffector* CParticleSystemSceneNode::createAttractionAffector( + const core::vector3df& point, f32 speed, bool attract, + bool affectX, bool affectY, bool affectZ ) +{ + return new CParticleAttractionAffector( point, speed, attract, affectX, affectY, affectZ ); +} + +//! Creates a scale particle affector. +IParticleAffector* CParticleSystemSceneNode::createScaleParticleAffector(const core::dimension2df& scaleTo) +{ + return new CParticleScaleAffector(scaleTo); +} + + +//! Creates a fade out particle affector. +IParticleFadeOutAffector* CParticleSystemSceneNode::createFadeOutParticleAffector( + const video::SColor& targetColor, u32 timeNeededToFadeOut) +{ + return new CParticleFadeOutAffector(targetColor, timeNeededToFadeOut); +} + + +//! Creates a gravity affector. +IParticleGravityAffector* CParticleSystemSceneNode::createGravityAffector( + const core::vector3df& gravity, u32 timeForceLost) +{ + return new CParticleGravityAffector(gravity, timeForceLost); +} + + +//! Creates a rotation affector. This affector rotates the particles around a specified pivot +//! point. The speed represents Degrees of rotation per second. +IParticleRotationAffector* CParticleSystemSceneNode::createRotationAffector( + const core::vector3df& speed, const core::vector3df& pivotPoint ) +{ + return new CParticleRotationAffector( speed, pivotPoint ); +} + + +//! pre render event +void CParticleSystemSceneNode::OnRegisterSceneNode() +{ + doParticleSystem(os::Timer::getTime()); + + if (IsVisible && (Particles.size() != 0)) + { + SceneManager->registerNodeForRendering(this); + ISceneNode::OnRegisterSceneNode(); + } +} + + +//! render +void CParticleSystemSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + +#if 0 + // calculate vectors for letting particles look to camera + core::vector3df view(camera->getTarget() - camera->getAbsolutePosition()); + view.normalize(); + + view *= -1.0f; + +#else + + const core::matrix4 &m = camera->getViewFrustum()->getTransform( video::ETS_VIEW ); + + const core::vector3df view ( -m[2], -m[6] , -m[10] ); + +#endif + + // reallocate arrays, if they are too small + reallocateBuffers(); + + // create particle vertex data + s32 idx = 0; + for (u32 i=0; igetUpVector().crossProduct(view); + horizontal.normalize(); + horizontal *= 0.5f * particle.size.Width; + + core::vector3df vertical = horizontal.crossProduct(view); + vertical.normalize(); + vertical *= 0.5f * particle.size.Height; + + #else + f32 f; + + f = 0.5f * particle.size.Width; + const core::vector3df horizontal ( m[0] * f, m[4] * f, m[8] * f ); + + f = -0.5f * particle.size.Height; + const core::vector3df vertical ( m[1] * f, m[5] * f, m[9] * f ); + #endif + + Buffer->Vertices[0+idx].Pos = particle.pos + horizontal + vertical; + Buffer->Vertices[0+idx].Color = particle.color; + Buffer->Vertices[0+idx].Normal = view; + + Buffer->Vertices[1+idx].Pos = particle.pos + horizontal - vertical; + Buffer->Vertices[1+idx].Color = particle.color; + Buffer->Vertices[1+idx].Normal = view; + + Buffer->Vertices[2+idx].Pos = particle.pos - horizontal - vertical; + Buffer->Vertices[2+idx].Color = particle.color; + Buffer->Vertices[2+idx].Normal = view; + + Buffer->Vertices[3+idx].Pos = particle.pos - horizontal + vertical; + Buffer->Vertices[3+idx].Color = particle.color; + Buffer->Vertices[3+idx].Normal = view; + + idx +=4; + } + + // render all + core::matrix4 mat; + if (!ParticlesAreGlobal) + mat.setTranslation(AbsoluteTransformation.getTranslation()); + driver->setTransform(video::ETS_WORLD, mat); + + driver->setMaterial(Buffer->Material); + + driver->drawVertexPrimitiveList(Buffer->getVertices(), Particles.size()*4, + Buffer->getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES,Buffer->getIndexType()); + + // for debug purposes only: + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial deb_m; + deb_m.Lighting = false; + driver->setMaterial(deb_m); + driver->draw3DBox(Buffer->BoundingBox, video::SColor(0,255,255,255)); + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CParticleSystemSceneNode::getBoundingBox() const +{ + return Buffer->getBoundingBox(); +} + + +void CParticleSystemSceneNode::doParticleSystem(u32 time) +{ + if (LastEmitTime==0) + { + LastEmitTime = time; + return; + } + + u32 now = time; + u32 timediff = time - LastEmitTime; + LastEmitTime = time; + + // run emitter + + if (Emitter && IsVisible) + { + SParticle* array = 0; + s32 newParticles = Emitter->emitt(now, timediff, array); + + if (newParticles && array) + { + s32 j=Particles.size(); + if (newParticles > 16250-j) + newParticles=16250-j; + Particles.set_used(j+newParticles); + for (s32 i=j; i::Iterator ait = AffectorList.begin(); + for (; ait != AffectorList.end(); ++ait) + (*ait)->affect(now, Particles.pointer(), Particles.size()); + + if (ParticlesAreGlobal) + Buffer->BoundingBox.reset(AbsoluteTransformation.getTranslation()); + else + Buffer->BoundingBox.reset(core::vector3df(0,0,0)); + + // animate all particles + f32 scale = (f32)timediff; + + for (u32 i=0; i Particles[i].endTime) + { + // Particle order does not seem to matter. + // So we can delete by switching with last particle and deleting that one. + // This is a lot faster and speed is very important here as the erase otherwise + // can cause noticable freezes. + Particles[i] = Particles[Particles.size()-1]; + Particles.erase( Particles.size()-1 ); + } + else + { + Particles[i].pos += (Particles[i].vector * scale); + Buffer->BoundingBox.addInternalPoint(Particles[i].pos); + ++i; + } + } + + const f32 m = (ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height) * 0.5f; + Buffer->BoundingBox.MaxEdge.X += m; + Buffer->BoundingBox.MaxEdge.Y += m; + Buffer->BoundingBox.MaxEdge.Z += m; + + Buffer->BoundingBox.MinEdge.X -= m; + Buffer->BoundingBox.MinEdge.Y -= m; + Buffer->BoundingBox.MinEdge.Z -= m; + + if (ParticlesAreGlobal) + { + core::matrix4 absinv( AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE ); + absinv.transformBoxEx(Buffer->BoundingBox); + } +} + + +//! Sets if the particles should be global. If it is, the particles are affected by +//! the movement of the particle system scene node too, otherwise they completely +//! ignore it. Default is true. +void CParticleSystemSceneNode::setParticlesAreGlobal(bool global) +{ + ParticlesAreGlobal = global; +} + +//! Remove all currently visible particles +void CParticleSystemSceneNode::clearParticles() +{ + Particles.set_used(0); +} + +//! Sets the size of all particles. +void CParticleSystemSceneNode::setParticleSize(const core::dimension2d &size) +{ + os::Printer::log("setParticleSize is deprecated, use setMinStartSize/setMaxStartSize in emitter.", irr::ELL_WARNING); + //A bit of a hack, but better here than in the particle code + if (Emitter) + { + Emitter->setMinStartSize(size); + Emitter->setMaxStartSize(size); + } + ParticleSize = size; +} + + +void CParticleSystemSceneNode::reallocateBuffers() +{ + if (Particles.size() * 4 > Buffer->getVertexCount() || + Particles.size() * 6 > Buffer->getIndexCount()) + { + u32 oldSize = Buffer->getVertexCount(); + Buffer->Vertices.set_used(Particles.size() * 4); + + u32 i; + + // fill remaining vertices + for (i=oldSize; iVertices.size(); i+=4) + { + Buffer->Vertices[0+i].TCoords.set(0.0f, 0.0f); + Buffer->Vertices[1+i].TCoords.set(0.0f, 1.0f); + Buffer->Vertices[2+i].TCoords.set(1.0f, 1.0f); + Buffer->Vertices[3+i].TCoords.set(1.0f, 0.0f); + } + + // fill remaining indices + u32 oldIdxSize = Buffer->getIndexCount(); + u32 oldvertices = oldSize; + Buffer->Indices.set_used(Particles.size() * 6); + + for (i=oldIdxSize; iIndices.size(); i+=6) + { + Buffer->Indices[0+i] = (u16)0+oldvertices; + Buffer->Indices[1+i] = (u16)2+oldvertices; + Buffer->Indices[2+i] = (u16)1+oldvertices; + Buffer->Indices[3+i] = (u16)0+oldvertices; + Buffer->Indices[4+i] = (u16)3+oldvertices; + Buffer->Indices[5+i] = (u16)2+oldvertices; + oldvertices += 4; + } + } +} + + +//! Writes attributes of the scene node. +void CParticleSystemSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + IParticleSystemSceneNode::serializeAttributes(out, options); + + out->addBool("GlobalParticles", ParticlesAreGlobal); + out->addFloat("ParticleWidth", ParticleSize.Width); + out->addFloat("ParticleHeight", ParticleSize.Height); + + // write emitter + + E_PARTICLE_EMITTER_TYPE type = EPET_COUNT; + if (Emitter) + type = Emitter->getType(); + + out->addEnum("Emitter", (s32)type, ParticleEmitterTypeNames); + + if (Emitter) + Emitter->serializeAttributes(out, options); + + // write affectors + + E_PARTICLE_AFFECTOR_TYPE atype = EPAT_NONE; + + for (core::list::ConstIterator it = AffectorList.begin(); + it != AffectorList.end(); ++it) + { + atype = (*it)->getType(); + + out->addEnum("Affector", (s32)atype, ParticleAffectorTypeNames); + + (*it)->serializeAttributes(out); + } + + // add empty affector to make it possible to add further affectors + + if (options && options->Flags & io::EARWF_FOR_EDITOR) + out->addEnum("Affector", EPAT_NONE, ParticleAffectorTypeNames); +} + + +//! Reads attributes of the scene node. +void CParticleSystemSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + IParticleSystemSceneNode::deserializeAttributes(in, options); + + ParticlesAreGlobal = in->getAttributeAsBool("GlobalParticles"); + ParticleSize.Width = in->getAttributeAsFloat("ParticleWidth"); + ParticleSize.Height = in->getAttributeAsFloat("ParticleHeight"); + + // read emitter + + int emitterIdx = in->findAttribute("Emitter"); + if (emitterIdx == -1) + return; + + if (Emitter) + Emitter->drop(); + Emitter = 0; + + E_PARTICLE_EMITTER_TYPE type = (E_PARTICLE_EMITTER_TYPE) + in->getAttributeAsEnumeration("Emitter", ParticleEmitterTypeNames); + + switch(type) + { + case EPET_POINT: + Emitter = createPointEmitter(); + break; + case EPET_ANIMATED_MESH: + Emitter = createAnimatedMeshSceneNodeEmitter(NULL); // we can't set the node - the user will have to do this + break; + case EPET_BOX: + Emitter = createBoxEmitter(); + break; + case EPET_CYLINDER: + Emitter = createCylinderEmitter(core::vector3df(0,0,0), 10.f, core::vector3df(0,1,0), 10.f); // (values here don't matter) + break; + case EPET_MESH: + Emitter = createMeshEmitter(NULL); // we can't set the mesh - the user will have to do this + break; + case EPET_RING: + Emitter = createRingEmitter(core::vector3df(0,0,0), 10.f, 10.f); // (values here don't matter) + break; + case EPET_SPHERE: + Emitter = createSphereEmitter(core::vector3df(0,0,0), 10.f); // (values here don't matter) + break; + default: + break; + } + + u32 idx = 0; + +#if 0 + if (Emitter) + idx = Emitter->deserializeAttributes(idx, in); + + ++idx; +#else + if (Emitter) + Emitter->deserializeAttributes(in); +#endif + + // read affectors + + removeAllAffectors(); + u32 cnt = in->getAttributeCount(); + + while(idx < cnt) + { + const char* name = in->getAttributeName(idx); + + if (!name || strcmp("Affector", name)) + return; + + E_PARTICLE_AFFECTOR_TYPE atype = + (E_PARTICLE_AFFECTOR_TYPE)in->getAttributeAsEnumeration(idx, ParticleAffectorTypeNames); + + IParticleAffector* aff = 0; + + switch(atype) + { + case EPAT_ATTRACT: + aff = createAttractionAffector(core::vector3df(0,0,0)); + break; + case EPAT_FADE_OUT: + aff = createFadeOutParticleAffector(); + break; + case EPAT_GRAVITY: + aff = createGravityAffector(); + break; + case EPAT_ROTATE: + aff = createRotationAffector(); + break; + case EPAT_SCALE: + aff = createScaleParticleAffector(); + break; + case EPAT_NONE: + default: + break; + } + + ++idx; + + if (aff) + { +#if 0 + idx = aff->deserializeAttributes(idx, in, options); + ++idx; +#else + aff->deserializeAttributes(in, options); +#endif + + addAffector(aff); + aff->drop(); + } + } +} + + +} // end namespace scene +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.h new file mode 100644 index 0000000..24ae48c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CParticleSystemSceneNode.h @@ -0,0 +1,239 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ +#define __C_PARTICLE_SYSTEM_SCENE_NODE_H_INCLUDED__ + +#include "IParticleSystemSceneNode.h" +#include "irrArray.h" +#include "irrList.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +//! A particle system scene node. +/** A scene node controlling a particle system. The behavior of the particles +can be controlled by setting the right particle emitters and affectors. +*/ +class CParticleSystemSceneNode : public IParticleSystemSceneNode +{ +public: + + //! constructor + CParticleSystemSceneNode(bool createDefaultEmitter, + ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale); + + //! destructor + virtual ~CParticleSystemSceneNode(); + + //! Gets the particle emitter, which creates the particles. + virtual IParticleEmitter* getEmitter(); + + //! Sets the particle emitter, which creates the particles. + virtual void setEmitter(IParticleEmitter* emitter); + + //! Adds new particle affector to the particle system. + virtual void addAffector(IParticleAffector* affector); + + //! Get a list of all particle affectors. + virtual const core::list& getAffectors() const; + + //! Removes all particle affectors in the particle system. + virtual void removeAllAffectors(); + + //! Returns the material based on the zero based index i. + virtual video::SMaterial& getMaterial(u32 i); + + //! Returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! pre render event + virtual void OnRegisterSceneNode(); + + //! render + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Creates a particle emitter for an animated mesh scene node + virtual IParticleAnimatedMeshSceneNodeEmitter* createAnimatedMeshSceneNodeEmitter( + scene::IAnimatedMeshSceneNode* node, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a box particle emitter. + virtual IParticleBoxEmitter* createBoxEmitter( + const core::aabbox3df& box = core::aabbox3d(-10,0,-10,5,30,10), + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a particle emitter for emitting from a cylinder + virtual IParticleCylinderEmitter* createCylinderEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& normal, f32 length, + bool outlineOnly = false, const core::vector3df& direction = core::vector3df(0.0f,0.5f,0.0f), + u32 minParticlesPerSecond = 5, u32 maxParticlesPersSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a mesh particle emitter. + virtual IParticleMeshEmitter* createMeshEmitter( + scene::IMesh* mesh, bool useNormalDirection = true, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + f32 normalDirectionModifier = 100.0f, s32 mbNumber = -1, + bool everyMeshVertex = false, + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin = 2000, u32 lifeTimeMax = 4000, + s32 maxAngleDegrees = 0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a point particle emitter. + virtual IParticlePointEmitter* createPointEmitter( + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a ring particle emitter. + virtual IParticleRingEmitter* createRingEmitter( + const core::vector3df& center, f32 radius, f32 ringThickness, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a sphere particle emitter. + virtual IParticleSphereEmitter* createSphereEmitter( + const core::vector3df& center, f32 radius, + const core::vector3df& direction = core::vector3df(0.0f,0.03f,0.0f), + u32 minParticlesPerSecond = 5, + u32 maxParticlesPerSecond = 10, + const video::SColor& minStartColor = video::SColor(255,0,0,0), + const video::SColor& maxStartColor = video::SColor(255,255,255,255), + u32 lifeTimeMin=2000, u32 lifeTimeMax=4000, + s32 maxAngleDegrees=0, + const core::dimension2df& minStartSize = core::dimension2df(5.0f,5.0f), + const core::dimension2df& maxStartSize = core::dimension2df(5.0f,5.0f) ); + + //! Creates a point attraction affector. This affector modifies the positions of the + //! particles and attracts them to a specified point at a specified speed per second. + virtual IParticleAttractionAffector* createAttractionAffector( + const core::vector3df& point, f32 speed = 1.0f, bool attract = true, + bool affectX = true, bool affectY = true, bool affectZ = true); + + //! Creates a scale particle affector. + virtual IParticleAffector* createScaleParticleAffector(const core::dimension2df& scaleTo = core::dimension2df(1.0f, 1.0f)); + + //! Creates a fade out particle affector. + virtual IParticleFadeOutAffector* createFadeOutParticleAffector( + const video::SColor& targetColor = video::SColor(0,0,0,0), + u32 timeNeededToFadeOut = 1000); + + //! Creates a gravity affector. + virtual IParticleGravityAffector* createGravityAffector( + const core::vector3df& gravity = core::vector3df(0.0f,-0.03f,0.0f), + u32 timeForceLost = 1000); + + //! Creates a rotation affector. This affector rotates the particles + //! around a specified pivot point. The speed is in Degrees per second. + virtual IParticleRotationAffector* createRotationAffector( + const core::vector3df& speed = core::vector3df(5.0f,5.0f,5.0f), + const core::vector3df& pivotPoint = core::vector3df(0.0f,0.0f,0.0f) ); + + //! Sets the size of all particles. + virtual void setParticleSize( + const core::dimension2d &size = core::dimension2d(5.0f, 5.0f)); + + //! Sets if the particles should be global. If they are, the particles are affected by + //! the movement of the particle system scene node too, otherwise they completely + //! ignore it. Default is true. + virtual void setParticlesAreGlobal(bool global=true); + + //! Remove all currently visible particles + virtual void clearParticles(); + + //! Do manually update the particles. + //! This should only be called when you want to render the node outside the scenegraph, + //! as the node will care about this otherwise automatically. + virtual void doParticleSystem(u32 time); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_PARTICLE_SYSTEM; } + +private: + + void reallocateBuffers(); + + core::list AffectorList; + IParticleEmitter* Emitter; + core::array Particles; + core::dimension2d ParticleSize; + u32 LastEmitTime; + s32 MaxParticles; + + SMeshBuffer* Buffer; + + enum E_PARTICLES_PRIMITIVE + { + EPP_POINT=0, + EPP_BILLBOARD, + EPP_POINTSPRITE + }; + E_PARTICLES_PRIMITIVE ParticlePrimitive; + + bool ParticlesAreGlobal; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.cpp new file mode 100644 index 0000000..0e0c05a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.cpp @@ -0,0 +1,2082 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + +#include "CQ3LevelMesh.h" +#include "ISceneManager.h" +#include "os.h" +#include "SMeshBufferLightMap.h" +#include "irrString.h" +#include "ILightSceneNode.h" +#include "IQ3Shader.h" +#include "IFileList.h" + +//#define TJUNCTION_SOLVER_ROUND +//#define TJUNCTION_SOLVER_0125 + +namespace irr +{ +namespace scene +{ + + using namespace quake3; + +//! constructor +CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, scene::ISceneManager* smgr, + const Q3LevelLoadParameter &loadParam) + : LoadParam(loadParam), Textures(0), NumTextures(0), LightMaps(0), NumLightMaps(0), + Vertices(0), NumVertices(0), Faces(0), NumFaces(0), Models(0), NumModels(0), + Planes(0), NumPlanes(0), Nodes(0), NumNodes(0), Leafs(0), NumLeafs(0), + LeafFaces(0), NumLeafFaces(0), MeshVerts(0), NumMeshVerts(0), + Brushes(0), NumBrushes(0), BrushEntities(0), FileSystem(fs), + SceneManager(smgr), FramesPerSecond(25.f) +{ + #ifdef _DEBUG + IReferenceCounted::setDebugName("CQ3LevelMesh"); + #endif + + for ( s32 i = 0; i!= E_Q3_MESH_SIZE; ++i ) + { + Mesh[i] = 0; + } + + Driver = smgr ? smgr->getVideoDriver() : 0; + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); + + // load default shaders + InitShader(); +} + + +//! destructor +CQ3LevelMesh::~CQ3LevelMesh() +{ + cleanLoader (); + + if (Driver) + Driver->drop(); + + if (FileSystem) + FileSystem->drop(); + + s32 i; + + for ( i = 0; i!= E_Q3_MESH_SIZE; ++i ) + { + if ( Mesh[i] ) + { + Mesh[i]->drop(); + Mesh[i] = 0; + } + } + + for ( i = 1; i < NumModels; i++ ) + { + BrushEntities[i]->drop(); + } + delete [] BrushEntities; BrushEntities = 0; + + ReleaseShader(); + ReleaseEntity(); +} + + +//! loads a level from a .bsp-File. Also tries to load all needed textures. Returns true if successful. +bool CQ3LevelMesh::loadFile(io::IReadFile* file) +{ + if (!file) + return false; + + LevelName = file->getFileName(); + + file->read(&header, sizeof(tBSPHeader)); + + #ifdef __BIG_ENDIAN__ + header.strID = os::Byteswap::byteswap(header.strID); + header.version = os::Byteswap::byteswap(header.version); + #endif + + if ( (header.strID != 0x50534249 || // IBSP + ( header.version != 0x2e // quake3 + && header.version != 0x2f // rtcw + ) + ) + && + ( header.strID != 0x50534252 || header.version != 1 ) // RBSP, starwars jedi, sof + ) + { + os::Printer::log("Could not load .bsp file, unknown header.", file->getFileName(), ELL_ERROR); + return false; + } + +#if 0 + if ( header.strID == 0x50534252 ) // RBSP Raven + { + LoadParam.swapHeader = 1; + } +#endif + + // now read lumps + file->read(&Lumps[0], sizeof(tBSPLump)*kMaxLumps); + + s32 i; + if ( LoadParam.swapHeader ) + { + for ( i=0; i< kMaxLumps;++i) + { + Lumps[i].offset = os::Byteswap::byteswap(Lumps[i].offset); + Lumps[i].length = os::Byteswap::byteswap(Lumps[i].length); + } + } + + ReleaseEntity(); + + // load everything + loadEntities(&Lumps[kEntities], file); // load the entities + loadTextures(&Lumps[kShaders], file); // Load the textures + loadLightmaps(&Lumps[kLightmaps], file); // Load the lightmaps + loadVerts(&Lumps[kVertices], file); // Load the vertices + loadFaces(&Lumps[kFaces], file); // Load the faces + loadPlanes(&Lumps[kPlanes], file); // Load the Planes of the BSP + loadNodes(&Lumps[kNodes], file); // load the Nodes of the BSP + loadLeafs(&Lumps[kLeafs], file); // load the Leafs of the BSP + loadLeafFaces(&Lumps[kLeafFaces], file); // load the Faces of the Leafs of the BSP + loadVisData(&Lumps[kVisData], file); // load the visibility data of the clusters + loadModels(&Lumps[kModels], file); // load the models + loadMeshVerts(&Lumps[kMeshVerts], file); // load the mesh vertices + loadBrushes(&Lumps[kBrushes], file); // load the brushes of the BSP + loadBrushSides(&Lumps[kBrushSides], file); // load the brushsides of the BSP + loadLeafBrushes(&Lumps[kLeafBrushes], file); // load the brushes of the leaf + loadFogs(&Lumps[kFogs], file ); // load the fogs + + loadTextures(); + constructMesh(); + solveTJunction(); + + cleanMeshes(); + calcBoundingBoxes(); + cleanLoader(); + + return true; +} + +/*! +*/ +void CQ3LevelMesh::cleanLoader () +{ + delete [] Textures; Textures = 0; + delete [] LightMaps; LightMaps = 0; + delete [] Vertices; Vertices = 0; + delete [] Faces; Faces = 0; + delete [] Models; Models = 0; + delete [] Planes; Planes = 0; + delete [] Nodes; Nodes = 0; + delete [] Leafs; Leafs = 0; + delete [] LeafFaces; LeafFaces = 0; + delete [] MeshVerts; MeshVerts = 0; + delete [] Brushes; Brushes = 0; + + Lightmap.clear(); + Tex.clear(); +} + +//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. +u32 CQ3LevelMesh::getFrameCount() const +{ + return 1; +} + + +//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. +IMesh* CQ3LevelMesh::getMesh(s32 frameInMs, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + return Mesh[frameInMs]; +} + + +void CQ3LevelMesh::loadTextures(tBSPLump* l, io::IReadFile* file) +{ + NumTextures = l->length / sizeof(tBSPTexture); + if ( !NumTextures ) + return; + Textures = new tBSPTexture[NumTextures]; + + file->seek(l->offset); + file->read(Textures, l->length); + + if ( LoadParam.swapHeader ) + { + for (s32 i=0;ilength / sizeof(tBSPLightmap); + if ( !NumLightMaps ) + return; + LightMaps = new tBSPLightmap[NumLightMaps]; + + file->seek(l->offset); + file->read(LightMaps, l->length); +} + +/*! +*/ +void CQ3LevelMesh::loadVerts(tBSPLump* l, io::IReadFile* file) +{ + NumVertices = l->length / sizeof(tBSPVertex); + if ( !NumVertices ) + return; + Vertices = new tBSPVertex[NumVertices]; + + file->seek(l->offset); + file->read(Vertices, l->length); + + if ( LoadParam.swapHeader ) + for (s32 i=0;ilength / sizeof(tBSPFace); + if (!NumFaces) + return; + Faces = new tBSPFace[NumFaces]; + + file->seek(l->offset); + file->read(Faces, l->length); + + if ( LoadParam.swapHeader ) + { + for ( s32 i=0;i entity; + entity.set_used( l->length + 2 ); + entity[l->length + 1 ] = 0; + + file->seek(l->offset); + file->read( entity.pointer(), l->length); + + parser_parse( entity.pointer(), l->length, &CQ3LevelMesh::scriptcallback_entity ); +} + + +/*! + load fog brushes +*/ +void CQ3LevelMesh::loadFogs(tBSPLump* l, io::IReadFile* file) +{ + u32 files = l->length / sizeof(tBSPFog); + + file->seek( l->offset ); + tBSPFog fog; + const IShader *shader; + STexShader t; + for ( u32 i = 0; i!= files; ++i ) + { + file->read( &fog, sizeof( fog ) ); + + shader = getShader( fog.shader ); + t.Texture = 0; + t.ShaderID = shader ? shader->ID : -1; + + FogMap.push_back ( t ); + } +} + + +/*! + load models named in bsp +*/ +void CQ3LevelMesh::loadModels(tBSPLump* l, io::IReadFile* file) +{ + NumModels = l->length / sizeof(tBSPModel); + Models = new tBSPModel[NumModels]; + + file->seek( l->offset ); + file->read(Models, l->length); + + if ( LoadParam.swapHeader ) + { + for ( s32 i = 0; i < NumModels; i++) + { + Models[i].min[0] = os::Byteswap::byteswap(Models[i].min[0]); + Models[i].min[1] = os::Byteswap::byteswap(Models[i].min[1]); + Models[i].min[2] = os::Byteswap::byteswap(Models[i].min[2]); + Models[i].max[0] = os::Byteswap::byteswap(Models[i].max[0]); + Models[i].max[1] = os::Byteswap::byteswap(Models[i].max[1]); + Models[i].max[2] = os::Byteswap::byteswap(Models[i].max[2]); + + Models[i].faceIndex = os::Byteswap::byteswap(Models[i].faceIndex); + Models[i].numOfFaces = os::Byteswap::byteswap(Models[i].numOfFaces); + Models[i].brushIndex = os::Byteswap::byteswap(Models[i].brushIndex); + Models[i].numOfBrushes = os::Byteswap::byteswap(Models[i].numOfBrushes); + } + } + + BrushEntities = new SMesh*[NumModels]; +} + +/*! +*/ +void CQ3LevelMesh::loadMeshVerts(tBSPLump* l, io::IReadFile* file) +{ + NumMeshVerts = l->length / sizeof(s32); + if (!NumMeshVerts) + return; + MeshVerts = new s32[NumMeshVerts]; + + file->seek(l->offset); + file->read(MeshVerts, l->length); + + if ( LoadParam.swapHeader ) + { + for (int i=0;i= 'a' && symbol <= 'z' ) || + (symbol >= 'A' && symbol <= 'Z' ) || + (symbol >= '0' && symbol <= '9' ) || + (symbol == '/' || symbol == '_' || symbol == '.' ); +} + +/*! +*/ +void CQ3LevelMesh::parser_nextToken() +{ + u8 symbol; + + Parser.token = ""; + Parser.tokenresult = Q3_TOKEN_UNRESOLVED; + + // skip white space + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + } while ( isQ3WhiteSpace( symbol ) ); + + // first symbol, one symbol + switch ( symbol ) + { + case 0: + Parser.tokenresult = Q3_TOKEN_EOF; + return; + + case '/': + // comment or divide + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + if ( isQ3WhiteSpace( symbol ) ) + { + Parser.tokenresult = Q3_TOKEN_MATH_DIVIDE; + return; + } + else + if ( symbol == '*' ) + { + // C-style comment in quake? + } + else + if ( symbol == '/' ) + { + // skip to eol + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + } while ( symbol != '\n' ); + Parser.tokenresult = Q3_TOKEN_COMMENT; + return; + } + // take /[name] as valid token..?!?!?. mhmm, maybe + break; + + case '\n': + Parser.tokenresult = Q3_TOKEN_EOL; + return; + case '{': + Parser.tokenresult = Q3_TOKEN_START_LIST; + return; + case '}': + Parser.tokenresult = Q3_TOKEN_END_LIST; + return; + + case '"': + // string literal + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + Parser.index += 1; + if ( symbol != '"' ) + Parser.token.append( symbol ); + } while ( symbol != '"' ); + Parser.tokenresult = Q3_TOKEN_ENTITY; + return; + } + + // user identity + Parser.token.append( symbol ); + + // continue till whitespace + bool validName = true; + do + { + if ( Parser.index >= Parser.sourcesize ) + { + Parser.tokenresult = Q3_TOKEN_EOF; + return; + } + symbol = Parser.source [ Parser.index ]; + + validName = isQ3ValidName( symbol ); + if ( validName ) + { + Parser.token.append( symbol ); + Parser.index += 1; + } + } while ( validName ); + + Parser.tokenresult = Q3_TOKEN_TOKEN; + return; +} + + +/* + parse entity & shader + calls callback on content in {} +*/ +void CQ3LevelMesh::parser_parse( const void * data, const u32 size, CQ3LevelMesh::tParserCallback callback ) +{ + Parser.source = static_cast(data); + Parser.sourcesize = size; + Parser.index = 0; + + SVarGroupList *groupList; + + s32 active; + s32 last; + + SVariable entity ( "" ); + + groupList = new SVarGroupList(); + + groupList->VariableGroup.push_back( SVarGroup() ); + active = last = 0; + + do + { + parser_nextToken(); + + switch ( Parser.tokenresult ) + { + case Q3_TOKEN_START_LIST: + { + //stack = core::min_( stack + 1, 7 ); + + groupList->VariableGroup.push_back( SVarGroup() ); + last = active; + active = groupList->VariableGroup.size() - 1; + entity.clear(); + } break; + + // a unregisterd variable is finished + case Q3_TOKEN_EOL: + { + if ( entity.isValid() ) + { + groupList->VariableGroup[active].Variable.push_back( entity ); + entity.clear(); + } + } break; + + case Q3_TOKEN_TOKEN: + case Q3_TOKEN_ENTITY: + { + Parser.token.make_lower(); + + // store content based on line-delemiter + if ( 0 == entity.isValid() ) + { + entity.name = Parser.token; + entity.content = ""; + + } + else + { + if ( entity.content.size() ) + { + entity.content += " "; + } + entity.content += Parser.token; + } + } break; + + case Q3_TOKEN_END_LIST: + { + //stack = core::max_( stack - 1, 0 ); + + // close tag for first + if ( active == 1 ) + { + (this->*callback)( groupList, Q3_TOKEN_END_LIST ); + + // new group + groupList->drop(); + groupList = new SVarGroupList(); + groupList->VariableGroup.push_back( SVarGroup() ); + last = 0; + } + + active = last; + entity.clear(); + + } break; + + default: + break; + } + + } while ( Parser.tokenresult != Q3_TOKEN_EOF ); + + (this->*callback)( groupList, Q3_TOKEN_EOF ); + + groupList->drop(); +} + + +/* + this loader applies only textures for stage 1 & 2 +*/ +s32 CQ3LevelMesh::setShaderFogMaterial( video::SMaterial &material, const tBSPFace * face ) const +{ + material.MaterialType = video::EMT_SOLID; + material.Wireframe = false; + material.Lighting = false; + material.BackfaceCulling = false; + material.setTexture(0, 0); + material.setTexture(1, 0); + material.setTexture(2, 0); + material.setTexture(3, 0); + material.ZBuffer = video::ECFN_LESSEQUAL; + material.ZWriteEnable = false; + material.MaterialTypeParam = 0.f; + + s32 shaderState = -1; + + if ( (u32) face->fogNum < FogMap.size() ) + { + material.setTexture(0, FogMap [ face->fogNum ].Texture); + shaderState = FogMap [ face->fogNum ].ShaderID; + } + + return shaderState; + +} +/* + this loader applies only textures for stage 1 & 2 +*/ +s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace * face ) const +{ + material.MaterialType = video::EMT_SOLID; + material.Wireframe = false; + material.Lighting = false; + material.BackfaceCulling = true; + material.setTexture(0, 0); + material.setTexture(1, 0); + material.setTexture(2, 0); + material.setTexture(3, 0); + material.ZBuffer = video::ECFN_LESSEQUAL; + material.ZWriteEnable = true; + material.MaterialTypeParam = 0.f; + + s32 shaderState = -1; + + if ( face->textureID >= 0 && face->textureID < (s32)Tex.size() ) + { + material.setTexture(0, Tex [ face->textureID ].Texture); + shaderState = Tex [ face->textureID ].ShaderID; + } + + if ( face->lightmapID >= 0 && face->lightmapID < (s32)Lightmap.size() ) + { + material.setTexture(1, Lightmap [ face->lightmapID ]); + material.MaterialType = LoadParam.defaultLightMapMaterial; + } + + // store shader ID + material.MaterialTypeParam2 = (f32) shaderState; + + const IShader *shader = getShader(shaderState); + if ( 0 == shader ) + return shaderState; + + return shaderState; + +#if 0 + const SVarGroup *group; + + + // generic + group = shader->getGroup( 1 ); + if ( group ) + { + material.BackfaceCulling = getCullingFunction( group->get( "cull" ) ); + + if ( group->isDefined( "surfaceparm", "nolightmap" ) ) + { + material.MaterialType = video::EMT_SOLID; + material.setTexture(1, 0); + } + + } + + // try to get the best of the 8 texture stages.. + + // texture 1, texture 2 + u32 startPos; + for ( s32 g = 2; g <= 3; ++g ) + { + group = shader->getGroup( g ); + if ( 0 == group ) + continue; + + startPos = 0; + + if ( group->isDefined( "depthwrite" ) ) + { + material.ZWriteEnable = true; + } + + SBlendFunc blendfunc ( LoadParam.defaultModulate ); + getBlendFunc( group->get( "blendfunc" ), blendfunc ); + getBlendFunc( group->get( "alphafunc" ), blendfunc ); + + if ( 0 == LoadParam.alpharef && + ( blendfunc.type == video::EMT_TRANSPARENT_ALPHA_CHANNEL || + blendfunc.type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF + ) + ) + { + blendfunc.type = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + blendfunc.param0 = 0.f; + } + + material.MaterialType = blendfunc.type; + material.MaterialTypeParam = blendfunc.param0; + + // try if we can match better + shaderState |= (material.MaterialType == video::EMT_SOLID ) ? 0x00020000 : 0; + } + + //material.BackfaceCulling = false; + + if ( shader->VarGroup->VariableGroup.size() <= 4 ) + { + shaderState |= 0x00010000; + } + + material.MaterialTypeParam2 = (f32) shaderState; + return shaderState; +#endif +} + +/*! + Internal function to build a mesh. +*/ +scene::SMesh** CQ3LevelMesh::buildMesh(s32 num) +{ + scene::SMesh** newmesh = new SMesh *[quake3::E_Q3_MESH_SIZE]; + + s32 i, j, k,s; + + for (i = 0; i < E_Q3_MESH_SIZE; i++) + { + newmesh[i] = new SMesh(); + } + + s32 *index; + + video::S3DVertex2TCoords temp[3]; + video::SMaterial material; + video::SMaterial material2; + + SToBuffer item [ E_Q3_MESH_SIZE ]; + u32 itemSize; + + for (i = Models[num].faceIndex; i < Models[num].numOfFaces + Models[num].faceIndex; ++i) + { + const tBSPFace * face = Faces + i; + + s32 shaderState = setShaderMaterial( material, face ); + itemSize = 0; + + const IShader *shader = getShader(shaderState); + + if ( face->fogNum >= 0 ) + { + setShaderFogMaterial ( material2, face ); + item[itemSize].index = E_Q3_MESH_FOG; + item[itemSize].takeVertexColor = 1; + itemSize += 1; + } + + switch( face->type ) + { + case 1: // normal polygons + case 2: // patches + case 3: // meshes + if ( 0 == shader ) + { + if ( LoadParam.cleanUnResolvedMeshes || material.getTexture(0) ) + { + item[itemSize].takeVertexColor = 1; + item[itemSize].index = E_Q3_MESH_GEOMETRY; + itemSize += 1; + } + else + { + item[itemSize].takeVertexColor = 1; + item[itemSize].index = E_Q3_MESH_UNRESOLVED; + itemSize += 1; + } + } + else + { + item[itemSize].takeVertexColor = 1; + item[itemSize].index = E_Q3_MESH_ITEMS; + itemSize += 1; + } + break; + + case 4: // billboards + //item[itemSize].takeVertexColor = 1; + //item[itemSize].index = E_Q3_MESH_ITEMS; + //itemSize += 1; + break; + + } + + for ( u32 g = 0; g != itemSize; ++g ) + { + scene::SMeshBufferLightMap* buffer = 0; + + if ( item[g].index == E_Q3_MESH_GEOMETRY ) + { + if ( 0 == item[g].takeVertexColor ) + { + item[g].takeVertexColor = material.getTexture(0) == 0 || material.getTexture(1) == 0; + } + + if (Faces[i].lightmapID < -1 || Faces[i].lightmapID > NumLightMaps-1) + { + Faces[i].lightmapID = -1; + } + +#if 0 + // there are lightmapsids and textureid with -1 + const s32 tmp_index = ((Faces[i].lightmapID+1) * (NumTextures+1)) + (Faces[i].textureID+1); + buffer = (SMeshBufferLightMap*) newmesh[E_Q3_MESH_GEOMETRY]->getMeshBuffer(tmp_index); + buffer->setHardwareMappingHint ( EHM_STATIC ); + buffer->getMaterial() = material; +#endif + } + + // Construct a unique mesh for each shader or combine meshbuffers for same shader + if ( 0 == buffer ) + { + + if ( LoadParam.mergeShaderBuffer == 1 ) + { + // combine + buffer = (SMeshBufferLightMap*) newmesh[ item[g].index ]->getMeshBuffer( + item[g].index != E_Q3_MESH_FOG ? material : material2 ); + } + + // create a seperate mesh buffer + if ( 0 == buffer ) + { + buffer = new scene::SMeshBufferLightMap(); + newmesh[ item[g].index ]->addMeshBuffer( buffer ); + buffer->drop(); + buffer->getMaterial() = item[g].index != E_Q3_MESH_FOG ? material : material2; + if ( item[g].index == E_Q3_MESH_GEOMETRY ) + buffer->setHardwareMappingHint ( EHM_STATIC ); + } + } + + + switch(Faces[i].type) + { + case 4: // billboards + break; + case 2: // patches + createCurvedSurface_bezier( buffer, i, + LoadParam.patchTesselation, + item[g].takeVertexColor + ); + break; + + case 1: // normal polygons + case 3: // mesh vertices + index = MeshVerts + face->meshVertIndex; + k = buffer->getVertexCount(); + + // reallocate better if many small meshes are used + s = buffer->getIndexCount()+face->numMeshVerts; + if ( buffer->Indices.allocated_size () < (u32) s ) + { + if ( buffer->Indices.allocated_size () > 0 && + face->numMeshVerts < 20 && NumFaces > 1000 + ) + { + s = buffer->getIndexCount() + (NumFaces >> 3 * face->numMeshVerts ); + } + buffer->Indices.reallocate( s); + } + + for ( j = 0; j < face->numMeshVerts; ++j ) + { + buffer->Indices.push_back( k + index [j] ); + } + + s = k+face->numOfVerts; + if ( buffer->Vertices.allocated_size () < (u32) s ) + { + if ( buffer->Indices.allocated_size () > 0 && + face->numOfVerts < 20 && NumFaces > 1000 + ) + { + s = buffer->getIndexCount() + (NumFaces >> 3 * face->numOfVerts ); + } + buffer->Vertices.reallocate( s); + } + for ( j = 0; j != face->numOfVerts; ++j ) + { + copy( &temp[0], &Vertices[ j + face->vertexIndex ], item[g].takeVertexColor ); + buffer->Vertices.push_back( temp[0] ); + } + break; + + } // end switch + } + } + + return newmesh; +} + +/*! +*/ +void CQ3LevelMesh::solveTJunction() +{ +} + +/*! + constructs a mesh from the quake 3 level file. +*/ +void CQ3LevelMesh::constructMesh() +{ + if ( LoadParam.verbose > 0 ) + { + LoadParam.startTime = os::Timer::getRealTime(); + + if ( LoadParam.verbose > 1 ) + { + snprintf( buf, sizeof ( buf ), + "quake3::constructMesh start to create %d faces, %d vertices,%d mesh vertices", + NumFaces, + NumVertices, + NumMeshVerts + ); + os::Printer::log(buf, ELL_INFORMATION); + } + + } + + s32 i, j; + + // First the main level + SMesh **tmp = buildMesh(0); + + for (i = 0; i < E_Q3_MESH_SIZE; i++) + { + Mesh[i] = tmp[i]; + } + delete [] tmp; + + // Then the brush entities + + for (i = 1; i < NumModels; i++) + { + tmp = buildMesh(i); + BrushEntities[i] = tmp[0]; + + // We only care about the main geometry here + for (j = 1; j < E_Q3_MESH_SIZE; j++) + { + tmp[j]->drop(); + } + delete [] tmp; + } + + if ( LoadParam.verbose > 0 ) + { + LoadParam.endTime = os::Timer::getRealTime(); + + snprintf( buf, sizeof ( buf ), + "quake3::constructMesh needed %04d ms to create %d faces, %d vertices,%d mesh vertices", + LoadParam.endTime - LoadParam.startTime, + NumFaces, + NumVertices, + NumMeshVerts + ); + os::Printer::log(buf, ELL_INFORMATION); + } + +} + + +void CQ3LevelMesh::S3DVertex2TCoords_64::copy( video::S3DVertex2TCoords &dest ) const +{ +#if defined (TJUNCTION_SOLVER_ROUND) + dest.Pos.X = core::round_( (f32) Pos.X ); + dest.Pos.Y = core::round_( (f32) Pos.Y ); + dest.Pos.Z = core::round_( (f32) Pos.Z ); +#elif defined (TJUNCTION_SOLVER_0125) + dest.Pos.X = (f32) ( floor ( Pos.X * 8.f + 0.5 ) * 0.125 ); + dest.Pos.Y = (f32) ( floor ( Pos.Y * 8.f + 0.5 ) * 0.125 ); + dest.Pos.Z = (f32) ( floor ( Pos.Z * 8.f + 0.5 ) * 0.125 ); +#else + dest.Pos.X = (f32) Pos.X; + dest.Pos.Y = (f32) Pos.Y; + dest.Pos.Z = (f32) Pos.Z; +#endif + + dest.Normal.X = (f32) Normal.X; + dest.Normal.Y = (f32) Normal.Y; + dest.Normal.Z = (f32) Normal.Z; + dest.Normal.normalize(); + + dest.Color = Color.toSColor(); + + dest.TCoords.X = (f32) TCoords.X; + dest.TCoords.Y = (f32) TCoords.Y; + + dest.TCoords2.X = (f32) TCoords2.X; + dest.TCoords2.Y = (f32) TCoords2.Y; +} + + +void CQ3LevelMesh::copy( S3DVertex2TCoords_64 * dest, const tBSPVertex * source, s32 vertexcolor ) const +{ +#if defined (TJUNCTION_SOLVER_ROUND) + dest->Pos.X = core::round_( source->vPosition[0] ); + dest->Pos.Y = core::round_( source->vPosition[2] ); + dest->Pos.Z = core::round_( source->vPosition[1] ); +#elif defined (TJUNCTION_SOLVER_0125) + dest->Pos.X = (f32) ( floor ( source->vPosition[0] * 8.f + 0.5 ) * 0.125 ); + dest->Pos.Y = (f32) ( floor ( source->vPosition[2] * 8.f + 0.5 ) * 0.125 ); + dest->Pos.Z = (f32) ( floor ( source->vPosition[1] * 8.f + 0.5 ) * 0.125 ); +#else + dest->Pos.X = source->vPosition[0]; + dest->Pos.Y = source->vPosition[2]; + dest->Pos.Z = source->vPosition[1]; +#endif + + dest->Normal.X = source->vNormal[0]; + dest->Normal.Y = source->vNormal[2]; + dest->Normal.Z = source->vNormal[1]; + dest->Normal.normalize(); + + dest->TCoords.X = source->vTextureCoord[0]; + dest->TCoords.Y = source->vTextureCoord[1]; + dest->TCoords2.X = source->vLightmapCoord[0]; + dest->TCoords2.Y = source->vLightmapCoord[1]; + + if ( vertexcolor ) + { + //u32 a = core::s32_min( source->color[3] * LoadParam.defaultModulate, 255 ); + u32 a = source->color[3]; + u32 r = core::s32_min( source->color[0] * LoadParam.defaultModulate, 255 ); + u32 g = core::s32_min( source->color[1] * LoadParam.defaultModulate, 255 ); + u32 b = core::s32_min( source->color[2] * LoadParam.defaultModulate, 255 ); + + dest->Color.set(a * 1.f/255.f, r * 1.f/255.f, + g * 1.f/255.f, b * 1.f/255.f); + } + else + { + dest->Color.set( 1.f, 1.f, 1.f, 1.f ); + } +} + + +inline void CQ3LevelMesh::copy( video::S3DVertex2TCoords * dest, const tBSPVertex * source, s32 vertexcolor ) const +{ +#if defined (TJUNCTION_SOLVER_ROUND) + dest->Pos.X = core::round_( source->vPosition[0] ); + dest->Pos.Y = core::round_( source->vPosition[2] ); + dest->Pos.Z = core::round_( source->vPosition[1] ); +#elif defined (TJUNCTION_SOLVER_0125) + dest->Pos.X = (f32) ( floor ( source->vPosition[0] * 8.f + 0.5 ) * 0.125 ); + dest->Pos.Y = (f32) ( floor ( source->vPosition[2] * 8.f + 0.5 ) * 0.125 ); + dest->Pos.Z = (f32) ( floor ( source->vPosition[1] * 8.f + 0.5 ) * 0.125 ); +#else + dest->Pos.X = source->vPosition[0]; + dest->Pos.Y = source->vPosition[2]; + dest->Pos.Z = source->vPosition[1]; +#endif + + dest->Normal.X = source->vNormal[0]; + dest->Normal.Y = source->vNormal[2]; + dest->Normal.Z = source->vNormal[1]; + dest->Normal.normalize(); + + dest->TCoords.X = source->vTextureCoord[0]; + dest->TCoords.Y = source->vTextureCoord[1]; + dest->TCoords2.X = source->vLightmapCoord[0]; + dest->TCoords2.Y = source->vLightmapCoord[1]; + + if ( vertexcolor ) + { + //u32 a = core::s32_min( source->color[3] * LoadParam.defaultModulate, 255 ); + u32 a = source->color[3]; + u32 r = core::s32_min( source->color[0] * LoadParam.defaultModulate, 255 ); + u32 g = core::s32_min( source->color[1] * LoadParam.defaultModulate, 255 ); + u32 b = core::s32_min( source->color[2] * LoadParam.defaultModulate, 255 ); + + dest->Color.set(a << 24 | r << 16 | g << 8 | b); + } + else + { + dest->Color.set(0xFFFFFFFF); + } +} + + +void CQ3LevelMesh::SBezier::tesselate( s32 level ) +{ + //Calculate how many vertices across/down there are + s32 j, k; + + column[0].set_used( level + 1 ); + column[1].set_used( level + 1 ); + column[2].set_used( level + 1 ); + + const f64 w = 0.0 + (1.0 / (f64) level ); + + //Tesselate along the columns + for( j = 0; j <= level; ++j) + { + const f64 f = w * (f64) j; + + column[0][j] = control[0].getInterpolated_quadratic(control[3], control[6], f ); + column[1][j] = control[1].getInterpolated_quadratic(control[4], control[7], f ); + column[2][j] = control[2].getInterpolated_quadratic(control[5], control[8], f ); + } + + const u32 idx = Patch->Vertices.size(); + Patch->Vertices.reallocate(idx+level*level); + //Tesselate across the rows to get final vertices + video::S3DVertex2TCoords v; + S3DVertex2TCoords_64 f; + for( j = 0; j <= level; ++j) + { + for( k = 0; k <= level; ++k) + { + f = column[0][j].getInterpolated_quadratic(column[1][j], column[2][j], w * (f64) k); + f.copy( v ); + Patch->Vertices.push_back( v ); + } + } + + Patch->Indices.reallocate(Patch->Indices.size()+6*level*level); + // connect + for( j = 0; j < level; ++j) + { + for( k = 0; k < level; ++k) + { + const s32 inx = idx + ( k * ( level + 1 ) ) + j; + + Patch->Indices.push_back( inx + 0 ); + Patch->Indices.push_back( inx + (level + 1 ) + 0 ); + Patch->Indices.push_back( inx + (level + 1 ) + 1 ); + + Patch->Indices.push_back( inx + 0 ); + Patch->Indices.push_back( inx + (level + 1 ) + 1 ); + Patch->Indices.push_back( inx + 1 ); + } + } +} + + +/*! + no subdivision +*/ +void CQ3LevelMesh::createCurvedSurface_nosubdivision(SMeshBufferLightMap* meshBuffer, + s32 faceIndex, + s32 patchTesselation, + s32 storevertexcolor) +{ + tBSPFace * face = &Faces[faceIndex]; + u32 j,k,m; + + // number of control points across & up + const u32 controlWidth = face->size[0]; + const u32 controlHeight = face->size[1]; + if ( 0 == controlWidth || 0 == controlHeight ) + return; + + video::S3DVertex2TCoords v; + + m = meshBuffer->Vertices.size(); + meshBuffer->Vertices.reallocate(m+controlHeight * controlWidth); + for ( j = 0; j!= controlHeight * controlWidth; ++j ) + { + copy( &v, &Vertices [ face->vertexIndex + j ], storevertexcolor ); + meshBuffer->Vertices.push_back( v ); + } + + meshBuffer->Indices.reallocate(meshBuffer->Indices.size()+6*(controlHeight-1) * (controlWidth-1)); + for ( j = 0; j!= controlHeight - 1; ++j ) + { + for ( k = 0; k!= controlWidth - 1; ++k ) + { + meshBuffer->Indices.push_back( m + k + 0 ); + meshBuffer->Indices.push_back( m + k + controlWidth + 0 ); + meshBuffer->Indices.push_back( m + k + controlWidth + 1 ); + + meshBuffer->Indices.push_back( m + k + 0 ); + meshBuffer->Indices.push_back( m + k + controlWidth + 1 ); + meshBuffer->Indices.push_back( m + k + 1 ); + } + m += controlWidth; + } +} + + +/*! +*/ +void CQ3LevelMesh::createCurvedSurface_bezier(SMeshBufferLightMap* meshBuffer, + s32 faceIndex, + s32 patchTesselation, + s32 storevertexcolor) +{ + + tBSPFace * face = &Faces[faceIndex]; + u32 j,k; + + // number of control points across & up + const u32 controlWidth = face->size[0]; + const u32 controlHeight = face->size[1]; + + if ( 0 == controlWidth || 0 == controlHeight ) + return; + + // number of biquadratic patches + const u32 biquadWidth = (controlWidth - 1)/2; + const u32 biquadHeight = (controlHeight -1)/2; + + if ( LoadParam.verbose > 1 ) + { + LoadParam.startTime = os::Timer::getRealTime(); + } + + // Create space for a temporary array of the patch's control points + core::array controlPoint; + controlPoint.set_used( controlWidth * controlHeight ); + + for( j = 0; j < controlPoint.size(); ++j) + { + copy( &controlPoint[j], &Vertices [ face->vertexIndex + j ], storevertexcolor ); + } + + // create a temporary patch + Bezier.Patch = new scene::SMeshBufferLightMap(); + + //Loop through the biquadratic patches + for( j = 0; j < biquadHeight; ++j) + { + for( k = 0; k < biquadWidth; ++k) + { + // set up this patch + const s32 inx = j*controlWidth*2 + k*2; + + // setup bezier control points for this patch + Bezier.control[0] = controlPoint[ inx + 0]; + Bezier.control[1] = controlPoint[ inx + 1]; + Bezier.control[2] = controlPoint[ inx + 2]; + Bezier.control[3] = controlPoint[ inx + controlWidth + 0 ]; + Bezier.control[4] = controlPoint[ inx + controlWidth + 1 ]; + Bezier.control[5] = controlPoint[ inx + controlWidth + 2 ]; + Bezier.control[6] = controlPoint[ inx + controlWidth * 2 + 0]; + Bezier.control[7] = controlPoint[ inx + controlWidth * 2 + 1]; + Bezier.control[8] = controlPoint[ inx + controlWidth * 2 + 2]; + + Bezier.tesselate( patchTesselation ); + } + } + + // stitch together with existing geometry + // TODO: only border needs to be checked + const u32 bsize = Bezier.Patch->getVertexCount(); + const u32 msize = meshBuffer->getVertexCount(); +/* + for ( j = 0; j!= bsize; ++j ) + { + const core::vector3df &v = Bezier.Patch->Vertices[j].Pos; + + for ( k = 0; k!= msize; ++k ) + { + const core::vector3df &m = meshBuffer->Vertices[k].Pos; + + if ( !v.equals( m, tolerance ) ) + continue; + + meshBuffer->Vertices[k].Pos = v; + //Bezier.Patch->Vertices[j].Pos = m; + } + } +*/ + + // add Patch to meshbuffer + meshBuffer->Vertices.reallocate(msize+bsize); + for ( j = 0; j!= bsize; ++j ) + { + meshBuffer->Vertices.push_back( Bezier.Patch->Vertices[j] ); + } + + // add indices to meshbuffer + meshBuffer->Indices.reallocate(meshBuffer->getIndexCount()+Bezier.Patch->getIndexCount()); + for ( j = 0; j!= Bezier.Patch->getIndexCount(); ++j ) + { + meshBuffer->Indices.push_back( msize + Bezier.Patch->Indices[j] ); + } + + delete Bezier.Patch; + + if ( LoadParam.verbose > 1 ) + { + LoadParam.endTime = os::Timer::getRealTime(); + + snprintf( buf, sizeof ( buf ), + "quake3::createCurvedSurface_bezier needed %04d ms to create bezier patch.(%dx%d)", + LoadParam.endTime - LoadParam.startTime, + biquadWidth, + biquadHeight + ); + os::Printer::log(buf, ELL_INFORMATION); + } + +} + + + +/*! + Loads entities from file +*/ +void CQ3LevelMesh::getConfiguration( io::IReadFile* file ) +{ + tBSPLump l; + l.offset = file->getPos(); + l.length = file->getSize (); + + core::array entity; + entity.set_used( l.length + 2 ); + entity[l.length + 1 ] = 0; + + file->seek(l.offset); + file->read( entity.pointer(), l.length); + + parser_parse( entity.pointer(), l.length, &CQ3LevelMesh::scriptcallback_config ); + + if ( Entity.size () ) + Entity.getLast().name = file->getFileName(); +} + + +//! get's an interface to the entities +tQ3EntityList & CQ3LevelMesh::getEntityList() +{ +// Entity.sort(); + return Entity; +} + +//! returns the requested brush entity +IMesh* CQ3LevelMesh::getBrushEntityMesh(s32 num) const +{ + if (num < 1 || num >= NumModels) + return 0; + + return BrushEntities[num]; +} + +//! returns the requested brush entity +IMesh* CQ3LevelMesh::getBrushEntityMesh(quake3::IEntity &ent) const +{ + // This is a helper function to parse the entity, + // so you don't have to. + + s32 num; + + const quake3::SVarGroup* group = ent.getGroup(1); + const core::stringc& modnum = group->get("model"); + + if (!group->isDefined("model")) + return 0; + + const char *temp = modnum.c_str() + 1; // We skip the first character. + num = core::strtol10(temp); + + return getBrushEntityMesh(num); +} + + +/*! +*/ +const IShader * CQ3LevelMesh::getShader(u32 index) const +{ + index &= 0xFFFF; + + if ( index < Shader.size() ) + { + return &Shader[index]; + } + + return 0; +} + + +/*! + loads the shader definition +*/ +const IShader* CQ3LevelMesh::getShader( const c8 * filename, bool fileNameIsValid ) +{ + core::stringc searchName ( filename ); + + IShader search; + search.name = searchName; + search.name.replace( '\\', '/' ); + search.name.make_lower(); + + + core::stringc message; + s32 index; + + //! is Shader already in cache? + index = Shader.linear_search( search ); + if ( index >= 0 ) + { + if ( LoadParam.verbose > 1 ) + { + message = searchName + " found " + Shader[index].name; + os::Printer::log("quake3:getShader", message.c_str(), ELL_INFORMATION); + } + + return &Shader[index]; + } + + io::path loadFile; + + if ( !fileNameIsValid ) + { + // extract the shader name from the last path component in filename + // "scripts/[name].shader" + core::stringc cut( search.name ); + + s32 end = cut.findLast( '/' ); + s32 start = cut.findLast( '/', end - 1 ); + + loadFile = LoadParam.scriptDir; + loadFile.append( cut.subString( start, end - start ) ); + loadFile.append( ".shader" ); + } + else + { + loadFile = search.name; + } + + // already loaded the file ? + index = ShaderFile.binary_search( loadFile ); + if ( index >= 0 ) + return 0; + + // add file to loaded files + ShaderFile.push_back( loadFile ); + + if ( !FileSystem->existFile( loadFile.c_str() ) ) + { + if ( LoadParam.verbose > 1 ) + { + message = loadFile + " for " + searchName + " failed "; + os::Printer::log("quake3:getShader", message.c_str(), ELL_INFORMATION); + } + return 0; + } + + if ( LoadParam.verbose ) + { + message = loadFile + " for " + searchName; + os::Printer::log("quake3:getShader Load shader", message.c_str(), ELL_INFORMATION); + } + + + io::IReadFile *file = FileSystem->createAndOpenFile( loadFile.c_str() ); + if ( file ) + { + getShader ( file ); + file->drop (); + } + + + // search again + index = Shader.linear_search( search ); + return index >= 0 ? &Shader[index] : 0; +} + +/*! + loads the shader definition +*/ +void CQ3LevelMesh::getShader( io::IReadFile* file ) +{ + if ( 0 == file ) + return; + + // load script + core::array script; + const long len = file->getSize(); + + script.set_used( len + 2 ); + + file->seek( 0 ); + file->read( script.pointer(), len ); + script[ len + 1 ] = 0; + + // start a parser instance + parser_parse( script.pointer(), len, &CQ3LevelMesh::scriptcallback_shader ); +} + + +//! adding default shaders +void CQ3LevelMesh::InitShader() +{ + ReleaseShader(); + + IShader element; + + SVarGroup group; + SVariable variable ( "noshader" ); + + group.Variable.push_back( variable ); + + element.VarGroup = new SVarGroupList(); + element.VarGroup->VariableGroup.push_back( group ); + element.VarGroup->VariableGroup.push_back( SVarGroup() ); + element.name = element.VarGroup->VariableGroup[0].Variable[0].name; + element.ID = Shader.size(); + Shader.push_back( element ); + + if ( LoadParam.loadAllShaders ) + { + io::EFileSystemType current = FileSystem->setFileListSystem ( io::FILESYSTEM_VIRTUAL ); + io::path save = FileSystem->getWorkingDirectory(); + + io::path newDir; + newDir = "/"; + newDir += LoadParam.scriptDir; + newDir += "/"; + FileSystem->changeWorkingDirectoryTo ( newDir.c_str() ); + + core::stringc s; + io::IFileList *fileList = FileSystem->createFileList (); + for (u32 i=0; i< fileList->getFileCount(); ++i) + { + s = fileList->getFullFileName(i); + if ( s.find ( ".shader" ) >= 0 ) + { + if ( 0 == LoadParam.loadSkyShader && s.find ( "sky.shader" ) >= 0 ) + { + } + else + { + getShader ( s.c_str () ); + } + } + } + fileList->drop (); + + FileSystem->changeWorkingDirectoryTo ( save ); + FileSystem->setFileListSystem ( current ); + } +} + + +//! script callback for shaders +//! i'm having troubles with the reference counting, during callback.. resorting.. +void CQ3LevelMesh::ReleaseShader() +{ + for ( u32 i = 0; i!= Shader.size(); ++i ) + { + Shader[i].VarGroup->drop(); + } + Shader.clear(); + ShaderFile.clear(); +} + + +/*! +*/ +void CQ3LevelMesh::ReleaseEntity() +{ + for ( u32 i = 0; i!= Entity.size(); ++i ) + { + Entity[i].VarGroup->drop(); + } + Entity.clear(); +} + + +// config in simple (quake3) and advanced style +void CQ3LevelMesh::scriptcallback_config( SVarGroupList *& grouplist, eToken token ) +{ + IShader element; + + if ( token == Q3_TOKEN_END_LIST ) + { + if ( 0 == grouplist->VariableGroup[0].Variable.size() ) + return; + + element.name = grouplist->VariableGroup[0].Variable[0].name; + } + else + { + if ( grouplist->VariableGroup.size() != 2 ) + return; + + element.name = "configuration"; + } + + grouplist->grab(); + element.VarGroup = grouplist; + element.ID = Entity.size(); + Entity.push_back( element ); +} + + +// entity only has only one valid level.. and no assoziative name.. +void CQ3LevelMesh::scriptcallback_entity( SVarGroupList *& grouplist, eToken token ) +{ + if ( token != Q3_TOKEN_END_LIST || grouplist->VariableGroup.size() != 2 ) + return; + + grouplist->grab(); + + IEntity element; + element.VarGroup = grouplist; + element.ID = Entity.size(); + element.name = grouplist->VariableGroup[1].get( "classname" ); + + + Entity.push_back( element ); +} + + +//!. script callback for shaders +void CQ3LevelMesh::scriptcallback_shader( SVarGroupList *& grouplist,eToken token ) +{ + if ( token != Q3_TOKEN_END_LIST || grouplist->VariableGroup[0].Variable.size()==0) + return; + + + IShader element; + + grouplist->grab(); + element.VarGroup = grouplist; + element.name = element.VarGroup->VariableGroup[0].Variable[0].name; + element.ID = Shader.size(); +/* + core::stringc s; + dumpShader ( s, &element ); + printf ( s.c_str () ); +*/ + Shader.push_back( element ); +} + + +/*! + delete all buffers without geometry in it. +*/ +void CQ3LevelMesh::cleanMeshes() +{ + if ( 0 == LoadParam.cleanUnResolvedMeshes ) + return; + + s32 i; + + // First the main level + for (i = 0; i < E_Q3_MESH_SIZE; i++) + { + bool texture0important = ( i == 0 ); + + cleanMesh(Mesh[i], texture0important); + } + + // Then the brush entities + for (i = 1; i < NumModels; i++) + { + cleanMesh(BrushEntities[i], true); + } +} + +void CQ3LevelMesh::cleanMesh(SMesh *m, const bool texture0important) +{ + // delete all buffers without geometry in it. + u32 run = 0; + u32 remove = 0; + + IMeshBuffer *b; + + run = 0; + remove = 0; + + if ( LoadParam.verbose > 0 ) + { + LoadParam.startTime = os::Timer::getRealTime(); + if ( LoadParam.verbose > 1 ) + { + snprintf( buf, sizeof ( buf ), + "quake3::cleanMeshes start for %d meshes", + m->MeshBuffers.size() + ); + os::Printer::log(buf, ELL_INFORMATION); + } + } + + u32 i = 0; + s32 blockstart = -1; + s32 blockcount = 0; + + while( i < m->MeshBuffers.size()) + { + run += 1; + + b = m->MeshBuffers[i]; + + if ( b->getVertexCount() == 0 || b->getIndexCount() == 0 || + ( texture0important && b->getMaterial().getTexture(0) == 0 ) + ) + { + if ( blockstart < 0 ) + { + blockstart = i; + blockcount = 0; + } + blockcount += 1; + i += 1; + + // delete Meshbuffer + i -= 1; + remove += 1; + b->drop(); + m->MeshBuffers.erase(i); + } + else + { + // clean blockwise + if ( blockstart >= 0 ) + { + if ( LoadParam.verbose > 1 ) + { + snprintf( buf, sizeof ( buf ), + "quake3::cleanMeshes cleaning mesh %d %d size", + blockstart, + blockcount + ); + os::Printer::log(buf, ELL_INFORMATION); + } + blockstart = -1; + } + i += 1; + } + } + + if ( LoadParam.verbose > 0 ) + { + LoadParam.endTime = os::Timer::getRealTime(); + snprintf( buf, sizeof ( buf ), + "quake3::cleanMeshes needed %04d ms to clean %d of %d meshes", + LoadParam.endTime - LoadParam.startTime, + remove, + run + ); + os::Printer::log(buf, ELL_INFORMATION); + } +} + + +// recalculate bounding boxes +void CQ3LevelMesh::calcBoundingBoxes() +{ + if ( LoadParam.verbose > 0 ) + { + LoadParam.startTime = os::Timer::getRealTime(); + + if ( LoadParam.verbose > 1 ) + { + snprintf( buf, sizeof ( buf ), + "quake3::calcBoundingBoxes start create %d textures and %d lightmaps", + NumTextures, + NumLightMaps + ); + os::Printer::log(buf, ELL_INFORMATION); + } + } + + s32 g; + + // create bounding box + for ( g = 0; g != E_Q3_MESH_SIZE; ++g ) + { + for ( u32 j=0; j < Mesh[g]->MeshBuffers.size(); ++j) + { + ((SMeshBufferLightMap*)Mesh[g]->MeshBuffers[j])->recalculateBoundingBox(); + } + + Mesh[g]->recalculateBoundingBox(); + // Mesh[0] is the main bbox + if (g!=0) + Mesh[0]->BoundingBox.addInternalBox(Mesh[g]->getBoundingBox()); + } + + for (g = 1; g < NumModels; g++) + { + for ( u32 j=0; j < BrushEntities[g]->MeshBuffers.size(); ++j) + { + ((SMeshBufferLightMap*)BrushEntities[g]->MeshBuffers[j])-> + recalculateBoundingBox(); + } + + BrushEntities[g]->recalculateBoundingBox(); + } + + if ( LoadParam.verbose > 0 ) + { + LoadParam.endTime = os::Timer::getRealTime(); + + snprintf( buf, sizeof ( buf ), + "quake3::calcBoundingBoxes needed %04d ms to create %d textures and %d lightmaps", + LoadParam.endTime - LoadParam.startTime, + NumTextures, + NumLightMaps + ); + os::Printer::log( buf, ELL_INFORMATION); + } +} + + +//! loads the textures +void CQ3LevelMesh::loadTextures() +{ + if (!Driver) + return; + + if ( LoadParam.verbose > 0 ) + { + LoadParam.startTime = os::Timer::getRealTime(); + + if ( LoadParam.verbose > 1 ) + { + snprintf( buf, sizeof ( buf ), + "quake3::loadTextures start create %d textures and %d lightmaps", + NumTextures, + NumLightMaps + ); + os::Printer::log( buf, ELL_INFORMATION); + } + } + + c8 lightmapname[255]; + s32 t; + + // load lightmaps. + Lightmap.set_used(NumLightMaps); + +/* + bool oldMipMapState = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); +*/ + core::dimension2d lmapsize(128,128); + + video::IImage* lmapImg; + for ( t = 0; t < NumLightMaps ; ++t) + { + sprintf(lightmapname, "%s.lightmap.%d", LevelName.c_str(), t); + + // lightmap is a CTexture::R8G8B8 format + lmapImg = Driver->createImageFromData( + video::ECF_R8G8B8, lmapsize, + LightMaps[t].imageBits, false, true ); + + Lightmap[t] = Driver->addTexture( lightmapname, lmapImg ); + lmapImg->drop(); + } + +// Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState); + + // load textures + Tex.set_used( NumTextures ); + + const IShader* shader; + + core::stringc list; + io::path check; + tTexArray textureArray; + + // pre-load shaders + for ( t=0; t< NumTextures; ++t) + { + shader = getShader(Textures[t].strName, false); + } + + for ( t=0; t< NumTextures; ++t) + { + Tex[t].ShaderID = -1; + Tex[t].Texture = 0; + + list = ""; + + // get a shader ( if one exists ) + shader = getShader( Textures[t].strName, false); + if ( shader ) + { + Tex[t].ShaderID = shader->ID; + + // if texture name == stage1 Texture map + const SVarGroup * group; + + group = shader->getGroup( 2 ); + if ( group ) + { + if ( core::cutFilenameExtension( check, group->get( "map" ) ) == Textures[t].strName ) + { + list += check; + } + else + if ( check == "$lightmap" ) + { + // we check if lightmap is in stage 1 and texture in stage 2 + group = shader->getGroup( 3 ); + if ( group ) + list += group->get( "map" ); + } + } + } + else + { + // no shader, take it + list += Textures[t].strName; + } + + u32 pos = 0; + getTextures( textureArray, list, pos, FileSystem, Driver ); + + Tex[t].Texture = textureArray[0]; + } + + if ( LoadParam.verbose > 0 ) + { + LoadParam.endTime = os::Timer::getRealTime(); + + snprintf( buf, sizeof ( buf ), + "quake3::loadTextures needed %04d ms to create %d textures and %d lightmaps", + LoadParam.endTime - LoadParam.startTime, + NumTextures, + NumLightMaps + ); + os::Printer::log( buf, ELL_INFORMATION); + } +} + + +//! Returns an axis aligned bounding box of the mesh. +const core::aabbox3d& CQ3LevelMesh::getBoundingBox() const +{ + return Mesh[0]->getBoundingBox(); +} + + +void CQ3LevelMesh::setBoundingBox(const core::aabbox3df& box) +{ + Mesh[0]->setBoundingBox(box); +} + + +//! Returns the type of the animated mesh. +E_ANIMATED_MESH_TYPE CQ3LevelMesh::getMeshType() const +{ + return scene::EAMT_BSP; +} + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BSP_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.h new file mode 100644 index 0000000..b7e9cf1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CQ3LevelMesh.h @@ -0,0 +1,491 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_Q3_LEVEL_MESH_H_INCLUDED__ +#define __C_Q3_LEVEL_MESH_H_INCLUDED__ + +#include "IQ3LevelMesh.h" +#include "IReadFile.h" +#include "IFileSystem.h" +#include "SMesh.h" +#include "SMeshBufferLightMap.h" +#include "IVideoDriver.h" +#include "irrString.h" +#include "ISceneManager.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + class CQ3LevelMesh : public IQ3LevelMesh + { + public: + + //! constructor + CQ3LevelMesh(io::IFileSystem* fs, scene::ISceneManager* smgr, + const quake3::Q3LevelLoadParameter &loadParam); + + //! destructor + virtual ~CQ3LevelMesh(); + + //! loads a level from a .bsp-File. Also tries to load all + //! needed textures. Returns true if successful. + bool loadFile(io::IReadFile* file); + + //! returns the amount of frames in milliseconds. If the amount + //! is 1, it is a static (=non animated) mesh. + virtual u32 getFrameCount() const; + + //! Gets the default animation speed of the animated mesh. + /** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ + virtual f32 getAnimationSpeed() const + { + return FramesPerSecond; + } + + //! Gets the frame count of the animated mesh. + /** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. + The actual speed is set in the scene node the mesh is instantiated in.*/ + virtual void setAnimationSpeed(f32 fps) + { + FramesPerSecond=fps; + } + + //! returns the animated mesh based on a detail level. 0 is the + //! lowest, 255 the highest detail. Note, that some Meshes will + //! ignore the detail level. + virtual IMesh* getMesh(s32 frameInMs, s32 detailLevel=255, + s32 startFrameLoop=-1, s32 endFrameLoop=-1); + + //! Returns an axis aligned bounding box of the mesh. + //! \return A bounding box of this mesh is returned. + virtual const core::aabbox3d& getBoundingBox() const; + + virtual void setBoundingBox( const core::aabbox3df& box); + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! loads the shader definition + virtual void getShader( io::IReadFile* file ); + + //! loads the shader definition + virtual const quake3::IShader * getShader( const c8 * filename, bool fileNameIsValid=true ); + + //! returns a already loaded Shader + virtual const quake3::IShader * getShader( u32 index ) const; + + + //! loads a configuration file + virtual void getConfiguration( io::IReadFile* file ); + //! get's an interface to the entities + virtual quake3::tQ3EntityList & getEntityList(); + + //! returns the requested brush entity + virtual IMesh* getBrushEntityMesh(s32 num) const; + + //! returns the requested brush entity + virtual IMesh* getBrushEntityMesh(quake3::IEntity &ent) const; + + //Link to held meshes? ... + + + //! returns amount of mesh buffers. + virtual u32 getMeshBufferCount() const + { + return 0; + } + + //! returns pointer to a mesh buffer + virtual IMeshBuffer* getMeshBuffer(u32 nr) const + { + return 0; + } + + //! Returns pointer to a mesh buffer which fits a material + /** \param material: material to search for + \return Pointer to the mesh buffer or 0 if there is no such mesh buffer. */ + virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const + { + return 0; + } + + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) + { + return; + } + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) + { + return; + } + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) + { + return; + } + + private: + + + void constructMesh(); + void solveTJunction(); + void loadTextures(); + scene::SMesh** buildMesh(s32 num); + + struct STexShader + { + video::ITexture* Texture; + s32 ShaderID; + }; + + core::array< STexShader > Tex; + core::array Lightmap; + + enum eLumps + { + kEntities = 0, // Stores player/object positions, etc... + kShaders = 1, // Stores texture information + kPlanes = 2, // Stores the splitting planes + kNodes = 3, // Stores the BSP nodes + kLeafs = 4, // Stores the leafs of the nodes + kLeafFaces = 5, // Stores the leaf's indices into the faces + kLeafBrushes = 6, // Stores the leaf's indices into the brushes + kModels = 7, // Stores the info of world models + kBrushes = 8, // Stores the brushes info (for collision) + kBrushSides = 9, // Stores the brush surfaces info + kVertices = 10, // Stores the level vertices + kMeshVerts = 11, // Stores the model vertices offsets + kFogs = 12, // Stores the shader files (blending, anims..) + kFaces = 13, // Stores the faces for the level + kLightmaps = 14, // Stores the lightmaps for the level + kLightGrid = 15, // Stores extra world lighting information + kVisData = 16, // Stores PVS and cluster info (visibility) + kLightArray = 17, // RBSP + kMaxLumps // A constant to store the number of lumps + }; + + enum eBspSurfaceType + { + BSP_MST_BAD, + BSP_MST_PLANAR, + BSP_MST_PATCH, + BSP_MST_TRIANGLE_SOUP, + BSP_MST_FLARE, + BSP_MST_FOLIAGE + + }; + + struct tBSPHeader + { + s32 strID; // This should always be 'IBSP' + s32 version; // This should be 0x2e for Quake 3 files + }; + tBSPHeader header; + + struct tBSPLump + { + s32 offset; + s32 length; + }; + + + struct tBSPVertex + { + f32 vPosition[3]; // (x, y, z) position. + f32 vTextureCoord[2]; // (u, v) texture coordinate + f32 vLightmapCoord[2]; // (u, v) lightmap coordinate + f32 vNormal[3]; // (x, y, z) normal vector + u8 color[4]; // RGBA color for the vertex + }; + + struct tBSPFace + { + s32 textureID; // The index into the texture array + s32 fogNum; // The index for the effects (or -1 = n/a) + s32 type; // 1=polygon, 2=patch, 3=mesh, 4=billboard + s32 vertexIndex; // The index into this face's first vertex + s32 numOfVerts; // The number of vertices for this face + s32 meshVertIndex; // The index into the first meshvertex + s32 numMeshVerts; // The number of mesh vertices + s32 lightmapID; // The texture index for the lightmap + s32 lMapCorner[2]; // The face's lightmap corner in the image + s32 lMapSize[2]; // The size of the lightmap section + f32 lMapPos[3]; // The 3D origin of lightmap. + f32 lMapBitsets[2][3]; // The 3D space for s and t unit vectors. + f32 vNormal[3]; // The face normal. + s32 size[2]; // The bezier patch dimensions. + }; + + struct tBSPTexture + { + c8 strName[64]; // The name of the texture w/o the extension + u32 flags; // The surface flags (unknown) + u32 contents; // The content flags (unknown) + }; + + struct tBSPLightmap + { + u8 imageBits[128][128][3]; // The RGB data in a 128x128 image + }; + + struct tBSPNode + { + s32 plane; // The index into the planes array + s32 front; // The child index for the front node + s32 back; // The child index for the back node + s32 mins[3]; // The bounding box min position. + s32 maxs[3]; // The bounding box max position. + }; + + struct tBSPLeaf + { + s32 cluster; // The visibility cluster + s32 area; // The area portal + s32 mins[3]; // The bounding box min position + s32 maxs[3]; // The bounding box max position + s32 leafface; // The first index into the face array + s32 numOfLeafFaces; // The number of faces for this leaf + s32 leafBrush; // The first index for into the brushes + s32 numOfLeafBrushes; // The number of brushes for this leaf + }; + + struct tBSPPlane + { + f32 vNormal[3]; // Plane normal. + f32 d; // The plane distance from origin + }; + + struct tBSPVisData + { + s32 numOfClusters; // The number of clusters + s32 bytesPerCluster; // Bytes (8 bits) in the cluster's bitset + c8 *pBitsets; // Array of bytes holding the cluster vis. + }; + + struct tBSPBrush + { + s32 brushSide; // The starting brush side for the brush + s32 numOfBrushSides; // Number of brush sides for the brush + s32 textureID; // The texture index for the brush + }; + + struct tBSPBrushSide + { + s32 plane; // The plane index + s32 textureID; // The texture index + }; + + struct tBSPModel + { + f32 min[3]; // The min position for the bounding box + f32 max[3]; // The max position for the bounding box. + s32 faceIndex; // The first face index in the model + s32 numOfFaces; // The number of faces in the model + s32 brushIndex; // The first brush index in the model + s32 numOfBrushes; // The number brushes for the model + }; + + struct tBSPFog + { + c8 shader[64]; // The name of the shader file + s32 brushIndex; // The brush index for this shader + s32 visibleSide; // the brush side that ray tests need to clip against (-1 == none + }; + core::array < STexShader > FogMap; + + struct tBSPLights + { + u8 ambient[3]; // This is the ambient color in RGB + u8 directional[3]; // This is the directional color in RGB + u8 direction[2]; // The direction of the light: [phi,theta] + }; + + void loadTextures (tBSPLump* l, io::IReadFile* file); // Load the textures + void loadLightmaps (tBSPLump* l, io::IReadFile* file); // Load the lightmaps + void loadVerts (tBSPLump* l, io::IReadFile* file); // Load the vertices + void loadFaces (tBSPLump* l, io::IReadFile* file); // Load the faces + void loadPlanes (tBSPLump* l, io::IReadFile* file); // Load the Planes of the BSP + void loadNodes (tBSPLump* l, io::IReadFile* file); // load the Nodes of the BSP + void loadLeafs (tBSPLump* l, io::IReadFile* file); // load the Leafs of the BSP + void loadLeafFaces (tBSPLump* l, io::IReadFile* file); // load the Faces of the Leafs of the BSP + void loadVisData (tBSPLump* l, io::IReadFile* file); // load the visibility data of the clusters + void loadEntities (tBSPLump* l, io::IReadFile* file); // load the entities + void loadModels (tBSPLump* l, io::IReadFile* file); // load the models + void loadMeshVerts (tBSPLump* l, io::IReadFile* file); // load the mesh vertices + void loadBrushes (tBSPLump* l, io::IReadFile* file); // load the brushes of the BSP + void loadBrushSides (tBSPLump* l, io::IReadFile* file); // load the brushsides of the BSP + void loadLeafBrushes(tBSPLump* l, io::IReadFile* file); // load the brushes of the leaf + void loadFogs (tBSPLump* l, io::IReadFile* file); // load the shaders + + //bi-quadratic bezier patches + void createCurvedSurface_bezier(SMeshBufferLightMap* meshBuffer, + s32 faceIndex, s32 patchTesselation, s32 storevertexcolor); + + void createCurvedSurface_nosubdivision(SMeshBufferLightMap* meshBuffer, + s32 faceIndex, s32 patchTesselation, s32 storevertexcolor); + + struct S3DVertex2TCoords_64 + { + core::vector3d Pos; + core::vector3d Normal; + video::SColorf Color; + core::vector2d TCoords; + core::vector2d TCoords2; + + void copy( video::S3DVertex2TCoords &dest ) const; + + S3DVertex2TCoords_64() {} + S3DVertex2TCoords_64(const core::vector3d& pos, const core::vector3d& normal, const video::SColorf& color, + const core::vector2d& tcoords, const core::vector2d& tcoords2) + : Pos(pos), Normal(normal), Color(color), TCoords(tcoords), TCoords2(tcoords2) {} + + S3DVertex2TCoords_64 getInterpolated_quadratic(const S3DVertex2TCoords_64& v2, + const S3DVertex2TCoords_64& v3, const f64 d) const + { + return S3DVertex2TCoords_64 ( + Pos.getInterpolated_quadratic ( v2.Pos, v3.Pos, d ), + Normal.getInterpolated_quadratic ( v2.Normal, v3.Normal, d ), + Color.getInterpolated_quadratic ( v2.Color, v3.Color, (f32) d ), + TCoords.getInterpolated_quadratic ( v2.TCoords, v3.TCoords, d ), + TCoords2.getInterpolated_quadratic ( v2.TCoords2, v3.TCoords2, d )); + } + }; + + inline void copy( video::S3DVertex2TCoords * dest, const tBSPVertex * source, + s32 vertexcolor ) const; + void copy( S3DVertex2TCoords_64 * dest, const tBSPVertex * source, s32 vertexcolor ) const; + + + struct SBezier + { + SMeshBufferLightMap *Patch; + S3DVertex2TCoords_64 control[9]; + + void tesselate(s32 level); + + private: + s32 Level; + + core::array column[3]; + + }; + SBezier Bezier; + + quake3::Q3LevelLoadParameter LoadParam; + + tBSPLump Lumps[kMaxLumps]; + + tBSPTexture* Textures; + s32 NumTextures; + + tBSPLightmap* LightMaps; + s32 NumLightMaps; + + tBSPVertex* Vertices; + s32 NumVertices; + + tBSPFace* Faces; + s32 NumFaces; + + tBSPModel* Models; + s32 NumModels; + + tBSPPlane* Planes; + s32 NumPlanes; + + tBSPNode* Nodes; + s32 NumNodes; + + tBSPLeaf* Leafs; + s32 NumLeafs; + + s32 *LeafFaces; + s32 NumLeafFaces; + + s32 *MeshVerts; // The vertex offsets for a mesh + s32 NumMeshVerts; + + tBSPBrush* Brushes; + s32 NumBrushes; + + scene::SMesh** BrushEntities; + + scene::SMesh* Mesh[quake3::E_Q3_MESH_SIZE]; + video::IVideoDriver* Driver; + core::stringc LevelName; + io::IFileSystem* FileSystem; // needs because there are no file extenstions stored in .bsp files. + + // Additional content + scene::ISceneManager* SceneManager; + enum eToken + { + Q3_TOKEN_UNRESOLVED = 0, + Q3_TOKEN_EOF = 1, + Q3_TOKEN_START_LIST, + Q3_TOKEN_END_LIST, + Q3_TOKEN_ENTITY, + Q3_TOKEN_TOKEN, + Q3_TOKEN_EOL, + Q3_TOKEN_COMMENT, + Q3_TOKEN_MATH_DIVIDE, + Q3_TOKEN_MATH_ADD, + Q3_TOKEN_MATH_MULTIPY + }; + struct SQ3Parser + { + const c8 *source; + u32 sourcesize; + u32 index; + core::stringc token; + eToken tokenresult; + }; + SQ3Parser Parser; + + + typedef void( CQ3LevelMesh::*tParserCallback ) ( quake3::SVarGroupList *& groupList, eToken token ); + void parser_parse( const void * data, u32 size, tParserCallback callback ); + void parser_nextToken(); + + void dumpVarGroup( const quake3::SVarGroup * group, s32 stack ) const; + + void scriptcallback_entity( quake3::SVarGroupList *& grouplist, eToken token ); + void scriptcallback_shader( quake3::SVarGroupList *& grouplist, eToken token ); + void scriptcallback_config( quake3::SVarGroupList *& grouplist, eToken token ); + + core::array < quake3::IShader > Shader; + core::array < quake3::IShader > Entity; //quake3::tQ3EntityList Entity; + + + quake3::tStringList ShaderFile; + void InitShader(); + void ReleaseShader(); + void ReleaseEntity(); + + + s32 setShaderMaterial( video::SMaterial & material, const tBSPFace * face ) const; + s32 setShaderFogMaterial( video::SMaterial &material, const tBSPFace * face ) const; + + struct SToBuffer + { + s32 takeVertexColor; + u32 index; + }; + + void cleanMeshes(); + void cleanMesh(SMesh *m, const bool texture0important = false); + void cleanLoader (); + void calcBoundingBoxes(); + c8 buf[128]; + f32 FramesPerSecond; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.cpp new file mode 100644 index 0000000..9219782 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.cpp @@ -0,0 +1,1376 @@ +// Copyright (C) 2002-2012 Thomas Alten / Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + +#include "CQuake3ShaderSceneNode.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" +#include "IMeshManipulator.h" +#include "SMesh.h" +#include "IMaterialRenderer.h" +#include "CShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + +// who, if not you.. +using namespace quake3; + +/*! +*/ +CQuake3ShaderSceneNode::CQuake3ShaderSceneNode( + scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id, + io::IFileSystem *fileSystem, const scene::IMeshBuffer *original, + const IShader * shader) +: scene::IMeshSceneNode(parent, mgr, id, + core::vector3df(0.f, 0.f, 0.f), + core::vector3df(0.f, 0.f, 0.f), + core::vector3df(1.f, 1.f, 1.f)), + Shader(shader), Mesh(0), Shadow(0), Original(0), MeshBuffer(0), TimeAbs(0.f) +{ + #ifdef _DEBUG + core::stringc dName = "CQuake3ShaderSceneNode "; + dName += Shader->name; + + setDebugName( dName.c_str() ); + #endif + + // name the Scene Node + this->Name = Shader->name; + + // take lightmap vertex type + MeshBuffer = new SMeshBuffer(); + + Mesh = new SMesh (); + Mesh->addMeshBuffer ( MeshBuffer ); + MeshBuffer->drop (); + + //Original = new SMeshBufferLightMap(); + Original = (const scene::SMeshBufferLightMap*) original; + Original->grab(); + + // clone meshbuffer to modifiable buffer + cloneBuffer(MeshBuffer, Original, + Original->getMaterial().ColorMask != 0); + + // load all Textures in all stages + loadTextures( fileSystem ); + + setAutomaticCulling( scene::EAC_OFF ); +} + + +/*! +*/ +CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode() +{ + if (Shadow) + Shadow->drop(); + + if (Mesh) + Mesh->drop(); + + if (Original) + Original->drop(); +} + + + +/* + create single copies +*/ +void CQuake3ShaderSceneNode::cloneBuffer( scene::SMeshBuffer *dest, const scene::SMeshBufferLightMap * buffer, bool translateCenter ) +{ + dest->Material = buffer->Material; + dest->Indices = buffer->Indices; + + const u32 vsize = buffer->Vertices.size(); + + dest->Vertices.set_used( vsize ); + for ( u32 i = 0; i!= vsize; ++i ) + { + const video::S3DVertex2TCoords& src = buffer->Vertices[i]; + video::S3DVertex &dst = dest->Vertices[i]; + + dst.Pos = src.Pos; + dst.Normal = src.Normal; + dst.Color = 0xFFFFFFFF; + dst.TCoords = src.TCoords; + + if ( i == 0 ) + dest->BoundingBox.reset ( src.Pos ); + else + dest->BoundingBox.addInternalPoint ( src.Pos ); + } + + // move the (temp) Mesh to a ScenePosititon + // set Scene Node Position + + if ( translateCenter ) + { + MeshOffset = dest->BoundingBox.getCenter(); + setPosition( MeshOffset ); + + core::matrix4 m; + m.setTranslation( -MeshOffset ); + SceneManager->getMeshManipulator()->transform( dest, m ); + } + + // No Texture!. Use Shader-Pointer for sorting + dest->Material.setTexture(0, (video::ITexture*) Shader); +} + + +/* + load the textures for all stages +*/ +void CQuake3ShaderSceneNode::loadTextures( io::IFileSystem * fileSystem ) +{ + const SVarGroup *group; + u32 i; + + video::IVideoDriver *driver = SceneManager->getVideoDriver(); + + // generic stage + u32 mipmap = 0; + group = Shader->getGroup( 1 ); + if ( group->isDefined ( "nomipmaps" ) ) + { + mipmap = 2 | (driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS)? 1: 0 ); + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); + } + + // clear all stages and prefill empty + Q3Texture.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); + Q3Texture.clear(); + for ( i = 0; i != Shader->VarGroup->VariableGroup.size(); ++i ) + { + Q3Texture.push_back( SQ3Texture() ); + } + + u32 pos; + + // get texture map + for ( i = 0; i < Shader->VarGroup->VariableGroup.size(); ++i ) + { + group = Shader->getGroup( i ); + + const core::stringc &mapname = group->get( "map" ); + if ( 0 == mapname.size() ) + continue; + + // our lightmap is passed in material.Texture[2] + if ( mapname == "$lightmap" ) + { + Q3Texture [i].Texture.push_back( Original->getMaterial().getTexture(1) ); + } + else + { + pos = 0; + getTextures( Q3Texture [i].Texture, mapname, pos, fileSystem, driver ); + } + } + + // get anim map + for ( i = 0; i < Shader->VarGroup->VariableGroup.size(); ++i ) + { + if ( Q3Texture [i].Texture.size() ) + continue; + + group = Shader->getGroup( i ); + + const core::stringc &animmap = group->get( "animmap" ); + if ( 0 == animmap.size() ) + continue; + + // first parameter is frequency + pos = 0; + Q3Texture [i].TextureFrequency = core::max_( 0.0001f, getAsFloat( animmap, pos ) ); + + getTextures( Q3Texture [i].Texture, animmap, pos,fileSystem, driver ); + } + + // get clamp map + for ( i = 0; i < Shader->VarGroup->VariableGroup.size(); ++i ) + { + if ( Q3Texture [i].Texture.size() ) + continue; + + group = Shader->getGroup( i ); + + const core::stringc &clampmap = group->get( "clampmap" ); + if ( 0 == clampmap.size() ) + continue; + + Q3Texture [i].TextureAddressMode = video::ETC_CLAMP_TO_EDGE; + pos = 0; + getTextures( Q3Texture [i].Texture, clampmap, pos,fileSystem, driver ); + } + + if ( mipmap & 2 ) + driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap & 1); +} + +/* + Register each texture stage, if first is visible +*/ +void CQuake3ShaderSceneNode::OnRegisterSceneNode() +{ + if ( isVisible() ) + { + SceneManager->registerNodeForRendering(this, getRenderStage() ); + } + ISceneNode::OnRegisterSceneNode(); +} + +/* + is this a transparent node ? +*/ +E_SCENE_NODE_RENDER_PASS CQuake3ShaderSceneNode::getRenderStage() const +{ + E_SCENE_NODE_RENDER_PASS ret = ESNRP_SOLID; + + // generic stage + const SVarGroup *group; + + group = Shader->getGroup( 1 ); +/* + else + if ( group->getIndex( "portal" ) >= 0 ) + { + ret = ESNRP_TRANSPARENT_EFFECT; + } + else +*/ + if ( group->isDefined( "sort", "opaque" ) ) + { + ret = ESNRP_SOLID; + } + else + if ( group->isDefined( "sort", "additive" ) ) + { + ret = ESNRP_TRANSPARENT; + } + else + if ( strstr ( Shader->name.c_str(), "flame" ) || + group->isDefined( "surfaceparm", "water" ) || + group->isDefined( "sort", "underwater" ) || + group->isDefined( "sort", "underwater" ) + ) + { + ret = ESNRP_TRANSPARENT_EFFECT; + } + else + { + // Look if first drawing stage needs graphical underlay + for ( u32 stage = 2; stage < Shader->VarGroup->VariableGroup.size(); ++stage ) + { + if ( 0 == Q3Texture [ stage ].Texture.size() ) + continue; + + group = Shader->getGroup( stage ); + + SBlendFunc blendfunc ( video::EMFN_MODULATE_1X ); + getBlendFunc( group->get( "blendfunc" ), blendfunc ); + getBlendFunc( group->get( "alphafunc" ), blendfunc ); + + //ret = blendfunc.isTransparent ? ESNRP_TRANSPARENT : ESNRP_SOLID; + if ( blendfunc.isTransparent ) + { + ret = ESNRP_TRANSPARENT; + } + break; + } + } + + return ret; +} + + +/* + render in multipass technique +*/ +void CQuake3ShaderSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + E_SCENE_NODE_RENDER_PASS pass = SceneManager->getSceneNodeRenderPass(); + + video::SMaterial material; + const SVarGroup *group; + + material.Lighting = false; + material.setTexture(1, 0); + material.NormalizeNormals = false; + + // generic stage + group = Shader->getGroup( 1 ); + material.BackfaceCulling = getCullingFunction( group->get( "cull" ) ); + + u32 pushProjection = 0; + core::matrix4 projection ( core::matrix4::EM4CONST_NOTHING ); + + // decal ( solve z-fighting ) + if ( group->isDefined( "polygonoffset" ) ) + { + projection = driver->getTransform( video::ETS_PROJECTION ); + + core::matrix4 decalProjection ( projection ); + +/* + f32 n = SceneManager->getActiveCamera()->getNearValue(); + f32 f = SceneManager->getActiveCamera()->getFarValue (); + + f32 delta = 0.01f; + f32 pz = 0.2f; + f32 epsilon = -2.f * f * n * delta / ( ( f + n ) * pz * ( pz + delta ) ); + decalProjection[10] *= 1.f + epsilon; +*/ + // TODO: involve camera + decalProjection[10] -= 0.0002f; + driver->setTransform( video::ETS_PROJECTION, decalProjection ); + pushProjection |= 1; + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation ); + if (Shadow) + Shadow->updateShadowVolumes(); + + //! render all stages + u32 drawCount = (pass == ESNRP_TRANSPARENT_EFFECT) ? 1 : 0; + core::matrix4 textureMatrix ( core::matrix4::EM4CONST_NOTHING ); + for ( u32 stage = 1; stage < Shader->VarGroup->VariableGroup.size(); ++stage ) + { + SQ3Texture &q = Q3Texture[stage]; + + // advance current stage + textureMatrix.makeIdentity(); + animate( stage, textureMatrix ); + + // stage finished, no drawing stage ( vertex transform only ) + video::ITexture * tex = q.Texture.size() ? q.Texture [ q.TextureIndex ] : 0; + if ( 0 == tex ) + continue; + + // current stage + group = Shader->getGroup( stage ); + + material.setTexture(0, tex ); + material.ZBuffer = getDepthFunction( group->get( "depthfunc" ) ); + + if ( group->isDefined( "depthwrite" ) ) + { + material.ZWriteEnable = true; + } + else + { + material.ZWriteEnable = drawCount == 0; + } + + //resolve quake3 blendfunction to irrlicht Material Type + SBlendFunc blendfunc ( video::EMFN_MODULATE_1X ); + getBlendFunc( group->get( "blendfunc" ), blendfunc ); + getBlendFunc( group->get( "alphafunc" ), blendfunc ); + + material.MaterialType = blendfunc.type; + material.MaterialTypeParam = blendfunc.param0; + + material.TextureLayer[0].TextureWrapU = q.TextureAddressMode; + material.TextureLayer[0].TextureWrapV = q.TextureAddressMode; + //material.TextureLayer[0].TrilinearFilter = 1; + //material.TextureLayer[0].AnisotropicFilter = 0xFF; + material.setTextureMatrix( 0, textureMatrix ); + + driver->setMaterial( material ); + driver->drawMeshBuffer( MeshBuffer ); + drawCount += 1; + + } + + if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY ) + { + video::SMaterial deb_m; + deb_m.Wireframe = true; + deb_m.Lighting = false; + deb_m.BackfaceCulling = material.BackfaceCulling; + driver->setMaterial( deb_m ); + + driver->drawMeshBuffer( MeshBuffer ); + } + + // show normals + if ( DebugDataVisible & scene::EDS_NORMALS ) + { + video::SMaterial deb_m; + + IAnimatedMesh * arrow = SceneManager->addArrowMesh ( + "__debugnormalq3", + 0xFFECEC00,0xFF999900, + 4, 8, + 8.f, 6.f, + 0.5f,1.f + ); + if ( 0 == arrow ) + { + arrow = SceneManager->getMesh ( "__debugnormalq3" ); + } + const IMesh *mesh = arrow->getMesh ( 0 ); + + // find a good scaling factor + + core::matrix4 m2; + + // draw normals + const scene::IMeshBuffer* mb = MeshBuffer; + const u32 vSize = video::getVertexPitchFromType(mb->getVertexType()); + const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices(); + + //f32 colCycle = 270.f / (f32) core::s32_max ( mb->getVertexCount() - 1, 1 ); + + for ( u32 i=0; i != mb->getVertexCount(); ++i ) + { + // Align to v->normal + m2.buildRotateFromTo ( core::vector3df ( 0.f, 1.f, 0 ), v->Normal ); + m2.setTranslation ( v->Pos + AbsoluteTransformation.getTranslation () ); +/* + core::quaternion quatRot( v->Normal.Z, 0.f, -v->Normal.X, 1 + v->Normal.Y ); + quatRot.normalize(); + quatRot.getMatrix ( m2, v->Pos ); + + m2 [ 12 ] += AbsoluteTransformation [ 12 ]; + m2 [ 13 ] += AbsoluteTransformation [ 13 ]; + m2 [ 14 ] += AbsoluteTransformation [ 14 ]; +*/ + driver->setTransform(video::ETS_WORLD, m2 ); + + deb_m.Lighting = true; +/* + irr::video::SColorHSL color; + irr::video::SColor rgb(0); + color.Hue = i * colCycle * core::DEGTORAD; + color.Saturation = 1.f; + color.Luminance = 0.5f; + color.toRGB( deb_m.EmissiveColor ); +*/ + switch ( i ) + { + case 0: deb_m.EmissiveColor.set(0xFFFFFFFF); break; + case 1: deb_m.EmissiveColor.set(0xFFFF0000); break; + case 2: deb_m.EmissiveColor.set(0xFF00FF00); break; + case 3: deb_m.EmissiveColor.set(0xFF0000FF); break; + default: + deb_m.EmissiveColor = v->Color; break; + } + driver->setMaterial( deb_m ); + + for ( u32 a = 0; a != mesh->getMeshBufferCount(); ++a ) + driver->drawMeshBuffer ( mesh->getMeshBuffer ( a ) ); + + v = (const video::S3DVertex*) ( (u8*) v + vSize ); + } + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + } + + + if ( pushProjection & 1 ) + { + driver->setTransform( video::ETS_PROJECTION, projection ); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + { + video::SMaterial deb_m; + deb_m.Lighting = false; + driver->setMaterial(deb_m); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + driver->draw3DBox( getBoundingBox(), video::SColor(255,255,0,0)); + } + +} + + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool CQuake3ShaderSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + } + + return ISceneNode::removeChild(child); +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* CQuake3ShaderSceneNode::addShadowVolumeSceneNode( + const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (!shadowMesh) + shadowMesh = Mesh; // if null is given, use the mesh of node + + if (Shadow) + Shadow->drop(); + + Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + + +/*! +3.3.1 deformVertexes wave
+ Designed for water surfaces, modifying the values differently at each point. + It accepts the standard wave functions of the type sin, triangle, square, sawtooth + or inversesawtooth. The "div" parameter is used to control the wave "spread" + - a value equal to the tessSize of the surface is a good default value + (tessSize is subdivision size, in game units, used for the shader when seen in the game world) . +*/ +void CQuake3ShaderSceneNode::deformvertexes_wave( f32 dt, SModifierFunction &function ) +{ + function.wave = core::reciprocal( function.wave ); + + const f32 phase = function.phase; + + const u32 vsize = Original->Vertices.size(); + for ( u32 i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original->Vertices[i]; + video::S3DVertex &dst = MeshBuffer->Vertices[i]; + + if ( 0 == function.count ) + dst.Pos = src.Pos - MeshOffset; + + const f32 wavephase = (dst.Pos.X + dst.Pos.Y + dst.Pos.Z) * function.wave; + function.phase = phase + wavephase; + + const f32 f = function.evaluate( dt ); + + dst.Pos.X += f * src.Normal.X; + dst.Pos.Y += f * src.Normal.Y; + dst.Pos.Z += f * src.Normal.Z; + + if ( i == 0 ) + MeshBuffer->BoundingBox.reset ( dst.Pos ); + else + MeshBuffer->BoundingBox.addInternalPoint ( dst.Pos ); + } + function.count = 1; +} + +/*! + deformVertexes move x y z func base amplitude phase freq + The move parameter is used to make a brush, curve patch or model + appear to move together as a unit. The x y z values are the distance + and direction in game units the object appears to move relative to + it's point of origin in the map. The func base amplitude phase freq values are + the same as found in other waveform manipulations. + + The product of the function modifies the values x, y, and z. + Therefore, if you have an amplitude of 5 and an x value of 2, + the object will travel 10 units from its point of origin along the x axis. + This results in a total of 20 units of motion along the x axis, since the + amplitude is the variation both above and below the base. + + It must be noted that an object made with this shader does not actually + change position, it only appears to. + + Design Notes: + If an object is made up of surfaces with different shaders, all must have + matching deformVertexes move values or the object will appear to tear itself apart. +*/ +void CQuake3ShaderSceneNode::deformvertexes_move( f32 dt, SModifierFunction &function ) +{ + function.wave = core::reciprocal( function.wave ); + const f32 f = function.evaluate( dt ); + + const u32 vsize = Original->Vertices.size(); + for ( u32 i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original->Vertices[i]; + video::S3DVertex &dst = MeshBuffer->Vertices[i]; + + if ( 0 == function.count ) + dst.Pos = src.Pos - MeshOffset; + + dst.Pos.X += f * function.x; + dst.Pos.Y += f * function.y; + dst.Pos.Z += f * function.z; + + if ( i == 0 ) + MeshBuffer->BoundingBox.reset ( dst.Pos ); + else + MeshBuffer->BoundingBox.addInternalPoint ( dst.Pos ); + } + function.count = 1; + +} + +/*! + 3.3.2 deformVertexes normal
+ This deformation affects the normals of a vertex without actually moving it, + which will effect later shader options like lighting and especially environment mapping. + If the shader stages don't use normals in any of their calculations, there will + be no visible effect. + + Design Notes: Putting values of 0.1 t o 0.5 in Amplitude and 1.0 to 4.0 in the + Frequency can produce some satisfying results. Some things that have been + done with it: A small fluttering bat, falling leaves, rain, flags. +*/ +void CQuake3ShaderSceneNode::deformvertexes_normal( f32 dt, SModifierFunction &function ) +{ + function.func = SINUS; + const u32 vsize = Original->Vertices.size(); + for ( u32 i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original->Vertices[i]; + video::S3DVertex &dst = MeshBuffer->Vertices[i]; + + function.base = atan2f ( src.Pos.X, src.Pos.Y ); + function.phase = src.Pos.X + src.Pos.Z; + + const f32 lat = function.evaluate( dt ); + + function.base = src.Normal.Y; + function.phase = src.Normal.Z + src.Normal.X; + + const f32 lng = function.evaluate( dt ); + + dst.Normal.X = cosf ( lat ) * sinf ( lng ); + dst.Normal.Y = sinf ( lat ) * sinf ( lng ); + dst.Normal.Z = cosf ( lng ); + + } +} + + +/*! + 3.3.3 deformVertexes bulge + This forces a bulge to move along the given s and t directions. Designed for use + on curved pipes. + + Specific parameter definitions for deform keywords: +
This is roughly defined as the size of the waves that occur. + It is measured in game units. Smaller values create a greater + density of smaller wave forms occurring in a given area. + Larger values create a lesser density of waves, or otherwise put, + the appearance of larger waves. To look correct this value should + closely correspond to the value (in pixels) set for tessSize (tessellation size) + of the texture. A value of 100.0 is a good default value + (which means your tessSize should be close to that for things to look "wavelike"). + + This is the type of wave form being created. Sin stands for sine wave, + a regular smoothly flowing wave. Triangle is a wave with a sharp ascent + and a sharp decay. It will make a choppy looking wave forms. + A square wave is simply on or off for the period of the + frequency with no in between. The sawtooth wave has the ascent of a + triangle wave, but has the decay cut off sharply like a square wave. + An inversesawtooth wave reverses this. + + This is the distance, in game units that the apparent surface of the + texture is displaced from the actual surface of the brush as placed + in the editor. A positive value appears above the brush surface. + A negative value appears below the brush surface. + An example of this is the Quad effect, which essentially is a + shell with a positive base value to stand it away from the model + surface and a 0 (zero) value for amplitude. + + The distance that the deformation moves away from the base value. + See Wave Forms in the introduction for a description of amplitude. + + See Wave Forms in the introduction for a description of phase) + + See Wave Forms in the introduction for a description of frequency) + + Design Note: The div and amplitude parameters, when used in conjunction with + liquid volumes like water should take into consideration how much the water + will be moving. A large ocean area would have have massive swells (big div values) + that rose and fell dramatically (big amplitude values). While a small, quiet pool + may move very little. +*/ +void CQuake3ShaderSceneNode::deformvertexes_bulge( f32 dt, SModifierFunction &function ) +{ + function.func = SINUS; + function.wave = core::reciprocal( function.bulgewidth ); + + dt *= function.bulgespeed * 0.1f; + const f32 phase = function.phase; + + const u32 vsize = Original->Vertices.size(); + for ( u32 i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original->Vertices[i]; + video::S3DVertex &dst = MeshBuffer->Vertices[i]; + + const f32 wavephase = (Original->Vertices[i].TCoords.X ) * function.wave; + function.phase = phase + wavephase; + + const f32 f = function.evaluate( dt ); + + if ( 0 == function.count ) + dst.Pos = src.Pos - MeshOffset; + + dst.Pos.X += f * src.Normal.X; + dst.Pos.Y += f * src.Normal.Y; + dst.Pos.Z += f * src.Normal.Z; + + if ( i == 0 ) + MeshBuffer->BoundingBox.reset ( dst.Pos ); + else + MeshBuffer->BoundingBox.addInternalPoint ( dst.Pos ); + } + + function.count = 1; +} + + +/*! + deformVertexes autosprite + + This function can be used to make any given triangle quad + (pair of triangles that form a square rectangle) automatically behave + like a sprite without having to make it a separate entity. This means + that the "sprite" on which the texture is placed will rotate to always + appear at right angles to the player's view as a sprite would. Any four-sided + brush side, flat patch, or pair of triangles in a model can have the autosprite + effect on it. The brush face containing a texture with this shader keyword must + be square. +*/ +void CQuake3ShaderSceneNode::deformvertexes_autosprite( f32 dt, SModifierFunction &function ) +{ + u32 vsize = Original->Vertices.size(); + u32 g; + u32 i; + + const core::vector3df& camPos = SceneManager->getActiveCamera()->getPosition(); + + video::S3DVertex * dv = MeshBuffer->Vertices.pointer(); + const video::S3DVertex2TCoords * vin = Original->Vertices.const_pointer(); + + core::matrix4 lookat ( core::matrix4::EM4CONST_NOTHING ); + core::quaternion q; + for ( i = 0; i < vsize; i += 4 ) + { + // quad-plane + core::vector3df center = 0.25f * ( vin[i+0].Pos + vin[i+1].Pos + vin[i+2].Pos + vin[i+3].Pos ); + core::vector3df forward = camPos - center; + + q.rotationFromTo ( vin[i].Normal, forward ); + q.getMatrixCenter ( lookat, center, MeshOffset ); + + for ( g = 0; g < 4; ++g ) + { + lookat.transformVect ( dv[i+g].Pos, vin[i+g].Pos ); + lookat.rotateVect ( dv[i+g].Normal, vin[i+g].Normal ); + } + + } + function.count = 1; +} + + +/*! + deformVertexes autosprite2 + Is a slightly modified "sprite" that only rotates around the middle of its longest axis. + This allows you to make a pillar of fire that you can walk around, or an energy beam + stretched across the room. +*/ + +struct sortaxis +{ + core::vector3df v; + bool operator < ( const sortaxis &other ) const + { + return v.getLengthSQ () < other.v.getLengthSQ (); + } +}; +/*! +*/ +void CQuake3ShaderSceneNode::deformvertexes_autosprite2( f32 dt, SModifierFunction &function ) +{ + u32 vsize = Original->Vertices.size(); + u32 g; + u32 i; + + const core::vector3df camPos = SceneManager->getActiveCamera()->getAbsolutePosition(); + + video::S3DVertex * dv = MeshBuffer->Vertices.pointer(); + const video::S3DVertex2TCoords * vin = Original->Vertices.const_pointer(); + + core::matrix4 lookat ( core::matrix4::EM4CONST_NOTHING ); + + core::array < sortaxis > axis; + axis.set_used ( 3 ); + + for ( i = 0; i < vsize; i += 4 ) + { + // quad-plane + core::vector3df center = 0.25f * ( vin[i+0].Pos + vin[i+1].Pos + vin[i+2].Pos + vin[i+3].Pos ); + + // longes axe + axis[0].v = vin[i+1].Pos - vin[i+0].Pos; + axis[1].v = vin[i+2].Pos - vin[i+0].Pos; + axis[2].v = vin[i+3].Pos - vin[i+0].Pos; + axis.set_sorted ( false ); + axis.sort (); + + lookat.buildAxisAlignedBillboard ( camPos, center, MeshOffset, axis[1].v, vin[i+0].Normal ); + + for ( g = 0; g < 4; ++g ) + { + lookat.transformVect ( dv[i+g].Pos, vin[i+g].Pos ); + lookat.rotateVect ( dv[i+g].Normal, vin[i+g].Normal ); + } + } + function.count = 1; +} + +/* + Generate Vertex Color +*/ +void CQuake3ShaderSceneNode::vertextransform_rgbgen( f32 dt, SModifierFunction &function ) +{ + u32 i; + const u32 vsize = Original->Vertices.size(); + + switch ( function.rgbgen ) + { + case IDENTITY: + //rgbgen identity + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.set(0xFFFFFFFF); + break; + + case IDENTITYLIGHTING: + // rgbgen identitylighting TODO: overbright + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.set(0xFF7F7F7F); + break; + + case EXACTVERTEX: + // alphagen exactvertex TODO lighting + case VERTEX: + // rgbgen vertex + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color=Original->Vertices[i].Color; + break; + case WAVE: + { + // rgbGen wave + f32 f = function.evaluate( dt ) * 255.f; + s32 value = core::clamp( core::floor32(f), 0, 255 ); + value = 0xFF000000 | value << 16 | value << 8 | value; + + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.set(value); + } break; + case CONSTANT: + { + //rgbgen const ( x y z ) + video::SColorf cf( function.x, function.y, function.z ); + video::SColor col = cf.toSColor(); + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color=col; + } break; + default: + break; + } +} + +/* + Generate Vertex Color, Alpha +*/ +void CQuake3ShaderSceneNode::vertextransform_alphagen( f32 dt, SModifierFunction &function ) +{ + u32 i; + const u32 vsize = Original->Vertices.size(); + + switch ( function.alphagen ) + { + case IDENTITY: + //alphagen identity + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.setAlpha ( 0xFF ); + break; + + case EXACTVERTEX: + // alphagen exactvertex TODO lighting + case VERTEX: + // alphagen vertex + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.setAlpha ( Original->Vertices[i].Color.getAlpha() ); + break; + case CONSTANT: + { + // alphagen const + u32 a = (u32) ( function.x * 255.f ); + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.setAlpha ( a ); + } break; + + case LIGHTINGSPECULAR: + { + // alphagen lightingspecular TODO!!! + const SViewFrustum *frustum = SceneManager->getActiveCamera()->getViewFrustum(); + const core::matrix4 &view = frustum->getTransform ( video::ETS_VIEW ); + + const f32 *m = view.pointer(); + + for ( i = 0; i != vsize; ++i ) + { + const core::vector3df &n = Original->Vertices[i].Normal; + MeshBuffer->Vertices[i].Color.setAlpha ((u32)( 128.f *(1.f+(n.X*m[0]+n.Y*m[1]+n.Z*m[2])))); + } + + } break; + + + case WAVE: + { + // alphagen wave + f32 f = function.evaluate( dt ) * 255.f; + s32 value = core::clamp( core::floor32(f), 0, 255 ); + + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].Color.setAlpha ( value ); + } break; + default: + break; + } +} + + + +/* + Generate Texture Coordinates +*/ +void CQuake3ShaderSceneNode::vertextransform_tcgen( f32 dt, SModifierFunction &function ) +{ + u32 i; + const u32 vsize = Original->Vertices.size(); + + switch ( function.tcgen ) + { + case TURBULENCE: + //tcgen turb + { + function.wave = core::reciprocal( function.phase ); + + const f32 phase = function.phase; + + for ( i = 0; i != vsize; ++i ) + { + const video::S3DVertex2TCoords &src = Original->Vertices[i]; + video::S3DVertex &dst = MeshBuffer->Vertices[i]; + + const f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave; + function.phase = phase + wavephase; + + const f32 f = function.evaluate( dt ); + + dst.TCoords.X = src.TCoords.X + f * src.Normal.X; + dst.TCoords.Y = src.TCoords.Y + f * src.Normal.Y; + } + } + break; + + case TEXTURE: + // tcgen texture + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords; + break; + case LIGHTMAP: + // tcgen lightmap + for ( i = 0; i != vsize; ++i ) + MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords2; + break; + case ENVIRONMENT: + { + // tcgen environment + const SViewFrustum *frustum = SceneManager->getActiveCamera()->getViewFrustum(); + const core::matrix4 &view = frustum->getTransform ( video::ETS_VIEW ); + + const f32 *m = view.pointer(); + + core::vector3df n; + for ( i = 0; i != vsize; ++i ) + { + //const core::vector3df &n = Original->Vertices[i].Normal; + + n = frustum->cameraPosition - Original->Vertices[i].Pos; + n.normalize(); + n += Original->Vertices[i].Normal; + n.normalize(); + + MeshBuffer->Vertices[i].TCoords.X = 0.5f*(1.f+(n.X*m[0]+n.Y*m[1]+n.Z*m[2])); + MeshBuffer->Vertices[i].TCoords.Y = 0.5f*(1.f+(n.X*m[4]+n.Y*m[5]+n.Z*m[6])); + } + + } break; + default: + break; + } +} + + +#if 0 +/* + Transform Texture Coordinates +*/ +void CQuake3ShaderSceneNode::transformtex( const core::matrix4 &m, const u32 addressMode ) +{ + u32 i; + const u32 vsize = MeshBuffer->Vertices.size(); + + f32 tx1; + f32 ty1; + + if ( addressMode ) + { + for ( i = 0; i != vsize; ++i ) + { + core::vector2df &tx = MeshBuffer->Vertices[i].TCoords; + + tx1 = m[0] * tx.X + m[4] * tx.Y + m[8]; + ty1 = m[1] * tx.X + m[5] * tx.Y + m[9]; + + tx.X = tx1; + tx.Y = ty1; + } + } + else + { + + for ( i = 0; i != vsize; ++i ) + { + core::vector2df &tx = MeshBuffer->Vertices[i].TCoords; + + tx1 = m[0] * tx.X + m[4] * tx.Y + m[8]; + ty1 = m[1] * tx.X + m[5] * tx.Y + m[9]; + + tx.X = tx1 <= 0.f ? 0.f : tx1 >= 1.f ? 1.f : tx1; + tx.Y = ty1 <= 0.f ? 0.f : ty1 >= 1.f ? 1.f : ty1; + + //tx.X = core::clamp( tx1, 0.f, 1.f ); + //tx.Y = core::clamp( ty1, 0.f, 1.f ); + } + } +} + +#endif + + +/* + Texture & Vertex Transform Animator + + Return a Texture Transformation for this stage + Vertex transformation are called if found + +*/ +void CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture ) +{ + const SVarGroup *group = Shader->getGroup( stage ); + + // select current texture + SQ3Texture &q3Tex = Q3Texture [ stage ]; + if ( q3Tex.TextureFrequency != 0.f ) + { + s32 v = core::floor32( TimeAbs * q3Tex.TextureFrequency ); + q3Tex.TextureIndex = v % q3Tex.Texture.size(); + } + + core::matrix4 m2; + SModifierFunction function; + + f32 f[16]; + + // walk group for all modifiers + for ( u32 g = 0; g != group->Variable.size(); ++g ) + { + const SVariable &v = group->Variable[g]; + + // get the modifier + static const c8 * modifierList[] = + { + "tcmod","deformvertexes","rgbgen","tcgen","map","alphagen" + }; + + u32 pos = 0; + function.masterfunc0 = (eQ3ModifierFunction) isEqual( v.name, pos, modifierList, 6 ); + + if ( UNKNOWN == function.masterfunc0 ) + continue; + + switch ( function.masterfunc0 ) + { + //tcmod + case TCMOD: + m2.makeIdentity(); + break; + default: + break; + } + + // get the modifier function + static const c8 * funclist[] = + { + "scroll","scale","rotate","stretch","turb", + "wave","identity","vertex", + "texture","lightmap","environment","$lightmap", + "bulge","autosprite","autosprite2","transform", + "exactvertex","const","lightingspecular","move","normal", + "identitylighting" + }; + static const c8 * groupToken[] = { "(", ")" }; + + pos = 0; + function.masterfunc1 = (eQ3ModifierFunction) isEqual( v.content, pos, funclist, 22 ); + if ( function.masterfunc1 != UNKNOWN ) + function.masterfunc1 = (eQ3ModifierFunction) ((u32) function.masterfunc1 + FUNCTION2 + 1); + + switch ( function.masterfunc1 ) + { + case SCROLL: + // tcMod scroll + f[0] = getAsFloat( v.content, pos ) * TimeAbs; + f[1] = getAsFloat( v.content, pos ) * TimeAbs; + m2.setTextureTranslate( f[0], f[1] ); + break; + case SCALE: + // tcmod scale + f[0] = getAsFloat( v.content, pos ); + f[1] = getAsFloat( v.content, pos ); + m2.setTextureScale( f[0], f[1] ); + break; + case ROTATE: + // tcmod rotate + m2.setTextureRotationCenter( getAsFloat( v.content, pos ) * + core::DEGTORAD * + TimeAbs + ); + break; + case TRANSFORM: + // tcMod + memset(f, 0, sizeof ( f )); + f[10] = f[15] = 1.f; + + f[0] = getAsFloat( v.content, pos ); + f[1] = getAsFloat( v.content, pos ); + f[4] = getAsFloat( v.content, pos ); + f[5] = getAsFloat( v.content, pos ); + f[8] = getAsFloat( v.content, pos ); + f[9] = getAsFloat( v.content, pos ); + m2.setM ( f ); + break; + + case STRETCH: // stretch + case TURBULENCE: // turb + case WAVE: // wave + case IDENTITY: // identity + case IDENTITYLIGHTING: + case VERTEX: // vertex + case MOVE: + case CONSTANT: + { + // turb == sin, default == sin + function.func = SINUS; + + if ( function.masterfunc0 == DEFORMVERTEXES ) + { + switch ( function.masterfunc1 ) + { + case WAVE: + // deformvertexes wave + function.wave = getAsFloat( v.content, pos ); + break; + case MOVE: + //deformvertexes move + function.x = getAsFloat( v.content, pos ); + function.z = getAsFloat( v.content, pos ); + function.y = getAsFloat( v.content, pos ); + break; + default: + break; + } + } + + switch ( function.masterfunc1 ) + { + case STRETCH: + case TURBULENCE: + case WAVE: + case MOVE: + getModifierFunc( function, v.content, pos ); + break; + default: + break; + } + + switch ( function.masterfunc1 ) + { + case STRETCH: + //tcMod stretch + f[0] = core::reciprocal( function.evaluate(TimeAbs) ); + m2.setTextureScaleCenter( f[0], f[0] ); + break; + case TURBULENCE: + //tcMod turb + //function.tcgen = TURBULENCE; + m2.setTextureRotationCenter( function.frequency * + core::DEGTORAD * + TimeAbs + ); + break; + case WAVE: + case IDENTITY: + case IDENTITYLIGHTING: + case VERTEX: + case EXACTVERTEX: + case CONSTANT: + case LIGHTINGSPECULAR: + case MOVE: + switch ( function.masterfunc0 ) + { + case DEFORMVERTEXES: + switch ( function.masterfunc1 ) + { + case WAVE: + deformvertexes_wave( TimeAbs, function ); + break; + case MOVE: + deformvertexes_move( TimeAbs, function ); + break; + default: + break; + } + break; + case RGBGEN: + function.rgbgen = function.masterfunc1; + if ( function.rgbgen == CONSTANT ) + { + isEqual ( v.content, pos, groupToken, 2 ); + function.x = getAsFloat( v.content, pos ); + function.y = getAsFloat( v.content, pos ); + function.z = getAsFloat( v.content, pos ); + } + //vertextransform_rgbgen( TimeAbs, function ); + break; + case ALPHAGEN: + function.alphagen = function.masterfunc1; + if ( function.alphagen == CONSTANT ) + { + function.x = getAsFloat( v.content, pos ); + } + + //vertextransform_alphagen( TimeAbs, function ); + break; + default: + break; + } + break; + default: + break; + } + + } break; + case TEXTURE: + case LIGHTMAP: + case ENVIRONMENT: + // "texture","lightmap","environment" + function.tcgen = function.masterfunc1; + break; + case DOLLAR_LIGHTMAP: + // map == lightmap, tcgen == lightmap + function.tcgen = LIGHTMAP; + break; + case BULGE: + // deformvertexes bulge + function.bulgewidth = getAsFloat( v.content, pos ); + function.bulgeheight = getAsFloat( v.content, pos ); + function.bulgespeed = getAsFloat( v.content, pos ); + + deformvertexes_bulge(TimeAbs, function); + break; + + case NORMAL: + // deformvertexes normal + function.amp = getAsFloat( v.content, pos ); + function.frequency = getAsFloat( v.content, pos ); + + deformvertexes_normal(TimeAbs, function); + break; + + case AUTOSPRITE: + // deformvertexes autosprite + deformvertexes_autosprite(TimeAbs, function); + break; + + case AUTOSPRITE2: + // deformvertexes autosprite2 + deformvertexes_autosprite2(TimeAbs, function); + break; + default: + break; + } // func + + switch ( function.masterfunc0 ) + { + case TCMOD: + texture *= m2; + break; + default: + break; + } + + } // group + + vertextransform_rgbgen( TimeAbs, function ); + vertextransform_alphagen( TimeAbs, function ); + vertextransform_tcgen( TimeAbs, function ); +} + + +void CQuake3ShaderSceneNode::OnAnimate(u32 timeMs) +{ + TimeAbs = f32( timeMs ) * (1.f/1000.f); + ISceneNode::OnAnimate( timeMs ); +} + +const core::aabbox3d& CQuake3ShaderSceneNode::getBoundingBox() const +{ + return MeshBuffer->getBoundingBox(); +} + + +u32 CQuake3ShaderSceneNode::getMaterialCount() const +{ + return Q3Texture.size(); +} + +video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i) +{ + video::SMaterial& m = MeshBuffer->Material; + m.setTexture(0, 0); + if ( Q3Texture [ i ].TextureIndex ) + m.setTexture(0, Q3Texture [ i ].Texture [ Q3Texture [ i ].TextureIndex ]); + return m; +} + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.h new file mode 100644 index 0000000..6ec026f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CQuake3ShaderSceneNode.h @@ -0,0 +1,118 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_QUAKE3_SCENE_NODE_H_INCLUDED__ +#define __C_QUAKE3_SCENE_NODE_H_INCLUDED__ + +#include "IMeshSceneNode.h" +#include "IQ3Shader.h" +#include "IFileSystem.h" +#include "SMeshBuffer.h" +#include "SMeshBufferLightMap.h" +#include "SMesh.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! Scene node which is a quake3 shader. +class CQuake3ShaderSceneNode : public scene::IMeshSceneNode +{ +public: + + CQuake3ShaderSceneNode( ISceneNode* parent, ISceneManager* mgr, s32 id, + io::IFileSystem* fileSystem, + const IMeshBuffer* original, + const quake3::IShader* shader + ); + + virtual ~CQuake3ShaderSceneNode(); + + virtual void OnRegisterSceneNode(); + virtual void render(); + virtual void OnAnimate(u32 timeMs); + virtual const core::aabbox3d& getBoundingBox() const; + + virtual u32 getMaterialCount() const; + virtual video::SMaterial& getMaterial(u32 i); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_Q3SHADER_SCENE_NODE; } + + virtual void setMesh(IMesh* mesh){} + virtual IMesh* getMesh() { return Mesh; } + virtual void setReadOnlyMaterials(bool readonly) {} + virtual bool isReadOnlyMaterials() const { return true; } + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh, + s32 id, bool zfailmethod=true, f32 infinity=10000.0f); + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + +private: + const quake3::IShader* Shader; + SMesh *Mesh; + IShadowVolumeSceneNode* Shadow; + const SMeshBufferLightMap* Original; + SMeshBuffer* MeshBuffer; + core::vector3df MeshOffset; + + struct SQ3Texture + { + SQ3Texture () : + TextureIndex ( 0 ), + TextureFrequency(0.f), + TextureAddressMode( video::ETC_REPEAT ) + { + Texture.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); + } + + quake3::tTexArray Texture; + + u32 TextureIndex; + f32 TextureFrequency; + video::E_TEXTURE_CLAMP TextureAddressMode; // Wrapping/Clamping + }; + + core::array< SQ3Texture > Q3Texture; + + void loadTextures ( io::IFileSystem * fileSystem ); + void addBuffer ( scene::SMeshBufferLightMap * buffer ); + void cloneBuffer ( scene::SMeshBuffer *dest, const scene::SMeshBufferLightMap * buffer, bool translateCenter ); + + void deformvertexes_wave ( f32 dt, quake3::SModifierFunction &function ); + void deformvertexes_move ( f32 dt, quake3::SModifierFunction &function ); + void deformvertexes_bulge( f32 dt, quake3::SModifierFunction &function ); + void deformvertexes_autosprite( f32 dt, quake3::SModifierFunction &function ); + void deformvertexes_autosprite2( f32 dt, quake3::SModifierFunction &function ); + void deformvertexes_normal ( f32 dt, quake3::SModifierFunction &function ); + + void vertextransform_tcgen ( f32 dt, quake3::SModifierFunction &function ); + void vertextransform_rgbgen ( f32 dt, quake3::SModifierFunction &function ); + void vertextransform_alphagen ( f32 dt, quake3::SModifierFunction &function ); + + void transformtex ( const core::matrix4 &m, const u32 clamp ); + + f32 TimeAbs; + + void animate( u32 stage, core::matrix4 &texture ); + + E_SCENE_NODE_RENDER_PASS getRenderStage() const; + +}; + + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.cpp new file mode 100644 index 0000000..2f067e6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CReadFile.h" + +namespace irr +{ +namespace io +{ + + +CReadFile::CReadFile(const io::path& fileName) +: File(0), FileSize(0), Filename(fileName) +{ + #ifdef _DEBUG + setDebugName("CReadFile"); + #endif + + openFile(); +} + + +CReadFile::~CReadFile() +{ + if (File) + fclose(File); +} + + +//! returns how much was read +s32 CReadFile::read(void* buffer, u32 sizeToRead) +{ + if (!isOpen()) + return 0; + + return (s32)fread(buffer, 1, sizeToRead, File); +} + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CReadFile::seek(long finalPos, bool relativeMovement) +{ + if (!isOpen()) + return false; + + return fseek(File, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET) == 0; +} + + +//! returns size of file +long CReadFile::getSize() const +{ + return FileSize; +} + + +//! returns where in the file we are. +long CReadFile::getPos() const +{ + return ftell(File); +} + + +//! opens the file +void CReadFile::openFile() +{ + if (Filename.size() == 0) // bugfix posted by rt + { + File = 0; + return; + } + +#if defined ( _IRR_WCHAR_FILESYSTEM ) + File = _wfopen(Filename.c_str(), L"rb"); +#else + File = fopen(Filename.c_str(), "rb"); +#endif + + if (File) + { + // get FileSize + + fseek(File, 0, SEEK_END); + FileSize = getPos(); + fseek(File, 0, SEEK_SET); + } +} + + +//! returns name of file +const io::path& CReadFile::getFileName() const +{ + return Filename; +} + + + +IReadFile* createReadFile(const io::path& fileName) +{ + CReadFile* file = new CReadFile(fileName); + if (file->isOpen()) + return file; + + file->drop(); + return 0; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.h new file mode 100644 index 0000000..09f3501 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CReadFile.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_READ_FILE_H_INCLUDED__ +#define __C_READ_FILE_H_INCLUDED__ + +#include +#include "IReadFile.h" +#include "irrString.h" + +namespace irr +{ + +namespace io +{ + + /*! + Class for reading a real file from disk. + */ + class CReadFile : public IReadFile + { + public: + + CReadFile(const io::path& fileName); + + virtual ~CReadFile(); + + //! returns how much was read + virtual s32 read(void* buffer, u32 sizeToRead); + + //! changes position in file, returns true if successful + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! returns size of file + virtual long getSize() const; + + //! returns if file is open + virtual bool isOpen() const + { + return File != 0; + } + + //! returns where in the file we are. + virtual long getPos() const; + + //! returns name of file + virtual const io::path& getFileName() const; + + private: + + //! opens the file + void openFile(); + + FILE* File; + long FileSize; + io::path Filename; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp new file mode 100644 index 0000000..099f2aa --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.cpp @@ -0,0 +1,232 @@ +// Copyright (C) 2010-2012 Gaz Davidson / Joseph Ellis +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_SMF_LOADER_ + +#include "CSMFMeshFileLoader.h" +#include "SAnimatedMesh.h" +#include "SMeshBuffer.h" +#include "IReadFile.h" +#include "coreutil.h" +#include "os.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + +CSMFMeshFileLoader::CSMFMeshFileLoader(video::IVideoDriver* driver) +: Driver(driver) +{ +} + +//! Returns true if the file might be loaded by this class. +bool CSMFMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension(filename, "smf"); +} + +//! Creates/loads an animated mesh from the file. +IAnimatedMesh* CSMFMeshFileLoader::createMesh(io::IReadFile* file) +{ + // create empty mesh + SMesh *mesh = new SMesh(); + + // load file + u16 version; + u8 flags; + s32 limbCount; + s32 i; + + io::BinaryFile::read(file, version); + io::BinaryFile::read(file, flags); + io::BinaryFile::read(file, limbCount); + + // load mesh data + core::matrix4 identity; + for (i=0; i < limbCount; ++i) + loadLimb(file, mesh, identity); + + // recalculate buffer bounding boxes + for (i=0; i < (s32)mesh->getMeshBufferCount(); ++i) + mesh->getMeshBuffer(i)->recalculateBoundingBox(); + + mesh->recalculateBoundingBox(); + SAnimatedMesh *am = new SAnimatedMesh(); + am->addMesh(mesh); + mesh->drop(); + am->recalculateBoundingBox(); + + return am; +} + +void CSMFMeshFileLoader::loadLimb(io::IReadFile* file, SMesh* mesh, const core::matrix4 &parentTransformation) +{ + core::matrix4 transformation; + + // limb transformation + core::vector3df translate, rotate, scale; + io::BinaryFile::read(file, translate); + io::BinaryFile::read(file, rotate); + io::BinaryFile::read(file, scale); + + transformation.setTranslation(translate); + transformation.setRotationDegrees(rotate); + transformation.setScale(scale); + + transformation = parentTransformation * transformation; + + core::stringc textureName, textureGroupName; + + // texture information + io::BinaryFile::read(file, textureGroupName); + io::BinaryFile::read(file, textureName); + + // attempt to load texture using known formats + video::ITexture* texture = 0; + + const c8* extensions[] = {".jpg", ".png", ".tga", ".bmp", 0}; + + for (const c8 **ext = extensions; !texture && *ext; ++ext) + { + texture = Driver->getTexture(textureName + *ext); + if (texture) + textureName = textureName + *ext; + } + // find the correct mesh buffer + u32 i; + for (i=0; iMeshBuffers.size(); ++i) + if (mesh->MeshBuffers[i]->getMaterial().TextureLayer[0].Texture == texture) + break; + + // create mesh buffer if none was found + if (i == mesh->MeshBuffers.size()) + { + CMeshBuffer* mb = new CMeshBuffer(); + mb->Material.TextureLayer[0].Texture = texture; + + // horribly hacky way to do this, maybe it's in the flags? + if (core::hasFileExtension(textureName, "tga", "png")) + mb->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + else + mb->Material.MaterialType = video::EMT_SOLID; + + mesh->MeshBuffers.push_back(mb); + } + + CMeshBuffer* mb = (CMeshBuffer*)mesh->MeshBuffers[i]; + + u16 vertexCount, firstVertex = mb->getVertexCount(); + + io::BinaryFile::read(file, vertexCount); + mb->Vertices.reallocate(mb->Vertices.size() + vertexCount); + + // add vertices and set positions + for (i=0; iVertices.push_back(vert); + } + + // set vertex normals + for (i=0; i < vertexCount; ++i) + { + core::vector3df normal; + io::BinaryFile::read(file, normal); + transformation.rotateVect(normal); + mb->Vertices[firstVertex + i].Normal = normal; + } + // set texture coordinates + + for (i=0; i < vertexCount; ++i) + { + core::vector2df tcoords; + io::BinaryFile::read(file, tcoords); + mb->Vertices[firstVertex + i].TCoords = tcoords; + } + + // triangles + u32 triangleCount; + // vertexCount used as temporary + io::BinaryFile::read(file, vertexCount); + triangleCount=3*vertexCount; + mb->Indices.reallocate(mb->Indices.size() + triangleCount); + + for (i=0; i < triangleCount; ++i) + { + u16 index; + io::BinaryFile::read(file, index); + mb->Indices.push_back(firstVertex + index); + } + + // read limbs + s32 limbCount; + io::BinaryFile::read(file, limbCount); + + for (s32 l=0; l < limbCount; ++l) + loadLimb(file, mesh, transformation); +} + +} // namespace scene + +// todo: at some point in the future let's move these to a place where everyone can use them. +namespace io +{ + +#if _BIGENDIAN +#define _SYSTEM_BIG_ENDIAN_ (true) +#else +#define _SYSTEM_BIG_ENDIAN_ (false) +#endif + +template +void BinaryFile::read(io::IReadFile* file, T &out, bool bigEndian) +{ + file->read((void*)&out, sizeof(out)); + if (bigEndian != (_SYSTEM_BIG_ENDIAN_)) + out = os::Byteswap::byteswap(out); +} + +//! reads a 3d vector from the file, moving the file pointer along +void BinaryFile::read(io::IReadFile* file, core::vector3df &outVector2d, bool bigEndian) +{ + BinaryFile::read(file, outVector2d.X, bigEndian); + BinaryFile::read(file, outVector2d.Y, bigEndian); + BinaryFile::read(file, outVector2d.Z, bigEndian); +} + +//! reads a 2d vector from the file, moving the file pointer along +void BinaryFile::read(io::IReadFile* file, core::vector2df &outVector2d, bool bigEndian) +{ + BinaryFile::read(file, outVector2d.X, bigEndian); + BinaryFile::read(file, outVector2d.Y, bigEndian); +} + +//! reads a null terminated string from the file, moving the file pointer along +void BinaryFile::read(io::IReadFile* file, core::stringc &outString, bool bigEndian) +{ + c8 c; + file->read((void*)&c, 1); + + while (c) + { + outString += c; + file->read((void*)&c, 1); + } +} + +} // namespace io + +} // namespace irr + +#endif // compile with SMF loader + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.h new file mode 100644 index 0000000..2e87aca --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSMFMeshFileLoader.h @@ -0,0 +1,67 @@ +// Copyright (C) 2010-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SMF_MESH_LOADER_H_INCLUDED__ +#define __C_SMF_MESH_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "SMesh.h" + +namespace irr +{ + +namespace video +{ + class IVideoDriver; +} + +namespace scene +{ + +//! Class which can load +class CSMFMeshFileLoader : public virtual IMeshLoader +{ +public: + + CSMFMeshFileLoader(video::IVideoDriver* driver); + + //! Returns true if the file might be loaded by this class. + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! Creates/loads an animated mesh from the file. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); +private: + + void loadLimb(io::IReadFile* file, scene::SMesh* mesh, const core::matrix4 &parentTransformation); + + video::IVideoDriver* Driver; +}; + +} // end namespace scene + +namespace io +{ + class BinaryFile + { + public: + //! reads most types from the given file, moving the file pointer along + template + static void read(io::IReadFile* file, T &out, bool bigEndian=false); + + //! reads a 3d vector from the file, moving the file pointer along + static void read(io::IReadFile* file, core::vector3df &outVector2d, bool bigEndian=false); + + //! reads a 2d vector from the file, moving the file pointer along + static void read(io::IReadFile* file, core::vector2df &outVector2d, bool bigEndian=false); + + //! reads a null terminated string from the file, moving the file pointer along + static void read(io::IReadFile* file, core::stringc &outString, bool bigEndian=false); + + }; +} + +} // end namespace irr + +#endif // __C_SMF_MESH_LOADER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp new file mode 100644 index 0000000..bf9ffb3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.cpp @@ -0,0 +1,253 @@ +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_STL_LOADER_ + +#include "CSTLMeshFileLoader.h" +#include "SMesh.h" +#include "SMeshBuffer.h" +#include "SAnimatedMesh.h" +#include "IReadFile.h" +#include "fast_atof.h" +#include "coreutil.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CSTLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "stl" ); +} + + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CSTLMeshFileLoader::createMesh(io::IReadFile* file) +{ + const long filesize = file->getSize(); + if (filesize < 6) // we need a header + return 0; + + SMesh* mesh = new SMesh(); + SMeshBuffer* meshBuffer = new SMeshBuffer(); + mesh->addMeshBuffer(meshBuffer); + meshBuffer->drop(); + + core::vector3df vertex[3]; + core::vector3df normal; + + bool binary = false; + core::stringc token; + if (getNextToken(file, token) != "solid") + binary = true; + // read/skip header + u32 binFaceCount = 0; + if (binary) + { + file->seek(80); + file->read(&binFaceCount, 4); +#ifdef __BIG_ENDIAN__ + binFaceCount = os::Byteswap::byteswap(binFaceCount); +#endif + } + else + goNextLine(file); + + u16 attrib=0; + token.reserve(32); + + while (file->getPos() < filesize) + { + if (!binary) + { + if (getNextToken(file, token) != "facet") + { + if (token=="endsolid") + break; + mesh->drop(); + return 0; + } + if (getNextToken(file, token) != "normal") + { + mesh->drop(); + return 0; + } + } + getNextVector(file, normal, binary); + if (!binary) + { + if (getNextToken(file, token) != "outer") + { + mesh->drop(); + return 0; + } + if (getNextToken(file, token) != "loop") + { + mesh->drop(); + return 0; + } + } + for (u32 i=0; i<3; ++i) + { + if (!binary) + { + if (getNextToken(file, token) != "vertex") + { + mesh->drop(); + return 0; + } + } + getNextVector(file, vertex[i], binary); + } + if (!binary) + { + if (getNextToken(file, token) != "endloop") + { + mesh->drop(); + return 0; + } + if (getNextToken(file, token) != "endfacet") + { + mesh->drop(); + return 0; + } + } + else + { + file->read(&attrib, 2); +#ifdef __BIG_ENDIAN__ + attrib = os::Byteswap::byteswap(attrib); +#endif + } + + SMeshBuffer* mb = reinterpret_cast(mesh->getMeshBuffer(mesh->getMeshBufferCount()-1)); + u32 vCount = mb->getVertexCount(); + video::SColor color(0xffffffff); + if (attrib & 0x8000) + color = video::A1R5G5B5toA8R8G8B8(attrib); + if (normal==core::vector3df()) + normal=core::plane3df(vertex[2],vertex[1],vertex[0]).Normal; + mb->Vertices.push_back(video::S3DVertex(vertex[2],normal,color, core::vector2df())); + mb->Vertices.push_back(video::S3DVertex(vertex[1],normal,color, core::vector2df())); + mb->Vertices.push_back(video::S3DVertex(vertex[0],normal,color, core::vector2df())); + mb->Indices.push_back(vCount); + mb->Indices.push_back(vCount+1); + mb->Indices.push_back(vCount+2); + } // end while (file->getPos() < filesize) + mesh->getMeshBuffer(0)->recalculateBoundingBox(); + + // Create the Animated mesh if there's anything in the mesh + SAnimatedMesh* pAM = 0; + if ( 0 != mesh->getMeshBufferCount() ) + { + mesh->recalculateBoundingBox(); + pAM = new SAnimatedMesh(); + pAM->Type = EAMT_OBJ; + pAM->addMesh(mesh); + pAM->recalculateBoundingBox(); + } + + mesh->drop(); + + return pAM; +} + + +//! Read 3d vector of floats +void CSTLMeshFileLoader::getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const +{ + if (binary) + { + file->read(&vec.X, 4); + file->read(&vec.Y, 4); + file->read(&vec.Z, 4); +#ifdef __BIG_ENDIAN__ + vec.X = os::Byteswap::byteswap(vec.X); + vec.Y = os::Byteswap::byteswap(vec.Y); + vec.Z = os::Byteswap::byteswap(vec.Z); +#endif + } + else + { + goNextWord(file); + core::stringc tmp; + + getNextToken(file, tmp); + core::fast_atof_move(tmp.c_str(), vec.X); + getNextToken(file, tmp); + core::fast_atof_move(tmp.c_str(), vec.Y); + getNextToken(file, tmp); + core::fast_atof_move(tmp.c_str(), vec.Z); + } + vec.X=-vec.X; +} + + +//! Read next word +const core::stringc& CSTLMeshFileLoader::getNextToken(io::IReadFile* file, core::stringc& token) const +{ + goNextWord(file); + u8 c; + token = ""; + while(file->getPos() != file->getSize()) + { + file->read(&c, 1); + // found it, so leave + if (core::isspace(c)) + break; + token.append(c); + } + return token; +} + + +//! skip to next word +void CSTLMeshFileLoader::goNextWord(io::IReadFile* file) const +{ + u8 c; + while(file->getPos() != file->getSize()) + { + file->read(&c, 1); + // found it, so leave + if (!core::isspace(c)) + { + file->seek(-1, true); + break; + } + } +} + + +//! Read until line break is reached and stop at the next non-space character +void CSTLMeshFileLoader::goNextLine(io::IReadFile* file) const +{ + u8 c; + // look for newline characters + while(file->getPos() != file->getSize()) + { + file->read(&c, 1); + // found it, so leave + if (c=='\n' || c=='\r') + break; + } +} + + +} // end namespace scene +} // end namespace irr + + +#endif // _IRR_COMPILE_WITH_STL_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.h new file mode 100644 index 0000000..fb5dc90 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshFileLoader.h @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_STL_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_STL_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "irrString.h" +#include "vector3d.h" + +namespace irr +{ +namespace scene +{ + +//! Meshloader capable of loading STL meshes. +class CSTLMeshFileLoader : public IMeshLoader +{ +public: + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (i.e. ".stl") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + +private: + + // skips to the first non-space character available + void goNextWord(io::IReadFile* file) const; + // returns the next word + const core::stringc& getNextToken(io::IReadFile* file, core::stringc& token) const; + // skip to next printable character after the first line break + void goNextLine(io::IReadFile* file) const; + + //! Read 3d vector of floats + void getNextVector(io::IReadFile* file, core::vector3df& vec, bool binary) const; +}; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.cpp new file mode 100644 index 0000000..998a73f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.cpp @@ -0,0 +1,187 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_STL_WRITER_ + +#include "CSTLMeshWriter.h" +#include "os.h" +#include "IMesh.h" +#include "IMeshBuffer.h" +#include "IAttributes.h" +#include "ISceneManager.h" +#include "IMeshCache.h" +#include "IWriteFile.h" + +namespace irr +{ +namespace scene +{ + +CSTLMeshWriter::CSTLMeshWriter(scene::ISceneManager* smgr) + : SceneManager(smgr) +{ + #ifdef _DEBUG + setDebugName("CSTLMeshWriter"); + #endif + + if (SceneManager) + SceneManager->grab(); +} + + +CSTLMeshWriter::~CSTLMeshWriter() +{ + if (SceneManager) + SceneManager->drop(); +} + + +//! Returns the type of the mesh writer +EMESH_WRITER_TYPE CSTLMeshWriter::getType() const +{ + return EMWT_STL; +} + + +//! writes a mesh +bool CSTLMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + if (!file) + return false; + + os::Printer::log("Writing mesh", file->getFileName()); + + if (flags & scene::EMWF_WRITE_COMPRESSED) + return writeMeshBinary(file, mesh, flags); + else + return writeMeshASCII(file, mesh, flags); +} + + +bool CSTLMeshWriter::writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + // write STL MESH header + + file->write("binary ",7); + const core::stringc name(SceneManager->getMeshCache()->getMeshName(mesh)); + const s32 sizeleft = 73-name.size(); // 80 byte header + if (sizeleft<0) + file->write(name.c_str(),73); + else + { + char* buf = new char[80]; + memset(buf, 0, 80); + file->write(name.c_str(),name.size()); + file->write(buf,sizeleft); + delete [] buf; + } + u32 facenum = 0; + for (u32 j=0; jgetMeshBufferCount(); ++j) + facenum += mesh->getMeshBuffer(j)->getIndexCount()/3; + file->write(&facenum,4); + + // write mesh buffers + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer) + { + const u32 indexCount = buffer->getIndexCount(); + const u16 attributes = 0; + for (u32 j=0; jgetPosition(buffer->getIndices()[j]); + const core::vector3df& v2 = buffer->getPosition(buffer->getIndices()[j+1]); + const core::vector3df& v3 = buffer->getPosition(buffer->getIndices()[j+2]); + const core::plane3df tmpplane(v1,v2,v3); + file->write(&tmpplane.Normal, 12); + file->write(&v1, 12); + file->write(&v2, 12); + file->write(&v3, 12); + file->write(&attributes, 2); + } + } + } + return true; +} + + +bool CSTLMeshWriter::writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags) +{ + // write STL MESH header + + file->write("solid ",6); + const core::stringc name(SceneManager->getMeshCache()->getMeshName(mesh)); + file->write(name.c_str(),name.size()); + file->write("\n\n",2); + + // write mesh buffers + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + IMeshBuffer* buffer = mesh->getMeshBuffer(i); + if (buffer) + { + const u32 indexCount = buffer->getIndexCount(); + for (u32 j=0; jgetPosition(buffer->getIndices()[j]), + buffer->getPosition(buffer->getIndices()[j+1]), + buffer->getPosition(buffer->getIndices()[j+2])); + } + file->write("\n",1); + } + } + + file->write("endsolid ",9); + file->write(name.c_str(),name.size()); + + return true; +} + + +void CSTLMeshWriter::getVectorAsStringLine(const core::vector3df& v, core::stringc& s) const +{ + s = core::stringc(v.X); + s += " "; + s += core::stringc(v.Y); + s += " "; + s += core::stringc(v.Z); + s += "\n"; +} + + +void CSTLMeshWriter::writeFace(io::IWriteFile* file, + const core::vector3df& v1, + const core::vector3df& v2, + const core::vector3df& v3) +{ + core::stringc tmp; + file->write("facet normal ",13); + getVectorAsStringLine(core::plane3df(v1,v2,v3).Normal, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" outer loop\n",13); + file->write(" vertex ",11); + getVectorAsStringLine(v1, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" vertex ",11); + getVectorAsStringLine(v2, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" vertex ",11); + getVectorAsStringLine(v3, tmp); + file->write(tmp.c_str(),tmp.size()); + file->write(" endloop\n",10); + file->write("endfacet\n",9); +} + + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.h new file mode 100644 index 0000000..0b0b76d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSTLMeshWriter.h @@ -0,0 +1,55 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_STL_MESH_WRITER_H_INCLUDED__ +#define __IRR_STL_MESH_WRITER_H_INCLUDED__ + +#include "IMeshWriter.h" +#include "S3DVertex.h" +#include "irrString.h" + +namespace irr +{ +namespace scene +{ + class IMeshBuffer; + class ISceneManager; + + //! class to write meshes, implementing a STL writer + class CSTLMeshWriter : public IMeshWriter + { + public: + + CSTLMeshWriter(scene::ISceneManager* smgr); + virtual ~CSTLMeshWriter(); + + //! Returns the type of the mesh writer + virtual EMESH_WRITER_TYPE getType() const; + + //! writes a mesh + virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE); + + protected: + // write binary format + bool writeMeshBinary(io::IWriteFile* file, scene::IMesh* mesh, s32 flags); + + // write text format + bool writeMeshASCII(io::IWriteFile* file, scene::IMesh* mesh, s32 flags); + + // create vector output with line end into string + void getVectorAsStringLine(const core::vector3df& v, + core::stringc& s) const; + + // write face information to file + void writeFace(io::IWriteFile* file, const core::vector3df& v1, + const core::vector3df& v2, const core::vector3df& v3); + + scene::ISceneManager* SceneManager; + }; + +} // end namespace +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.cpp new file mode 100644 index 0000000..cda4133 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.cpp @@ -0,0 +1,960 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneCollisionManager.h" +#include "ISceneNode.h" +#include "ICameraSceneNode.h" +#include "ITriangleSelector.h" +#include "SViewFrustum.h" + +#include "os.h" +#include "irrMath.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneCollisionManager::CSceneCollisionManager(ISceneManager* smanager, video::IVideoDriver* driver) +: SceneManager(smanager), Driver(driver) +{ + #ifdef _DEBUG + setDebugName("CSceneCollisionManager"); + #endif + + if (Driver) + Driver->grab(); +} + + +//! destructor +CSceneCollisionManager::~CSceneCollisionManager() +{ + if (Driver) + Driver->drop(); +} + + +//! Returns the scene node, which is currently visible at the given +//! screen coordinates, viewed from the currently active camera. +ISceneNode* CSceneCollisionManager::getSceneNodeFromScreenCoordinatesBB( + const core::position2d& pos, s32 idBitMask, bool noDebugObjects, scene::ISceneNode* root) +{ + const core::line3d ln = getRayFromScreenCoordinates(pos, 0); + + if ( ln.start == ln.end ) + return 0; + + return getSceneNodeFromRayBB(ln, idBitMask, noDebugObjects, root); +} + + +//! Returns the nearest scene node which collides with a 3d ray and +//! which id matches a bitmask. +ISceneNode* CSceneCollisionManager::getSceneNodeFromRayBB( + const core::line3d& ray, + s32 idBitMask, bool noDebugObjects, scene::ISceneNode* root) +{ + ISceneNode* best = 0; + f32 dist = FLT_MAX; + + core::line3d truncatableRay(ray); + + getPickedNodeBB((root==0)?SceneManager->getRootSceneNode():root, truncatableRay, + idBitMask, noDebugObjects, dist, best); + + return best; +} + + +//! recursive method for going through all scene nodes +void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, + core::line3df& ray, s32 bits, bool noDebugObjects, + f32& outbestdistance, ISceneNode*& outbestnode) +{ + const ISceneNodeList& children = root->getChildren(); + const core::vector3df rayVector = ray.getVector().normalize(); + + ISceneNodeList::ConstIterator it = children.begin(); + for (; it != children.end(); ++it) + { + ISceneNode* current = *it; + + if (current->isVisible()) + { + if((noDebugObjects ? !current->isDebugObject() : true) && + (bits==0 || (bits != 0 && (current->getID() & bits)))) + { + // get world to object space transform + core::matrix4 worldToObject; + if (!current->getAbsoluteTransformation().getInverse(worldToObject)) + continue; + + // transform vector from world space to object space + core::line3df objectRay(ray); + worldToObject.transformVect(objectRay.start); + worldToObject.transformVect(objectRay.end); + + const core::aabbox3df & objectBox = current->getBoundingBox(); + + // Do the initial intersection test in object space, since the + // object space box test is more accurate. + if(objectBox.isPointInside(objectRay.start)) + { + // use fast bbox intersection to find distance to hitpoint + // algorithm from Kay et al., code from gamedev.net + const core::vector3df dir = (objectRay.end-objectRay.start).normalize(); + const core::vector3df minDist = (objectBox.MinEdge - objectRay.start)/dir; + const core::vector3df maxDist = (objectBox.MaxEdge - objectRay.start)/dir; + const core::vector3df realMin(core::min_(minDist.X, maxDist.X),core::min_(minDist.Y, maxDist.Y),core::min_(minDist.Z, maxDist.Z)); + const core::vector3df realMax(core::max_(minDist.X, maxDist.X),core::max_(minDist.Y, maxDist.Y),core::max_(minDist.Z, maxDist.Z)); + + const f32 minmax = core::min_(realMax.X, realMax.Y, realMax.Z); + // nearest distance to intersection + const f32 maxmin = core::max_(realMin.X, realMin.Y, realMin.Z); + + const f32 toIntersectionSq = (maxmin>0?maxmin*maxmin:minmax*minmax); + if (toIntersectionSq < outbestdistance) + { + outbestdistance = toIntersectionSq; + outbestnode = current; + + // And we can truncate the ray to stop us hitting further nodes. + ray.end = ray.start + (rayVector * sqrtf(toIntersectionSq)); + } + } + else + if (objectBox.intersectsWithLine(objectRay)) + { + // Now transform into world space, since we need to use world space + // scales and distances. + core::aabbox3df worldBox(objectBox); + current->getAbsoluteTransformation().transformBox(worldBox); + + core::vector3df edges[8]; + worldBox.getEdges(edges); + + /* We need to check against each of 6 faces, composed of these corners: + /3--------/7 + / | / | + / | / | + 1---------5 | + | 2- - -| -6 + | / | / + |/ | / + 0---------4/ + + Note that we define them as opposite pairs of faces. + */ + static const s32 faceEdges[6][3] = + { + { 0, 1, 5 }, // Front + { 6, 7, 3 }, // Back + { 2, 3, 1 }, // Left + { 4, 5, 7 }, // Right + { 1, 3, 7 }, // Top + { 2, 0, 4 } // Bottom + }; + + core::vector3df intersection; + core::plane3df facePlane; + f32 bestDistToBoxBorder = FLT_MAX; + f32 bestToIntersectionSq = FLT_MAX; + + for(s32 face = 0; face < 6; ++face) + { + facePlane.setPlane(edges[faceEdges[face][0]], + edges[faceEdges[face][1]], + edges[faceEdges[face][2]]); + + // Only consider lines that might be entering through this face, since we + // already know that the start point is outside the box. + if(facePlane.classifyPointRelation(ray.start) != core::ISREL3D_FRONT) + continue; + + // Don't bother using a limited ray, since we already know that it should be long + // enough to intersect with the box. + if(facePlane.getIntersectionWithLine(ray.start, rayVector, intersection)) + { + const f32 toIntersectionSq = ray.start.getDistanceFromSQ(intersection); + if(toIntersectionSq < outbestdistance) + { + // We have to check that the intersection with this plane is actually + // on the box, so need to go back to object space again. + worldToObject.transformVect(intersection); + + // find the closest point on the box borders. Have to do this as exact checks will fail due to floating point problems. + f32 distToBorder = core::max_ ( core::min_ (core::abs_(objectBox.MinEdge.X-intersection.X), core::abs_(objectBox.MaxEdge.X-intersection.X)), + core::min_ (core::abs_(objectBox.MinEdge.Y-intersection.Y), core::abs_(objectBox.MaxEdge.Y-intersection.Y)), + core::min_ (core::abs_(objectBox.MinEdge.Z-intersection.Z), core::abs_(objectBox.MaxEdge.Z-intersection.Z)) ); + if ( distToBorder < bestDistToBoxBorder ) + { + bestDistToBoxBorder = distToBorder; + bestToIntersectionSq = toIntersectionSq; + } + } + } + + // If the ray could be entering through the first face of a pair, then it can't + // also be entering through the opposite face, and so we can skip that face. + if (!(face & 0x01)) + ++face; + } + + if ( bestDistToBoxBorder < FLT_MAX ) + { + outbestdistance = bestToIntersectionSq; + outbestnode = current; + + // If we got a hit, we can now truncate the ray to stop us hitting further nodes. + ray.end = ray.start + (rayVector * sqrtf(outbestdistance)); + } + } + } + + // Only check the children if this node is visible. + getPickedNodeBB(current, ray, bits, noDebugObjects, outbestdistance, outbestnode); + } + } +} + + +ISceneNode* CSceneCollisionManager::getSceneNodeAndCollisionPointFromRay( + core::line3df ray, + core::vector3df & outCollisionPoint, + core::triangle3df & outTriangle, + s32 idBitMask, + ISceneNode * collisionRootNode, + bool noDebugObjects) +{ + ISceneNode* bestNode = 0; + f32 bestDistanceSquared = FLT_MAX; + + if(0 == collisionRootNode) + collisionRootNode = SceneManager->getRootSceneNode(); + + // We don't try to do anything too clever, like sorting the candidate + // nodes by distance to bounding-box. In the example below, we could do the + // triangle collision check with node A first, but we'd have to check node B + // anyway, as the actual collision point could be (and is) closer than the + // collision point in node A. + // + // ray end + // | + // AAAAAAAAAA + // A | + // A | B + // A | B + // A BBBBB + // A | + // A | + // | + // | + // ray start + // + // We therefore have to do a full BB and triangle collision on every scene + // node in order to find the nearest collision point, so sorting them by + // bounding box would be pointless. + + getPickedNodeFromBBAndSelector(collisionRootNode, ray, idBitMask, + noDebugObjects, bestDistanceSquared, bestNode, + outCollisionPoint, outTriangle); + return bestNode; +} + + +void CSceneCollisionManager::getPickedNodeFromBBAndSelector( + ISceneNode * root, + core::line3df & ray, + s32 bits, + bool noDebugObjects, + f32 & outBestDistanceSquared, + ISceneNode * & outBestNode, + core::vector3df & outBestCollisionPoint, + core::triangle3df & outBestTriangle) +{ + const ISceneNodeList& children = root->getChildren(); + + ISceneNodeList::ConstIterator it = children.begin(); + for (; it != children.end(); ++it) + { + ISceneNode* current = *it; + ITriangleSelector * selector = current->getTriangleSelector(); + + if (selector && current->isVisible() && + (noDebugObjects ? !current->isDebugObject() : true) && + (bits==0 || (bits != 0 && (current->getID() & bits)))) + { + // get world to object space transform + core::matrix4 mat; + if (!current->getAbsoluteTransformation().getInverse(mat)) + continue; + + // transform vector from world space to object space + core::line3df line(ray); + mat.transformVect(line.start); + mat.transformVect(line.end); + + const core::aabbox3df& box = current->getBoundingBox(); + + core::vector3df candidateCollisionPoint; + core::triangle3df candidateTriangle; + + // do intersection test in object space + ISceneNode * hitNode = 0; + if (box.intersectsWithLine(line) && + getCollisionPoint(ray, selector, candidateCollisionPoint, candidateTriangle, hitNode)) + { + const f32 distanceSquared = (candidateCollisionPoint - ray.start).getLengthSQ(); + + if(distanceSquared < outBestDistanceSquared) + { + outBestDistanceSquared = distanceSquared; + outBestNode = current; + outBestCollisionPoint = candidateCollisionPoint; + outBestTriangle = candidateTriangle; + const core::vector3df rayVector = ray.getVector().normalize(); + ray.end = ray.start + (rayVector * sqrtf(distanceSquared)); + } + } + } + + getPickedNodeFromBBAndSelector(current, ray, bits, noDebugObjects, + outBestDistanceSquared, outBestNode, + outBestCollisionPoint, outBestTriangle); + } +} + + +//! Returns the scene node, at which the overgiven camera is looking at and +//! which id matches the bitmask. +ISceneNode* CSceneCollisionManager::getSceneNodeFromCameraBB( + ICameraSceneNode* camera, s32 idBitMask, bool noDebugObjects) +{ + if (!camera) + return 0; + + const core::vector3df start = camera->getAbsolutePosition(); + core::vector3df end = camera->getTarget(); + + end = start + ((end - start).normalize() * camera->getFarValue()); + + return getSceneNodeFromRayBB(core::line3d(start, end), idBitMask, noDebugObjects); +} + + +//! Finds the collision point of a line and lots of triangles, if there is one. +bool CSceneCollisionManager::getCollisionPoint(const core::line3d& ray, + ITriangleSelector* selector, core::vector3df& outIntersection, + core::triangle3df& outTriangle, + ISceneNode*& outNode) +{ + if (!selector) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + s32 totalcnt = selector->getTriangleCount(); + if ( totalcnt <= 0 ) + return false; + + Triangles.set_used(totalcnt); + + s32 cnt = 0; + selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray); + + const core::vector3df linevect = ray.getVector().normalize(); + core::vector3df intersection; + f32 nearest = FLT_MAX; + bool found = false; + const f32 raylength = ray.getLengthSQ(); + + const f32 minX = core::min_(ray.start.X, ray.end.X); + const f32 maxX = core::max_(ray.start.X, ray.end.X); + const f32 minY = core::min_(ray.start.Y, ray.end.Y); + const f32 maxY = core::max_(ray.start.Y, ray.end.Y); + const f32 minZ = core::min_(ray.start.Z, ray.end.Z); + const f32 maxZ = core::max_(ray.start.Z, ray.end.Z); + + for (s32 i=0; i triangle.pointA.X && minX > triangle.pointB.X && minX > triangle.pointC.X) + continue; + if(maxX < triangle.pointA.X && maxX < triangle.pointB.X && maxX < triangle.pointC.X) + continue; + if(minY > triangle.pointA.Y && minY > triangle.pointB.Y && minY > triangle.pointC.Y) + continue; + if(maxY < triangle.pointA.Y && maxY < triangle.pointB.Y && maxY < triangle.pointC.Y) + continue; + if(minZ > triangle.pointA.Z && minZ > triangle.pointB.Z && minZ > triangle.pointC.Z) + continue; + if(maxZ < triangle.pointA.Z && maxZ < triangle.pointB.Z && maxZ < triangle.pointC.Z) + continue; + + if (triangle.getIntersectionWithLine(ray.start, linevect, intersection)) + { + const f32 tmp = intersection.getDistanceFromSQ(ray.start); + const f32 tmp2 = intersection.getDistanceFromSQ(ray.end); + + if (tmp < raylength && tmp2 < raylength && tmp < nearest) + { + nearest = tmp; + outTriangle = triangle; + outIntersection = intersection; + outNode = selector->getSceneNodeForTriangle(i); + found = true; + } + } + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return found; +} + + +//! Collides a moving ellipsoid with a 3d world with gravity and returns +//! the resulting new position of the ellipsoid. +core::vector3df CSceneCollisionManager::getCollisionResultPosition( + ITriangleSelector* selector, + const core::vector3df &position, const core::vector3df& radius, + const core::vector3df& direction, + core::triangle3df& triout, + core::vector3df& hitPosition, + bool& outFalling, + ISceneNode*& outNode, + f32 slidingSpeed, + const core::vector3df& gravity) +{ + return collideEllipsoidWithWorld(selector, position, + radius, direction, slidingSpeed, gravity, triout, hitPosition, outFalling, outNode); +} + + +bool CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData, + const core::triangle3df& triangle) +{ + const core::plane3d trianglePlane = triangle.getPlane(); + + // only check front facing polygons + if ( !trianglePlane.isFrontFacing(colData->normalizedVelocity) ) + return false; + + // get interval of plane intersection + + f32 t1, t0; + bool embeddedInPlane = false; + + // calculate signed distance from sphere position to triangle plane + f32 signedDistToTrianglePlane = trianglePlane.getDistanceTo( + colData->basePoint); + + f32 normalDotVelocity = + trianglePlane.Normal.dotProduct(colData->velocity); + + if ( core::iszero ( normalDotVelocity ) ) + { + // sphere is traveling parallel to plane + + if (fabs(signedDistToTrianglePlane) >= 1.0f) + return false; // no collision possible + else + { + // sphere is embedded in plane + embeddedInPlane = true; + t0 = 0.0; + t1 = 1.0; + } + } + else + { + normalDotVelocity = core::reciprocal ( normalDotVelocity ); + + // N.D is not 0. Calculate intersection interval + t0 = (-1.f - signedDistToTrianglePlane) * normalDotVelocity; + t1 = (1.f - signedDistToTrianglePlane) * normalDotVelocity; + + // Swap so t0 < t1 + if (t0 > t1) { f32 tmp = t1; t1 = t0; t0 = tmp; } + + // check if at least one value is within the range + if (t0 > 1.0f || t1 < 0.0f) + return false; // both t values are outside 1 and 0, no collision possible + + // clamp to 0 and 1 + t0 = core::clamp ( t0, 0.f, 1.f ); + t1 = core::clamp ( t1, 0.f, 1.f ); + } + + // at this point we have t0 and t1, if there is any intersection, it + // is between this interval + core::vector3df collisionPoint; + bool foundCollision = false; + f32 t = 1.0f; + + // first check the easy case: Collision within the triangle; + // if this happens, it must be at t0 and this is when the sphere + // rests on the front side of the triangle plane. This can only happen + // if the sphere is not embedded in the triangle plane. + + if (!embeddedInPlane) + { + core::vector3df planeIntersectionPoint = + (colData->basePoint - trianglePlane.Normal) + + (colData->velocity * t0); + + if (triangle.isPointInside(planeIntersectionPoint)) + { + foundCollision = true; + t = t0; + collisionPoint = planeIntersectionPoint; + } + } + + // if we havent found a collision already we will have to sweep + // the sphere against points and edges of the triangle. Note: A + // collision inside the triangle will always happen before a + // vertex or edge collision. + + if (!foundCollision) + { + core::vector3df velocity = colData->velocity; + core::vector3df base = colData->basePoint; + + f32 velocitySqaredLength = velocity.getLengthSQ(); + f32 a,b,c; + f32 newT; + + // for each edge or vertex a quadratic equation has to be solved: + // a*t^2 + b*t + c = 0. We calculate a,b, and c for each test. + + // check against points + a = velocitySqaredLength; + + // p1 + b = 2.0f * (velocity.dotProduct(base - triangle.pointA)); + c = (triangle.pointA-base).getLengthSQ() - 1.f; + if (getLowestRoot(a,b,c,t, &newT)) + { + t = newT; + foundCollision = true; + collisionPoint = triangle.pointA; + } + + // p2 + if (!foundCollision) + { + b = 2.0f * (velocity.dotProduct(base - triangle.pointB)); + c = (triangle.pointB-base).getLengthSQ() - 1.f; + if (getLowestRoot(a,b,c,t, &newT)) + { + t = newT; + foundCollision = true; + collisionPoint = triangle.pointB; + } + } + + // p3 + if (!foundCollision) + { + b = 2.0f * (velocity.dotProduct(base - triangle.pointC)); + c = (triangle.pointC-base).getLengthSQ() - 1.f; + if (getLowestRoot(a,b,c,t, &newT)) + { + t = newT; + foundCollision = true; + collisionPoint = triangle.pointC; + } + } + + // check against edges: + + // p1 --- p2 + core::vector3df edge = triangle.pointB - triangle.pointA; + core::vector3df baseToVertex = triangle.pointA - base; + f32 edgeSqaredLength = edge.getLengthSQ(); + f32 edgeDotVelocity = edge.dotProduct(velocity); + f32 edgeDotBaseToVertex = edge.dotProduct(baseToVertex); + + // calculate parameters for equation + a = edgeSqaredLength* -velocitySqaredLength + + edgeDotVelocity*edgeDotVelocity; + b = edgeSqaredLength* (2.f *velocity.dotProduct(baseToVertex)) - + 2.0f*edgeDotVelocity*edgeDotBaseToVertex; + c = edgeSqaredLength* (1.f -baseToVertex.getLengthSQ()) + + edgeDotBaseToVertex*edgeDotBaseToVertex; + + // does the swept sphere collide against infinite edge? + if (getLowestRoot(a,b,c,t,&newT)) + { + f32 f = (edgeDotVelocity*newT - edgeDotBaseToVertex) / edgeSqaredLength; + if (f >=0.0f && f <= 1.0f) + { + // intersection took place within segment + t = newT; + foundCollision = true; + collisionPoint = triangle.pointA + (edge*f); + } + } + + // p2 --- p3 + edge = triangle.pointC-triangle.pointB; + baseToVertex = triangle.pointB - base; + edgeSqaredLength = edge.getLengthSQ(); + edgeDotVelocity = edge.dotProduct(velocity); + edgeDotBaseToVertex = edge.dotProduct(baseToVertex); + + // calculate parameters for equation + a = edgeSqaredLength* -velocitySqaredLength + + edgeDotVelocity*edgeDotVelocity; + b = edgeSqaredLength* (2*velocity.dotProduct(baseToVertex)) - + 2.0f*edgeDotVelocity*edgeDotBaseToVertex; + c = edgeSqaredLength* (1-baseToVertex.getLengthSQ()) + + edgeDotBaseToVertex*edgeDotBaseToVertex; + + // does the swept sphere collide against infinite edge? + if (getLowestRoot(a,b,c,t,&newT)) + { + f32 f = (edgeDotVelocity*newT-edgeDotBaseToVertex) / + edgeSqaredLength; + if (f >=0.0f && f <= 1.0f) + { + // intersection took place within segment + t = newT; + foundCollision = true; + collisionPoint = triangle.pointB + (edge*f); + } + } + + + // p3 --- p1 + edge = triangle.pointA-triangle.pointC; + baseToVertex = triangle.pointC - base; + edgeSqaredLength = edge.getLengthSQ(); + edgeDotVelocity = edge.dotProduct(velocity); + edgeDotBaseToVertex = edge.dotProduct(baseToVertex); + + // calculate parameters for equation + a = edgeSqaredLength* -velocitySqaredLength + + edgeDotVelocity*edgeDotVelocity; + b = edgeSqaredLength* (2*velocity.dotProduct(baseToVertex)) - + 2.0f*edgeDotVelocity*edgeDotBaseToVertex; + c = edgeSqaredLength* (1-baseToVertex.getLengthSQ()) + + edgeDotBaseToVertex*edgeDotBaseToVertex; + + // does the swept sphere collide against infinite edge? + if (getLowestRoot(a,b,c,t,&newT)) + { + f32 f = (edgeDotVelocity*newT-edgeDotBaseToVertex) / + edgeSqaredLength; + if (f >=0.0f && f <= 1.0f) + { + // intersection took place within segment + t = newT; + foundCollision = true; + collisionPoint = triangle.pointC + (edge*f); + } + } + }// end no collision found + + // set result: + if (foundCollision) + { + // distance to collision is t + f32 distToCollision = t*colData->velocity.getLength(); + + // does this triangle qualify for closest hit? + if (!colData->foundCollision || + distToCollision < colData->nearestDistance) + { + colData->nearestDistance = distToCollision; + colData->intersectionPoint = collisionPoint; + colData->foundCollision = true; + colData->intersectionTriangle = triangle; + ++colData->triangleHits; + return true; + } + }// end found collision + + return false; +} + + +//! Collides a moving ellipsoid with a 3d world with gravity and returns +//! the resulting new position of the ellipsoid. +core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld( + ITriangleSelector* selector, const core::vector3df &position, + const core::vector3df& radius, const core::vector3df& velocity, + f32 slidingSpeed, + const core::vector3df& gravity, + core::triangle3df& triout, + core::vector3df& hitPosition, + bool& outFalling, + ISceneNode*& outNode) +{ + if (!selector || radius.X == 0.0f || radius.Y == 0.0f || radius.Z == 0.0f) + return position; + + // This code is based on the paper "Improved Collision detection and Response" + // by Kasper Fauerby, but some parts are modified. + + SCollisionData colData; + colData.R3Position = position; + colData.R3Velocity = velocity; + colData.eRadius = radius; + colData.nearestDistance = FLT_MAX; + colData.selector = selector; + colData.slidingSpeed = slidingSpeed; + colData.triangleHits = 0; + colData.triangleIndex = -1; + + core::vector3df eSpacePosition = colData.R3Position / colData.eRadius; + core::vector3df eSpaceVelocity = colData.R3Velocity / colData.eRadius; + + // iterate until we have our final position + + core::vector3df finalPos = collideWithWorld( + 0, colData, eSpacePosition, eSpaceVelocity); + + outFalling = false; + + // add gravity + + if (gravity != core::vector3df(0,0,0)) + { + colData.R3Position = finalPos * colData.eRadius; + colData.R3Velocity = gravity; + colData.triangleHits = 0; + + eSpaceVelocity = gravity/colData.eRadius; + + finalPos = collideWithWorld(0, colData, + finalPos, eSpaceVelocity); + + outFalling = (colData.triangleHits == 0); + } + + if (colData.triangleHits) + { + triout = colData.intersectionTriangle; + triout.pointA *= colData.eRadius; + triout.pointB *= colData.eRadius; + triout.pointC *= colData.eRadius; + outNode = selector->getSceneNodeForTriangle(colData.triangleIndex); + } + + finalPos *= colData.eRadius; + hitPosition = colData.intersectionPoint * colData.eRadius; + return finalPos; +} + + +core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth, + SCollisionData &colData, core::vector3df pos, core::vector3df vel) +{ + f32 veryCloseDistance = colData.slidingSpeed; + + if (recursionDepth > 5) + return pos; + + colData.velocity = vel; + colData.normalizedVelocity = vel; + colData.normalizedVelocity.normalize(); + colData.basePoint = pos; + colData.foundCollision = false; + colData.nearestDistance = FLT_MAX; + + //------------------ collide with world + + // get all triangles with which we might collide + core::aabbox3d box(colData.R3Position); + box.addInternalPoint(colData.R3Position + colData.R3Velocity); + box.MinEdge -= colData.eRadius; + box.MaxEdge += colData.eRadius; + + s32 totalTriangleCnt = colData.selector->getTriangleCount(); + Triangles.set_used(totalTriangleCnt); + + core::matrix4 scaleMatrix; + scaleMatrix.setScale( + core::vector3df(1.0f / colData.eRadius.X, + 1.0f / colData.eRadius.Y, + 1.0f / colData.eRadius.Z)); + + s32 triangleCnt = 0; + colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, box, &scaleMatrix); + + for (s32 i=0; i= veryCloseDistance) + { + core::vector3df v = vel; + v.setLength( colData.nearestDistance - veryCloseDistance ); + newBasePoint = colData.basePoint + v; + + v.normalize(); + colData.intersectionPoint -= (v * veryCloseDistance); + } + + // calculate sliding plane + + const core::vector3df slidePlaneOrigin = colData.intersectionPoint; + const core::vector3df slidePlaneNormal = (newBasePoint - colData.intersectionPoint).normalize(); + core::plane3d slidingPlane(slidePlaneOrigin, slidePlaneNormal); + + core::vector3df newDestinationPoint = + destinationPoint - + (slidePlaneNormal * slidingPlane.getDistanceTo(destinationPoint)); + + // generate slide vector + + const core::vector3df newVelocityVector = newDestinationPoint - + colData.intersectionPoint; + + if (newVelocityVector.getLength() < veryCloseDistance) + return newBasePoint; + + return collideWithWorld(recursionDepth+1, colData, + newBasePoint, newVelocityVector); +} + + +//! Returns a 3d ray which would go through the 2d screen coodinates. +core::line3d CSceneCollisionManager::getRayFromScreenCoordinates( + const core::position2d & pos, ICameraSceneNode* camera) +{ + core::line3d ln(0,0,0,0,0,0); + + if (!SceneManager) + return ln; + + if (!camera) + camera = SceneManager->getActiveCamera(); + + if (!camera) + return ln; + + const scene::SViewFrustum* f = camera->getViewFrustum(); + + core::vector3df farLeftUp = f->getFarLeftUp(); + core::vector3df lefttoright = f->getFarRightUp() - farLeftUp; + core::vector3df uptodown = f->getFarLeftDown() - farLeftUp; + + const core::rect& viewPort = Driver->getViewPort(); + core::dimension2d screenSize(viewPort.getWidth(), viewPort.getHeight()); + + f32 dx = pos.X / (f32)screenSize.Width; + f32 dy = pos.Y / (f32)screenSize.Height; + + if (camera->isOrthogonal()) + ln.start = f->cameraPosition + (lefttoright * (dx-0.5f)) + (uptodown * (dy-0.5f)); + else + ln.start = f->cameraPosition; + + ln.end = farLeftUp + (lefttoright * dx) + (uptodown * dy); + + return ln; +} + + +//! Calculates 2d screen position from a 3d position. +core::position2d CSceneCollisionManager::getScreenCoordinatesFrom3DPosition( + const core::vector3df & pos3d, ICameraSceneNode* camera, bool useViewPort) +{ + if (!SceneManager || !Driver) + return core::position2d(-1000,-1000); + + if (!camera) + camera = SceneManager->getActiveCamera(); + + if (!camera) + return core::position2d(-1000,-1000); + + core::dimension2d dim; + if (useViewPort) + dim.set(Driver->getViewPort().getWidth(), Driver->getViewPort().getHeight()); + else + dim=(Driver->getCurrentRenderTargetSize()); + + dim.Width /= 2; + dim.Height /= 2; + + core::matrix4 trans = camera->getProjectionMatrix(); + trans *= camera->getViewMatrix(); + + f32 transformedPos[4] = { pos3d.X, pos3d.Y, pos3d.Z, 1.0f }; + + trans.multiplyWith1x4Matrix(transformedPos); + + if (transformedPos[3] < 0) + return core::position2d(-10000,-10000); + + const f32 zDiv = transformedPos[3] == 0.0f ? 1.0f : + core::reciprocal(transformedPos[3]); + + return core::position2d( + dim.Width + core::round32(dim.Width * (transformedPos[0] * zDiv)), + dim.Height - core::round32(dim.Height * (transformedPos[1] * zDiv))); +} + + +inline bool CSceneCollisionManager::getLowestRoot(f32 a, f32 b, f32 c, f32 maxR, f32* root) +{ + // check if solution exists + const f32 determinant = b*b - 4.0f*a*c; + + // if determinant is negative, no solution + if (determinant < 0.0f || a == 0.f ) + return false; + + // calculate two roots: (if det==0 then x1==x2 + // but lets disregard that slight optimization) + + const f32 sqrtD = sqrtf(determinant); + const f32 invDA = core::reciprocal(2*a); + f32 r1 = (-b - sqrtD) * invDA; + f32 r2 = (-b + sqrtD) * invDA; + + // sort so x1 <= x2 + if (r1 > r2) + core::swap(r1,r2); + + // get lowest root + if (r1 > 0 && r1 < maxR) + { + *root = r1; + return true; + } + + // its possible that we want x2, this can happen if x1 < 0 + if (r2 > 0 && r2 < maxR) + { + *root = r2; + return true; + } + + return false; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.h new file mode 100644 index 0000000..c581a47 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneCollisionManager.h @@ -0,0 +1,158 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_COLLISION_MANAGER_H_INCLUDED__ +#define __C_SCENE_COLLISION_MANAGER_H_INCLUDED__ + +#include "ISceneCollisionManager.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" + +namespace irr +{ +namespace scene +{ + + //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes. + class CSceneCollisionManager : public ISceneCollisionManager + { + public: + + //! constructor + CSceneCollisionManager(ISceneManager* smanager, video::IVideoDriver* driver); + + //! destructor + virtual ~CSceneCollisionManager(); + + //! Returns the scene node, which is currently visible at the given + //! screen coordinates, viewed from the currently active camera. + virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(const core::position2d& pos, + s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0); + + //! Returns the nearest scene node which collides with a 3d ray and + //! whose id matches a bitmask. + virtual ISceneNode* getSceneNodeFromRayBB(const core::line3d& ray, + s32 idBitMask=0, bool bNoDebugObjects=false, + ISceneNode* root=0); + + //! Returns the scene node, at which the overgiven camera is looking at and + //! which id matches the bitmask. + virtual ISceneNode* getSceneNodeFromCameraBB(ICameraSceneNode* camera, + s32 idBitMask=0, bool bNoDebugObjects = false); + + //! Finds the collision point of a line and lots of triangles, if there is one. + virtual bool getCollisionPoint(const core::line3d& ray, + ITriangleSelector* selector, core::vector3df& outCollisionPoint, + core::triangle3df& outTriangle, + ISceneNode* & outNode); + + //! Collides a moving ellipsoid with a 3d world with gravity and returns + //! the resulting new position of the ellipsoid. + virtual core::vector3df getCollisionResultPosition( + ITriangleSelector* selector, + const core::vector3df &ellipsoidPosition, + const core::vector3df& ellipsoidRadius, + const core::vector3df& ellipsoidDirectionAndSpeed, + core::triangle3df& triout, + core::vector3df& hitPosition, + bool& outFalling, + ISceneNode*& outNode, + f32 slidingSpeed, + const core::vector3df& gravityDirectionAndSpeed); + + //! Returns a 3d ray which would go through the 2d screen coodinates. + virtual core::line3d getRayFromScreenCoordinates( + const core::position2d & pos, ICameraSceneNode* camera = 0); + + //! Calculates 2d screen position from a 3d position. + virtual core::position2d getScreenCoordinatesFrom3DPosition( + const core::vector3df & pos, ICameraSceneNode* camera=0, bool useViewPort=false); + + //! Gets the scene node and nearest collision point for a ray based on + //! the nodes' id bitmasks, bounding boxes and triangle selectors. + virtual ISceneNode* getSceneNodeAndCollisionPointFromRay( + core::line3df ray, + core::vector3df & outCollisionPoint, + core::triangle3df & outTriangle, + s32 idBitMask = 0, + ISceneNode * collisionRootNode = 0, + bool noDebugObjects = false); + + + private: + + //! recursive method for going through all scene nodes + void getPickedNodeBB(ISceneNode* root, core::line3df& ray, s32 bits, + bool bNoDebugObjects, + f32& outbestdistance, ISceneNode*& outbestnode); + + //! recursive method for going through all scene nodes + void getPickedNodeFromBBAndSelector(ISceneNode * root, + core::line3df & ray, + s32 bits, + bool noDebugObjects, + f32 & outBestDistanceSquared, + ISceneNode * & outBestNode, + core::vector3df & outBestCollisionPoint, + core::triangle3df & outBestTriangle); + + + struct SCollisionData + { + core::vector3df eRadius; + + core::vector3df R3Velocity; + core::vector3df R3Position; + + core::vector3df velocity; + core::vector3df normalizedVelocity; + core::vector3df basePoint; + + bool foundCollision; + f32 nearestDistance; + core::vector3df intersectionPoint; + + core::triangle3df intersectionTriangle; + s32 triangleIndex; + s32 triangleHits; + + f32 slidingSpeed; + + ITriangleSelector* selector; + }; + + //! Tests the current collision data against an individual triangle. + /** + \param colData: the collision data. + \param triangle: the triangle to test against. + \return true if the triangle is hit (and is the closest hit), false otherwise */ + bool testTriangleIntersection(SCollisionData* colData, + const core::triangle3df& triangle); + + //! recursive method for doing collision response + core::vector3df collideEllipsoidWithWorld(ITriangleSelector* selector, + const core::vector3df &position, + const core::vector3df& radius, const core::vector3df& velocity, + f32 slidingSpeed, + const core::vector3df& gravity, core::triangle3df& triout, + core::vector3df& hitPosition, + bool& outFalling, + ISceneNode*& outNode); + + core::vector3df collideWithWorld(s32 recursionDepth, SCollisionData &colData, + core::vector3df pos, core::vector3df vel); + + inline bool getLowestRoot(f32 a, f32 b, f32 c, f32 maxR, f32* root); + + ISceneManager* SceneManager; + video::IVideoDriver* Driver; + core::array Triangles; // triangle buffer + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.cpp new file mode 100644 index 0000000..7705436 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.cpp @@ -0,0 +1,284 @@ +// Copyright (C) 2010-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneLoaderIrr.h" +#include "ISceneNodeAnimatorFactory.h" +#include "ISceneUserDataSerializer.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! Constructor +CSceneLoaderIrr::CSceneLoaderIrr(ISceneManager *smgr, io::IFileSystem* fs) + : SceneManager(smgr), FileSystem(fs), + IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type"), + IRR_XML_FORMAT_ATTRIBUTES(L"attributes"), IRR_XML_FORMAT_MATERIALS(L"materials"), + IRR_XML_FORMAT_ANIMATORS(L"animators"), IRR_XML_FORMAT_USERDATA(L"userData") +{ + +} + +//! Destructor +CSceneLoaderIrr::~CSceneLoaderIrr() +{ + +} + +//! Returns true if the class might be able to load this file. +bool CSceneLoaderIrr::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension(filename, "irr"); +} + +//! Returns true if the class might be able to load this file. +bool CSceneLoaderIrr::isALoadableFileFormat(io::IReadFile *file) const +{ + // todo: check inside the file + return true; +} + +//! Loads the scene into the scene manager. +bool CSceneLoaderIrr::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer, + ISceneNode* rootNode) +{ + if (!file) + { + os::Printer::log("Unable to open scene file", ELL_ERROR); + return false; + } + + io::IXMLReader* reader = FileSystem->createXMLReader(file); + if (!reader) + { + os::Printer::log("Scene is not a valid XML file", file->getFileName().c_str(), ELL_ERROR); + return false; + } + + // TODO: COLLADA_CREATE_SCENE_INSTANCES can be removed when the COLLADA loader is a scene loader + bool oldColladaSingleMesh = SceneManager->getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES); + SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false); + + // read file + while (reader->read()) + { + readSceneNode(reader, rootNode, userDataSerializer); + } + + // restore old collada parameters + SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh); + + // clean up + reader->drop(); + return true; +} + + +//! Reads the next node +void CSceneLoaderIrr::readSceneNode(io::IXMLReader* reader, ISceneNode* parent, + ISceneUserDataSerializer* userDataSerializer) +{ + if (!reader) + return; + + scene::ISceneNode* node = 0; + + if (!parent && IRR_XML_FORMAT_SCENE==reader->getNodeName()) + node = SceneManager->getRootSceneNode(); + else if (parent && IRR_XML_FORMAT_NODE==reader->getNodeName()) + { + // find node type and create it + core::stringc attrName = reader->getAttributeValue(IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str()); + + node = SceneManager->addSceneNode(attrName.c_str(), parent); + + if (!node) + os::Printer::log("Could not create scene node of unknown type", attrName.c_str()); + } + else + node=parent; + + // read attributes + while(reader->read()) + { + bool endreached = false; + + const wchar_t* name = reader->getNodeName(); + + switch (reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if ((IRR_XML_FORMAT_NODE == name) || + (IRR_XML_FORMAT_SCENE == name)) + { + endreached = true; + } + break; + case io::EXN_ELEMENT: + if (IRR_XML_FORMAT_ATTRIBUTES == name) + { + // read attributes + io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); + attr->read(reader, true); + + if (node) + node->deserializeAttributes(attr); + + attr->drop(); + } + else + if (IRR_XML_FORMAT_MATERIALS == name) + readMaterials(reader, node); + else + if (IRR_XML_FORMAT_ANIMATORS == name) + readAnimators(reader, node); + else + if (IRR_XML_FORMAT_USERDATA == name) + readUserData(reader, node, userDataSerializer); + else + if ((IRR_XML_FORMAT_NODE == name) || + (IRR_XML_FORMAT_SCENE == name)) + { + readSceneNode(reader, node, userDataSerializer); + } + else + { + os::Printer::log("Found unknown element in irrlicht scene file", + core::stringc(name).c_str()); + } + break; + default: + break; + } + + if (endreached) + break; + } + if (node && userDataSerializer) + userDataSerializer->OnCreateNode(node); +} + +//! reads materials of a node +void CSceneLoaderIrr::readMaterials(io::IXMLReader* reader, ISceneNode* node) +{ + u32 nr = 0; + + while(reader->read()) + { + const wchar_t* name = reader->getNodeName(); + + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (IRR_XML_FORMAT_MATERIALS == name) + return; + break; + case io::EXN_ELEMENT: + if (IRR_XML_FORMAT_ATTRIBUTES == name) + { + // read materials from attribute list + io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); + attr->read(reader); + + if (node && node->getMaterialCount() > nr) + { + SceneManager->getVideoDriver()->fillMaterialStructureFromAttributes( + node->getMaterial(nr), attr); + } + + attr->drop(); + ++nr; + } + break; + default: + break; + } + } +} + + +//! reads animators of a node +void CSceneLoaderIrr::readAnimators(io::IXMLReader* reader, ISceneNode* node) +{ + while(reader->read()) + { + const wchar_t* name = reader->getNodeName(); + + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (IRR_XML_FORMAT_ANIMATORS == name) + return; + break; + case io::EXN_ELEMENT: + if (IRR_XML_FORMAT_ATTRIBUTES == name) + { + // read animator data from attribute list + io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); + attr->read(reader); + + if (node) + { + core::stringc typeName = attr->getAttributeAsString("Type"); + ISceneNodeAnimator* anim = SceneManager->createSceneNodeAnimator(typeName.c_str(), node); + + if (anim) + { + anim->deserializeAttributes(attr); + anim->drop(); + } + } + + attr->drop(); + } + break; + default: + break; + } + } +} + + +//! reads user data of a node +void CSceneLoaderIrr::readUserData(io::IXMLReader* reader, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer) +{ + while(reader->read()) + { + const wchar_t* name = reader->getNodeName(); + + switch(reader->getNodeType()) + { + case io::EXN_ELEMENT_END: + if (IRR_XML_FORMAT_USERDATA == name) + return; + break; + case io::EXN_ELEMENT: + if (IRR_XML_FORMAT_ATTRIBUTES == name) + { + // read user data from attribute list + io::IAttributes* attr = FileSystem->createEmptyAttributes(SceneManager->getVideoDriver()); + attr->read(reader); + + if (node && userDataSerializer) + { + userDataSerializer->OnReadUserData(node, attr); + } + + attr->drop(); + } + break; + default: + break; + } + } +} + +} // scene +} // irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.h new file mode 100644 index 0000000..f8c9532 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneLoaderIrr.h @@ -0,0 +1,82 @@ +// Copyright (C) 2010-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_LOADER_IRR_H_INCLUDED__ +#define __C_SCENE_LOADER_IRR_H_INCLUDED__ + +#include "ISceneLoader.h" + +#include "IXMLReader.h" + +namespace irr +{ + +namespace io +{ + class IFileSystem; +} + +namespace scene +{ + +class ISceneManager; + +//! Class which can load a scene into the scene manager. +class CSceneLoaderIrr : public virtual ISceneLoader +{ +public: + + //! Constructor + CSceneLoaderIrr(ISceneManager *smgr, io::IFileSystem* fs); + + //! Destructor + virtual ~CSceneLoaderIrr(); + + //! Returns true if the class might be able to load this file. + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! Returns true if the class might be able to load this file. + virtual bool isALoadableFileFormat(io::IReadFile *file) const; + + //! Loads the scene into the scene manager. + virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0, + ISceneNode* rootNode=0); + +private: + + //! Recursively reads nodes from the xml file + void readSceneNode(io::IXMLReader* reader, ISceneNode* parent, + ISceneUserDataSerializer* userDataSerializer); + + //! read a node's materials + void readMaterials(io::IXMLReader* reader, ISceneNode* node); + + //! read a node's animators + void readAnimators(io::IXMLReader* reader, ISceneNode* node); + + //! read any other data into the user serializer + void readUserData(io::IXMLReader* reader, ISceneNode* node, + ISceneUserDataSerializer* userDataSerializer); + + ISceneManager *SceneManager; + io::IFileSystem *FileSystem; + + //! constants for reading and writing XML. + //! Not made static due to portability problems. + // TODO: move to own header + const core::stringw IRR_XML_FORMAT_SCENE; + const core::stringw IRR_XML_FORMAT_NODE; + const core::stringw IRR_XML_FORMAT_NODE_ATTR_TYPE; + const core::stringw IRR_XML_FORMAT_ATTRIBUTES; + const core::stringw IRR_XML_FORMAT_MATERIALS; + const core::stringw IRR_XML_FORMAT_ANIMATORS; + const core::stringw IRR_XML_FORMAT_USERDATA; +}; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.cpp new file mode 100644 index 0000000..dd3652b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.cpp @@ -0,0 +1,2522 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CSceneManager.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "SAnimatedMesh.h" +#include "CMeshCache.h" +#include "IXMLWriter.h" +#include "ISceneUserDataSerializer.h" +#include "IGUIEnvironment.h" +#include "IMaterialRenderer.h" +#include "IReadFile.h" +#include "IWriteFile.h" +#include "ISceneLoader.h" + +#include "os.h" + +// We need this include for the case of skinned mesh support without +// any such loader +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ +#include "CSkinnedMesh.h" +#endif + +#ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ +#include "CIrrMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ +#include "CBSPMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MD2_LOADER_ +#include "CMD2MeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ +#include "CAnimatedMeshHalfLife.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ +#include "CMS3DMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_3DS_LOADER_ +#include "C3DSMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_X_LOADER_ +#include "CXMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OCT_LOADER_ +#include "COCTLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_CSM_LOADER_ +#include "CCSMLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_LMTS_LOADER_ +#include "CLMTSMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MY3D_LOADER_ +#include "CMY3DMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ +#include "CColladaFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_DMF_LOADER_ +#include "CDMFLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ +#include "COgreMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OBJ_LOADER_ +#include "COBJMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_MD3_LOADER_ +#include "CMD3MeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_B3D_LOADER_ +#include "CB3DMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_LWO_LOADER_ +#include "CLWOMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_STL_LOADER_ +#include "CSTLMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_PLY_LOADER_ +#include "CPLYMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_SMF_LOADER_ +#include "CSMFMeshFileLoader.h" +#endif + +#ifdef _IRR_COMPILE_WITH_IRR_SCENE_LOADER_ +#include "CSceneLoaderIrr.h" +#endif + +#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_ +#include "CColladaMeshWriter.h" +#endif + +#ifdef _IRR_COMPILE_WITH_IRR_WRITER_ +#include "CIrrMeshWriter.h" +#endif + +#ifdef _IRR_COMPILE_WITH_STL_WRITER_ +#include "CSTLMeshWriter.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OBJ_WRITER_ +#include "COBJMeshWriter.h" +#endif + +#ifdef _IRR_COMPILE_WITH_PLY_WRITER_ +#include "CPLYMeshWriter.h" +#endif + +#include "CCubeSceneNode.h" +#include "CSphereSceneNode.h" +#include "CAnimatedMeshSceneNode.h" +#include "COctreeSceneNode.h" +#include "CCameraSceneNode.h" +#include "CLightSceneNode.h" +#include "CBillboardSceneNode.h" +#include "CMeshSceneNode.h" +#include "CSkyBoxSceneNode.h" +#include "CSkyDomeSceneNode.h" +#include "CParticleSystemSceneNode.h" +#include "CDummyTransformationSceneNode.h" +#include "CWaterSurfaceSceneNode.h" +#include "CTerrainSceneNode.h" +#include "CEmptySceneNode.h" +#include "CTextSceneNode.h" +#include "CQuake3ShaderSceneNode.h" +#include "CVolumeLightSceneNode.h" + +#include "CDefaultSceneNodeFactory.h" + +#include "CSceneCollisionManager.h" +#include "CTriangleSelector.h" +#include "COctreeTriangleSelector.h" +#include "CTriangleBBSelector.h" +#include "CMetaTriangleSelector.h" +#include "CTerrainTriangleSelector.h" + +#include "CSceneNodeAnimatorRotation.h" +#include "CSceneNodeAnimatorFlyCircle.h" +#include "CSceneNodeAnimatorFlyStraight.h" +#include "CSceneNodeAnimatorTexture.h" +#include "CSceneNodeAnimatorCollisionResponse.h" +#include "CSceneNodeAnimatorDelete.h" +#include "CSceneNodeAnimatorFollowSpline.h" +#include "CSceneNodeAnimatorCameraFPS.h" +#include "CSceneNodeAnimatorCameraMaya.h" +#include "CDefaultSceneNodeAnimatorFactory.h" + +#include "CGeometryCreator.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, + gui::ICursorControl* cursorControl, IMeshCache* cache, + gui::IGUIEnvironment* gui) +: ISceneNode(0, 0), Driver(driver), FileSystem(fs), GUIEnvironment(gui), + CursorControl(cursorControl), CollisionManager(0), + ActiveCamera(0), ShadowColor(150,0,0,0), AmbientLight(0,0,0,0), + MeshCache(cache), CurrentRendertime(ESNRP_NONE), LightManager(0), + IRR_XML_FORMAT_SCENE(L"irr_scene"), IRR_XML_FORMAT_NODE(L"node"), IRR_XML_FORMAT_NODE_ATTR_TYPE(L"type") +{ + #ifdef _DEBUG + ISceneManager::setDebugName("CSceneManager ISceneManager"); + ISceneNode::setDebugName("CSceneManager ISceneNode"); + #endif + + // root node's scene manager + SceneManager = this; + + // set scene parameters + Parameters.setAttribute( DEBUG_NORMAL_LENGTH, 1.f ); + Parameters.setAttribute( DEBUG_NORMAL_COLOR, video::SColor(255, 34, 221, 221)); + + if (Driver) + Driver->grab(); + + if (FileSystem) + FileSystem->grab(); + + if (CursorControl) + CursorControl->grab(); + + if (GUIEnvironment) + GUIEnvironment->grab(); + + // create mesh cache if not there already + if (!MeshCache) + MeshCache = new CMeshCache(); + else + MeshCache->grab(); + + // create collision manager + CollisionManager = new CSceneCollisionManager(this, Driver); + + // create geometry creator + GeometryCreator = new CGeometryCreator(); + + // add file format loaders. add the least commonly used ones first, + // as these are checked last + + // TODO: now that we have multiple scene managers, these should be + // shallow copies from the previous manager if there is one. + + #ifdef _IRR_COMPILE_WITH_STL_LOADER_ + MeshLoaderList.push_back(new CSTLMeshFileLoader()); + #endif + #ifdef _IRR_COMPILE_WITH_PLY_LOADER_ + MeshLoaderList.push_back(new CPLYMeshFileLoader(this)); + #endif + #ifdef _IRR_COMPILE_WITH_SMF_LOADER_ + MeshLoaderList.push_back(new CSMFMeshFileLoader(Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_OCT_LOADER_ + MeshLoaderList.push_back(new COCTLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_CSM_LOADER_ + MeshLoaderList.push_back(new CCSMLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_LMTS_LOADER_ + MeshLoaderList.push_back(new CLMTSMeshFileLoader(FileSystem, Driver, &Parameters)); + #endif + #ifdef _IRR_COMPILE_WITH_MY3D_LOADER_ + MeshLoaderList.push_back(new CMY3DMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_DMF_LOADER_ + MeshLoaderList.push_back(new CDMFLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_OGRE_LOADER_ + MeshLoaderList.push_back(new COgreMeshFileLoader(FileSystem, Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ + MeshLoaderList.push_back(new CHalflifeMDLMeshFileLoader( this )); + #endif + #ifdef _IRR_COMPILE_WITH_MD3_LOADER_ + MeshLoaderList.push_back(new CMD3MeshFileLoader( this)); + #endif + #ifdef _IRR_COMPILE_WITH_LWO_LOADER_ + MeshLoaderList.push_back(new CLWOMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_MD2_LOADER_ + MeshLoaderList.push_back(new CMD2MeshFileLoader()); + #endif + #ifdef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ + MeshLoaderList.push_back(new CIrrMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + MeshLoaderList.push_back(new CBSPMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_COLLADA_LOADER_ + MeshLoaderList.push_back(new CColladaFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_3DS_LOADER_ + MeshLoaderList.push_back(new C3DSMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_X_LOADER_ + MeshLoaderList.push_back(new CXMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_MS3D_LOADER_ + MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver)); + #endif + #ifdef _IRR_COMPILE_WITH_OBJ_LOADER_ + MeshLoaderList.push_back(new COBJMeshFileLoader(this, FileSystem)); + #endif + #ifdef _IRR_COMPILE_WITH_B3D_LOADER_ + MeshLoaderList.push_back(new CB3DMeshFileLoader(this)); + #endif + + // scene loaders + #ifdef _IRR_COMPILE_WITH_IRR_SCENE_LOADER_ + SceneLoaderList.push_back(new CSceneLoaderIrr(this, FileSystem)); + #endif + + + // factories + ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this); + registerSceneNodeFactory(factory); + factory->drop(); + + ISceneNodeAnimatorFactory* animatorFactory = new CDefaultSceneNodeAnimatorFactory(this, CursorControl); + registerSceneNodeAnimatorFactory(animatorFactory); + animatorFactory->drop(); +} + + +//! destructor +CSceneManager::~CSceneManager() +{ + clearDeletionList(); + + //! force to remove hardwareTextures from the driver + //! because Scenes may hold internally data bounded to sceneNodes + //! which may be destroyed twice + if (Driver) + Driver->removeAllHardwareBuffers(); + + if (FileSystem) + FileSystem->drop(); + + if (CursorControl) + CursorControl->drop(); + + if (CollisionManager) + CollisionManager->drop(); + + if (GeometryCreator) + GeometryCreator->drop(); + + if (GUIEnvironment) + GUIEnvironment->drop(); + + u32 i; + for (i=0; idrop(); + + for (i=0; idrop(); + + if (ActiveCamera) + ActiveCamera->drop(); + ActiveCamera = 0; + + if (MeshCache) + MeshCache->drop(); + + for (i=0; idrop(); + + for (i=0; idrop(); + + if (LightManager) + LightManager->drop(); + + // remove all nodes and animators before dropping the driver + // as render targets may be destroyed twice + + removeAll(); + removeAnimators(); + + if (Driver) + Driver->drop(); +} + + +//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped. +IAnimatedMesh* CSceneManager::getMesh(const io::path& filename) +{ + IAnimatedMesh* msh = MeshCache->getMeshByName(filename); + if (msh) + return msh; + + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + if (!file) + { + os::Printer::log("Could not load mesh, because file could not be opened: ", filename, ELL_ERROR); + return 0; + } + + // iterate the list in reverse order so user-added loaders can override the built-in ones + s32 count = MeshLoaderList.size(); + for (s32 i=count-1; i>=0; --i) + { + if (MeshLoaderList[i]->isALoadableFileExtension(filename)) + { + // reset file to avoid side effects of previous calls to createMesh + file->seek(0); + msh = MeshLoaderList[i]->createMesh(file); + if (msh) + { + MeshCache->addMesh(filename, msh); + msh->drop(); + break; + } + } + } + + file->drop(); + + if (!msh) + os::Printer::log("Could not load mesh, file format seems to be unsupported", filename, ELL_ERROR); + else + os::Printer::log("Loaded mesh", filename, ELL_INFORMATION); + + return msh; +} + + +//! gets an animateable mesh. loads it if needed. returned pointer must not be dropped. +IAnimatedMesh* CSceneManager::getMesh(io::IReadFile* file) +{ + if (!file) + return 0; + + io::path name = file->getFileName(); + IAnimatedMesh* msh = MeshCache->getMeshByName(file->getFileName()); + if (msh) + return msh; + + // iterate the list in reverse order so user-added loaders can override the built-in ones + s32 count = MeshLoaderList.size(); + for (s32 i=count-1; i>=0; --i) + { + if (MeshLoaderList[i]->isALoadableFileExtension(name)) + { + // reset file to avoid side effects of previous calls to createMesh + file->seek(0); + msh = MeshLoaderList[i]->createMesh(file); + if (msh) + { + MeshCache->addMesh(file->getFileName(), msh); + msh->drop(); + break; + } + } + } + + if (!msh) + os::Printer::log("Could not load mesh, file format seems to be unsupported", file->getFileName(), ELL_ERROR); + else + os::Printer::log("Loaded mesh", file->getFileName(), ELL_INFORMATION); + + return msh; +} + + +//! returns the video driver +video::IVideoDriver* CSceneManager::getVideoDriver() +{ + return Driver; +} + + +//! returns the GUI Environment +gui::IGUIEnvironment* CSceneManager::getGUIEnvironment() +{ + return GUIEnvironment; +} + +//! Get the active FileSystem +/** \return Pointer to the FileSystem +This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ +io::IFileSystem* CSceneManager::getFileSystem() +{ + return FileSystem; +} + +//! Adds a text scene node, which is able to display +//! 2d text at a position in three dimensional space +ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font, + const wchar_t* text, video::SColor color, ISceneNode* parent, + const core::vector3df& position, s32 id) +{ + if (!font) + return 0; + + if (!parent) + parent = this; + + ITextSceneNode* t = new CTextSceneNode(parent, this, id, font, + getSceneCollisionManager(), position, text, color); + t->drop(); + + return t; +} + + +//! Adds a text scene node, which uses billboards +IBillboardTextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font, + const wchar_t* text, ISceneNode* parent, + const core::dimension2d& size, + const core::vector3df& position, s32 id, + video::SColor colorTop, video::SColor colorBottom) +{ + if (!font && GUIEnvironment) + font = GUIEnvironment->getBuiltInFont(); + + if (!font) + return 0; + + if (!parent) + parent = this; + + IBillboardTextSceneNode* node = new CBillboardTextSceneNode(parent, this, id, font, text, position, size, + colorTop, colorBottom); + node->drop(); + + return node; + +} + + +//! Adds a scene node, which can render a quake3 shader +IMeshSceneNode* CSceneManager::addQuake3SceneNode(const IMeshBuffer* meshBuffer, + const quake3::IShader * shader, + ISceneNode* parent, s32 id ) +{ +#ifdef _IRR_COMPILE_WITH_BSP_LOADER_ + if (!shader) + return 0; + + if (!parent) + parent = this; + + CQuake3ShaderSceneNode* node = new CQuake3ShaderSceneNode( parent, + this, id, FileSystem, + meshBuffer, shader ); + node->drop(); + + return node; +#else + return 0; +#endif +} + + +//! adds Volume Lighting Scene Node. +//! the returned pointer must not be dropped. +IVolumeLightSceneNode* CSceneManager::addVolumeLightSceneNode( + ISceneNode* parent, s32 id, + const u32 subdivU, const u32 subdivV, + const video::SColor foot, const video::SColor tail, + const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) +{ + if (!parent) + parent = this; + + IVolumeLightSceneNode* node = new CVolumeLightSceneNode(parent, this, id, subdivU, subdivV, foot, tail, position, rotation, scale); + node->drop(); + + return node; +} + + +//! adds a test scene node for test purposes to the scene. It is a simple cube of (1,1,1) size. +//! the returned pointer must not be dropped. +IMeshSceneNode* CSceneManager::addCubeSceneNode(f32 size, ISceneNode* parent, + s32 id, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) +{ + if (!parent) + parent = this; + + IMeshSceneNode* node = new CCubeSceneNode(size, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a sphere scene node for test purposes to the scene. +IMeshSceneNode* CSceneManager::addSphereSceneNode(f32 radius, s32 polyCount, + ISceneNode* parent, s32 id, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) +{ + if (!parent) + parent = this; + + IMeshSceneNode* node = new CSphereSceneNode(radius, polyCount, polyCount, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! adds a scene node for rendering a static mesh +//! the returned pointer must not be dropped. +IMeshSceneNode* CSceneManager::addMeshSceneNode(IMesh* mesh, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && !mesh) + return 0; + + if (!parent) + parent = this; + + IMeshSceneNode* node = new CMeshSceneNode(mesh, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a scene node for rendering a animated water surface mesh. +ISceneNode* CSceneManager::addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 waveLength, + ISceneNode* parent, s32 id, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CWaterSurfaceSceneNode(waveHeight, waveSpeed, waveLength, + mesh, parent, this, id, position, rotation, scale); + + node->drop(); + + return node; +} + + +//! adds a scene node for rendering an animated mesh model +IAnimatedMeshSceneNode* CSceneManager::addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && !mesh) + return 0; + + if (!parent) + parent = this; + + IAnimatedMeshSceneNode* node = + new CAnimatedMeshSceneNode(mesh, parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a scene node for rendering using a octree to the scene graph. This a good method for rendering +//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much +//! faster then a bsp tree. +IMeshSceneNode* CSceneManager::addOctreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent, + s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && (!mesh || !mesh->getFrameCount())) + return 0; + + return addOctreeSceneNode(mesh ? mesh->getMesh(0) : 0, + parent, id, minimalPolysPerNode, + alsoAddIfMeshPointerZero); +} + + +//! Adds a scene node for rendering using a octree. This a good method for rendering +//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much +//! faster then a bsp tree. +IMeshSceneNode* CSceneManager::addOctreeSceneNode(IMesh* mesh, ISceneNode* parent, + s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero) +{ + if (!alsoAddIfMeshPointerZero && !mesh) + return 0; + + if (!parent) + parent = this; + + COctreeSceneNode* node = new COctreeSceneNode(parent, this, id, minimalPolysPerNode); + + if (node) + { + node->setMesh(mesh); + node->drop(); + } + + return node; +} + + +//! Adds a camera scene node to the tree and sets it as active camera. +//! \param position: Position of the space relative to its parent where the camera will be placed. +//! \param lookat: Position where the camera will look at. Also known as target. +//! \param parent: Parent scene node of the camera. Can be null. If the parent moves, +//! the camera will move too. +//! \return Returns pointer to interface to camera +ICameraSceneNode* CSceneManager::addCameraSceneNode(ISceneNode* parent, + const core::vector3df& position, const core::vector3df& lookat, s32 id, + bool makeActive) +{ + if (!parent) + parent = this; + + ICameraSceneNode* node = new CCameraSceneNode(parent, this, id, position, lookat); + + if (makeActive) + setActiveCamera(node); + node->drop(); + + return node; +} + + +//! Adds a camera scene node which is able to be controlled with the mouse similar +//! to in the 3D Software Maya by Alias Wavefront. +//! The returned pointer must not be dropped. +ICameraSceneNode* CSceneManager::addCameraSceneNodeMaya(ISceneNode* parent, + f32 rotateSpeed, f32 zoomSpeed, f32 translationSpeed, s32 id, f32 distance, + bool makeActive) +{ + ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(), + core::vector3df(0,0,100), id, makeActive); + if (node) + { + ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraMaya(CursorControl, + rotateSpeed, zoomSpeed, translationSpeed, distance); + + node->addAnimator(anm); + anm->drop(); + } + + return node; +} + + +//! Adds a camera scene node which is able to be controlled with the mouse and keys +//! like in most first person shooters (FPS): +ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent, + f32 rotateSpeed, f32 moveSpeed, s32 id, SKeyMap* keyMapArray, + s32 keyMapSize, bool noVerticalMovement, f32 jumpSpeed, + bool invertMouseY, bool makeActive) +{ + ICameraSceneNode* node = addCameraSceneNode(parent, core::vector3df(), + core::vector3df(0,0,100), id, makeActive); + if (node) + { + ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraFPS(CursorControl, + rotateSpeed, moveSpeed, jumpSpeed, + keyMapArray, keyMapSize, noVerticalMovement, invertMouseY); + + // Bind the node's rotation to its target. This is consistent with 1.4.2 and below. + node->bindTargetAndRotation(true); + node->addAnimator(anm); + anm->drop(); + } + + return node; +} + + +//! Adds a dynamic light scene node. The light will cast dynamic light on all +//! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING +//! turned on. (This is the default setting in most scene nodes). +ILightSceneNode* CSceneManager::addLightSceneNode(ISceneNode* parent, + const core::vector3df& position, video::SColorf color, f32 range, s32 id) +{ + if (!parent) + parent = this; + + ILightSceneNode* node = new CLightSceneNode(parent, this, id, position, color, range); + node->drop(); + + return node; +} + + +//! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element, +//! which always looks to the camera. It is usually used for things like explosions, fire, +//! lensflares and things like that. +IBillboardSceneNode* CSceneManager::addBillboardSceneNode(ISceneNode* parent, + const core::dimension2d& size, const core::vector3df& position, s32 id, + video::SColor colorTop, video::SColor colorBottom + ) +{ + if (!parent) + parent = this; + + IBillboardSceneNode* node = new CBillboardSceneNode(parent, this, id, position, size, + colorTop, colorBottom); + node->drop(); + + return node; +} + + +//! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and +//! is drawn around the camera position. +ISceneNode* CSceneManager::addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, + video::ITexture* left, video::ITexture* right, video::ITexture* front, + video::ITexture* back, ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CSkyBoxSceneNode(top, bottom, left, right, + front, back, parent, this, id); + + node->drop(); + return node; +} + + +//! Adds a skydome scene node. A skydome is a large (half-) sphere with a +//! panoramic texture on it and is drawn around the camera position. +ISceneNode* CSceneManager::addSkyDomeSceneNode(video::ITexture* texture, + u32 horiRes, u32 vertRes, f32 texturePercentage,f32 spherePercentage, f32 radius, + ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CSkyDomeSceneNode(texture, horiRes, vertRes, + texturePercentage, spherePercentage, radius, parent, this, id); + + node->drop(); + return node; +} + + +//! Adds a particle system scene node. +IParticleSystemSceneNode* CSceneManager::addParticleSystemSceneNode( + bool withDefaultEmitter, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) +{ + if (!parent) + parent = this; + + IParticleSystemSceneNode* node = new CParticleSystemSceneNode(withDefaultEmitter, + parent, this, id, position, rotation, scale); + node->drop(); + + return node; +} + + +//! Adds a terrain scene node to the scene graph. +ITerrainSceneNode* CSceneManager::addTerrainSceneNode( + const io::path& heightMapFileName, + ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale, + video::SColor vertexColor, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 smoothFactor, + bool addAlsoIfHeightmapEmpty) +{ + io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName); + + if (!file && !addAlsoIfHeightmapEmpty) + { + os::Printer::log("Could not load terrain, because file could not be opened.", + heightMapFileName, ELL_ERROR); + return 0; + } + + ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id, + position, rotation, scale, vertexColor, maxLOD, patchSize, + smoothFactor, addAlsoIfHeightmapEmpty); + + if (file) + file->drop(); + + return terrain; +} + +//! Adds a terrain scene node to the scene graph. +ITerrainSceneNode* CSceneManager::addTerrainSceneNode( + io::IReadFile* heightMapFile, + ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale, + video::SColor vertexColor, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, + s32 smoothFactor, + bool addAlsoIfHeightmapEmpty) +{ + if (!parent) + parent = this; + + if (!heightMapFile && !addAlsoIfHeightmapEmpty) + { + os::Printer::log("Could not load terrain, because file could not be opened.", ELL_ERROR); + return 0; + } + + CTerrainSceneNode* node = new CTerrainSceneNode(parent, this, FileSystem, id, + maxLOD, patchSize, position, rotation, scale); + + if (!node->loadHeightMap(heightMapFile, vertexColor, smoothFactor)) + { + if (!addAlsoIfHeightmapEmpty) + { + node->remove(); + node->drop(); + return 0; + } + } + + node->drop(); + return node; +} + + +//! Adds an empty scene node. +ISceneNode* CSceneManager::addEmptySceneNode(ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + ISceneNode* node = new CEmptySceneNode(parent, this, id); + node->drop(); + + return node; +} + + +//! Adds a dummy transformation scene node to the scene graph. +IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode( + ISceneNode* parent, s32 id) +{ + if (!parent) + parent = this; + + IDummyTransformationSceneNode* node = new CDummyTransformationSceneNode( + parent, this, id); + node->drop(); + + return node; +} + +//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly +//! and looks like a plane with some hills on it. You can specify how many hills +//! there should be on the plane and how high they should be. Also you must +//! specify a name for the mesh, because the mesh is added to the mesh pool, +//! and can be retrieved again using ISceneManager::getMesh with the name as +//! parameter. +IAnimatedMesh* CSceneManager::addHillPlaneMesh(const io::path& name, + const core::dimension2d& tileSize, + const core::dimension2d& tileCount, + video::SMaterial* material, f32 hillHeight, + const core::dimension2d& countHills, + const core::dimension2d& textureRepeatCount) +{ + if (MeshCache->isMeshLoaded(name)) + return MeshCache->getMeshByName(name); + + IMesh* mesh = GeometryCreator->createHillPlaneMesh(tileSize, + tileCount, material, hillHeight, countHills, + textureRepeatCount); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + { + mesh->drop(); + return 0; + } + + animatedMesh->addMesh(mesh); + mesh->drop(); + animatedMesh->recalculateBoundingBox(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + +//! Adds a terrain mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addTerrainMesh(const io::path& name, + video::IImage* texture, video::IImage* heightmap, + const core::dimension2d& stretchSize, + f32 maxHeight, + const core::dimension2d& defaultVertexBlockSize) +{ + if (MeshCache->isMeshLoaded(name)) + return MeshCache->getMeshByName(name); + + const bool debugBorders=false; + IMesh* mesh = GeometryCreator->createTerrainMesh(texture, heightmap, + stretchSize, maxHeight, Driver, + defaultVertexBlockSize, debugBorders); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + { + mesh->drop(); + return 0; + } + + animatedMesh->addMesh(mesh); + mesh->drop(); + animatedMesh->recalculateBoundingBox(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + +//! Adds an arrow mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addArrowMesh(const io::path& name, + video::SColor vtxColor0, video::SColor vtxColor1, + u32 tesselationCylinder, u32 tesselationCone, f32 height, + f32 cylinderHeight, f32 width0,f32 width1) +{ + if (MeshCache->isMeshLoaded(name)) + return MeshCache->getMeshByName(name); + + IMesh* mesh = GeometryCreator->createArrowMesh( tesselationCylinder, + tesselationCone, height, cylinderHeight, width0,width1, + vtxColor0, vtxColor1); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + { + mesh->drop(); + return 0; + } + + animatedMesh->addMesh(mesh); + mesh->drop(); + animatedMesh->recalculateBoundingBox(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + +//! Adds a static sphere mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addSphereMesh(const io::path& name, + f32 radius, u32 polyCountX, u32 polyCountY) +{ + if (MeshCache->isMeshLoaded(name)) + return MeshCache->getMeshByName(name); + + IMesh* mesh = GeometryCreator->createSphereMesh(radius, polyCountX, polyCountY); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + { + mesh->drop(); + return 0; + } + + animatedMesh->addMesh(mesh); + mesh->drop(); + animatedMesh->recalculateBoundingBox(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + + +//! Adds a static volume light mesh to the mesh pool. +IAnimatedMesh* CSceneManager::addVolumeLightMesh(const io::path& name, + const u32 SubdivideU, const u32 SubdivideV, + const video::SColor FootColor, const video::SColor TailColor) +{ + if (MeshCache->isMeshLoaded(name)) + return MeshCache->getMeshByName(name); + + IMesh* mesh = GeometryCreator->createVolumeLightMesh(SubdivideU, SubdivideV, FootColor, TailColor); + if (!mesh) + return 0; + + SAnimatedMesh* animatedMesh = new SAnimatedMesh(); + if (!animatedMesh) + { + mesh->drop(); + return 0; + } + + animatedMesh->addMesh(mesh); + mesh->drop(); + animatedMesh->recalculateBoundingBox(); + + MeshCache->addMesh(name, animatedMesh); + animatedMesh->drop(); + + return animatedMesh; +} + + +//! Returns the root scene node. This is the scene node wich is parent +//! of all scene nodes. The root scene node is a special scene node which +//! only exists to manage all scene nodes. It is not rendered and cannot +//! be removed from the scene. +//! \return Returns a pointer to the root scene node. +ISceneNode* CSceneManager::getRootSceneNode() +{ + return this; +} + + +//! Returns the current active camera. +//! \return The active camera is returned. Note that this can be NULL, if there +//! was no camera created yet. +ICameraSceneNode* CSceneManager::getActiveCamera() const +{ + return ActiveCamera; +} + + +//! Sets the active camera. The previous active camera will be deactivated. +//! \param camera: The new camera which should be active. +void CSceneManager::setActiveCamera(ICameraSceneNode* camera) +{ + if (camera) + camera->grab(); + if (ActiveCamera) + ActiveCamera->drop(); + + ActiveCamera = camera; +} + + +//! renders the node. +void CSceneManager::render() +{ +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSceneManager::getBoundingBox() const +{ + _IRR_DEBUG_BREAK_IF(true) // Bounding Box of Scene Manager wanted. + + // should never be used. + return *((core::aabbox3d*)0); +} + + +//! returns if node is culled +bool CSceneManager::isCulled(const ISceneNode* node) const +{ + const ICameraSceneNode* cam = getActiveCamera(); + if (!cam) + { + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + bool result = false; + + // has occlusion query information + if (node->getAutomaticCulling() & scene::EAC_OCC_QUERY) + { + result = (Driver->getOcclusionQueryResult(const_cast(node))==0); + } + + // can be seen by a bounding box ? + if (!result && (node->getAutomaticCulling() & scene::EAC_BOX)) + { + core::aabbox3d tbox = node->getBoundingBox(); + node->getAbsoluteTransformation().transformBoxEx(tbox); + result = !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox() )); + } + + // can be seen by a bounding sphere + if (!result && (node->getAutomaticCulling() & scene::EAC_FRUSTUM_SPHERE)) + { // requires bbox diameter + } + + // can be seen by cam pyramid planes ? + if (!result && (node->getAutomaticCulling() & scene::EAC_FRUSTUM_BOX)) + { + SViewFrustum frust = *cam->getViewFrustum(); + + //transform the frustum to the node's current absolute transformation + core::matrix4 invTrans(node->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE); + //invTrans.makeInverse(); + frust.transform(invTrans); + + core::vector3df edges[8]; + node->getBoundingBox().getEdges(edges); + + for (s32 i=0; igetMaterialCount(); + + taken = 0; + for (u32 i=0; igetMaterialRenderer(node->getMaterial(i).MaterialType); + if (rnd && rnd->isTransparent()) + { + // register as transparent node + TransparentNodeEntry e(node, camWorldPos); + TransparentNodeList.push_back(e); + taken = 1; + break; + } + } + + // not transparent, register as solid + if (!taken) + { + SolidNodeList.push_back(node); + taken = 1; + } + } + break; + case ESNRP_SHADOW: + if (!isCulled(node)) + { + ShadowNodeList.push_back(node); + taken = 1; + } + break; + + case ESNRP_NONE: // ignore this one + break; + } + +#ifdef _IRR_SCENEMANAGER_DEBUG + s32 index = Parameters.findAttribute ( "calls" ); + Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 ); + + if (!taken) + { + index = Parameters.findAttribute ( "culled" ); + Parameters.setAttribute ( index, Parameters.getAttributeAsInt ( index ) + 1 ); + } +#endif + + return taken; +} + + +//! This method is called just before the rendering process of the whole scene. +//! draws all scene nodes +void CSceneManager::drawAll() +{ + if (!Driver) + return; + +#ifdef _IRR_SCENEMANAGER_DEBUG + // reset attributes + Parameters.setAttribute ( "culled", 0 ); + Parameters.setAttribute ( "calls", 0 ); + Parameters.setAttribute ( "drawn_solid", 0 ); + Parameters.setAttribute ( "drawn_transparent", 0 ); + Parameters.setAttribute ( "drawn_transparent_effect", 0 ); +#endif + + u32 i; // new ISO for scoping problem in some compilers + + // reset all transforms + Driver->setMaterial(video::SMaterial()); + Driver->setTransform ( video::ETS_PROJECTION, core::IdentityMatrix ); + Driver->setTransform ( video::ETS_VIEW, core::IdentityMatrix ); + Driver->setTransform ( video::ETS_WORLD, core::IdentityMatrix ); + for (i=video::ETS_COUNT-1; i>=video::ETS_TEXTURE_0; --i) + Driver->setTransform ( (video::E_TRANSFORMATION_STATE)i, core::IdentityMatrix ); + + // TODO: This should not use an attribute here but a real parameter when necessary (too slow!) + Driver->setAllowZWriteOnTransparent(Parameters.getAttributeAsBool( ALLOW_ZWRITE_ON_TRANSPARENT) ); + + // do animations and other stuff. + OnAnimate(os::Timer::getTime()); + + /*! + First Scene Node for prerendering should be the active camera + consistent Camera is needed for culling + */ + camWorldPos.set(0,0,0); + if (ActiveCamera) + { + ActiveCamera->render(); + camWorldPos = ActiveCamera->getAbsolutePosition(); + } + + // let all nodes register themselves + OnRegisterSceneNode(); + + if (LightManager) + LightManager->OnPreRender(LightList); + + //render camera scenes + { + CurrentRendertime = ESNRP_CAMERA; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + if (LightManager) + LightManager->OnRenderPassPreRender(CurrentRendertime); + + for (i=0; irender(); + + CameraList.set_used(0); + + if (LightManager) + LightManager->OnRenderPassPostRender(CurrentRendertime); + } + + //render lights scenes + { + CurrentRendertime = ESNRP_LIGHT; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + if (LightManager) + { + LightManager->OnRenderPassPreRender(CurrentRendertime); + } + else + { + // Sort the lights by distance from the camera + core::vector3df camWorldPos(0, 0, 0); + if (ActiveCamera) + camWorldPos = ActiveCamera->getAbsolutePosition(); + + core::array SortedLights; + SortedLights.set_used(LightList.size()); + for (s32 light = (s32)LightList.size() - 1; light >= 0; --light) + SortedLights[light].setNodeAndDistanceFromPosition(LightList[light], camWorldPos); + + SortedLights.set_sorted(false); + SortedLights.sort(); + + for(s32 light = (s32)LightList.size() - 1; light >= 0; --light) + LightList[light] = SortedLights[light].Node; + } + + Driver->deleteAllDynamicLights(); + + Driver->setAmbientLight(AmbientLight); + + u32 maxLights = LightList.size(); + + if (!LightManager) + maxLights = core::min_ ( Driver->getMaximalDynamicLightAmount(), maxLights); + + for (i=0; i< maxLights; ++i) + LightList[i]->render(); + + if (LightManager) + LightManager->OnRenderPassPostRender(CurrentRendertime); + } + + // render skyboxes + { + CurrentRendertime = ESNRP_SKY_BOX; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + if (LightManager) + { + LightManager->OnRenderPassPreRender(CurrentRendertime); + for (i=0; iOnNodePreRender(node); + node->render(); + LightManager->OnNodePostRender(node); + } + } + else + { + for (i=0; irender(); + } + + SkyBoxList.set_used(0); + + if (LightManager) + LightManager->OnRenderPassPostRender(CurrentRendertime); + } + + + // render default objects + { + CurrentRendertime = ESNRP_SOLID; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + SolidNodeList.sort(); // sort by textures + + if (LightManager) + { + LightManager->OnRenderPassPreRender(CurrentRendertime); + for (i=0; iOnNodePreRender(node); + node->render(); + LightManager->OnNodePostRender(node); + } + } + else + { + for (i=0; irender(); + } + +#ifdef _IRR_SCENEMANAGER_DEBUG + Parameters.setAttribute("drawn_solid", (s32) SolidNodeList.size() ); +#endif + SolidNodeList.set_used(0); + + if (LightManager) + LightManager->OnRenderPassPostRender(CurrentRendertime); + } + + // render shadows + { + CurrentRendertime = ESNRP_SHADOW; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + if (LightManager) + { + LightManager->OnRenderPassPreRender(CurrentRendertime); + for (i=0; iOnNodePreRender(node); + node->render(); + LightManager->OnNodePostRender(node); + } + } + else + { + for (i=0; irender(); + } + + if (!ShadowNodeList.empty()) + Driver->drawStencilShadow(true,ShadowColor, ShadowColor, + ShadowColor, ShadowColor); + + ShadowNodeList.set_used(0); + + if (LightManager) + LightManager->OnRenderPassPostRender(CurrentRendertime); + } + + // render transparent objects. + { + CurrentRendertime = ESNRP_TRANSPARENT; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + TransparentNodeList.sort(); // sort by distance from camera + if (LightManager) + { + LightManager->OnRenderPassPreRender(CurrentRendertime); + + for (i=0; iOnNodePreRender(node); + node->render(); + LightManager->OnNodePostRender(node); + } + } + else + { + for (i=0; irender(); + } + +#ifdef _IRR_SCENEMANAGER_DEBUG + Parameters.setAttribute ( "drawn_transparent", (s32) TransparentNodeList.size() ); +#endif + TransparentNodeList.set_used(0); + + if (LightManager) + LightManager->OnRenderPassPostRender(CurrentRendertime); + } + + // render transparent effect objects. + { + CurrentRendertime = ESNRP_TRANSPARENT_EFFECT; + Driver->getOverrideMaterial().Enabled = ((Driver->getOverrideMaterial().EnablePasses & CurrentRendertime) != 0); + + TransparentEffectNodeList.sort(); // sort by distance from camera + + if (LightManager) + { + LightManager->OnRenderPassPreRender(CurrentRendertime); + + for (i=0; iOnNodePreRender(node); + node->render(); + LightManager->OnNodePostRender(node); + } + } + else + { + for (i=0; irender(); + } +#ifdef _IRR_SCENEMANAGER_DEBUG + Parameters.setAttribute ( "drawn_transparent_effect", (s32) TransparentEffectNodeList.size() ); +#endif + TransparentEffectNodeList.set_used(0); + } + + if (LightManager) + LightManager->OnPostRender(); + + LightList.set_used(0); + clearDeletionList(); + + CurrentRendertime = ESNRP_NONE; +} + +void CSceneManager::setLightManager(ILightManager* lightManager) +{ + if (lightManager) + lightManager->grab(); + if (LightManager) + LightManager->drop(); + + LightManager = lightManager; +} + + +//! Sets the color of stencil buffers shadows drawn by the scene manager. +void CSceneManager::setShadowColor(video::SColor color) +{ + ShadowColor = color; +} + + +//! Returns the current color of shadows. +video::SColor CSceneManager::getShadowColor() const +{ + return ShadowColor; +} + + +//! creates a rotation animator, which rotates the attached scene node around itself. +ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& rotationPerSecond) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorRotation(os::Timer::getTime(), + rotationPerSecond); + + return anim; +} + + +//! creates a fly circle animator, which lets the attached scene node fly around a center. +ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator( + const core::vector3df& center, f32 radius, f32 speed, + const core::vector3df& direction, + f32 startPosition, + f32 radiusEllipsoid) +{ + const f32 orbitDurationMs = (core::DEGTORAD * 360.f) / speed; + const u32 effectiveTime = os::Timer::getTime() + (u32)(orbitDurationMs * startPosition); + + ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle( + effectiveTime, center, + radius, speed, direction,radiusEllipsoid); + return anim; +} + + +//! Creates a fly straight animator, which lets the attached scene node +//! fly or move along a line between two points. +ISceneNodeAnimator* CSceneManager::createFlyStraightAnimator(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, bool loop,bool pingpong) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyStraight(startPoint, + endPoint, timeForWay, loop, os::Timer::getTime(), pingpong); + + return anim; +} + + +//! Creates a texture animator, which switches the textures of the target scene +//! node based on a list of textures. +ISceneNodeAnimator* CSceneManager::createTextureAnimator(const core::array& textures, + s32 timePerFrame, bool loop) +{ + ISceneNodeAnimator* anim = new CSceneNodeAnimatorTexture(textures, + timePerFrame, loop, os::Timer::getTime()); + + return anim; +} + + +//! Creates a scene node animator, which deletes the scene node after +//! some time automaticly. +ISceneNodeAnimator* CSceneManager::createDeleteAnimator(u32 when) +{ + return new CSceneNodeAnimatorDelete(this, os::Timer::getTime() + when); +} + + +//! Creates a special scene node animator for doing automatic collision detection +//! and response. +ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnimator( + ITriangleSelector* world, ISceneNode* sceneNode, const core::vector3df& ellipsoidRadius, + const core::vector3df& gravityPerSecond, + const core::vector3df& ellipsoidTranslation, f32 slidingValue) +{ + ISceneNodeAnimatorCollisionResponse* anim = new + CSceneNodeAnimatorCollisionResponse(this, world, sceneNode, + ellipsoidRadius, gravityPerSecond, + ellipsoidTranslation, slidingValue); + + return anim; +} + + +//! Creates a follow spline animator. +ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime, + const core::array< core::vector3df >& points, + f32 speed, f32 tightness, bool loop, bool pingpong) +{ + ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points, + speed, tightness, loop, pingpong); + return a; +} + + +//! Adds an external mesh loader. +void CSceneManager::addExternalMeshLoader(IMeshLoader* externalLoader) +{ + if (!externalLoader) + return; + + externalLoader->grab(); + MeshLoaderList.push_back(externalLoader); +} + + +//! Returns the number of mesh loaders supported by Irrlicht at this time +u32 CSceneManager::getMeshLoaderCount() const +{ + return MeshLoaderList.size(); +} + + +//! Retrieve the given mesh loader +IMeshLoader* CSceneManager::getMeshLoader(u32 index) const +{ + if (index < MeshLoaderList.size()) + return MeshLoaderList[index]; + else + return 0; +} + + +//! Adds an external scene loader. +void CSceneManager::addExternalSceneLoader(ISceneLoader* externalLoader) +{ + if (!externalLoader) + return; + + externalLoader->grab(); + SceneLoaderList.push_back(externalLoader); +} + + +//! Returns the number of scene loaders +u32 CSceneManager::getSceneLoaderCount() const +{ + return SceneLoaderList.size(); +} + + +//! Retrieve the given scene loader +ISceneLoader* CSceneManager::getSceneLoader(u32 index) const +{ + if (index < SceneLoaderList.size()) + return SceneLoaderList[index]; + else + return 0; +} + + +//! Returns a pointer to the scene collision manager. +ISceneCollisionManager* CSceneManager::getSceneCollisionManager() +{ + return CollisionManager; +} + + +//! Returns a pointer to the mesh manipulator. +IMeshManipulator* CSceneManager::getMeshManipulator() +{ + return Driver->getMeshManipulator(); +} + + +//! Creates a simple ITriangleSelector, based on a mesh. +ITriangleSelector* CSceneManager::createTriangleSelector(IMesh* mesh, ISceneNode* node) +{ + if (!mesh) + return 0; + + return new CTriangleSelector(mesh, node); +} + + +//! Creates a simple and updatable ITriangleSelector, based on a the mesh owned by an +//! animated scene node +ITriangleSelector* CSceneManager::createTriangleSelector(IAnimatedMeshSceneNode* node) +{ + if (!node || !node->getMesh()) + return 0; + + return new CTriangleSelector(node); +} + + +//! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box. +ITriangleSelector* CSceneManager::createTriangleSelectorFromBoundingBox(ISceneNode* node) +{ + if (!node) + return 0; + + return new CTriangleBBSelector(node); +} + + +//! Creates a simple ITriangleSelector, based on a mesh. +ITriangleSelector* CSceneManager::createOctreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode) +{ + if (!mesh) + return 0; + + return new COctreeTriangleSelector(mesh, node, minimalPolysPerNode); +} + + +//! Creates a meta triangle selector. +IMetaTriangleSelector* CSceneManager::createMetaTriangleSelector() +{ + return new CMetaTriangleSelector(); +} + + +//! Creates a triangle selector which can select triangles from a terrain scene node +ITriangleSelector* CSceneManager::createTerrainTriangleSelector( + ITerrainSceneNode* node, s32 LOD) +{ + return new CTerrainTriangleSelector(node, LOD); +} + + + +//! Adds a scene node to the deletion queue. +void CSceneManager::addToDeletionQueue(ISceneNode* node) +{ + if (!node) + return; + + node->grab(); + DeletionList.push_back(node); +} + + +//! clears the deletion list +void CSceneManager::clearDeletionList() +{ + if (DeletionList.empty()) + return; + + for (u32 i=0; iremove(); + DeletionList[i]->drop(); + } + + DeletionList.clear(); +} + + +//! Returns the first scene node with the specified name. +ISceneNode* CSceneManager::getSceneNodeFromName(const char* name, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (!strcmp(start->getName(),name)) + return start; + + ISceneNode* node = 0; + + const ISceneNodeList& list = start->getChildren(); + ISceneNodeList::ConstIterator it = list.begin(); + for (; it!=list.end(); ++it) + { + node = getSceneNodeFromName(name, *it); + if (node) + return node; + } + + return 0; +} + + +//! Returns the first scene node with the specified id. +ISceneNode* CSceneManager::getSceneNodeFromId(s32 id, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (start->getID() == id) + return start; + + ISceneNode* node = 0; + + const ISceneNodeList& list = start->getChildren(); + ISceneNodeList::ConstIterator it = list.begin(); + for (; it!=list.end(); ++it) + { + node = getSceneNodeFromId(id, *it); + if (node) + return node; + } + + return 0; +} + + +//! Returns the first scene node with the specified type. +ISceneNode* CSceneManager::getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (start->getType() == type || ESNT_ANY == type) + return start; + + ISceneNode* node = 0; + + const ISceneNodeList& list = start->getChildren(); + ISceneNodeList::ConstIterator it = list.begin(); + for (; it!=list.end(); ++it) + { + node = getSceneNodeFromType(type, *it); + if (node) + return node; + } + + return 0; +} + + +//! returns scene nodes by type. +void CSceneManager::getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start) +{ + if (start == 0) + start = getRootSceneNode(); + + if (start->getType() == type || ESNT_ANY == type) + outNodes.push_back(start); + + const ISceneNodeList& list = start->getChildren(); + ISceneNodeList::ConstIterator it = list.begin(); + + for (; it!=list.end(); ++it) + { + getSceneNodesFromType(type, outNodes, *it); + } +} + + +//! Posts an input event to the environment. Usually you do not have to +//! use this method, it is used by the internal engine. +bool CSceneManager::postEventFromUser(const SEvent& event) +{ + bool ret = false; + ICameraSceneNode* cam = getActiveCamera(); + if (cam) + ret = cam->OnEvent(event); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! Removes all children of this scene node +void CSceneManager::removeAll() +{ + ISceneNode::removeAll(); + setActiveCamera(0); + // Make sure the driver is reset, might need a more complex method at some point + if (Driver) + Driver->setMaterial(video::SMaterial()); +} + + +//! Clears the whole scene. All scene nodes are removed. +void CSceneManager::clear() +{ + removeAll(); +} + + +//! Returns interface to the parameters set in this scene. +io::IAttributes* CSceneManager::getParameters() +{ + return &Parameters; +} + + +//! Returns current render pass. +E_SCENE_NODE_RENDER_PASS CSceneManager::getSceneNodeRenderPass() const +{ + return CurrentRendertime; +} + + +//! Returns an interface to the mesh cache which is shared beween all existing scene managers. +IMeshCache* CSceneManager::getMeshCache() +{ + return MeshCache; +} + + +//! Creates a new scene manager. +ISceneManager* CSceneManager::createNewSceneManager(bool cloneContent) +{ + CSceneManager* manager = new CSceneManager(Driver, FileSystem, CursorControl, MeshCache, GUIEnvironment); + + if (cloneContent) + manager->cloneMembers(this, manager); + + return manager; +} + + +//! Returns the default scene node factory which can create all built in scene nodes +ISceneNodeFactory* CSceneManager::getDefaultSceneNodeFactory() +{ + return getSceneNodeFactory(0); +} + + +//! Adds a scene node factory to the scene manager. +void CSceneManager::registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd) +{ + if (factoryToAdd) + { + factoryToAdd->grab(); + SceneNodeFactoryList.push_back(factoryToAdd); + } +} + + +//! Returns amount of registered scene node factories. +u32 CSceneManager::getRegisteredSceneNodeFactoryCount() const +{ + return SceneNodeFactoryList.size(); +} + + +//! Returns a scene node factory by index +ISceneNodeFactory* CSceneManager::getSceneNodeFactory(u32 index) +{ + if (index < SceneNodeFactoryList.size()) + return SceneNodeFactoryList[index]; + + return 0; +} + + +//! Returns the default scene node animator factory which can create all built-in scene node animators +ISceneNodeAnimatorFactory* CSceneManager::getDefaultSceneNodeAnimatorFactory() +{ + return getSceneNodeAnimatorFactory(0); +} + +//! Adds a scene node animator factory to the scene manager. +void CSceneManager::registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd) +{ + if (factoryToAdd) + { + factoryToAdd->grab(); + SceneNodeAnimatorFactoryList.push_back(factoryToAdd); + } +} + + +//! Returns amount of registered scene node animator factories. +u32 CSceneManager::getRegisteredSceneNodeAnimatorFactoryCount() const +{ + return SceneNodeAnimatorFactoryList.size(); +} + + +//! Returns a scene node animator factory by index +ISceneNodeAnimatorFactory* CSceneManager::getSceneNodeAnimatorFactory(u32 index) +{ + if (index < SceneNodeAnimatorFactoryList.size()) + return SceneNodeAnimatorFactoryList[index]; + + return 0; +} + + +//! Saves the current scene into a file. +//! \param filename: Name of the file . +bool CSceneManager::saveScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node) +{ + bool ret = false; + io::IWriteFile* file = FileSystem->createAndWriteFile(filename); + if (file) + { + ret = saveScene(file, userDataSerializer, node); + file->drop(); + } + else + os::Printer::log("Unable to open file", filename, ELL_ERROR); + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; +} + + +//! Saves the current scene into a file. +bool CSceneManager::saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node) +{ + if (!file) + { + return false; + } + + bool result=false; + io::IXMLWriter* writer = FileSystem->createXMLWriter(file); + if (!writer) + { + os::Printer::log("Unable to create XML writer", file->getFileName(), ELL_ERROR); + } + else + { + result = saveScene(writer, FileSystem->getFileDir(FileSystem->getAbsolutePath(file->getFileName())), userDataSerializer, node); + writer->drop(); + } + return result; +} + + +//! Saves the current scene into a file. +bool CSceneManager::saveScene(io::IXMLWriter* writer, const io::path& currentPath, ISceneUserDataSerializer* userDataSerializer, ISceneNode* node) +{ + if (!writer) + return false; + + if (!node) + node=this; + + writer->writeXMLHeader(); + writeSceneNode(writer, node, userDataSerializer, currentPath.c_str(), true); + + return true; +} + + +//! Loads a scene. +bool CSceneManager::loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer, ISceneNode* rootNode) +{ + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + if (!file) + { + os::Printer::log("Unable to open scene file", filename.c_str(), ELL_ERROR); + return false; + } + + const bool ret = loadScene(file, userDataSerializer, rootNode); + file->drop(); + + return ret; +} + + +//! Loads a scene. Note that the current scene is not cleared before. +bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer, ISceneNode* rootNode) +{ + if (!file) + { + os::Printer::log("Unable to open scene file", ELL_ERROR); + return false; + } + + bool ret = false; + + // try scene loaders in reverse order + s32 i = SceneLoaderList.size()-1; + for (; i >= 0 && !ret; --i) + if (SceneLoaderList[i]->isALoadableFileFormat(file)) + ret = SceneLoaderList[i]->loadScene(file, userDataSerializer, rootNode); + + if (!ret) + os::Printer::log("Could not load scene file, perhaps the format is unsupported: ", file->getFileName().c_str(), ELL_ERROR); + + return ret; +} + + +//! writes a scene node +void CSceneManager::writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer, + const fschar_t* currentPath, bool init) +{ + if (!writer || !node || node->isDebugObject()) + return; + + const wchar_t* name; + ISceneNode* tmpNode=node; + + if (init) + { + name = IRR_XML_FORMAT_SCENE.c_str(); + writer->writeElement(name, false); + node=this; + } + else + { + name = IRR_XML_FORMAT_NODE.c_str(); + writer->writeElement(name, false, IRR_XML_FORMAT_NODE_ATTR_TYPE.c_str(), + core::stringw(getSceneNodeTypeName(node->getType())).c_str()); + } + + writer->writeLineBreak(); + + // write properties + + io::IAttributes* attr = FileSystem->createEmptyAttributes(Driver); + io::SAttributeReadWriteOptions options; + if (currentPath) + { + options.Filename=currentPath; + options.Flags|=io::EARWF_USE_RELATIVE_PATHS; + } + node->serializeAttributes(attr, &options); + + if (attr->getAttributeCount() != 0) + { + attr->write(writer); + writer->writeLineBreak(); + } + + // write materials + + if (node->getMaterialCount() && Driver) + { + const wchar_t* materialElement = L"materials"; + + writer->writeElement(materialElement); + writer->writeLineBreak(); + + for (u32 i=0; i < node->getMaterialCount(); ++i) + { + io::IAttributes* tmp_attr = + Driver->createAttributesFromMaterial(node->getMaterial(i), &options); + tmp_attr->write(writer); + tmp_attr->drop(); + } + + writer->writeClosingTag(materialElement); + writer->writeLineBreak(); + } + + // write animators + + if (!node->getAnimators().empty()) + { + const wchar_t* animatorElement = L"animators"; + writer->writeElement(animatorElement); + writer->writeLineBreak(); + + ISceneNodeAnimatorList::ConstIterator it = node->getAnimators().begin(); + for (; it != node->getAnimators().end(); ++it) + { + attr->clear(); + attr->addString("Type", getAnimatorTypeName((*it)->getType())); + + (*it)->serializeAttributes(attr); + + attr->write(writer); + } + + writer->writeClosingTag(animatorElement); + writer->writeLineBreak(); + } + + // write possible user data + + if (userDataSerializer) + { + io::IAttributes* userData = userDataSerializer->createUserData(node); + if (userData) + { + const wchar_t* userDataElement = L"userData"; + + writer->writeLineBreak(); + writer->writeElement(userDataElement); + writer->writeLineBreak(); + + userData->write(writer); + + writer->writeClosingTag(userDataElement); + writer->writeLineBreak(); + writer->writeLineBreak(); + + userData->drop(); + } + } + // reset to actual root node + if (init) + node=tmpNode; + + // write children once root node is written + // if parent is not scene manager, we need to write out node first + if (init && (node != this)) + { + writeSceneNode(writer, node, userDataSerializer, currentPath); + } + else + { + ISceneNodeList::ConstIterator it = node->getChildren().begin(); + for (; it != node->getChildren().end(); ++it) + writeSceneNode(writer, (*it), userDataSerializer, currentPath); + } + + attr->drop(); + + writer->writeClosingTag(name); + writer->writeLineBreak(); + writer->writeLineBreak(); +} + + +//! Returns a typename from a scene node type or null if not found +const c8* CSceneManager::getSceneNodeTypeName(ESCENE_NODE_TYPE type) +{ + const char* name = 0; + + for (s32 i=(s32)SceneNodeFactoryList.size()-1; !name && i>=0; --i) + name = SceneNodeFactoryList[i]->getCreateableSceneNodeTypeName(type); + + return name; +} + +//! Adds a scene node to the scene by name +ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent) +{ + ISceneNode* node = 0; + + for (s32 i=(s32)SceneNodeFactoryList.size()-1; i>=0 && !node; --i) + node = SceneNodeFactoryList[i]->addSceneNode(sceneNodeTypeName, parent); + + return node; +} + +ISceneNodeAnimator* CSceneManager::createSceneNodeAnimator(const char* typeName, ISceneNode* target) +{ + ISceneNodeAnimator *animator = 0; + + for (s32 i=(s32)SceneNodeAnimatorFactoryList.size()-1; i>=0 && !animator; --i) + animator = SceneNodeAnimatorFactoryList[i]->createSceneNodeAnimator(typeName, target); + + return animator; +} + + +//! Returns a typename from a scene node animator type or null if not found +const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) +{ + const char* name = 0; + + for (s32 i=SceneNodeAnimatorFactoryList.size()-1; !name && i >= 0; --i) + name = SceneNodeAnimatorFactoryList[i]->getCreateableSceneNodeAnimatorTypeName(type); + + return name; +} + + +//! Writes attributes of the scene node. +void CSceneManager::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addString ("Name", Name.c_str()); + out->addInt ("Id", ID ); + out->addColorf ("AmbientLight", AmbientLight); + + // fog attributes from video driver + video::SColor color; + video::E_FOG_TYPE fogType; + f32 start, end, density; + bool pixelFog, rangeFog; + + Driver->getFog(color, fogType, start, end, density, pixelFog, rangeFog); + + out->addEnum("FogType", fogType, video::FogTypeNames); + out->addColorf("FogColor", color); + out->addFloat("FogStart", start); + out->addFloat("FogEnd", end); + out->addFloat("FogDensity", density); + out->addBool("FogPixel", pixelFog); + out->addBool("FogRange", rangeFog); +} + +//! Reads attributes of the scene node. +void CSceneManager::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Name = in->getAttributeAsString("Name"); + ID = in->getAttributeAsInt("Id"); + AmbientLight = in->getAttributeAsColorf("AmbientLight"); + + // fog attributes + video::SColor color; + video::E_FOG_TYPE fogType; + f32 start, end, density; + bool pixelFog, rangeFog; + if (in->existsAttribute("FogType")) + { + fogType = (video::E_FOG_TYPE) in->getAttributeAsEnumeration("FogType", video::FogTypeNames); + color = in->getAttributeAsColorf("FogColor").toSColor(); + start = in->getAttributeAsFloat("FogStart"); + end = in->getAttributeAsFloat("FogEnd"); + density = in->getAttributeAsFloat("FogDensity"); + pixelFog = in->getAttributeAsBool("FogPixel"); + rangeFog = in->getAttributeAsBool("FogRange"); + Driver->setFog(color, fogType, start, end, density, pixelFog, rangeFog); + } + + RelativeTranslation.set(0,0,0); + RelativeRotation.set(0,0,0); + RelativeScale.set(1,1,1); + IsVisible = true; + AutomaticCullingState = scene::EAC_BOX; + DebugDataVisible = scene::EDS_OFF; + IsDebugObject = false; + + updateAbsolutePosition(); +} + + +//! Sets ambient color of the scene +void CSceneManager::setAmbientLight(const video::SColorf &ambientColor) +{ + AmbientLight = ambientColor; +} + + +//! Returns ambient color of the scene +const video::SColorf& CSceneManager::getAmbientLight() const +{ + return AmbientLight; +} + + +//! Get a skinned mesh, which is not available as header-only code +ISkinnedMesh* CSceneManager::createSkinnedMesh() +{ +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + return new CSkinnedMesh(); +#else + return 0; +#endif +} + +//! Returns a mesh writer implementation if available +IMeshWriter* CSceneManager::createMeshWriter(EMESH_WRITER_TYPE type) +{ + switch(type) + { + case EMWT_IRR_MESH: +#ifdef _IRR_COMPILE_WITH_IRR_WRITER_ + return new CIrrMeshWriter(Driver, FileSystem); +#else + return 0; +#endif + case EMWT_COLLADA: +#ifdef _IRR_COMPILE_WITH_COLLADA_WRITER_ + return new CColladaMeshWriter(this, Driver, FileSystem); +#else + return 0; +#endif + case EMWT_STL: +#ifdef _IRR_COMPILE_WITH_STL_WRITER_ + return new CSTLMeshWriter(this); +#else + return 0; +#endif + case EMWT_OBJ: +#ifdef _IRR_COMPILE_WITH_OBJ_WRITER_ + return new COBJMeshWriter(this, FileSystem); +#else + return 0; +#endif + + case EMWT_PLY: +#ifdef _IRR_COMPILE_WITH_PLY_WRITER_ + return new CPLYMeshWriter(); +#else + return 0; +#endif + } + + return 0; +} + + +// creates a scenemanager +ISceneManager* createSceneManager(video::IVideoDriver* driver, + io::IFileSystem* fs, gui::ICursorControl* cursorcontrol, + gui::IGUIEnvironment *guiEnvironment) +{ + return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment ); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.h new file mode 100644 index 0000000..3957f85 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneManager.h @@ -0,0 +1,659 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_MANAGER_H_INCLUDED__ +#define __C_SCENE_MANAGER_H_INCLUDED__ + +#include "ISceneManager.h" +#include "ISceneNode.h" +#include "ICursorControl.h" +#include "irrString.h" +#include "irrArray.h" +#include "IMeshLoader.h" +#include "CAttributes.h" +#include "ILightManager.h" + +namespace irr +{ +namespace io +{ + class IXMLWriter; + class IFileSystem; +} +namespace scene +{ + class IMeshCache; + class IGeometryCreator; + + /*! + The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff. + */ + class CSceneManager : public ISceneManager, public ISceneNode + { + public: + + //! constructor + CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, + gui::ICursorControl* cursorControl, IMeshCache* cache = 0, + gui::IGUIEnvironment *guiEnvironment = 0); + + //! destructor + virtual ~CSceneManager(); + + //! gets an animateable mesh. loads it if needed. returned pointer must not be dropped. + virtual IAnimatedMesh* getMesh(const io::path& filename); + + //! gets an animateable mesh. loads it if needed. returned pointer must not be dropped. + virtual IAnimatedMesh* getMesh(io::IReadFile* file); + + //! Returns an interface to the mesh cache which is shared beween all existing scene managers. + virtual IMeshCache* getMeshCache(); + + //! returns the video driver + virtual video::IVideoDriver* getVideoDriver(); + + //! return the gui environment + virtual gui::IGUIEnvironment* getGUIEnvironment(); + + //! return the filesystem + virtual io::IFileSystem* getFileSystem(); + + //! adds Volume Lighting Scene Node. + //! the returned pointer must not be dropped. + virtual IVolumeLightSceneNode* addVolumeLightSceneNode(ISceneNode* parent=0, s32 id=-1, + const u32 subdivU = 32, const u32 subdivV = 32, + const video::SColor foot = video::SColor(51, 0, 230, 180), + const video::SColor tail = video::SColor(0, 0, 0, 0), + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! adds a cube scene node to the scene. It is a simple cube of (1,1,1) size. + //! the returned pointer must not be dropped. + virtual IMeshSceneNode* addCubeSceneNode(f32 size=10.0f, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), const core::vector3df& rotation = core::vector3df(0,0,0), const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! Adds a sphere scene node to the scene. + virtual IMeshSceneNode* addSphereSceneNode(f32 radius=5.0f, s32 polyCount=16, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! adds a scene node for rendering an animated mesh model + virtual IAnimatedMeshSceneNode* addAnimatedMeshSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false); + + //! adds a scene node for rendering a static mesh + //! the returned pointer must not be dropped. + virtual IMeshSceneNode* addMeshSceneNode(IMesh* mesh, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f), + bool alsoAddIfMeshPointerZero=false); + + //! Adds a scene node for rendering a animated water surface mesh. + virtual ISceneNode* addWaterSurfaceSceneNode(IMesh* mesh, f32 waveHeight, f32 waveSpeed, f32 wlenght, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! registers a node for rendering it at a specific time. + virtual u32 registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDER_PASS pass = ESNRP_AUTOMATIC); + + //! draws all scene nodes + virtual void drawAll(); + + //! Adds a scene node for rendering using a octree to the scene graph. This a good method for rendering + //! scenes with lots of geometry. The Octree is built on the fly from the mesh, much + //! faster then a bsp tree. + virtual IMeshSceneNode* addOctreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false); + + //! Adss a scene node for rendering using a octree. This a good method for rendering + //! scenes with lots of geometry. The Octree is built on the fly from the mesh, much + //! faster then a bsp tree. + virtual IMeshSceneNode* addOctreeSceneNode(IMesh* mesh, ISceneNode* parent=0, + s32 id=-1, s32 minimalPolysPerNode=128, bool alsoAddIfMeshPointerZero=false); + + //! Adds a camera scene node to the tree and sets it as active camera. + //! \param position: Position of the space relative to its parent where the camera will be placed. + //! \param lookat: Position where the camera will look at. Also known as target. + //! \param parent: Parent scene node of the camera. Can be null. If the parent moves, + //! the camera will move too. + //! \return Pointer to interface to camera + virtual ICameraSceneNode* addCameraSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& lookat = core::vector3df(0,0,100), + s32 id=-1, bool makeActive=true); + + //! Adds a camera scene node which is able to be controlle with the mouse similar + //! like in the 3D Software Maya by Alias Wavefront. + //! The returned pointer must not be dropped. + virtual ICameraSceneNode* addCameraSceneNodeMaya(ISceneNode* parent=0, + f32 rotateSpeed=-1500.f, f32 zoomSpeed=200.f, + f32 translationSpeed=1500.f, s32 id=-1, f32 distance=70.f, + bool makeActive=true); + + //! Adds a camera scene node which is able to be controled with the mouse and keys + //! like in most first person shooters (FPS): + virtual ICameraSceneNode* addCameraSceneNodeFPS(ISceneNode* parent = 0, + f32 rotateSpeed = 100.0f, f32 moveSpeed = .5f, s32 id=-1, + SKeyMap* keyMapArray=0, s32 keyMapSize=0, + bool noVerticalMovement=false, f32 jumpSpeed = 0.f, + bool invertMouseY=false, bool makeActive=true); + + //! Adds a dynamic light scene node. The light will cast dynamic light on all + //! other scene nodes in the scene, which have the material flag video::MTF_LIGHTING + //! turned on. (This is the default setting in most scene nodes). + virtual ILightSceneNode* addLightSceneNode(ISceneNode* parent = 0, + const core::vector3df& position = core::vector3df(0,0,0), + video::SColorf color = video::SColorf(1.0f, 1.0f, 1.0f), + f32 range=100.0f, s32 id=-1); + + //! Adds a billboard scene node to the scene. A billboard is like a 3d sprite: A 2d element, + //! which always looks to the camera. It is usually used for things like explosions, fire, + //! lensflares and things like that. + virtual IBillboardSceneNode* addBillboardSceneNode(ISceneNode* parent = 0, + const core::dimension2d& size = core::dimension2d(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor shadeTop = 0xFFFFFFFF, video::SColor shadeBottom = 0xFFFFFFFF); + + //! Adds a skybox scene node. A skybox is a big cube with 6 textures on it and + //! is drawn around the camera position. + virtual ISceneNode* addSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, + video::ITexture* left, video::ITexture* right, video::ITexture* front, + video::ITexture* back, ISceneNode* parent = 0, s32 id=-1); + + //! Adds a skydome scene node. A skydome is a large (half-) sphere with a + //! panoramic texture on it and is drawn around the camera position. + virtual ISceneNode* addSkyDomeSceneNode(video::ITexture* texture, + u32 horiRes=16, u32 vertRes=8, + f32 texturePercentage=0.9, f32 spherePercentage=2.0,f32 radius = 1000.f, + ISceneNode* parent=0, s32 id=-1); + + //! Adds a text scene node, which is able to display + //! 2d text at a position in three dimensional space + virtual ITextSceneNode* addTextSceneNode(gui::IGUIFont* font, const wchar_t* text, + video::SColor color=video::SColor(100,255,255,255), + ISceneNode* parent = 0, const core::vector3df& position = core::vector3df(0,0,0), + s32 id=-1); + + //! Adds a text scene node, which uses billboards + virtual IBillboardTextSceneNode* addBillboardTextSceneNode(gui::IGUIFont* font, const wchar_t* text, + ISceneNode* parent = 0, + const core::dimension2d& size = core::dimension2d(10.0f, 10.0f), + const core::vector3df& position = core::vector3df(0,0,0), s32 id=-1, + video::SColor colorTop = 0xFFFFFFFF, video::SColor colorBottom = 0xFFFFFFFF); + + //! Adds a scene node, which can render a quake3 shader + virtual IMeshSceneNode* addQuake3SceneNode(const IMeshBuffer* meshBuffer, const quake3::IShader * shader, + ISceneNode* parent=0, s32 id=-1 + ); + + + //! Adds a Hill Plane mesh to the mesh pool. The mesh is + //! generated on the fly and looks like a plane with some hills + //! on it. You can specify how many hills should be on the plane + //! and how high they should be. Also you must specify a name + //! for the mesh because the mesh is added to the mesh pool and + //! can be retrieved back using ISceneManager::getMesh with the + //! name as parameter. + virtual IAnimatedMesh* addHillPlaneMesh(const io::path& name, + const core::dimension2d& tileSize, const core::dimension2d& tileCount, + video::SMaterial* material = 0, f32 hillHeight = 0.0f, + const core::dimension2d& countHills = core::dimension2d(1.0f, 1.0f), + const core::dimension2d& textureRepeatCount = core::dimension2d(1.0f, 1.0f)); + + //! Adds a terrain mesh to the mesh pool. + virtual IAnimatedMesh* addTerrainMesh(const io::path& meshname, video::IImage* texture, video::IImage* heightmap, + const core::dimension2d& stretchSize = core::dimension2d(10.0f,10.0f), + f32 maxHeight=200.0f, + const core::dimension2d& defaultVertexBlockSize = core::dimension2d(64,64)); + + //! Add a arrow mesh to the mesh pool + virtual IAnimatedMesh* addArrowMesh(const io::path& name, + video::SColor vtxColor0, video::SColor vtxColor1, + u32 tesselationCylinder, u32 tesselationCone, + f32 height, f32 cylinderHeight, f32 width0, + f32 width1); + + //! Adds a static sphere mesh to the mesh pool. + IAnimatedMesh* addSphereMesh(const io::path& name, + f32 radius=5.f, u32 polyCountX=16, u32 polyCountY=16); + + //! Adds a static volume light mesh to the mesh pool. + IAnimatedMesh* addVolumeLightMesh(const io::path& name, + const u32 SubdivideU = 32, const u32 SubdivideV = 32, + const video::SColor FootColor = video::SColor(51, 0, 230, 180), + const video::SColor TailColor = video::SColor(0, 0, 0, 0)); + + //! Adds a particle system scene node. + virtual IParticleSystemSceneNode* addParticleSystemSceneNode( + bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! Adds a terrain scene node to the scene graph. + virtual ITerrainSceneNode* addTerrainSceneNode( + const io::path& heightMapFileName, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=4, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17,s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty = false); + + //! Adds a terrain scene node to the scene graph. + virtual ITerrainSceneNode* addTerrainSceneNode( + io::IReadFile* heightMap, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=4, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17,s32 smoothFactor=0, + bool addAlsoIfHeightmapEmpty=false); + + //! Adds a dummy transformation scene node to the scene graph. + virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode( + ISceneNode* parent=0, s32 id=-1); + + //! Adds an empty scene node. + virtual ISceneNode* addEmptySceneNode(ISceneNode* parent, s32 id=-1); + + //! Returns the root scene node. This is the scene node wich is parent + //! of all scene nodes. The root scene node is a special scene node which + //! only exists to manage all scene nodes. It is not rendered and cannot + //! be removed from the scene. + //! \return Pointer to the root scene node. + virtual ISceneNode* getRootSceneNode(); + + //! Returns the current active camera. + //! \return The active camera is returned. Note that this can be NULL, if there + //! was no camera created yet. + virtual ICameraSceneNode* getActiveCamera() const; + + //! Sets the active camera. The previous active camera will be deactivated. + //! \param camera: The new camera which should be active. + virtual void setActiveCamera(ICameraSceneNode* camera); + + //! creates a rotation animator, which rotates the attached scene node around itself. + //! \param rotationPerSecond: Specifies the speed of the animation + //! \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + //! and the animator will animate it. + virtual ISceneNodeAnimator* createRotationAnimator(const core::vector3df& rotationPerSecond); + + //! creates a fly circle animator + /** Lets the attached scene node fly around a center. + \param center Center relative to node origin + \param speed: The orbital speed, in radians per millisecond. + \param direction: Specifies the upvector used for alignment of the mesh. + \param startPosition: The position on the circle where the animator will + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. + \return The animator. Attach it to a scene node with ISceneNode::addAnimator() + */ + virtual ISceneNodeAnimator* createFlyCircleAnimator( + const core::vector3df& center=core::vector3df(0.f, 0.f, 0.f), + f32 radius=100.f, f32 speed=0.001f, + const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f), + f32 startPosition = 0.f, + f32 radiusEllipsoid = 0.f); + + //! Creates a fly straight animator, which lets the attached scene node + //! fly or move along a line between two points. + virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, bool loop=false,bool pingpong = false); + + //! Creates a texture animator, which switches the textures of the target scene + //! node based on a list of textures. + virtual ISceneNodeAnimator* createTextureAnimator(const core::array& textures, + s32 timePerFrame, bool loop); + + //! Creates a scene node animator, which deletes the scene node after + //! some time automaticly. + virtual ISceneNodeAnimator* createDeleteAnimator(u32 timeMS); + + + //! Creates a special scene node animator for doing automatic collision detection + //! and response. + virtual ISceneNodeAnimatorCollisionResponse* createCollisionResponseAnimator( + ITriangleSelector* world, ISceneNode* sceneNode, + const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30), + const core::vector3df& gravityPerSecond = core::vector3df(0,-1.0f,0), + const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0), + f32 slidingValue = 0.0005f); + + //! Creates a follow spline animator. + virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, + const core::array< core::vector3df >& points, + f32 speed, f32 tightness, bool loop, bool pingpong); + + + //! Creates a simple ITriangleSelector, based on a mesh. + virtual ITriangleSelector* createTriangleSelector(IMesh* mesh, ISceneNode* node); + + //! Creates a simple ITriangleSelector, based on an animated mesh scene node. + //! Details of the mesh associated with the node will be extracted internally. + //! Call ITriangleSelector::update() to have the triangle selector updated based + //! on the current frame of the animated mesh scene node. + //! \param: The animated mesh scene node from which to build the selector + virtual ITriangleSelector* createTriangleSelector(IAnimatedMeshSceneNode* node); + + //! Creates a simple ITriangleSelector, based on a mesh. + virtual ITriangleSelector* createOctreeTriangleSelector(IMesh* mesh, + ISceneNode* node, s32 minimalPolysPerNode); + + //! Creates a simple dynamic ITriangleSelector, based on a axis aligned bounding box. + virtual ITriangleSelector* createTriangleSelectorFromBoundingBox( + ISceneNode* node); + + //! Creates a meta triangle selector. + virtual IMetaTriangleSelector* createMetaTriangleSelector(); + + //! Creates a triangle selector which can select triangles from a terrain scene node + //! \param: Pointer to the created terrain scene node + //! \param: Level of detail, 0 for highest detail. + virtual ITriangleSelector* createTerrainTriangleSelector( + ITerrainSceneNode* node, s32 LOD=0); + + //! Adds an external mesh loader. + virtual void addExternalMeshLoader(IMeshLoader* externalLoader); + + //! Returns the number of mesh loaders supported by Irrlicht at this time + virtual u32 getMeshLoaderCount() const; + + //! Retrieve the given mesh loader + virtual IMeshLoader* getMeshLoader(u32 index) const; + + //! Adds an external scene loader. + virtual void addExternalSceneLoader(ISceneLoader* externalLoader); + + //! Returns the number of scene loaders supported by Irrlicht at this time + virtual u32 getSceneLoaderCount() const; + + //! Retrieve the given scene loader + virtual ISceneLoader* getSceneLoader(u32 index) const; + + //! Returns a pointer to the scene collision manager. + virtual ISceneCollisionManager* getSceneCollisionManager(); + + //! Returns a pointer to the mesh manipulator. + virtual IMeshManipulator* getMeshManipulator(); + + //! Sets the color of stencil buffers shadows drawn by the scene manager. + virtual void setShadowColor(video::SColor color); + + //! Returns the current color of shadows. + virtual video::SColor getShadowColor() const; + + //! Adds a scene node to the deletion queue. + virtual void addToDeletionQueue(ISceneNode* node); + + //! Returns the first scene node with the specified id. + virtual ISceneNode* getSceneNodeFromId(s32 id, ISceneNode* start=0); + + //! Returns the first scene node with the specified name. + virtual ISceneNode* getSceneNodeFromName(const c8* name, ISceneNode* start=0); + + //! Returns the first scene node with the specified type. + virtual ISceneNode* getSceneNodeFromType(scene::ESCENE_NODE_TYPE type, ISceneNode* start=0); + + //! returns scene nodes by type. + virtual void getSceneNodesFromType(ESCENE_NODE_TYPE type, core::array& outNodes, ISceneNode* start=0); + + //! Posts an input event to the environment. Usually you do not have to + //! use this method, it is used by the internal engine. + virtual bool postEventFromUser(const SEvent& event); + + //! Clears the whole scene. All scene nodes are removed. + virtual void clear(); + + //! Removes all children of this scene node + virtual void removeAll(); + + //! Returns interface to the parameters set in this scene. + virtual io::IAttributes* getParameters(); + + //! Returns current render pass. + virtual E_SCENE_NODE_RENDER_PASS getSceneNodeRenderPass() const; + + //! Creates a new scene manager. + virtual ISceneManager* createNewSceneManager(bool cloneContent); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SCENE_MANAGER; } + + //! Returns the default scene node factory which can create all built in scene nodes + virtual ISceneNodeFactory* getDefaultSceneNodeFactory(); + + //! Adds a scene node factory to the scene manager. + /** Use this to extend the scene manager with new scene node types which it should be + able to create automaticly, for example when loading data from xml files. */ + virtual void registerSceneNodeFactory(ISceneNodeFactory* factoryToAdd); + + //! Returns amount of registered scene node factories. + virtual u32 getRegisteredSceneNodeFactoryCount() const; + + //! Returns a scene node factory by index + virtual ISceneNodeFactory* getSceneNodeFactory(u32 index); + + //! Returns a typename from a scene node type or null if not found + virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type); + + //! Returns a typename from a scene node animator type or null if not found + virtual const c8* getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type); + + //! Adds a scene node to the scene by name + virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent=0); + + //! creates a scene node animator based on its type name + virtual ISceneNodeAnimator* createSceneNodeAnimator(const char* typeName, ISceneNode* target=0); + + //! Returns the default scene node animator factory which can create all built-in scene node animators + virtual ISceneNodeAnimatorFactory* getDefaultSceneNodeAnimatorFactory(); + + //! Adds a scene node animator factory to the scene manager. + virtual void registerSceneNodeAnimatorFactory(ISceneNodeAnimatorFactory* factoryToAdd); + + //! Returns amount of registered scene node animator factories. + virtual u32 getRegisteredSceneNodeAnimatorFactoryCount() const; + + //! Returns a scene node animator factory by index + virtual ISceneNodeAnimatorFactory* getSceneNodeAnimatorFactory(u32 index); + + //! Saves the current scene into a file. + virtual bool saveScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0); + + //! Saves the current scene into a file. + virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0); + + //! Saves the current scene into a file. + virtual bool saveScene(io::IXMLWriter* writer, const io::path& currentPath, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0); + + //! Loads a scene. Note that the current scene is not cleared before. + virtual bool loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* rootNode=0); + + //! Loads a scene. Note that the current scene is not cleared before. + virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* rootNode=0); + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns a mesh writer implementation if available + virtual IMeshWriter* createMeshWriter(EMESH_WRITER_TYPE type); + + //! Get a skinned mesh, which is not available as header-only code + virtual ISkinnedMesh* createSkinnedMesh(); + + //! Sets ambient color of the scene + virtual void setAmbientLight(const video::SColorf &ambientColor); + + //! Returns ambient color of the scene + virtual const video::SColorf& getAmbientLight() const; + + //! Register a custom callbacks manager which gets callbacks during scene rendering. + virtual void setLightManager(ILightManager* lightManager); + + //! Get current render time. + virtual E_SCENE_NODE_RENDER_PASS getCurrentRendertime() const { return CurrentRendertime; } + + //! Set current render time. + virtual void setCurrentRendertime(E_SCENE_NODE_RENDER_PASS currentRendertime) { CurrentRendertime = currentRendertime; } + + //! Get an instance of a geometry creator. + virtual const IGeometryCreator* getGeometryCreator(void) const { return GeometryCreator; } + + //! returns if node is culled + virtual bool isCulled(const ISceneNode* node) const; + + private: + + //! clears the deletion list + void clearDeletionList(); + + //! writes a scene node + void writeSceneNode(io::IXMLWriter* writer, ISceneNode* node, ISceneUserDataSerializer* userDataSerializer, const fschar_t* currentPath=0, bool init=false); + + struct DefaultNodeEntry + { + DefaultNodeEntry(ISceneNode* n) : + Node(n), TextureValue(0) + { + if (n->getMaterialCount()) + TextureValue = (n->getMaterial(0).getTexture(0)); + } + + bool operator < (const DefaultNodeEntry& other) const + { + return (TextureValue < other.TextureValue); + } + + ISceneNode* Node; + private: + void* TextureValue; + }; + + //! sort on distance (center) to camera + struct TransparentNodeEntry + { + TransparentNodeEntry(ISceneNode* n, const core::vector3df& camera) + : Node(n) + { + Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera); + } + + bool operator < (const TransparentNodeEntry& other) const + { + return Distance > other.Distance; + } + + ISceneNode* Node; + private: + f64 Distance; + }; + + //! sort on distance (sphere) to camera + struct DistanceNodeEntry + { + DistanceNodeEntry(ISceneNode* n, const core::vector3df& cameraPos) + : Node(n) + { + setNodeAndDistanceFromPosition(n, cameraPos); + } + + bool operator < (const DistanceNodeEntry& other) const + { + return Distance < other.Distance; + } + + void setNodeAndDistanceFromPosition(ISceneNode* n, const core::vector3df & fromPosition) + { + Node = n; + Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(fromPosition); + Distance -= Node->getBoundingBox().getExtent().getLengthSQ() * 0.5; + } + + ISceneNode* Node; + private: + f64 Distance; + }; + + //! video driver + video::IVideoDriver* Driver; + + //! file system + io::IFileSystem* FileSystem; + + //! GUI Enviroment ( Debug Purpose ) + gui::IGUIEnvironment* GUIEnvironment; + + //! cursor control + gui::ICursorControl* CursorControl; + + //! collision manager + ISceneCollisionManager* CollisionManager; + + //! render pass lists + core::array CameraList; + core::array LightList; + core::array ShadowNodeList; + core::array SkyBoxList; + core::array SolidNodeList; + core::array TransparentNodeList; + core::array TransparentEffectNodeList; + + core::array MeshLoaderList; + core::array SceneLoaderList; + core::array DeletionList; + core::array SceneNodeFactoryList; + core::array SceneNodeAnimatorFactoryList; + + //! current active camera + ICameraSceneNode* ActiveCamera; + core::vector3df camWorldPos; // Position of camera for transparent nodes. + + video::SColor ShadowColor; + video::SColorf AmbientLight; + + //! String parameters + // NODE: Attributes are slow and should only be used for debug-info and not in release + io::CAttributes Parameters; + + //! Mesh cache + IMeshCache* MeshCache; + + E_SCENE_NODE_RENDER_PASS CurrentRendertime; + + //! An optional callbacks manager to allow the user app finer control + //! over the scene lighting and rendering. + ILightManager* LightManager; + + //! constants for reading and writing XML. + //! Not made static due to portability problems. + const core::stringw IRR_XML_FORMAT_SCENE; + const core::stringw IRR_XML_FORMAT_NODE; + const core::stringw IRR_XML_FORMAT_NODE_ATTR_TYPE; + + IGeometryCreator* GeometryCreator; + }; + +} // end namespace video +} // end namespace scene + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp new file mode 100644 index 0000000..5612f8a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp @@ -0,0 +1,355 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorCameraFPS.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "Keycodes.h" +#include "ICursorControl.h" +#include "ICameraSceneNode.h" +#include "ISceneNodeAnimatorCollisionResponse.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl, + f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed, + SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY) +: CursorControl(cursorControl), MaxVerticalAngle(88.0f), + MoveSpeed(moveSpeed), RotateSpeed(rotateSpeed), JumpSpeed(jumpSpeed), + MouseYDirection(invertY ? -1.0f : 1.0f), + LastAnimationTime(0), firstUpdate(true), firstInput(true), NoVerticalMovement(noVerticalMovement) +{ + #ifdef _DEBUG + setDebugName("CCameraSceneNodeAnimatorFPS"); + #endif + + if (CursorControl) + CursorControl->grab(); + + allKeysUp(); + + // create key map + if (!keyMapArray || !keyMapSize) + { + // create default key map + KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP)); + KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN)); + KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT)); + KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT)); + KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J)); + } + else + { + // create custom key map + setKeyMap(keyMapArray, keyMapSize); + } +} + + +//! destructor +CSceneNodeAnimatorCameraFPS::~CSceneNodeAnimatorCameraFPS() +{ + if (CursorControl) + CursorControl->drop(); +} + + +//! It is possible to send mouse and key events to the camera. Most cameras +//! may ignore this input, but camera scene nodes which are created for +//! example with scene::ISceneManager::addMayaCameraSceneNode or +//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input +//! for changing their position, look at target or whatever. +bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt) +{ + switch(evt.EventType) + { + case EET_KEY_INPUT_EVENT: + for (u32 i=0; igetRelativePosition(); + return true; + } + break; + + default: + break; + } + + return false; +} + + +void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) +{ + if (!node || node->getType() != ESNT_CAMERA) + return; + + ICameraSceneNode* camera = static_cast(node); + + if (firstUpdate) + { + camera->updateAbsolutePosition(); + if (CursorControl ) + { + CursorControl->setPosition(0.5f, 0.5f); + CursorPos = CenterCursor = CursorControl->getRelativePosition(); + } + + LastAnimationTime = timeMs; + + firstUpdate = false; + } + + // If the camera isn't the active camera, and receiving input, then don't process it. + if(!camera->isInputReceiverEnabled()) + { + firstInput = true; + return; + } + + if ( firstInput ) + { + allKeysUp(); + firstInput = false; + } + + scene::ISceneManager * smgr = camera->getSceneManager(); + if(smgr && smgr->getActiveCamera() != camera) + return; + + // get time + f32 timeDiff = (f32) ( timeMs - LastAnimationTime ); + LastAnimationTime = timeMs; + + // update position + core::vector3df pos = camera->getPosition(); + + // Update rotation + core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); + core::vector3df relativeRotation = target.getHorizontalAngle(); + + if (CursorControl) + { + if (CursorPos != CenterCursor) + { + relativeRotation.Y -= (0.5f - CursorPos.X) * RotateSpeed; + relativeRotation.X -= (0.5f - CursorPos.Y) * RotateSpeed * MouseYDirection; + + // X < MaxVerticalAngle or X > 360-MaxVerticalAngle + + if (relativeRotation.X > MaxVerticalAngle*2 && + relativeRotation.X < 360.0f-MaxVerticalAngle) + { + relativeRotation.X = 360.0f-MaxVerticalAngle; + } + else + if (relativeRotation.X > MaxVerticalAngle && + relativeRotation.X < 360.0f-MaxVerticalAngle) + { + relativeRotation.X = MaxVerticalAngle; + } + + // Do the fix as normal, special case below + // reset cursor position to the centre of the window. + CursorControl->setPosition(0.5f, 0.5f); + CenterCursor = CursorControl->getRelativePosition(); + + // needed to avoid problems when the event receiver is disabled + CursorPos = CenterCursor; + } + + // Special case, mouse is whipped outside of window before it can update. + video::IVideoDriver* driver = smgr->getVideoDriver(); + core::vector2d mousepos(u32(CursorControl->getPosition().X), u32(CursorControl->getPosition().Y)); + core::rect screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); + + // Only if we are moving outside quickly. + bool reset = !screenRect.isPointInside(mousepos); + + if(reset) + { + // Force a reset. + CursorControl->setPosition(0.5f, 0.5f); + CenterCursor = CursorControl->getRelativePosition(); + CursorPos = CenterCursor; + } + } + + // set target + + target.set(0,0, core::max_(1.f, pos.getLength())); + core::vector3df movedir = target; + + core::matrix4 mat; + mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0)); + mat.transformVect(target); + + if (NoVerticalMovement) + { + mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0)); + mat.transformVect(movedir); + } + else + { + movedir = target; + } + + movedir.normalize(); + + if (CursorKeys[EKA_MOVE_FORWARD]) + pos += movedir * timeDiff * MoveSpeed; + + if (CursorKeys[EKA_MOVE_BACKWARD]) + pos -= movedir * timeDiff * MoveSpeed; + + // strafing + + core::vector3df strafevect = target; + strafevect = strafevect.crossProduct(camera->getUpVector()); + + if (NoVerticalMovement) + strafevect.Y = 0.0f; + + strafevect.normalize(); + + if (CursorKeys[EKA_STRAFE_LEFT]) + pos += strafevect * timeDiff * MoveSpeed; + + if (CursorKeys[EKA_STRAFE_RIGHT]) + pos -= strafevect * timeDiff * MoveSpeed; + + // For jumping, we find the collision response animator attached to our camera + // and if it's not falling, we tell it to jump. + if (CursorKeys[EKA_JUMP_UP]) + { + const ISceneNodeAnimatorList& animators = camera->getAnimators(); + ISceneNodeAnimatorList::ConstIterator it = animators.begin(); + while(it != animators.end()) + { + if(ESNAT_COLLISION_RESPONSE == (*it)->getType()) + { + ISceneNodeAnimatorCollisionResponse * collisionResponse = + static_cast(*it); + + if(!collisionResponse->isFalling()) + collisionResponse->jump(JumpSpeed); + } + + it++; + } + } + + // write translation + camera->setPosition(pos); + + // write right target + target += pos; + camera->setTarget(target); +} + + +void CSceneNodeAnimatorCameraFPS::allKeysUp() +{ + for (u32 i=0; i& keymap) +{ + KeyMap=keymap; +} + +const core::array& CSceneNodeAnimatorCameraFPS::getKeyMap() const +{ + return KeyMap; +} + + +//! Sets whether vertical movement should be allowed. +void CSceneNodeAnimatorCameraFPS::setVerticalMovement(bool allow) +{ + NoVerticalMovement = !allow; +} + + +//! Sets whether the Y axis of the mouse should be inverted. +void CSceneNodeAnimatorCameraFPS::setInvertMouse(bool invert) +{ + if (invert) + MouseYDirection = -1.0f; + else + MouseYDirection = 1.0f; +} + + +ISceneNodeAnimator* CSceneNodeAnimatorCameraFPS::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorCameraFPS * newAnimator = + new CSceneNodeAnimatorCameraFPS(CursorControl, RotateSpeed, MoveSpeed, JumpSpeed, + 0, 0, NoVerticalMovement); + newAnimator->setKeyMap(KeyMap); + return newAnimator; +} + + +} // namespace scene +} // namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.h new file mode 100644 index 0000000..9b4ad2e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraFPS.h @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__ + +#include "ISceneNodeAnimatorCameraFPS.h" +#include "vector2d.h" +#include "position2d.h" +#include "SKeyMap.h" +#include "irrArray.h" + +namespace irr +{ +namespace gui +{ + class ICursorControl; +} + +namespace scene +{ + + //! Special scene node animator for FPS cameras + class CSceneNodeAnimatorCameraFPS : public ISceneNodeAnimatorCameraFPS + { + public: + + //! Constructor + CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl, + f32 rotateSpeed = 100.0f, f32 moveSpeed = .5f, f32 jumpSpeed=0.f, + SKeyMap* keyMapArray=0, u32 keyMapSize=0, bool noVerticalMovement=false, + bool invertY=false); + + //! Destructor + virtual ~CSceneNodeAnimatorCameraFPS(); + + //! Animates the scene node, currently only works on cameras + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Event receiver + virtual bool OnEvent(const SEvent& event); + + //! Returns the speed of movement in units per second + virtual f32 getMoveSpeed() const; + + //! Sets the speed of movement in units per second + virtual void setMoveSpeed(f32 moveSpeed); + + //! Returns the rotation speed + virtual f32 getRotateSpeed() const; + + //! Set the rotation speed + virtual void setRotateSpeed(f32 rotateSpeed); + + //! Sets the keyboard mapping for this animator (old style) + //! \param keymap: an array of keyboard mappings, see SKeyMap + //! \param count: the size of the keyboard map array + virtual void setKeyMap(SKeyMap *map, u32 count); + + //! Sets the keyboard mapping for this animator + //! \param keymap The new keymap array + virtual void setKeyMap(const core::array& keymap); + + //! Gets the keyboard mapping for this animator + virtual const core::array& getKeyMap() const; + + //! Sets whether vertical movement should be allowed. + virtual void setVerticalMovement(bool allow); + + //! Sets whether the Y axis of the mouse should be inverted. + /** If enabled then moving the mouse down will cause + the camera to look up. It is disabled by default. */ + virtual void setInvertMouse(bool invert); + + //! This animator will receive events when attached to the active camera + virtual bool isEventReceiverEnabled() const + { + return true; + } + + //! Returns the type of this animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const + { + return ESNAT_CAMERA_FPS; + } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer once you're + done with it. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + void allKeysUp(); + + gui::ICursorControl *CursorControl; + + f32 MaxVerticalAngle; + + f32 MoveSpeed; + f32 RotateSpeed; + f32 JumpSpeed; + // -1.0f for inverted mouse, defaults to 1.0f + f32 MouseYDirection; + + s32 LastAnimationTime; + + core::array KeyMap; + core::position2d CenterCursor, CursorPos; + + bool CursorKeys[EKA_COUNT]; + + bool firstUpdate; + bool firstInput; + bool NoVerticalMovement; + }; + +} // end namespace scene +} // end namespace irr + +#endif // __C_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp new file mode 100644 index 0000000..00ac133 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp @@ -0,0 +1,317 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorCameraMaya.h" +#include "ICursorControl.h" +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorCameraMaya::CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, + f32 rotateSpeed, f32 zoomSpeed, f32 translateSpeed, f32 distance) + : CursorControl(cursor), OldCamera(0), MousePos(0.5f, 0.5f), + ZoomSpeed(zoomSpeed), RotateSpeed(rotateSpeed), TranslateSpeed(translateSpeed), + CurrentZoom(distance), RotX(0.0f), RotY(0.0f), + Zooming(false), Rotating(false), Moving(false), Translating(false) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorCameraMaya"); + #endif + + if (CursorControl) + { + CursorControl->grab(); + MousePos = CursorControl->getRelativePosition(); + } + + allKeysUp(); +} + + +//! destructor +CSceneNodeAnimatorCameraMaya::~CSceneNodeAnimatorCameraMaya() +{ + if (CursorControl) + CursorControl->drop(); +} + + +//! It is possible to send mouse and key events to the camera. Most cameras +//! may ignore this input, but camera scene nodes which are created for +//! example with scene::ISceneManager::addMayaCameraSceneNode or +//! scene::ISceneManager::addMeshViewerCameraSceneNode, may want to get this input +//! for changing their position, look at target or whatever. +bool CSceneNodeAnimatorCameraMaya::OnEvent(const SEvent& event) +{ + if (event.EventType != EET_MOUSE_INPUT_EVENT) + return false; + + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_PRESSED_DOWN: + MouseKeys[0] = true; + break; + case EMIE_RMOUSE_PRESSED_DOWN: + MouseKeys[2] = true; + break; + case EMIE_MMOUSE_PRESSED_DOWN: + MouseKeys[1] = true; + break; + case EMIE_LMOUSE_LEFT_UP: + MouseKeys[0] = false; + break; + case EMIE_RMOUSE_LEFT_UP: + MouseKeys[2] = false; + break; + case EMIE_MMOUSE_LEFT_UP: + MouseKeys[1] = false; + break; + case EMIE_MOUSE_MOVED: + MousePos = CursorControl->getRelativePosition(); + break; + case EMIE_MOUSE_WHEEL: + case EMIE_LMOUSE_DOUBLE_CLICK: + case EMIE_RMOUSE_DOUBLE_CLICK: + case EMIE_MMOUSE_DOUBLE_CLICK: + case EMIE_LMOUSE_TRIPLE_CLICK: + case EMIE_RMOUSE_TRIPLE_CLICK: + case EMIE_MMOUSE_TRIPLE_CLICK: + case EMIE_COUNT: + return false; + } + return true; +} + + +//! OnAnimate() is called just before rendering the whole scene. +void CSceneNodeAnimatorCameraMaya::animateNode(ISceneNode *node, u32 timeMs) +{ + //Alt + LM = Rotate around camera pivot + //Alt + LM + MM = Dolly forth/back in view direction (speed % distance camera pivot - max distance to pivot) + //Alt + MM = Move on camera plane (Screen center is about the mouse pointer, depending on move speed) + + if (!node || node->getType() != ESNT_CAMERA) + return; + + ICameraSceneNode* camera = static_cast(node); + + // If the camera isn't the active camera, and receiving input, then don't process it. + if (!camera->isInputReceiverEnabled()) + return; + + scene::ISceneManager * smgr = camera->getSceneManager(); + if (smgr && smgr->getActiveCamera() != camera) + return; + + if (OldCamera != camera) + { + LastCameraTarget = OldTarget = camera->getTarget(); + OldCamera = camera; + } + else + { + OldTarget += camera->getTarget() - LastCameraTarget; + } + + f32 nRotX = RotX; + f32 nRotY = RotY; + f32 nZoom = CurrentZoom; + + if ( (isMouseKeyDown(0) && isMouseKeyDown(2)) || isMouseKeyDown(1) ) + { + if (!Zooming) + { + ZoomStart = MousePos; + Zooming = true; + } + else + { + const f32 targetMinDistance = 0.1f; + nZoom += (ZoomStart.X - MousePos.X) * ZoomSpeed; + + if (nZoom < targetMinDistance) // jox: fixed bug: bounce back when zooming to close + nZoom = targetMinDistance; + } + } + else if (Zooming) + { + const f32 old = CurrentZoom; + CurrentZoom = CurrentZoom + (ZoomStart.X - MousePos.X ) * ZoomSpeed; + nZoom = CurrentZoom; + + if (nZoom < 0) + nZoom = CurrentZoom = old; + Zooming = false; + } + + // Translation --------------------------------- + + core::vector3df translate(OldTarget); + const core::vector3df upVector(camera->getUpVector()); + const core::vector3df target = camera->getTarget(); + + core::vector3df pos = camera->getPosition(); + core::vector3df tvectX = pos - target; + tvectX = tvectX.crossProduct(upVector); + tvectX.normalize(); + + const SViewFrustum* const va = camera->getViewFrustum(); + core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown()); + tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos); + tvectY.normalize(); + + if (isMouseKeyDown(2) && !Zooming) + { + if (!Translating) + { + TranslateStart = MousePos; + Translating = true; + } + else + { + translate += tvectX * (TranslateStart.X - MousePos.X)*TranslateSpeed + + tvectY * (TranslateStart.Y - MousePos.Y)*TranslateSpeed; + } + } + else if (Translating) + { + translate += tvectX * (TranslateStart.X - MousePos.X)*TranslateSpeed + + tvectY * (TranslateStart.Y - MousePos.Y)*TranslateSpeed; + OldTarget = translate; + Translating = false; + } + + // Rotation ------------------------------------ + + if (isMouseKeyDown(0) && !Zooming) + { + if (!Rotating) + { + RotateStart = MousePos; + Rotating = true; + nRotX = RotX; + nRotY = RotY; + } + else + { + nRotX += (RotateStart.X - MousePos.X) * RotateSpeed; + nRotY += (RotateStart.Y - MousePos.Y) * RotateSpeed; + } + } + else if (Rotating) + { + RotX += (RotateStart.X - MousePos.X) * RotateSpeed; + RotY += (RotateStart.Y - MousePos.Y) * RotateSpeed; + nRotX = RotX; + nRotY = RotY; + Rotating = false; + } + + // Set pos ------------------------------------ + + pos = translate; + pos.X += nZoom; + + pos.rotateXYBy(nRotY, translate); + pos.rotateXZBy(-nRotX, translate); + + camera->setPosition(pos); + camera->setTarget(translate); + + // Rotation Error ---------------------------- + + // jox: fixed bug: jitter when rotating to the top and bottom of y + pos.set(0,1,0); + pos.rotateXYBy(-nRotY); + pos.rotateXZBy(-nRotX+180.f); + camera->setUpVector(pos); + LastCameraTarget = camera->getTarget(); +} + + +bool CSceneNodeAnimatorCameraMaya::isMouseKeyDown(s32 key) const +{ + return MouseKeys[key]; +} + + +void CSceneNodeAnimatorCameraMaya::allKeysUp() +{ + for (s32 i=0; i<3; ++i) + MouseKeys[i] = false; +} + + +//! Sets the rotation speed +void CSceneNodeAnimatorCameraMaya::setRotateSpeed(f32 speed) +{ + RotateSpeed = speed; +} + + +//! Sets the movement speed +void CSceneNodeAnimatorCameraMaya::setMoveSpeed(f32 speed) +{ + TranslateSpeed = speed; +} + + +//! Sets the zoom speed +void CSceneNodeAnimatorCameraMaya::setZoomSpeed(f32 speed) +{ + ZoomSpeed = speed; +} + + +//! Set the distance +void CSceneNodeAnimatorCameraMaya::setDistance(f32 distance) +{ + CurrentZoom=distance; +} + + +//! Gets the rotation speed +f32 CSceneNodeAnimatorCameraMaya::getRotateSpeed() const +{ + return RotateSpeed; +} + + +// Gets the movement speed +f32 CSceneNodeAnimatorCameraMaya::getMoveSpeed() const +{ + return TranslateSpeed; +} + + +//! Gets the zoom speed +f32 CSceneNodeAnimatorCameraMaya::getZoomSpeed() const +{ + return ZoomSpeed; +} + + +//! Returns the current distance, i.e. orbit radius +f32 CSceneNodeAnimatorCameraMaya::getDistance() const +{ + return CurrentZoom; +} + + +ISceneNodeAnimator* CSceneNodeAnimatorCameraMaya::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorCameraMaya * newAnimator = + new CSceneNodeAnimatorCameraMaya(CursorControl, RotateSpeed, ZoomSpeed, TranslateSpeed); + return newAnimator; +} + +} // end namespace +} // end namespace + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h new file mode 100644 index 0000000..495a77b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCameraMaya.h @@ -0,0 +1,116 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_CAMERA_MAYA_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_CAMERA_MAYA_H_INCLUDED__ + +#include "ISceneNodeAnimatorCameraMaya.h" +#include "ICameraSceneNode.h" +#include "vector2d.h" + +namespace irr +{ + +namespace gui +{ + class ICursorControl; +} + +namespace scene +{ + + //! Special scene node animator for FPS cameras + /** This scene node animator can be attached to a camera to make it act + like a 3d modelling tool camera + */ + class CSceneNodeAnimatorCameraMaya : public ISceneNodeAnimatorCameraMaya + { + public: + //! Constructor + CSceneNodeAnimatorCameraMaya(gui::ICursorControl* cursor, f32 rotateSpeed = -1500.f, + f32 zoomSpeed = 200.f, f32 translationSpeed = 1500.f, f32 distance=70.f); + + //! Destructor + virtual ~CSceneNodeAnimatorCameraMaya(); + + //! Animates the scene node, currently only works on cameras + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Event receiver + virtual bool OnEvent(const SEvent& event); + + //! Returns the speed of movement in units per millisecond + virtual f32 getMoveSpeed() const; + + //! Sets the speed of movement in units per millisecond + virtual void setMoveSpeed(f32 moveSpeed); + + //! Returns the rotation speed + virtual f32 getRotateSpeed() const; + + //! Set the rotation speed + virtual void setRotateSpeed(f32 rotateSpeed); + + //! Returns the zoom speed + virtual f32 getZoomSpeed() const; + + //! Set the zoom speed + virtual void setZoomSpeed(f32 zoomSpeed); + + //! Returns the current distance, i.e. orbit radius + virtual f32 getDistance() const; + + //! Set the distance + virtual void setDistance(f32 distance); + + //! This animator will receive events when attached to the active camera + virtual bool isEventReceiverEnabled() const + { + return true; + } + + //! Returns type of the scene node + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const + { + return ESNAT_CAMERA_MAYA; + } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling + this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + + void allKeysUp(); + void animate(); + bool isMouseKeyDown(s32 key) const; + + bool MouseKeys[3]; + + gui::ICursorControl *CursorControl; + scene::ICameraSceneNode* OldCamera; + core::vector3df OldTarget; + core::vector3df LastCameraTarget; // to find out if the camera target was moved outside this animator + core::position2df RotateStart; + core::position2df ZoomStart; + core::position2df TranslateStart; + core::position2df MousePos; + f32 ZoomSpeed; + f32 RotateSpeed; + f32 TranslateSpeed; + f32 CurrentZoom; + f32 RotX, RotY; + bool Zooming; + bool Rotating; + bool Moving; + bool Translating; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp new file mode 100644 index 0000000..432d2ac --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp @@ -0,0 +1,303 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorCollisionResponse.h" +#include "ISceneCollisionManager.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSceneNodeAnimatorCollisionResponse::CSceneNodeAnimatorCollisionResponse( + ISceneManager* scenemanager, + ITriangleSelector* world, ISceneNode* object, + const core::vector3df& ellipsoidRadius, + const core::vector3df& gravityPerSecond, + const core::vector3df& ellipsoidTranslation, + f32 slidingSpeed) +: Radius(ellipsoidRadius), Gravity(gravityPerSecond), Translation(ellipsoidTranslation), + World(world), Object(object), SceneManager(scenemanager), LastTime(0), + SlidingSpeed(slidingSpeed), CollisionNode(0), CollisionCallback(0), + Falling(false), IsCamera(false), AnimateCameraTarget(true), CollisionOccurred(false), + FirstUpdate(true) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorCollisionResponse"); + #endif + + if (World) + World->grab(); + + setNode(Object); +} + + +//! destructor +CSceneNodeAnimatorCollisionResponse::~CSceneNodeAnimatorCollisionResponse() +{ + if (World) + World->drop(); + + if (CollisionCallback) + CollisionCallback->drop(); +} + + +//! Returns if the attached scene node is falling, which means that +//! there is no blocking wall from the scene node in the direction of +//! the gravity. +bool CSceneNodeAnimatorCollisionResponse::isFalling() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return Falling; +} + + +//! Sets the radius of the ellipsoid with which collision detection and +//! response is done. +void CSceneNodeAnimatorCollisionResponse::setEllipsoidRadius( + const core::vector3df& radius) +{ + Radius = radius; + FirstUpdate = true; +} + + +//! Returns the radius of the ellipsoid with wich the collision detection and +//! response is done. +core::vector3df CSceneNodeAnimatorCollisionResponse::getEllipsoidRadius() const +{ + return Radius; +} + + +//! Sets the gravity of the environment. +void CSceneNodeAnimatorCollisionResponse::setGravity(const core::vector3df& gravity) +{ + Gravity = gravity; + FirstUpdate = true; +} + + +//! Returns current vector of gravity. +core::vector3df CSceneNodeAnimatorCollisionResponse::getGravity() const +{ + return Gravity; +} + + +//! 'Jump' the animator, by adding a jump speed opposite to its gravity +void CSceneNodeAnimatorCollisionResponse::jump(f32 jumpSpeed) +{ + FallingVelocity -= (core::vector3df(Gravity).normalize()) * jumpSpeed; + Falling = true; +} + + +//! Sets the translation of the ellipsoid for collision detection. +void CSceneNodeAnimatorCollisionResponse::setEllipsoidTranslation(const core::vector3df &translation) +{ + Translation = translation; +} + + +//! Returns the translation of the ellipsoid for collision detection. +core::vector3df CSceneNodeAnimatorCollisionResponse::getEllipsoidTranslation() const +{ + return Translation; +} + + +//! Sets a triangle selector holding all triangles of the world with which +//! the scene node may collide. +void CSceneNodeAnimatorCollisionResponse::setWorld(ITriangleSelector* newWorld) +{ + if (newWorld) + newWorld->grab(); + + if (World) + World->drop(); + + World = newWorld; + + FirstUpdate = true; +} + + +//! Returns the current triangle selector containing all triangles for +//! collision detection. +ITriangleSelector* CSceneNodeAnimatorCollisionResponse::getWorld() const +{ + return World; +} + + +void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 timeMs) +{ + CollisionOccurred = false; + + if (node != Object) + setNode(node); + + if(!Object || !World) + return; + + // trigger reset + if ( timeMs == 0 ) + { + FirstUpdate = true; + timeMs = LastTime; + } + + if ( FirstUpdate ) + { + LastPosition = Object->getPosition(); + Falling = false; + LastTime = timeMs; + FallingVelocity.set ( 0, 0, 0 ); + + FirstUpdate = false; + } + + const u32 diff = timeMs - LastTime; + LastTime = timeMs; + + CollisionResultPosition = Object->getPosition(); + core::vector3df vel = CollisionResultPosition - LastPosition; + + FallingVelocity += Gravity * (f32)diff * 0.001f; + + CollisionTriangle = RefTriangle; + CollisionPoint = core::vector3df(); + CollisionResultPosition = core::vector3df(); + CollisionNode = 0; + + // core::vector3df force = vel + FallingVelocity; + + if ( AnimateCameraTarget ) + { + // TODO: divide SlidingSpeed by frame time + + bool f = false; + CollisionResultPosition + = SceneManager->getSceneCollisionManager()->getCollisionResultPosition( + World, LastPosition-Translation, + Radius, vel, CollisionTriangle, CollisionPoint, f, + CollisionNode, SlidingSpeed, FallingVelocity); + + CollisionOccurred = (CollisionTriangle != RefTriangle); + + CollisionResultPosition += Translation; + + if (f)//CollisionTriangle == RefTriangle) + { + Falling = true; + } + else + { + Falling = false; + FallingVelocity.set(0, 0, 0); + } + + bool collisionConsumed = false; + + if (CollisionOccurred && CollisionCallback) + collisionConsumed = CollisionCallback->onCollision(*this); + + if(!collisionConsumed) + Object->setPosition(CollisionResultPosition); + } + + // move camera target + if (AnimateCameraTarget && IsCamera) + { + const core::vector3df pdiff = Object->getPosition() - LastPosition - vel; + ICameraSceneNode* cam = (ICameraSceneNode*)Object; + cam->setTarget(cam->getTarget() + pdiff); + } + + LastPosition = Object->getPosition(); +} + + +void CSceneNodeAnimatorCollisionResponse::setNode(ISceneNode* node) +{ + Object = node; + + if (Object) + { + LastPosition = Object->getPosition(); + IsCamera = (Object->getType() == ESNT_CAMERA); + } + + LastTime = os::Timer::getTime(); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorCollisionResponse::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Radius", Radius); + out->addVector3d("Gravity", Gravity); + out->addVector3d("Translation", Translation); + out->addBool("AnimateCameraTarget", AnimateCameraTarget); +} + + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorCollisionResponse::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Radius = in->getAttributeAsVector3d("Radius"); + Gravity = in->getAttributeAsVector3d("Gravity"); + Translation = in->getAttributeAsVector3d("Translation"); + AnimateCameraTarget = in->getAttributeAsBool("AnimateCameraTarget"); +} + + +ISceneNodeAnimator* CSceneNodeAnimatorCollisionResponse::createClone(ISceneNode* node, ISceneManager* newManager) +{ + if (!newManager) newManager = SceneManager; + + CSceneNodeAnimatorCollisionResponse * newAnimator = + new CSceneNodeAnimatorCollisionResponse(newManager, World, Object, Radius, + (Gravity * 1000.0f), Translation, SlidingSpeed); + + return newAnimator; +} + +void CSceneNodeAnimatorCollisionResponse::setCollisionCallback(ICollisionCallback* callback) +{ + if ( CollisionCallback == callback ) + return; + + if (CollisionCallback) + CollisionCallback->drop(); + + CollisionCallback = callback; + + if (CollisionCallback) + CollisionCallback->grab(); +} + +//! Should the Target react on collision ( default = true ) +void CSceneNodeAnimatorCollisionResponse::setAnimateTarget ( bool enable ) +{ + AnimateCameraTarget = enable; + FirstUpdate = true; +} + +//! Should the Target react on collision ( default = true ) +bool CSceneNodeAnimatorCollisionResponse::getAnimateTarget () const +{ + return AnimateCameraTarget; +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h new file mode 100644 index 0000000..42ff71a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h @@ -0,0 +1,157 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_COLLISION_RESPONSE_H_INCLUDED__ + +#include "ISceneNodeAnimatorCollisionResponse.h" + +namespace irr +{ +namespace scene +{ + + //! Special scene node animator for doing automatic collision detection and response. + /** This scene node animator can be attached to any scene node modifying it in that + way, that it cannot move through walls of the world, is influenced by gravity and + acceleration. This animator is useful for example for first person shooter + games. Attach it for example to a first person shooter camera, and the camera will + behave as the player control in a first person shooter game: The camera stops and + slides at walls, walks up stairs, falls down if there is no floor under it, and so on. + */ + class CSceneNodeAnimatorCollisionResponse : public ISceneNodeAnimatorCollisionResponse + { + public: + + //! constructor + CSceneNodeAnimatorCollisionResponse(ISceneManager* scenemanager, + ITriangleSelector* world, ISceneNode* object, + const core::vector3df& ellipsoidRadius = core::vector3df(30,60,30), + const core::vector3df& gravityPerSecond = core::vector3df(0,-100.0f,0), + const core::vector3df& ellipsoidTranslation = core::vector3df(0,0,0), + f32 slidingSpeed = 0.0005f); + + //! destructor + virtual ~CSceneNodeAnimatorCollisionResponse(); + + //! Returns if the attached scene node is falling, which means that + //! there is no blocking wall from the scene node in the direction of + //! the gravity. + virtual bool isFalling() const; + + //! Sets the radius of the ellipsoid with which collision detection and + //! response is done. + virtual void setEllipsoidRadius(const core::vector3df& radius); + + //! Returns the radius of the ellipsoid with which the collision detection and + //! response is done. + virtual core::vector3df getEllipsoidRadius() const; + + //! Sets the gravity of the environment. + virtual void setGravity(const core::vector3df& gravity); + + //! 'Jump' the animator, by adding a jump speed opposite to its gravity + virtual void jump(f32 jumpSpeed); + + //! Should the Target react on collision ( default = true ) + virtual void setAnimateTarget ( bool enable ); + virtual bool getAnimateTarget () const; + + //! Returns current vector of gravity. + virtual core::vector3df getGravity() const; + + //! Sets the translation of the ellipsoid for collision detection. + virtual void setEllipsoidTranslation(const core::vector3df &translation); + + //! Returns the translation of the ellipsoid for collision detection. + virtual core::vector3df getEllipsoidTranslation() const; + + //! Sets a triangle selector holding all triangles of the world with which + //! the scene node may collide. + virtual void setWorld(ITriangleSelector* newWorld); + + //! Returns the current triangle selector containing all triangles for + //! collision detection. + virtual ITriangleSelector* getWorld() const; + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_COLLISION_RESPONSE; } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling + this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + //! Set the single node that this animator will act on. + virtual void setTargetNode(ISceneNode * node) { setNode(node); } + + //! Gets the single node that this animator is acting on. + virtual ISceneNode* getTargetNode(void) const { return Object; } + + //! Returns true if a collision occurred during the last animateNode() + virtual bool collisionOccurred() const { return CollisionOccurred; } + + //! Returns the last point of collision. + virtual const core::vector3df & getCollisionPoint() const { return CollisionPoint; } + + //! Returns the last triangle that caused a collision. + virtual const core::triangle3df & getCollisionTriangle() const { return CollisionTriangle; } + + virtual const core::vector3df & getCollisionResultPosition(void) const { return CollisionResultPosition; } + + virtual ISceneNode* getCollisionNode(void) const { return CollisionNode; } + + + //! Sets a callback interface which will be called if a collision occurs. + /** \param callback: collision callback handler that will be called when a collision + occurs. Set this to 0 to disable the callback. + */ + virtual void setCollisionCallback(ICollisionCallback* callback); + + private: + + void setNode(ISceneNode* node); + + core::vector3df Radius; + core::vector3df Gravity; + core::vector3df Translation; + core::vector3df FallingVelocity; // In the direction of Gravity. + + core::vector3df LastPosition; + core::triangle3df RefTriangle; + + ITriangleSelector* World; + ISceneNode* Object; + ISceneManager* SceneManager; + u32 LastTime; + f32 SlidingSpeed; + + core::vector3df CollisionPoint; + core::triangle3df CollisionTriangle; + core::vector3df CollisionResultPosition; + ISceneNode * CollisionNode; + ICollisionCallback* CollisionCallback; + + bool Falling; + bool IsCamera; + bool AnimateCameraTarget; + bool CollisionOccurred; + bool FirstUpdate; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.cpp new file mode 100644 index 0000000..2ef584d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.cpp @@ -0,0 +1,51 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorDelete.h" +#include "ISceneManager.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorDelete::CSceneNodeAnimatorDelete(ISceneManager* manager, u32 time) +: ISceneNodeAnimatorFinishing(time), SceneManager(manager) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorDelete"); + #endif +} + + +//! animates a scene node +void CSceneNodeAnimatorDelete::animateNode(ISceneNode* node, u32 timeMs) +{ + if (timeMs > FinishTime) + { + HasFinished = true; + if(node && SceneManager) + { + // don't delete if scene manager is attached to an editor + if (!SceneManager->getParameters()->getAttributeAsBool(IRR_SCENE_MANAGER_IS_EDITOR)) + SceneManager->addToDeletionQueue(node); + } + } +} + + +ISceneNodeAnimator* CSceneNodeAnimatorDelete::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorDelete * newAnimator = + new CSceneNodeAnimatorDelete(SceneManager, FinishTime); + + return newAnimator; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.h new file mode 100644 index 0000000..f62848f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorDelete.h @@ -0,0 +1,46 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_DELETE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_DELETE_H_INCLUDED__ + +#include "ISceneNodeAnimatorFinishing.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorDelete : public ISceneNodeAnimatorFinishing + { + public: + + //! constructor + CSceneNodeAnimatorDelete(ISceneManager* manager, u32 when); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const + { + return ESNAT_DELETION; + } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling + this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + + ISceneManager* SceneManager; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp new file mode 100644 index 0000000..dc887fa --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorFlyCircle.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorFlyCircle::CSceneNodeAnimatorFlyCircle(u32 time, + const core::vector3df& center, f32 radius, f32 speed, + const core::vector3df& direction, f32 radiusEllipsoid) + : Center(center), Direction(direction), Radius(radius), + RadiusEllipsoid(radiusEllipsoid), Speed(speed), StartTime(time) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorFlyCircle"); + #endif + init(); +} + + +void CSceneNodeAnimatorFlyCircle::init() +{ + Direction.normalize(); + + if (Direction.Y != 0) + VecV = core::vector3df(50,0,0).crossProduct(Direction).normalize(); + else + VecV = core::vector3df(0,50,0).crossProduct(Direction).normalize(); + VecU = VecV.crossProduct(Direction).normalize(); +} + + +//! animates a scene node +void CSceneNodeAnimatorFlyCircle::animateNode(ISceneNode* node, u32 timeMs) +{ + if ( 0 == node ) + return; + + f32 time; + + // Check for the condition where the StartTime is in the future. + if(StartTime > timeMs) + time = ((s32)timeMs - (s32)StartTime) * Speed; + else + time = (timeMs-StartTime) * Speed; + +// node->setPosition(Center + Radius * ((VecU*cosf(time)) + (VecV*sinf(time)))); + f32 r2 = RadiusEllipsoid == 0.f ? Radius : RadiusEllipsoid; + node->setPosition(Center + (Radius*cosf(time)*VecU) + (r2*sinf(time)*VecV ) ); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorFlyCircle::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Center", Center); + out->addFloat("Radius", Radius); + out->addFloat("Speed", Speed); + out->addVector3d("Direction", Direction); + out->addFloat("RadiusEllipsoid", RadiusEllipsoid); +} + + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorFlyCircle::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Center = in->getAttributeAsVector3d("Center"); + Radius = in->getAttributeAsFloat("Radius"); + Speed = in->getAttributeAsFloat("Speed"); + Direction = in->getAttributeAsVector3d("Direction"); + StartTime = 0; + + if (Direction.equals(core::vector3df(0,0,0))) + Direction.set(0,1,0); // irrlicht 1.1 backwards compatibility + else + Direction.normalize(); + + RadiusEllipsoid = in->getAttributeAsFloat("RadiusEllipsoid"); + init(); +} + + +ISceneNodeAnimator* CSceneNodeAnimatorFlyCircle::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorFlyCircle * newAnimator = + new CSceneNodeAnimatorFlyCircle(StartTime, Center, Radius, Speed, Direction, RadiusEllipsoid); + + return newAnimator; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h new file mode 100644 index 0000000..c17b036 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h @@ -0,0 +1,64 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_FLY_CIRCLE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_FLY_CIRCLE_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorFlyCircle : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorFlyCircle(u32 time, + const core::vector3df& center, f32 radius, + f32 speed, const core::vector3df& direction, + f32 radiusEllipsoid); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FLY_CIRCLE; } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling + this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + // do some initial calculations + void init(); + + // circle center + core::vector3df Center; + // up-vector, normal to the circle's plane + core::vector3df Direction; + // Two helper vectors + core::vector3df VecU; + core::vector3df VecV; + f32 Radius; + f32 RadiusEllipsoid; + f32 Speed; + u32 StartTime; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp new file mode 100644 index 0000000..28730b8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp @@ -0,0 +1,112 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorFlyStraight.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorFlyStraight::CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint, + const core::vector3df& endPoint, u32 timeForWay, + bool loop, u32 now, bool pingpong) +: ISceneNodeAnimatorFinishing(now + timeForWay), + Start(startPoint), End(endPoint), TimeFactor(0.0f), StartTime(now), + TimeForWay(timeForWay), Loop(loop), PingPong(pingpong) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorFlyStraight"); + #endif + + recalculateIntermediateValues(); +} + + +void CSceneNodeAnimatorFlyStraight::recalculateIntermediateValues() +{ + Vector = End - Start; + TimeFactor = (f32)Vector.getLength() / TimeForWay; + Vector.normalize(); +} + + +//! animates a scene node +void CSceneNodeAnimatorFlyStraight::animateNode(ISceneNode* node, u32 timeMs) +{ + if (!node) + return; + + u32 t = (timeMs-StartTime); + + core::vector3df pos; + + if (!Loop && !PingPong && t >= TimeForWay) + { + pos = End; + HasFinished = true; + } + else if (!Loop && PingPong && t >= TimeForWay * 2.f ) + { + pos = Start; + HasFinished = true; + } + else + { + f32 phase = fmodf( (f32) t, (f32) TimeForWay ); + core::vector3df rel = Vector * phase * TimeFactor; + const bool pong = PingPong && fmodf( (f32) t, (f32) TimeForWay*2.f ) >= TimeForWay; + + if ( !pong ) + { + pos += Start + rel; + } + else + { + pos = End - rel; + } + } + + node->setPosition(pos); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorFlyStraight::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Start", Start); + out->addVector3d("End", End); + out->addInt("TimeForWay", TimeForWay); + out->addBool("Loop", Loop); + out->addBool("PingPong", PingPong); +} + + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorFlyStraight::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Start = in->getAttributeAsVector3d("Start"); + End = in->getAttributeAsVector3d("End"); + TimeForWay = in->getAttributeAsInt("TimeForWay"); + Loop = in->getAttributeAsBool("Loop"); + PingPong = in->getAttributeAsBool("PingPong"); + + recalculateIntermediateValues(); +} + + +ISceneNodeAnimator* CSceneNodeAnimatorFlyStraight::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorFlyStraight * newAnimator = + new CSceneNodeAnimatorFlyStraight(Start, End, TimeForWay, Loop, StartTime, PingPong); + + return newAnimator; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h new file mode 100644 index 0000000..7a7fe81 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h @@ -0,0 +1,60 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_FLY_STRAIGHT_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_FLY_STRAIGHT_H_INCLUDED__ + +#include "ISceneNodeAnimatorFinishing.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorFlyStraight : public ISceneNodeAnimatorFinishing + { + public: + + //! constructor + CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint, + const core::vector3df& endPoint, + u32 timeForWay, + bool loop, u32 now, bool pingpong); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FLY_STRAIGHT; } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + + void recalculateIntermediateValues(); + + core::vector3df Start; + core::vector3df End; + core::vector3df Vector; + f32 TimeFactor; + u32 StartTime; + u32 TimeForWay; + bool Loop; + bool PingPong; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp new file mode 100644 index 0000000..efc7493 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp @@ -0,0 +1,161 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorFollowSpline.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time, + const core::array& points, f32 speed, + f32 tightness, bool loop, bool pingpong) +: ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness), StartTime(time) +, Loop(loop), PingPong(pingpong) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorFollowSpline"); + #endif +} + + +inline s32 CSceneNodeAnimatorFollowSpline::clamp(s32 idx, s32 size) +{ + return ( idx<0 ? size+idx : ( idx>=size ? idx-size : idx ) ); +} + + +//! animates a scene node +void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs) +{ + if(!node) + return; + + const u32 pSize = Points.size(); + if (pSize==0) + { + if ( !Loop ) + HasFinished = true; + return; + } + if (pSize==1) + { + if ( timeMs > StartTime ) + { + node->setPosition(Points[0]); + if ( !Loop ) + HasFinished = true; + } + return; + } + + const f32 dt = ( (timeMs-StartTime) * Speed * 0.001f ); + const s32 unwrappedIdx = core::floor32( dt ); + if ( !Loop && unwrappedIdx >= (s32)pSize-1 ) + { + node->setPosition(Points[pSize-1]); + HasFinished = true; + return; + } + const bool pong = PingPong && (unwrappedIdx/(pSize-1))%2; + const f32 u = pong ? 1.f-core::fract ( dt ) : core::fract ( dt ); + const s32 idx = pong ? (pSize-2) - (unwrappedIdx % (pSize-1)) + : (PingPong ? unwrappedIdx % (pSize-1) + : unwrappedIdx % pSize); + //const f32 u = 0.001f * fmodf( dt, 1000.0f ); + + const core::vector3df& p0 = Points[ clamp( idx - 1, pSize ) ]; + const core::vector3df& p1 = Points[ clamp( idx + 0, pSize ) ]; // starting point + const core::vector3df& p2 = Points[ clamp( idx + 1, pSize ) ]; // end point + const core::vector3df& p3 = Points[ clamp( idx + 2, pSize ) ]; + + // hermite polynomials + const f32 h1 = 2.0f * u * u * u - 3.0f * u * u + 1.0f; + const f32 h2 = -2.0f * u * u * u + 3.0f * u * u; + const f32 h3 = u * u * u - 2.0f * u * u + u; + const f32 h4 = u * u * u - u * u; + + // tangents + const core::vector3df t1 = ( p2 - p0 ) * Tightness; + const core::vector3df t2 = ( p3 - p1 ) * Tightness; + + // interpolated point + node->setPosition(p1 * h1 + p2 * h2 + t1 * h3 + t2 * h4); +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addFloat("Speed", Speed); + out->addFloat("Tightness", Tightness); + out->addBool("Loop", Loop); + out->addBool("PingPong", PingPong); + + u32 count = Points.size(); + + if ( options && (options->Flags & io::EARWF_FOR_EDITOR)) + { + // add one point in addition when serializing for editors + // to make it easier to add points quickly + count += 1; + } + + for (u32 i=0; iaddVector3d(tname.c_str(), igetAttributeAsFloat("Speed"); + Tightness = in->getAttributeAsFloat("Tightness"); + Loop = in->getAttributeAsBool("Loop"); + PingPong = in->getAttributeAsBool("PingPong"); + Points.clear(); + + for(u32 i=1; true; ++i) + { + core::stringc pname = "Point"; + pname += i; + + if (in->existsAttribute(pname.c_str())) + Points.push_back(in->getAttributeAsVector3d(pname.c_str())); + else + break; + } + + // remove last point if double entry from editor + if ( options && (options->Flags & io::EARWF_FOR_EDITOR) && + Points.size() > 2 && Points.getLast() == core::vector3df(0,0,0)) + { + Points.erase(Points.size()-1); + + if (Points.size() > 2 && Points.getLast() == core::vector3df(0,0,0)) + Points.erase(Points.size()-1); + } +} + + +ISceneNodeAnimator* CSceneNodeAnimatorFollowSpline::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorFollowSpline * newAnimator = + new CSceneNodeAnimatorFollowSpline(StartTime, Points, Speed, Tightness); + + return newAnimator; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h new file mode 100644 index 0000000..a202328 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_FOLLOW_SPLINE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_FOLLOW_SPLINE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "irrArray.h" +#include "ISceneNodeAnimatorFinishing.h" + +namespace irr +{ +namespace scene +{ + //! Scene node animator based free code Matthias Gall wrote and sent in. (Most of + //! this code is written by him, I only modified bits.) + class CSceneNodeAnimatorFollowSpline : public ISceneNodeAnimatorFinishing + { + public: + + //! constructor + CSceneNodeAnimatorFollowSpline(u32 startTime, + const core::array< core::vector3df >& points, + f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_FOLLOW_SPLINE; } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling + this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + protected: + + //! clamps a the value idx to fit into range 0..size-1 + s32 clamp(s32 idx, s32 size); + + core::array< core::vector3df > Points; + f32 Speed; + f32 Tightness; + u32 StartTime; + bool Loop; + bool PingPong; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.cpp new file mode 100644 index 0000000..f3c5473 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.cpp @@ -0,0 +1,73 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorRotation.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorRotation::CSceneNodeAnimatorRotation(u32 time, const core::vector3df& rotation) +: Rotation(rotation), StartTime(time) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorRotation"); + #endif +} + + +//! animates a scene node +void CSceneNodeAnimatorRotation::animateNode(ISceneNode* node, u32 timeMs) +{ + if (node) // thanks to warui for this fix + { + const u32 diffTime = timeMs - StartTime; + + if (diffTime != 0) + { + // clip the rotation to small values, to avoid + // precision problems with huge floats. + core::vector3df rot = node->getRotation() + Rotation*(diffTime*0.1f); + if (rot.X>360.f) + rot.X=fmodf(rot.X, 360.f); + if (rot.Y>360.f) + rot.Y=fmodf(rot.Y, 360.f); + if (rot.Z>360.f) + rot.Z=fmodf(rot.Z, 360.f); + node->setRotation(rot); + StartTime=timeMs; + } + } +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorRotation::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addVector3d("Rotation", Rotation); +} + + +//! Reads attributes of the scene node animator. +void CSceneNodeAnimatorRotation::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + Rotation = in->getAttributeAsVector3d("Rotation"); +} + + +ISceneNodeAnimator* CSceneNodeAnimatorRotation::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorRotation * newAnimator = + new CSceneNodeAnimatorRotation(StartTime, Rotation); + + return newAnimator; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.h new file mode 100644 index 0000000..aa26c66 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorRotation.h @@ -0,0 +1,49 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_ROTATION_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_ROTATION_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorRotation : public ISceneNodeAnimator + { + public: + + //! constructor + CSceneNodeAnimatorRotation(u32 time, const core::vector3df& rotation); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_ROTATION; } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + + core::vector3df Rotation; + u32 StartTime; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.cpp new file mode 100644 index 0000000..1cedf3d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.cpp @@ -0,0 +1,140 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSceneNodeAnimatorTexture.h" +#include "ITexture.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array& textures, + s32 timePerFrame, bool loop, u32 now) +: ISceneNodeAnimatorFinishing(0), + TimePerFrame(timePerFrame), StartTime(now), Loop(loop) +{ + #ifdef _DEBUG + setDebugName("CSceneNodeAnimatorTexture"); + #endif + + for (u32 i=0; igrab(); + + Textures.push_back(textures[i]); + } + + FinishTime = now + (timePerFrame * Textures.size()); +} + + +//! destructor +CSceneNodeAnimatorTexture::~CSceneNodeAnimatorTexture() +{ + clearTextures(); +} + + +void CSceneNodeAnimatorTexture::clearTextures() +{ + for (u32 i=0; idrop(); +} + + +//! animates a scene node +void CSceneNodeAnimatorTexture::animateNode(ISceneNode* node, u32 timeMs) +{ + if(!node) + return; + + if (Textures.size()) + { + const u32 t = (timeMs-StartTime); + + u32 idx = 0; + if (!Loop && timeMs >= FinishTime) + { + idx = Textures.size() - 1; + HasFinished = true; + } + else + { + idx = (t/TimePerFrame) % Textures.size(); + } + + if (idx < Textures.size()) + node->setMaterialTexture(0, Textures[idx]); + } +} + + +//! Writes attributes of the scene node animator. +void CSceneNodeAnimatorTexture::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addInt("TimePerFrame", TimePerFrame); + out->addBool("Loop", Loop); + + // add one texture in addition when serializing for editors + // to make it easier to add textures quickly + + u32 count = Textures.size(); + if ( options && (options->Flags & io::EARWF_FOR_EDITOR)) + count += 1; + + for (u32 i=0; iaddTexture(tname.c_str(), igetAttributeAsInt("TimePerFrame"); + Loop = in->getAttributeAsBool("Loop"); + + clearTextures(); + + for(u32 i=1; true; ++i) + { + core::stringc tname = "Texture"; + tname += (int)i; + + if (in->existsAttribute(tname.c_str())) + { + video::ITexture* tex = in->getAttributeAsTexture(tname.c_str()); + if (tex) + { + tex->grab(); + Textures.push_back(tex); + } + } + else + break; + } +} + + +ISceneNodeAnimator* CSceneNodeAnimatorTexture::createClone(ISceneNode* node, ISceneManager* newManager) +{ + CSceneNodeAnimatorTexture * newAnimator = + new CSceneNodeAnimatorTexture(Textures, TimePerFrame, Loop, StartTime); + + return newAnimator; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.h new file mode 100644 index 0000000..a27eef0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSceneNodeAnimatorTexture.h @@ -0,0 +1,59 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SCENE_NODE_ANIMATOR_TEXTURE_H_INCLUDED__ +#define __C_SCENE_NODE_ANIMATOR_TEXTURE_H_INCLUDED__ + +#include "irrArray.h" +#include "ISceneNodeAnimatorFinishing.h" + +namespace irr +{ +namespace scene +{ + class CSceneNodeAnimatorTexture : public ISceneNodeAnimatorFinishing + { + public: + + //! constructor + CSceneNodeAnimatorTexture(const core::array& textures, + s32 timePerFrame, bool loop, u32 now); + + //! destructor + virtual ~CSceneNodeAnimatorTexture(); + + //! animates a scene node + virtual void animateNode(ISceneNode* node, u32 timeMs); + + //! Writes attributes of the scene node animator. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node animator. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Returns type of the scene node animator + virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_TEXTURE; } + + //! Creates a clone of this animator. + /** Please note that you will have to drop + (IReferenceCounted::drop()) the returned pointer after calling + this. */ + virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0); + + private: + + void clearTextures(); + + core::array Textures; + u32 TimePerFrame; + u32 StartTime; + bool Loop; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.cpp new file mode 100644 index 0000000..55c802a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.cpp @@ -0,0 +1,419 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CShadowVolumeSceneNode.h" +#include "ISceneManager.h" +#include "IMesh.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" +#include "SLight.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CShadowVolumeSceneNode::CShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, + ISceneManager* mgr, s32 id, bool zfailmethod, f32 infinity) +: IShadowVolumeSceneNode(parent, mgr, id), + ShadowMesh(0), IndexCount(0), VertexCount(0), ShadowVolumesUsed(0), + Infinity(infinity), UseZFailMethod(zfailmethod) +{ + #ifdef _DEBUG + setDebugName("CShadowVolumeSceneNode"); + #endif + setShadowMesh(shadowMesh); + setAutomaticCulling(scene::EAC_OFF); +} + + +//! destructor +CShadowVolumeSceneNode::~CShadowVolumeSceneNode() +{ + if (ShadowMesh) + ShadowMesh->drop(); +} + + +void CShadowVolumeSceneNode::createShadowVolume(const core::vector3df& light, bool isDirectional) +{ + SShadowVolume* svp = 0; + core::aabbox3d* bb = 0; + + // builds the shadow volume and adds it to the shadow volume list. + + if (ShadowVolumes.size() > ShadowVolumesUsed) + { + // get the next unused buffer + + svp = &ShadowVolumes[ShadowVolumesUsed]; + svp->set_used(0); + + bb = &ShadowBBox[ShadowVolumesUsed]; + } + else + { + ShadowVolumes.push_back(SShadowVolume()); + svp = &ShadowVolumes.getLast(); + + ShadowBBox.push_back(core::aabbox3d()); + bb = &ShadowBBox.getLast(); + } + svp->reallocate(IndexCount*5); + ++ShadowVolumesUsed; + + // We use triangle lists + Edges.set_used(IndexCount*2); + u32 numEdges = 0; + + numEdges=createEdgesAndCaps(light, svp, bb); + + // for all edges add the near->far quads + for (u32 i=0; isize() >= svp->allocated_size()-5) + os::Printer::log("Allocation too small.", ELL_DEBUG); +#endif + svp->push_back(v1); + svp->push_back(v2); + svp->push_back(v3); + + svp->push_back(v2); + svp->push_back(v4); + svp->push_back(v3); + } +} + + +#define IRR_USE_ADJACENCY +#define IRR_USE_REVERSE_EXTRUDED + +u32 CShadowVolumeSceneNode::createEdgesAndCaps(const core::vector3df& light, + SShadowVolume* svp, core::aabbox3d* bb) +{ + u32 numEdges=0; + const u32 faceCount = IndexCount / 3; + + if(faceCount >= 1) + bb->reset(Vertices[Indices[0]]); + else + bb->reset(0,0,0); + + // Check every face if it is front or back facing the light. + for (u32 i=0; isize() >= svp->allocated_size()-5) + os::Printer::log("Allocation too small.", ELL_DEBUG); +#endif + // add front cap from light-facing faces + svp->push_back(v2); + svp->push_back(v1); + svp->push_back(v0); + + // add back cap + const core::vector3df i0 = v0+(v0-light).normalize()*Infinity; + const core::vector3df i1 = v1+(v1-light).normalize()*Infinity; + const core::vector3df i2 = v2+(v2-light).normalize()*Infinity; + + svp->push_back(i0); + svp->push_back(i1); + svp->push_back(i2); + + bb->addInternalPoint(i0); + bb->addInternalPoint(i1); + bb->addInternalPoint(i2); + } + } + + // Create edges + for (u32 i=0; idrop(); + ShadowMesh = mesh; + if (ShadowMesh) + { + ShadowMesh->grab(); + Box = ShadowMesh->getBoundingBox(); + } +} + + +void CShadowVolumeSceneNode::updateShadowVolumes() +{ + const u32 oldIndexCount = IndexCount; + const u32 oldVertexCount = VertexCount; + + const IMesh* const mesh = ShadowMesh; + if (!mesh) + return; + + // create as much shadow volumes as there are lights but + // do not ignore the max light settings. + const u32 lightCount = SceneManager->getVideoDriver()->getDynamicLightCount(); + if (!lightCount) + return; + + // calculate total amount of vertices and indices + + VertexCount = 0; + IndexCount = 0; + ShadowVolumesUsed = 0; + + u32 i; + u32 totalVertices = 0; + u32 totalIndices = 0; + const u32 bufcnt = mesh->getMeshBufferCount(); + + for (i=0; igetMeshBuffer(i); + totalIndices += buf->getIndexCount(); + totalVertices += buf->getVertexCount(); + } + + // allocate memory if necessary + + Vertices.set_used(totalVertices); + Indices.set_used(totalIndices); + FaceData.set_used(totalIndices / 3); + + // copy mesh + for (i=0; igetMeshBuffer(i); + + const u16* idxp = buf->getIndices(); + const u16* idxpend = idxp + buf->getIndexCount(); + for (; idxp!=idxpend; ++idxp) + Indices[IndexCount++] = *idxp + VertexCount; + + const u32 vtxcnt = buf->getVertexCount(); + for (u32 j=0; jgetPosition(j); + } + + // recalculate adjacency if necessary + if (oldVertexCount != VertexCount || oldIndexCount != IndexCount) + calculateAdjacency(); + + core::matrix4 mat = Parent->getAbsoluteTransformation(); + mat.makeInverse(); + const core::vector3df parentpos = Parent->getAbsolutePosition(); + + // TODO: Only correct for point lights. + for (i=0; igetVideoDriver()->getDynamicLight(i); + core::vector3df lpos = dl.Position; + if (dl.CastShadows && + fabs((lpos - parentpos).getLengthSQ()) <= (dl.Radius*dl.Radius*4.0f)) + { + mat.transformVect(lpos); + createShadowVolume(lpos); + } + } +} + + +//! pre render method +void CShadowVolumeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, scene::ESNRP_SHADOW); + ISceneNode::OnRegisterSceneNode(); + } +} + +//! renders the node. +void CShadowVolumeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (!ShadowVolumesUsed || !driver) + return; + + driver->setTransform(video::ETS_WORLD, Parent->getAbsoluteTransformation()); + + for (u32 i=0; igetActiveCamera()) + { + // Disable shadows drawing, when back cap is behind of ZFar plane. + + SViewFrustum frust = *SceneManager->getActiveCamera()->getViewFrustum(); + + core::matrix4 invTrans(Parent->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE); + frust.transform(invTrans); + + core::vector3df edges[8]; + ShadowBBox[i].getEdges(edges); + + core::vector3df largestEdge = edges[0]; + f32 maxDistance = core::vector3df(SceneManager->getActiveCamera()->getPosition() - edges[0]).getLength(); + f32 curDistance = 0.f; + + for(int j = 1; j < 8; ++j) + { + curDistance = core::vector3df(SceneManager->getActiveCamera()->getPosition() - edges[j]).getLength(); + + if(curDistance > maxDistance) + { + maxDistance = curDistance; + largestEdge = edges[j]; + } + } + + if (!(frust.planes[scene::SViewFrustum::VF_FAR_PLANE].classifyPointRelation(largestEdge) != core::ISREL3D_FRONT)) + drawShadow = false; + } + + if(drawShadow) + driver->drawStencilShadowVolume(ShadowVolumes[i], UseZFailMethod, DebugDataVisible); + else + { + core::array triangles; + driver->drawStencilShadowVolume(triangles, UseZFailMethod, DebugDataVisible); + } + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CShadowVolumeSceneNode::getBoundingBox() const +{ + return Box; +} + + +//! Generates adjacency information based on mesh indices. +void CShadowVolumeSceneNode::calculateAdjacency() +{ + Adjacency.set_used(IndexCount); + + // go through all faces and fetch their three neighbours + for (u32 f=0; f store face number, else store adjacent face + if (of >= IndexCount) + Adjacency[f + edge] = f/3; + else + Adjacency[f + edge] = of/3; + } + } +} + + +} // end namespace scene +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.h new file mode 100644 index 0000000..c66b8f9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CShadowVolumeSceneNode.h @@ -0,0 +1,87 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__ +#define __C_SHADOW_VOLUME_SCENE_NODE_H_INCLUDED__ + +#include "IShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + + //! Scene node for rendering a shadow volume into a stencil buffer. + class CShadowVolumeSceneNode : public IShadowVolumeSceneNode + { + public: + + //! constructor + CShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, ISceneManager* mgr, + s32 id, bool zfailmethod=true, f32 infinity=10000.0f); + + //! destructor + virtual ~CShadowVolumeSceneNode(); + + //! Sets the mesh from which the shadow volume should be generated. + /** To optimize shadow rendering, use a simpler mesh for shadows. + */ + virtual void setShadowMesh(const IMesh* mesh); + + //! Updates the shadow volumes for current light positions. + /** Called each render cycle from Animated Mesh SceneNode render method. */ + virtual void updateShadowVolumes(); + + //! pre render method + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SHADOW_VOLUME; } + + private: + + typedef core::array SShadowVolume; + + void createShadowVolume(const core::vector3df& pos, bool isDirectional=false); + u32 createEdgesAndCaps(const core::vector3df& light, SShadowVolume* svp, core::aabbox3d* bb); + + //! Generates adjacency information based on mesh indices. + void calculateAdjacency(); + + core::aabbox3d Box; + + // a shadow volume for every light + core::array ShadowVolumes; + + // a back cap bounding box for every light + core::array > ShadowBBox; + + core::array Vertices; + core::array Indices; + core::array Adjacency; + core::array Edges; + // tells if face is front facing + core::array FaceData; + + const scene::IMesh* ShadowMesh; + + u32 IndexCount; + u32 VertexCount; + u32 ShadowVolumesUsed; + + f32 Infinity; + + bool UseZFailMethod; + }; + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkinnedMesh.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkinnedMesh.cpp new file mode 100644 index 0000000..e1ab5a5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkinnedMesh.cpp @@ -0,0 +1,1471 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ + +#include "CSkinnedMesh.h" +#include "CBoneSceneNode.h" +#include "IAnimatedMeshSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CSkinnedMesh::CSkinnedMesh() +: SkinningBuffers(0), AnimationFrames(0.f), FramesPerSecond(25.f), + LastAnimatedFrame(-1), SkinnedLastFrame(false), + InterpolationMode(EIM_LINEAR), + HasAnimation(false), PreparedForSkinning(false), + AnimateNormals(true), HardwareSkinning(false) +{ + #ifdef _DEBUG + setDebugName("CSkinnedMesh"); + #endif + + SkinningBuffers=&LocalBuffers; +} + + +//! destructor +CSkinnedMesh::~CSkinnedMesh() +{ + for (u32 i=0; idrop(); + } +} + + +//! returns the amount of frames in milliseconds. +//! If the amount is 1, it is a static (=non animated) mesh. +u32 CSkinnedMesh::getFrameCount() const +{ + return core::floor32(AnimationFrames); +} + + +//! Gets the default animation speed of the animated mesh. +/** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ +f32 CSkinnedMesh::getAnimationSpeed() const +{ + return FramesPerSecond; +} + + +//! Gets the frame count of the animated mesh. +/** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. +The actual speed is set in the scene node the mesh is instantiated in.*/ +void CSkinnedMesh::setAnimationSpeed(f32 fps) +{ + FramesPerSecond=fps; +} + + +//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. +IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) +{ + //animate(frame,startFrameLoop, endFrameLoop); + if (frame==-1) + return this; + + animateMesh((f32)frame, 1.0f); + skinMesh(); + return this; +} + + +//-------------------------------------------------------------------------- +// Keyframe Animation +//-------------------------------------------------------------------------- + + +//! Animates this mesh's joints based on frame input +//! blend: {0-old position, 1-New position} +void CSkinnedMesh::animateMesh(f32 frame, f32 blend) +{ + if (!HasAnimation || LastAnimatedFrame==frame) + return; + + LastAnimatedFrame=frame; + SkinnedLastFrame=false; + + if (blend<=0.f) + return; //No need to animate + + for (u32 i=0; iAnimatedposition; + const core::vector3df oldScale = joint->Animatedscale; + const core::quaternion oldRotation = joint->Animatedrotation; + + core::vector3df position = oldPosition; + core::vector3df scale = oldScale; + core::quaternion rotation = oldRotation; + + getFrameData(frame, joint, + position, joint->positionHint, + scale, joint->scaleHint, + rotation, joint->rotationHint); + + if (blend==1.0f) + { + //No blending needed + joint->Animatedposition = position; + joint->Animatedscale = scale; + joint->Animatedrotation = rotation; + } + else + { + //Blend animation + joint->Animatedposition = core::lerp(oldPosition, position, blend); + joint->Animatedscale = core::lerp(oldScale, scale, blend); + joint->Animatedrotation.slerp(oldRotation, rotation, blend); + } + } + + //Note: + //LocalAnimatedMatrix needs to be built at some point, but this function may be called lots of times for + //one render (to play two animations at the same time) LocalAnimatedMatrix only needs to be built once. + //a call to buildAllLocalAnimatedMatrices is needed before skinning the mesh, and before the user gets the joints to move + + //---------------- + // Temp! + buildAllLocalAnimatedMatrices(); + //----------------- + + updateBoundingBox(); +} + + +void CSkinnedMesh::buildAllLocalAnimatedMatrices() +{ + for (u32 i=0; iUseAnimationFrom && + (joint->UseAnimationFrom->PositionKeys.size() || + joint->UseAnimationFrom->ScaleKeys.size() || + joint->UseAnimationFrom->RotationKeys.size() )) + { + joint->GlobalSkinningSpace=false; + + // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched to getMatrix_transposed instead of getMatrix for downward compatibility. + // Not tested so far if this was correct or wrong before quaternion fix! + joint->Animatedrotation.getMatrix_transposed(joint->LocalAnimatedMatrix); + + // --- joint->LocalAnimatedMatrix *= joint->Animatedrotation.getMatrix() --- + f32 *m1 = joint->LocalAnimatedMatrix.pointer(); + core::vector3df &Pos = joint->Animatedposition; + m1[0] += Pos.X*m1[3]; + m1[1] += Pos.Y*m1[3]; + m1[2] += Pos.Z*m1[3]; + m1[4] += Pos.X*m1[7]; + m1[5] += Pos.Y*m1[7]; + m1[6] += Pos.Z*m1[7]; + m1[8] += Pos.X*m1[11]; + m1[9] += Pos.Y*m1[11]; + m1[10] += Pos.Z*m1[11]; + m1[12] += Pos.X*m1[15]; + m1[13] += Pos.Y*m1[15]; + m1[14] += Pos.Z*m1[15]; + // ----------------------------------- + + if (joint->ScaleKeys.size()) + { + /* + core::matrix4 scaleMatrix; + scaleMatrix.setScale(joint->Animatedscale); + joint->LocalAnimatedMatrix *= scaleMatrix; + */ + + // -------- joint->LocalAnimatedMatrix *= scaleMatrix ----------------- + core::matrix4& mat = joint->LocalAnimatedMatrix; + mat[0] *= joint->Animatedscale.X; + mat[1] *= joint->Animatedscale.X; + mat[2] *= joint->Animatedscale.X; + mat[3] *= joint->Animatedscale.X; + mat[4] *= joint->Animatedscale.Y; + mat[5] *= joint->Animatedscale.Y; + mat[6] *= joint->Animatedscale.Y; + mat[7] *= joint->Animatedscale.Y; + mat[8] *= joint->Animatedscale.Z; + mat[9] *= joint->Animatedscale.Z; + mat[10] *= joint->Animatedscale.Z; + mat[11] *= joint->Animatedscale.Z; + // ----------------------------------- + } + } + else + { + joint->LocalAnimatedMatrix=joint->LocalMatrix; + } + } + SkinnedLastFrame=false; +} + + +void CSkinnedMesh::buildAllGlobalAnimatedMatrices(SJoint *joint, SJoint *parentJoint) +{ + if (!joint) + { + for (u32 i=0; iGlobalSkinningSpace) + joint->GlobalAnimatedMatrix = joint->LocalAnimatedMatrix; + else + joint->GlobalAnimatedMatrix = parentJoint->GlobalAnimatedMatrix * joint->LocalAnimatedMatrix; + } + + for (u32 j=0; jChildren.size(); ++j) + buildAllGlobalAnimatedMatrices(joint->Children[j], joint); +} + + +void CSkinnedMesh::getFrameData(f32 frame, SJoint *joint, + core::vector3df &position, s32 &positionHint, + core::vector3df &scale, s32 &scaleHint, + core::quaternion &rotation, s32 &rotationHint) +{ + s32 foundPositionIndex = -1; + s32 foundScaleIndex = -1; + s32 foundRotationIndex = -1; + + if (joint->UseAnimationFrom) + { + const core::array &PositionKeys=joint->UseAnimationFrom->PositionKeys; + const core::array &ScaleKeys=joint->UseAnimationFrom->ScaleKeys; + const core::array &RotationKeys=joint->UseAnimationFrom->RotationKeys; + + if (PositionKeys.size()) + { + foundPositionIndex = -1; + + //Test the Hints... + if (positionHint>=0 && (u32)positionHint < PositionKeys.size()) + { + //check this hint + if (positionHint>0 && PositionKeys[positionHint].frame>=frame && PositionKeys[positionHint-1].frame=frame && + PositionKeys[positionHint+0].frame= frame) //Keys should to be sorted by frame + { + foundPositionIndex=i; + positionHint=i; + break; + } + } + } + + //Do interpolation... + if (foundPositionIndex!=-1) + { + if (InterpolationMode==EIM_CONSTANT || foundPositionIndex==0) + { + position = PositionKeys[foundPositionIndex].position; + } + else if (InterpolationMode==EIM_LINEAR) + { + const SPositionKey& KeyA = PositionKeys[foundPositionIndex]; + const SPositionKey& KeyB = PositionKeys[foundPositionIndex-1]; + + const f32 fd1 = frame - KeyA.frame; + const f32 fd2 = KeyB.frame - frame; + position = ((KeyB.position-KeyA.position)/(fd1+fd2))*fd1 + KeyA.position; + } + } + } + + //------------------------------------------------------------ + + if (ScaleKeys.size()) + { + foundScaleIndex = -1; + + //Test the Hints... + if (scaleHint>=0 && (u32)scaleHint < ScaleKeys.size()) + { + //check this hint + if (scaleHint>0 && ScaleKeys[scaleHint].frame>=frame && ScaleKeys[scaleHint-1].frame=frame && + ScaleKeys[scaleHint+0].frame= frame) //Keys should to be sorted by frame + { + foundScaleIndex=i; + scaleHint=i; + break; + } + } + } + + //Do interpolation... + if (foundScaleIndex!=-1) + { + if (InterpolationMode==EIM_CONSTANT || foundScaleIndex==0) + { + scale = ScaleKeys[foundScaleIndex].scale; + } + else if (InterpolationMode==EIM_LINEAR) + { + const SScaleKey& KeyA = ScaleKeys[foundScaleIndex]; + const SScaleKey& KeyB = ScaleKeys[foundScaleIndex-1]; + + const f32 fd1 = frame - KeyA.frame; + const f32 fd2 = KeyB.frame - frame; + scale = ((KeyB.scale-KeyA.scale)/(fd1+fd2))*fd1 + KeyA.scale; + } + } + } + + //------------------------------------------------------------- + + if (RotationKeys.size()) + { + foundRotationIndex = -1; + + //Test the Hints... + if (rotationHint>=0 && (u32)rotationHint < RotationKeys.size()) + { + //check this hint + if (rotationHint>0 && RotationKeys[rotationHint].frame>=frame && RotationKeys[rotationHint-1].frame=frame && + RotationKeys[rotationHint+0].frame= frame) //Keys should be sorted by frame + { + foundRotationIndex=i; + rotationHint=i; + break; + } + } + } + + //Do interpolation... + if (foundRotationIndex!=-1) + { + if (InterpolationMode==EIM_CONSTANT || foundRotationIndex==0) + { + rotation = RotationKeys[foundRotationIndex].rotation; + } + else if (InterpolationMode==EIM_LINEAR) + { + const SRotationKey& KeyA = RotationKeys[foundRotationIndex]; + const SRotationKey& KeyB = RotationKeys[foundRotationIndex-1]; + + const f32 fd1 = frame - KeyA.frame; + const f32 fd2 = KeyB.frame - frame; + const f32 t = fd1/(fd1+fd2); + + /* + f32 t = 0; + if (KeyA.frame!=KeyB.frame) + t = (frame-KeyA.frame) / (KeyB.frame - KeyA.frame); + */ + + rotation.slerp(KeyA.rotation, KeyB.rotation, t); + } + } + } + } +} + +//-------------------------------------------------------------------------- +// Software Skinning +//-------------------------------------------------------------------------- + +//! Preforms a software skin on this mesh based of joint positions +void CSkinnedMesh::skinMesh() +{ + if (!HasAnimation || SkinnedLastFrame) + return; + + //---------------- + // This is marked as "Temp!". A shiny dubloon to whomever can tell me why. + buildAllGlobalAnimatedMatrices(); + //----------------- + + SkinnedLastFrame=true; + if (!HardwareSkinning) + { + //Software skin.... + u32 i; + + //rigid animation + for (i=0; iAttachedMeshes.size(); ++j) + { + SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ]; + Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix; + } + } + + //clear skinning helper array + for (i=0; isize(); ++i) + (*SkinningBuffers)[i]->setDirty(EBT_VERTEX); + } + updateBoundingBox(); +} + + +void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint) +{ + if (joint->Weights.size()) + { + //Find this joints pull on vertices... + core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING); + jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix); + + core::vector3df thisVertexMove, thisNormalMove; + + core::array &buffersUsed=*SkinningBuffers; + + //Skin Vertices Positions and Normals... + for (u32 i=0; iWeights.size(); ++i) + { + SWeight& weight = joint->Weights[i]; + + // Pull this vertex... + jointVertexPull.transformVect(thisVertexMove, weight.StaticPos); + + if (AnimateNormals) + jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal); + + if (! (*(weight.Moved)) ) + { + *(weight.Moved) = true; + + buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = thisVertexMove * weight.strength; + + if (AnimateNormals) + buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal = thisNormalMove * weight.strength; + + //*(weight._Pos) = thisVertexMove * weight.strength; + } + else + { + buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos += thisVertexMove * weight.strength; + + if (AnimateNormals) + buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal += thisNormalMove * weight.strength; + + //*(weight._Pos) += thisVertexMove * weight.strength; + } + + buffersUsed[weight.buffer_id]->boundingBoxNeedsRecalculated(); + } + } + + //Skin all children + for (u32 j=0; jChildren.size(); ++j) + skinJoint(joint->Children[j], joint); +} + + +E_ANIMATED_MESH_TYPE CSkinnedMesh::getMeshType() const +{ + return EAMT_SKINNED; +} + + +//! Gets joint count. +u32 CSkinnedMesh::getJointCount() const +{ + return AllJoints.size(); +} + + +//! Gets the name of a joint. +const c8* CSkinnedMesh::getJointName(u32 number) const +{ + if (number >= AllJoints.size()) + return 0; + return AllJoints[number]->Name.c_str(); +} + + +//! Gets a joint number from its name +s32 CSkinnedMesh::getJointNumber(const c8* name) const +{ + for (u32 i=0; iName == name) + return i; + } + + return -1; +} + + +//! returns amount of mesh buffers. +u32 CSkinnedMesh::getMeshBufferCount() const +{ + return LocalBuffers.size(); +} + + +//! returns pointer to a mesh buffer +IMeshBuffer* CSkinnedMesh::getMeshBuffer(u32 nr) const +{ + if (nr < LocalBuffers.size()) + return LocalBuffers[nr]; + else + return 0; +} + + +//! Returns pointer to a mesh buffer which fits a material +IMeshBuffer* CSkinnedMesh::getMeshBuffer(const video::SMaterial &material) const +{ + for (u32 i=0; igetMaterial() == material) + return LocalBuffers[i]; + } + return 0; +} + + +//! returns an axis aligned bounding box +const core::aabbox3d& CSkinnedMesh::getBoundingBox() const +{ + return BoundingBox; +} + + +//! set user axis aligned bounding box +void CSkinnedMesh::setBoundingBox( const core::aabbox3df& box) +{ + BoundingBox = box; +} + + +//! sets a flag of all contained materials to a new value +void CSkinnedMesh::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) +{ + for (u32 i=0; iMaterial.setFlag(flag,newvalue); +} + + +//! set the hardware mapping hint, for driver +void CSkinnedMesh::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, + E_BUFFER_TYPE buffer) +{ + for (u32 i=0; isetHardwareMappingHint(newMappingHint, buffer); +} + + +//! flags the meshbuffer as changed, reloads hardware buffers +void CSkinnedMesh::setDirty(E_BUFFER_TYPE buffer) +{ + for (u32 i=0; isetDirty(buffer); +} + + +//! uses animation from another mesh +bool CSkinnedMesh::useAnimationFrom(const ISkinnedMesh *mesh) +{ + bool unmatched=false; + + for(u32 i=0;iUseAnimationFrom=0; + + if (joint->Name=="") + unmatched=true; + else + { + for(u32 j=0;jgetAllJoints().size();++j) + { + SJoint *otherJoint=mesh->getAllJoints()[j]; + if (joint->Name==otherJoint->Name) + { + joint->UseAnimationFrom=otherJoint; + } + } + if (!joint->UseAnimationFrom) + unmatched=true; + } + } + + checkForAnimation(); + + return !unmatched; +} + + +//!Update Normals when Animating +//!False= Don't animate them, faster +//!True= Update normals (default) +void CSkinnedMesh::updateNormalsWhenAnimating(bool on) +{ + AnimateNormals = on; +} + + +//!Sets Interpolation Mode +void CSkinnedMesh::setInterpolationMode(E_INTERPOLATION_MODE mode) +{ + InterpolationMode = mode; +} + + +core::array &CSkinnedMesh::getMeshBuffers() +{ + return LocalBuffers; +} + + +core::array &CSkinnedMesh::getAllJoints() +{ + return AllJoints; +} + + +const core::array &CSkinnedMesh::getAllJoints() const +{ + return AllJoints; +} + + +//! (This feature is not implementated in irrlicht yet) +bool CSkinnedMesh::setHardwareSkinning(bool on) +{ + if (HardwareSkinning!=on) + { + if (on) + { + + //set mesh to static pose... + for (u32 i=0; iWeights.size(); ++j) + { + const u16 buffer_id=joint->Weights[j].buffer_id; + const u32 vertex_id=joint->Weights[j].vertex_id; + LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos; + LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal; + LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated(); + } + } + } + + HardwareSkinning=on; + } + return HardwareSkinning; +} + + +void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint) +{ + if (!joint && parentJoint) // bit of protection from endless loops + return; + + //Go through the root bones + if (!joint) + { + for (u32 i=0; iGlobalMatrix = joint->LocalMatrix; + else + joint->GlobalMatrix = parentJoint->GlobalMatrix * joint->LocalMatrix; + + joint->LocalAnimatedMatrix=joint->LocalMatrix; + joint->GlobalAnimatedMatrix=joint->GlobalMatrix; + + if (joint->GlobalInversedMatrix.isIdentity())//might be pre calculated + { + joint->GlobalInversedMatrix = joint->GlobalMatrix; + joint->GlobalInversedMatrix.makeInverse(); // slow + } + + for (u32 j=0; jChildren.size(); ++j) + calculateGlobalMatrices(joint->Children[j],joint); + SkinnedLastFrame=false; +} + + +void CSkinnedMesh::checkForAnimation() +{ + u32 i,j; + //Check for animation... + HasAnimation = false; + for(i=0;iUseAnimationFrom) + { + if (AllJoints[i]->UseAnimationFrom->PositionKeys.size() || + AllJoints[i]->UseAnimationFrom->ScaleKeys.size() || + AllJoints[i]->UseAnimationFrom->RotationKeys.size() ) + { + HasAnimation = true; + } + } + } + + //meshes with weights, are still counted as animated for ragdolls, etc + if (!HasAnimation) + { + for(i=0;iWeights.size()) + HasAnimation = true; + } + } + + if (HasAnimation) + { + //--- Find the length of the animation --- + AnimationFrames=0; + for(i=0;iUseAnimationFrom) + { + if (AllJoints[i]->UseAnimationFrom->PositionKeys.size()) + if (AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame > AnimationFrames) + AnimationFrames=AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame; + + if (AllJoints[i]->UseAnimationFrom->ScaleKeys.size()) + if (AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame > AnimationFrames) + AnimationFrames=AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame; + + if (AllJoints[i]->UseAnimationFrom->RotationKeys.size()) + if (AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame > AnimationFrames) + AnimationFrames=AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame; + } + } + } + + if (HasAnimation && !PreparedForSkinning) + { + PreparedForSkinning=true; + + //check for bugs: + for(i=0; i < AllJoints.size(); ++i) + { + SJoint *joint = AllJoints[i]; + for (j=0; jWeights.size(); ++j) + { + const u16 buffer_id=joint->Weights[j].buffer_id; + const u32 vertex_id=joint->Weights[j].vertex_id; + + //check for invalid ids + if (buffer_id>=LocalBuffers.size()) + { + os::Printer::log("Skinned Mesh: Weight buffer id too large", ELL_WARNING); + joint->Weights[j].buffer_id = joint->Weights[j].vertex_id =0; + } + else if (vertex_id>=LocalBuffers[buffer_id]->getVertexCount()) + { + os::Printer::log("Skinned Mesh: Weight vertex id too large", ELL_WARNING); + joint->Weights[j].buffer_id = joint->Weights[j].vertex_id =0; + } + } + } + + //An array used in skinning + + for (i=0; iWeights.size(); ++j) + { + const u16 buffer_id=joint->Weights[j].buffer_id; + const u32 vertex_id=joint->Weights[j].vertex_id; + + joint->Weights[j].Moved = &Vertices_Moved[buffer_id] [vertex_id]; + joint->Weights[j].StaticPos = LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos; + joint->Weights[j].StaticNormal = LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal; + + //joint->Weights[j]._Pos=&Buffers[buffer_id]->getVertex(vertex_id)->Pos; + } + } + + // normalize weights + normalizeWeights(); + } + SkinnedLastFrame=false; +} + + +//! called by loader after populating with mesh and bone data +void CSkinnedMesh::finalize() +{ + u32 i; + + // Make sure we recalc the next frame + LastAnimatedFrame=-1; + SkinnedLastFrame=false; + + //calculate bounding box + for (i=0; irecalculateBoundingBox(); + } + + if (AllJoints.size() || RootJoints.size()) + { + // populate AllJoints or RootJoints, depending on which is empty + if (!RootJoints.size()) + { + + for(u32 CheckingIdx=0; CheckingIdx < AllJoints.size(); ++CheckingIdx) + { + + bool foundParent=false; + for(i=0; i < AllJoints.size(); ++i) + { + for(u32 n=0; n < AllJoints[i]->Children.size(); ++n) + { + if (AllJoints[i]->Children[n] == AllJoints[CheckingIdx]) + foundParent=true; + } + } + + if (!foundParent) + RootJoints.push_back(AllJoints[CheckingIdx]); + } + } + else + { + AllJoints=RootJoints; + } + } + + for(i=0; i < AllJoints.size(); ++i) + { + AllJoints[i]->UseAnimationFrom=AllJoints[i]; + } + + //Set array sizes... + + for (i=0; i() ); + Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount()); + } + + //Todo: optimise keys here... + + checkForAnimation(); + + if (HasAnimation) + { + //--- optimize and check keyframes --- + for(i=0;i &PositionKeys =AllJoints[i]->PositionKeys; + core::array &ScaleKeys = AllJoints[i]->ScaleKeys; + core::array &RotationKeys = AllJoints[i]->RotationKeys; + + if (PositionKeys.size()>2) + { + for(u32 j=0;j1) + { + for(u32 j=0;j= PositionKeys[j+1].frame) //bad frame, unneed and may cause problems + { + PositionKeys.erase(j+1); + --j; + } + } + } + + if (ScaleKeys.size()>2) + { + for(u32 j=0;j1) + { + for(u32 j=0;j= ScaleKeys[j+1].frame) //bad frame, unneed and may cause problems + { + ScaleKeys.erase(j+1); + --j; + } + } + } + + if (RotationKeys.size()>2) + { + for(u32 j=0;j1) + { + for(u32 j=0;j= RotationKeys[j+1].frame) //bad frame, unneed and may cause problems + { + RotationKeys.erase(j+1); + --j; + } + } + } + + + //Fill empty keyframe areas + if (PositionKeys.size()) + { + SPositionKey *Key; + Key=&PositionKeys[0];//getFirst + if (Key->frame!=0) + { + PositionKeys.push_front(*Key); + Key=&PositionKeys[0];//getFirst + Key->frame=0; + } + + Key=&PositionKeys.getLast(); + if (Key->frame!=AnimationFrames) + { + PositionKeys.push_back(*Key); + Key=&PositionKeys.getLast(); + Key->frame=AnimationFrames; + } + } + + if (ScaleKeys.size()) + { + SScaleKey *Key; + Key=&ScaleKeys[0];//getFirst + if (Key->frame!=0) + { + ScaleKeys.push_front(*Key); + Key=&ScaleKeys[0];//getFirst + Key->frame=0; + } + + Key=&ScaleKeys.getLast(); + if (Key->frame!=AnimationFrames) + { + ScaleKeys.push_back(*Key); + Key=&ScaleKeys.getLast(); + Key->frame=AnimationFrames; + } + } + + if (RotationKeys.size()) + { + SRotationKey *Key; + Key=&RotationKeys[0];//getFirst + if (Key->frame!=0) + { + RotationKeys.push_front(*Key); + Key=&RotationKeys[0];//getFirst + Key->frame=0; + } + + Key=&RotationKeys.getLast(); + if (Key->frame!=AnimationFrames) + { + RotationKeys.push_back(*Key); + Key=&RotationKeys.getLast(); + Key->frame=AnimationFrames; + } + } + } + } + + //Needed for animation and skinning... + + calculateGlobalMatrices(0,0); + + //animateMesh(0, 1); + //buildAllLocalAnimatedMatrices(); + //buildAllGlobalAnimatedMatrices(); + + //rigid animation for non animated meshes + for (i=0; iAttachedMeshes.size(); ++j) + { + SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ]; + Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix; + } + } + + //calculate bounding box + if (LocalBuffers.empty()) + BoundingBox.reset(0,0,0); + else + { + irr::core::aabbox3df bb(LocalBuffers[0]->BoundingBox); + LocalBuffers[0]->Transformation.transformBoxEx(bb); + BoundingBox.reset(bb); + + for (u32 j=1; jBoundingBox; + LocalBuffers[j]->Transformation.transformBoxEx(bb); + + BoundingBox.addInternalBox(bb); + } + } +} + + +void CSkinnedMesh::updateBoundingBox(void) +{ + if(!SkinningBuffers) + return; + + core::array & buffer = *SkinningBuffers; + BoundingBox.reset(0,0,0); + + if (!buffer.empty()) + { + for (u32 j=0; jrecalculateBoundingBox(); + core::aabbox3df bb = buffer[j]->BoundingBox; + buffer[j]->Transformation.transformBoxEx(bb); + + BoundingBox.addInternalBox(bb); + } + } +} + + +scene::SSkinMeshBuffer *CSkinnedMesh::addMeshBuffer() +{ + scene::SSkinMeshBuffer *buffer=new scene::SSkinMeshBuffer(); + LocalBuffers.push_back(buffer); + return buffer; +} + + +CSkinnedMesh::SJoint *CSkinnedMesh::addJoint(SJoint *parent) +{ + SJoint *joint=new SJoint; + + AllJoints.push_back(joint); + if (!parent) + { + //Add root joints to array in finalize() + } + else + { + //Set parent (Be careful of the mesh loader also setting the parent) + parent->Children.push_back(joint); + } + + return joint; +} + + +CSkinnedMesh::SPositionKey *CSkinnedMesh::addPositionKey(SJoint *joint) +{ + if (!joint) + return 0; + + joint->PositionKeys.push_back(SPositionKey()); + return &joint->PositionKeys.getLast(); +} + + +CSkinnedMesh::SScaleKey *CSkinnedMesh::addScaleKey(SJoint *joint) +{ + if (!joint) + return 0; + + joint->ScaleKeys.push_back(SScaleKey()); + return &joint->ScaleKeys.getLast(); +} + + +CSkinnedMesh::SRotationKey *CSkinnedMesh::addRotationKey(SJoint *joint) +{ + if (!joint) + return 0; + + joint->RotationKeys.push_back(SRotationKey()); + return &joint->RotationKeys.getLast(); +} + + +CSkinnedMesh::SWeight *CSkinnedMesh::addWeight(SJoint *joint) +{ + if (!joint) + return 0; + + joint->Weights.push_back(SWeight()); + return &joint->Weights.getLast(); +} + + +bool CSkinnedMesh::isStatic() +{ + return !HasAnimation; +} + + +void CSkinnedMesh::normalizeWeights() +{ + // note: unsure if weights ids are going to be used. + + // Normalise the weights on bones.... + + u32 i,j; + core::array< core::array > verticesTotalWeight; + + verticesTotalWeight.reallocate(LocalBuffers.size()); + for (i=0; i()); + verticesTotalWeight[i].set_used(LocalBuffers[i]->getVertexCount()); + } + + for (i=0; iWeights.size(); ++j) + { + if (joint->Weights[j].strength<=0)//Check for invalid weights + { + joint->Weights.erase(j); + --j; + } + else + { + verticesTotalWeight[joint->Weights[j].buffer_id] [joint->Weights[j].vertex_id] += joint->Weights[j].strength; + } + } + } + + for (i=0; iWeights.size(); ++j) + { + const f32 total = verticesTotalWeight[joint->Weights[j].buffer_id] [joint->Weights[j].vertex_id]; + if (total != 0 && total != 1) + joint->Weights[j].strength /= total; + } + } +} + + +void CSkinnedMesh::recoverJointsFromMesh(core::array &jointChildSceneNodes) +{ + for (u32 i=0; isetPosition(joint->LocalAnimatedMatrix.getTranslation()); + node->setRotation(joint->LocalAnimatedMatrix.getRotationDegrees()); + node->setScale(joint->LocalAnimatedMatrix.getScale()); + + node->positionHint=joint->positionHint; + node->scaleHint=joint->scaleHint; + node->rotationHint=joint->rotationHint; + + node->updateAbsolutePosition(); + } +} + + +void CSkinnedMesh::transferJointsToMesh(const core::array &jointChildSceneNodes) +{ + for (u32 i=0; iLocalAnimatedMatrix.setRotationDegrees(node->getRotation()); + joint->LocalAnimatedMatrix.setTranslation(node->getPosition()); + joint->LocalAnimatedMatrix *= core::matrix4().setScale(node->getScale()); + + joint->positionHint=node->positionHint; + joint->scaleHint=node->scaleHint; + joint->rotationHint=node->rotationHint; + + joint->GlobalSkinningSpace=(node->getSkinningSpace()==EBSS_GLOBAL); + } + // Make sure we recalc the next frame + LastAnimatedFrame=-1; + SkinnedLastFrame=false; +} + + +void CSkinnedMesh::transferOnlyJointsHintsToMesh(const core::array &jointChildSceneNodes) +{ + for (u32 i=0; ipositionHint=node->positionHint; + joint->scaleHint=node->scaleHint; + joint->rotationHint=node->rotationHint; + } + SkinnedLastFrame=false; +} + + +void CSkinnedMesh::addJoints(core::array &jointChildSceneNodes, + IAnimatedMeshSceneNode* node, ISceneManager* smgr) +{ + //Create new joints + for (u32 i=0; iName.c_str())); + } + + //Match up parents + for (u32 i=0; iChildren.size(); ++n) + { + if (parentTest->Children[n]==joint) + { + parentID=j; + break; + } + } + } + } + + IBoneSceneNode* bone=jointChildSceneNodes[i]; + if (parentID!=-1) + bone->setParent(jointChildSceneNodes[parentID]); + else + bone->setParent(node); + + bone->drop(); + } + SkinnedLastFrame=false; +} + + +void CSkinnedMesh::convertMeshToTangents() +{ + // now calculate tangents + for (u32 b=0; b < LocalBuffers.size(); ++b) + { + if (LocalBuffers[b]) + { + LocalBuffers[b]->convertToTangents(); + + const s32 idxCnt = LocalBuffers[b]->getIndexCount(); + + u16* idx = LocalBuffers[b]->getIndices(); + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)LocalBuffers[b]->getVertices(); + + for (s32 i=0; i& getBoundingBox() const; + + //! set user axis aligned bounding box + virtual void setBoundingBox( const core::aabbox3df& box); + + //! sets a flag of all contained materials to a new value + virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue); + + //! set the hardware mapping hint, for driver + virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! flags the meshbuffer as changed, reloads hardware buffers + virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX); + + //! Returns the type of the animated mesh. + virtual E_ANIMATED_MESH_TYPE getMeshType() const; + + //! Gets joint count. + virtual u32 getJointCount() const; + + //! Gets the name of a joint. + virtual const c8* getJointName(u32 number) const; + + //! Gets a joint number from its name + virtual s32 getJointNumber(const c8* name) const; + + //! uses animation from another mesh + virtual bool useAnimationFrom(const ISkinnedMesh *mesh); + + //! Update Normals when Animating + //! False= Don't (default) + //! True = Update normals, slower + virtual void updateNormalsWhenAnimating(bool on); + + //! Sets Interpolation Mode + virtual void setInterpolationMode(E_INTERPOLATION_MODE mode); + + //! Convertes the mesh to contain tangent information + virtual void convertMeshToTangents(); + + //! Does the mesh have no animation + virtual bool isStatic(); + + //! (This feature is not implemented in irrlicht yet) + virtual bool setHardwareSkinning(bool on); + + //Interface for the mesh loaders (finalize should lock these functions, and they should have some prefix like loader_ + //these functions will use the needed arrays, set values, etc to help the loaders + + //! exposed for loaders to add mesh buffers + virtual core::array &getMeshBuffers(); + + //! alternative method for adding joints + virtual core::array &getAllJoints(); + + //! alternative method for adding joints + virtual const core::array &getAllJoints() const; + + //! loaders should call this after populating the mesh + virtual void finalize(); + + //! Adds a new meshbuffer to the mesh, access it as last one + virtual SSkinMeshBuffer *addMeshBuffer(); + + //! Adds a new joint to the mesh, access it as last one + virtual SJoint *addJoint(SJoint *parent=0); + + //! Adds a new position key to the mesh, access it as last one + virtual SPositionKey *addPositionKey(SJoint *joint); + //! Adds a new rotation key to the mesh, access it as last one + virtual SRotationKey *addRotationKey(SJoint *joint); + //! Adds a new scale key to the mesh, access it as last one + virtual SScaleKey *addScaleKey(SJoint *joint); + + //! Adds a new weight to the mesh, access it as last one + virtual SWeight *addWeight(SJoint *joint); + + virtual void updateBoundingBox(void); + + //! Recovers the joints from the mesh + void recoverJointsFromMesh(core::array &jointChildSceneNodes); + + //! Tranfers the joint data to the mesh + void transferJointsToMesh(const core::array &jointChildSceneNodes); + + //! Tranfers the joint hints to the mesh + void transferOnlyJointsHintsToMesh(const core::array &jointChildSceneNodes); + + //! Creates an array of joints from this mesh as children of node + void addJoints(core::array &jointChildSceneNodes, + IAnimatedMeshSceneNode* node, + ISceneManager* smgr); + +private: + void checkForAnimation(); + + void normalizeWeights(); + + void buildAllLocalAnimatedMatrices(); + + void buildAllGlobalAnimatedMatrices(SJoint *Joint=0, SJoint *ParentJoint=0); + + void getFrameData(f32 frame, SJoint *Node, + core::vector3df &position, s32 &positionHint, + core::vector3df &scale, s32 &scaleHint, + core::quaternion &rotation, s32 &rotationHint); + + void calculateGlobalMatrices(SJoint *Joint,SJoint *ParentJoint); + + void skinJoint(SJoint *Joint, SJoint *ParentJoint); + + void calculateTangents(core::vector3df& normal, + core::vector3df& tangent, core::vector3df& binormal, + core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3, + core::vector2df& tc1, core::vector2df& tc2, core::vector2df& tc3); + + core::array *SkinningBuffers; //Meshbuffer to skin, default is to skin localBuffers + + core::array LocalBuffers; + + core::array AllJoints; + core::array RootJoints; + + core::array< core::array > Vertices_Moved; + + core::aabbox3d BoundingBox; + + f32 AnimationFrames; + f32 FramesPerSecond; + + f32 LastAnimatedFrame; + bool SkinnedLastFrame; + + E_INTERPOLATION_MODE InterpolationMode:8; + + bool HasAnimation; + bool PreparedForSkinning; + bool AnimateNormals; + bool HardwareSkinning; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp new file mode 100644 index 0000000..756fab9 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.cpp @@ -0,0 +1,263 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSkyBoxSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "S3DVertex.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, video::ITexture* left, + video::ITexture* right, video::ITexture* front, video::ITexture* back, ISceneNode* parent, ISceneManager* mgr, s32 id) +: ISceneNode(parent, mgr, id) +{ + #ifdef _DEBUG + setDebugName("CSkyBoxSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); + Box.MaxEdge.set(0,0,0); + Box.MinEdge.set(0,0,0); + + // create indices + + Indices[0] = 0; + Indices[1] = 1; + Indices[2] = 2; + Indices[3] = 3; + + // create material + + video::SMaterial mat; + mat.Lighting = false; + mat.ZBuffer = video::ECFN_NEVER; + mat.ZWriteEnable = false; + mat.AntiAliasing=0; + mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; + mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; + + /* Hey, I am no artist, but look at that + cool ASCII art I made! ;) + + -111 111 + /6--------/5 y + / | / | ^ z + / | 11-1 | | / + -11-1 3---------2 | |/ + | 7- - -| -4 1-11 *---->x + | -1-11 | / 3-------|2 + |/ | / | //| + 0---------1/ | // | + -1-1-1 1-1-1 |// | + 0--------1 + */ + + video::ITexture* tex = front; + if (!tex) tex = left; + if (!tex) tex = back; + if (!tex) tex = right; + if (!tex) tex = top; + if (!tex) tex = bottom; + + const f32 onepixel = tex?(1.0f / (tex->getSize().Width * 1.5f)) : 0.0f; + const f32 t = 1.0f - onepixel; + const f32 o = 0.0f + onepixel; + + // create front side + + Material[0] = mat; + Material[0].setTexture(0, front); + Vertices[0] = video::S3DVertex(-1,-1,-1, 0,0,1, video::SColor(255,255,255,255), t, t); + Vertices[1] = video::S3DVertex( 1,-1,-1, 0,0,1, video::SColor(255,255,255,255), o, t); + Vertices[2] = video::S3DVertex( 1, 1,-1, 0,0,1, video::SColor(255,255,255,255), o, o); + Vertices[3] = video::S3DVertex(-1, 1,-1, 0,0,1, video::SColor(255,255,255,255), t, o); + + // create left side + + Material[1] = mat; + Material[1].setTexture(0, left); + Vertices[4] = video::S3DVertex( 1,-1,-1, -1,0,0, video::SColor(255,255,255,255), t, t); + Vertices[5] = video::S3DVertex( 1,-1, 1, -1,0,0, video::SColor(255,255,255,255), o, t); + Vertices[6] = video::S3DVertex( 1, 1, 1, -1,0,0, video::SColor(255,255,255,255), o, o); + Vertices[7] = video::S3DVertex( 1, 1,-1, -1,0,0, video::SColor(255,255,255,255), t, o); + + // create back side + + Material[2] = mat; + Material[2].setTexture(0, back); + Vertices[8] = video::S3DVertex( 1,-1, 1, 0,0,-1, video::SColor(255,255,255,255), t, t); + Vertices[9] = video::S3DVertex(-1,-1, 1, 0,0,-1, video::SColor(255,255,255,255), o, t); + Vertices[10] = video::S3DVertex(-1, 1, 1, 0,0,-1, video::SColor(255,255,255,255), o, o); + Vertices[11] = video::S3DVertex( 1, 1, 1, 0,0,-1, video::SColor(255,255,255,255), t, o); + + // create right side + + Material[3] = mat; + Material[3].setTexture(0, right); + Vertices[12] = video::S3DVertex(-1,-1, 1, 1,0,0, video::SColor(255,255,255,255), t, t); + Vertices[13] = video::S3DVertex(-1,-1,-1, 1,0,0, video::SColor(255,255,255,255), o, t); + Vertices[14] = video::S3DVertex(-1, 1,-1, 1,0,0, video::SColor(255,255,255,255), o, o); + Vertices[15] = video::S3DVertex(-1, 1, 1, 1,0,0, video::SColor(255,255,255,255), t, o); + + // create top side + + Material[4] = mat; + Material[4].setTexture(0, top); + Vertices[16] = video::S3DVertex( 1, 1,-1, 0,-1,0, video::SColor(255,255,255,255), t, t); + Vertices[17] = video::S3DVertex( 1, 1, 1, 0,-1,0, video::SColor(255,255,255,255), o, t); + Vertices[18] = video::S3DVertex(-1, 1, 1, 0,-1,0, video::SColor(255,255,255,255), o, o); + Vertices[19] = video::S3DVertex(-1, 1,-1, 0,-1,0, video::SColor(255,255,255,255), t, o); + + // create bottom side + + Material[5] = mat; + Material[5].setTexture(0, bottom); + Vertices[20] = video::S3DVertex( 1,-1, 1, 0,1,0, video::SColor(255,255,255,255), o, o); + Vertices[21] = video::S3DVertex( 1,-1,-1, 0,1,0, video::SColor(255,255,255,255), t, o); + Vertices[22] = video::S3DVertex(-1,-1,-1, 0,1,0, video::SColor(255,255,255,255), t, t); + Vertices[23] = video::S3DVertex(-1,-1, 1, 0,1,0, video::SColor(255,255,255,255), o, t); +} + + +//! renders the node. +void CSkyBoxSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + scene::ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + if ( !camera->isOrthogonal() ) + { + // draw perspective skybox + + core::matrix4 translate(AbsoluteTransformation); + translate.setTranslation(camera->getAbsolutePosition()); + + // Draw the sky box between the near and far clip plane + const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f; + core::matrix4 scale; + scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance)); + + driver->setTransform(video::ETS_WORLD, translate * scale); + + for (s32 i=0; i<6; ++i) + { + driver->setMaterial(Material[i]); + driver->drawIndexedTriangleFan(&Vertices[i*4], 4, Indices, 2); + } + } + else + { + // draw orthogonal skybox, + // simply choose one texture and draw it as 2d picture. + // there could be better ways to do this, but currently I think this is ok. + + core::vector3df lookVect = camera->getTarget() - camera->getAbsolutePosition(); + lookVect.normalize(); + core::vector3df absVect( core::abs_(lookVect.X), + core::abs_(lookVect.Y), + core::abs_(lookVect.Z)); + + int idx = 0; + + if ( absVect.X >= absVect.Y && absVect.X >= absVect.Z ) + { + // x direction + idx = lookVect.X > 0 ? 0 : 2; + } + else + if ( absVect.Y >= absVect.X && absVect.Y >= absVect.Z ) + { + // y direction + idx = lookVect.Y > 0 ? 4 : 5; + } + else + if ( absVect.Z >= absVect.X && absVect.Z >= absVect.Y ) + { + // z direction + idx = lookVect.Z > 0 ? 1 : 3; + } + + video::ITexture* tex = Material[idx].getTexture(0); + + if ( tex ) + { + core::rect rctDest(core::position2d(-1,0), + core::dimension2di(driver->getCurrentRenderTargetSize())); + core::rect rctSrc(core::position2d(0,0), + core::dimension2di(tex->getSize())); + + driver->draw2DImage(tex, rctDest, rctSrc); + } + } +} + + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSkyBoxSceneNode::getBoundingBox() const +{ + return Box; +} + + +void CSkyBoxSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSkyBoxSceneNode::getMaterial(u32 i) +{ + return Material[i]; +} + + +//! returns amount of materials used by this scene node. +u32 CSkyBoxSceneNode::getMaterialCount() const +{ + return 6; +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CSkyBoxSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) newParent = Parent; + if (!newManager) newManager = SceneManager; + + CSkyBoxSceneNode* nb = new CSkyBoxSceneNode(0,0,0,0,0,0, newParent, + newManager, ID); + + nb->cloneMembers(this, newManager); + + for (u32 i=0; i<6; ++i) + nb->Material[i] = Material[i]; + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.h new file mode 100644 index 0000000..91580dc --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyBoxSceneNode.h @@ -0,0 +1,62 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SKY_BOX_SCENE_NODE_H_INCLUDED__ +#define __C_SKY_BOX_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace scene +{ + + // Skybox, rendered with zbuffer turned off, before all other nodes. + class CSkyBoxSceneNode : public ISceneNode + { + public: + + //! constructor + CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom, video::ITexture* left, + video::ITexture* right, video::ITexture* front, video::ITexture* back, + ISceneNode* parent, ISceneManager* mgr, s32 id); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; } + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + core::aabbox3d Box; + u16 Indices[4]; + video::S3DVertex Vertices[4*6]; + video::SMaterial Material[6]; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp new file mode 100644 index 0000000..0554661 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.cpp @@ -0,0 +1,264 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code for this scene node has been contributed by Anders la Cour-Harbo (alc) + +#include "CSkyDomeSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "IAnimatedMesh.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +/* horiRes and vertRes: + Controls the number of faces along the horizontal axis (30 is a good value) + and the number of faces along the vertical axis (8 is a good value). + + texturePercentage: + Only the top texturePercentage of the image is used, e.g. 0.8 uses the top 80% of the image, + 1.0 uses the entire image. This is useful as some landscape images have a small banner + at the bottom that you don't want. + + spherePercentage: + This controls how far around the sphere the sky dome goes. For value 1.0 you get exactly the upper + hemisphere, for 1.1 you get slightly more, and for 2.0 you get a full sphere. It is sometimes useful + to use a value slightly bigger than 1 to avoid a gap between some ground place and the sky. This + parameters stretches the image to fit the chosen "sphere-size". */ + +CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes, + f32 texturePercentage, f32 spherePercentage, f32 radius, + ISceneNode* parent, ISceneManager* mgr, s32 id) + : ISceneNode(parent, mgr, id), Buffer(0), + HorizontalResolution(horiRes), VerticalResolution(vertRes), + TexturePercentage(texturePercentage), + SpherePercentage(spherePercentage), Radius(radius) +{ + #ifdef _DEBUG + setDebugName("CSkyDomeSceneNode"); + #endif + + setAutomaticCulling(scene::EAC_OFF); + + Buffer = new SMeshBuffer(); + Buffer->Material.Lighting = false; + Buffer->Material.ZBuffer = video::ECFN_NEVER; + Buffer->Material.ZWriteEnable = false; + Buffer->Material.AntiAliasing = video::EAAM_OFF; + Buffer->Material.setTexture(0, sky); + Buffer->BoundingBox.MaxEdge.set(0,0,0); + Buffer->BoundingBox.MinEdge.set(0,0,0); + + // regenerate the mesh + generateMesh(); +} + + +CSkyDomeSceneNode::~CSkyDomeSceneNode() +{ + if (Buffer) + Buffer->drop(); +} + + +void CSkyDomeSceneNode::generateMesh() +{ + f32 azimuth; + u32 k; + + Buffer->Vertices.clear(); + Buffer->Indices.clear(); + + const f32 azimuth_step = (core::PI * 2.f) / HorizontalResolution; + if (SpherePercentage < 0.f) + SpherePercentage = -SpherePercentage; + if (SpherePercentage > 2.f) + SpherePercentage = 2.f; + const f32 elevation_step = SpherePercentage * core::HALF_PI / (f32)VerticalResolution; + + Buffer->Vertices.reallocate( (HorizontalResolution + 1) * (VerticalResolution + 1) ); + Buffer->Indices.reallocate(3 * (2*VerticalResolution - 1) * HorizontalResolution); + + video::S3DVertex vtx; + vtx.Color.set(255,255,255,255); + vtx.Normal.set(0.0f,-1.f,0.0f); + + const f32 tcV = TexturePercentage / VerticalResolution; + for (k = 0, azimuth = 0; k <= HorizontalResolution; ++k) + { + f32 elevation = core::HALF_PI; + const f32 tcU = (f32)k / (f32)HorizontalResolution; + const f32 sinA = sinf(azimuth); + const f32 cosA = cosf(azimuth); + for (u32 j = 0; j <= VerticalResolution; ++j) + { + const f32 cosEr = Radius * cosf(elevation); + vtx.Pos.set(cosEr*sinA, Radius*sinf(elevation), cosEr*cosA); + vtx.TCoords.set(tcU, j*tcV); + + vtx.Normal = -vtx.Pos; + vtx.Normal.normalize(); + + Buffer->Vertices.push_back(vtx); + elevation -= elevation_step; + } + azimuth += azimuth_step; + } + + for (k = 0; k < HorizontalResolution; ++k) + { + Buffer->Indices.push_back(VerticalResolution + 2 + (VerticalResolution + 1)*k); + Buffer->Indices.push_back(1 + (VerticalResolution + 1)*k); + Buffer->Indices.push_back(0 + (VerticalResolution + 1)*k); + + for (u32 j = 1; j < VerticalResolution; ++j) + { + Buffer->Indices.push_back(VerticalResolution + 2 + (VerticalResolution + 1)*k + j); + Buffer->Indices.push_back(1 + (VerticalResolution + 1)*k + j); + Buffer->Indices.push_back(0 + (VerticalResolution + 1)*k + j); + + Buffer->Indices.push_back(VerticalResolution + 1 + (VerticalResolution + 1)*k + j); + Buffer->Indices.push_back(VerticalResolution + 2 + (VerticalResolution + 1)*k + j); + Buffer->Indices.push_back(0 + (VerticalResolution + 1)*k + j); + } + } + Buffer->setHardwareMappingHint(scene::EHM_STATIC); +} + + +//! renders the node. +void CSkyDomeSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + scene::ICameraSceneNode* camera = SceneManager->getActiveCamera(); + + if (!camera || !driver) + return; + + if ( !camera->isOrthogonal() ) + { + core::matrix4 mat(AbsoluteTransformation); + mat.setTranslation(camera->getAbsolutePosition()); + + driver->setTransform(video::ETS_WORLD, mat); + + driver->setMaterial(Buffer->Material); + driver->drawMeshBuffer(Buffer); + } + + // for debug purposes only: + if ( DebugDataVisible ) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + + if ( DebugDataVisible & scene::EDS_NORMALS ) + { + // draw normals + const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); + const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); + driver->drawMeshBufferNormals(Buffer, debugNormalLength, debugNormalColor); + } + + // show mesh + if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY ) + { + m.Wireframe = true; + driver->setMaterial(m); + + driver->drawMeshBuffer(Buffer); + } + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSkyDomeSceneNode::getBoundingBox() const +{ + return Buffer->BoundingBox; +} + + +void CSkyDomeSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, ESNRP_SKY_BOX ); + } + + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i) +{ + return Buffer->Material; +} + + +//! returns amount of materials used by this scene node. +u32 CSkyDomeSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Writes attributes of the scene node. +void CSkyDomeSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addInt ("HorizontalResolution", HorizontalResolution); + out->addInt ("VerticalResolution", VerticalResolution); + out->addFloat("TexturePercentage", TexturePercentage); + out->addFloat("SpherePercentage", SpherePercentage); + out->addFloat("Radius", Radius); +} + + +//! Reads attributes of the scene node. +void CSkyDomeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + HorizontalResolution = in->getAttributeAsInt ("HorizontalResolution"); + VerticalResolution = in->getAttributeAsInt ("VerticalResolution"); + TexturePercentage = in->getAttributeAsFloat("TexturePercentage"); + SpherePercentage = in->getAttributeAsFloat("SpherePercentage"); + Radius = in->getAttributeAsFloat("Radius"); + + ISceneNode::deserializeAttributes(in, options); + + // regenerate the mesh + generateMesh(); +} + +//! Creates a clone of this scene node and its children. +ISceneNode* CSkyDomeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CSkyDomeSceneNode* nb = new CSkyDomeSceneNode(Buffer->Material.TextureLayer[0].Texture, HorizontalResolution, VerticalResolution, TexturePercentage, + SpherePercentage, Radius, newParent, newManager, ID); + + nb->cloneMembers(this, newManager); + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // namespace scene +} // namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.h new file mode 100644 index 0000000..9795b68 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSkyDomeSceneNode.h @@ -0,0 +1,50 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code for this scene node has been contributed by Anders la Cour-Harbo (alc) + +#ifndef __C_SKY_DOME_SCENE_NODE_H_INCLUDED__ +#define __C_SKY_DOME_SCENE_NODE_H_INCLUDED__ + +#include "ISceneNode.h" +#include "SMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + +class CSkyDomeSceneNode : public ISceneNode +{ + public: + CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes, + f32 texturePercentage, f32 spherePercentage, f32 radius, + ISceneNode* parent, ISceneManager* smgr, s32 id); + virtual ~CSkyDomeSceneNode(); + virtual void OnRegisterSceneNode(); + virtual void render(); + virtual const core::aabbox3d& getBoundingBox() const; + virtual video::SMaterial& getMaterial(u32 i); + virtual u32 getMaterialCount() const; + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_DOME; } + + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + private: + + void generateMesh(); + + SMeshBuffer* Buffer; + + u32 HorizontalResolution, VerticalResolution; + f32 TexturePercentage, SpherePercentage, Radius; +}; + + +} +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftware2MaterialRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftware2MaterialRenderer.h new file mode 100644 index 0000000..8093613 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftware2MaterialRenderer.h @@ -0,0 +1,118 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SOFTWARE2_MATERIAL_RENDERER_H_INCLUDED__ +#define __C_SOFTWARE2_MATERIAL_RENDERER_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" + +#include "IMaterialRenderer.h" +#include "CSoftwareDriver2.h" + +namespace irr +{ +namespace video +{ + +//! Base class for all internal Software2 material renderers +class CSoftware2MaterialRenderer : public IMaterialRenderer +{ +public: + + //! Constructor + CSoftware2MaterialRenderer(video::CBurningVideoDriver* driver) + : Driver(driver) + { + } + +protected: + + video::CBurningVideoDriver* Driver; +}; + +//! solid material renderer +class CSoftware2MaterialRenderer_SOLID : public CSoftware2MaterialRenderer +{ +public: + CSoftware2MaterialRenderer_SOLID ( video::CBurningVideoDriver* driver ) + :CSoftware2MaterialRenderer ( driver ) {} + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return false; + } + +}; + + + +//! Transparent material renderer +class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer +{ +public: + CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR ( video::CBurningVideoDriver* driver ) + : CSoftware2MaterialRenderer ( driver ) {} + + + //! Returns if the material is transparent. + virtual bool isTransparent() const + { + return true; + } + +}; + +//! unsupported material renderer +class CSoftware2MaterialRenderer_UNSUPPORTED : public CSoftware2MaterialRenderer +{ +public: + CSoftware2MaterialRenderer_UNSUPPORTED ( video::CBurningVideoDriver* driver ) + : CSoftware2MaterialRenderer ( driver ) {} + + virtual s32 getRenderCapability() const { return 1; } + +}; + +//! unsupported material renderer +class CBurningShader_REFERENCE : public CSoftware2MaterialRenderer +{ +public: + CBurningShader_REFERENCE ( video::CBurningVideoDriver* driver ) + : CSoftware2MaterialRenderer ( driver ) {} + + virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, + bool resetAllRenderstates, IMaterialRendererServices* services) + { + } + + virtual void OnUnsetMaterial() + { + } + + virtual bool isTransparent() const + { + return false; + } + + virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) + { + return true; + }; + + + virtual s32 getRenderCapability() const + { + return 1; + } + +}; + + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.cpp new file mode 100644 index 0000000..e079b07 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.cpp @@ -0,0 +1,973 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CSoftwareDriver.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +#include "CSoftwareTexture.h" +#include "CBlit.h" +#include "os.h" +#include "S3DVertex.h" + +namespace irr +{ +namespace video +{ + + +//! constructor +CSoftwareDriver::CSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) +: CNullDriver(io, windowSize), BackBuffer(0), Presenter(presenter), WindowId(0), + SceneSourceRect(0), RenderTargetTexture(0), RenderTargetSurface(0), + CurrentTriangleRenderer(0), ZBuffer(0), Texture(0) +{ + #ifdef _DEBUG + setDebugName("CSoftwareDriver"); + #endif + + // create backbuffer + + BackBuffer = new CImage(ECF_A1R5G5B5, windowSize); + if (BackBuffer) + { + BackBuffer->fill(SColor(0)); + + // create z buffer + ZBuffer = video::createZBuffer(BackBuffer->getDimension()); + } + + DriverAttributes->setAttribute("MaxTextures", 1); + DriverAttributes->setAttribute("MaxIndices", 1<<16); + DriverAttributes->setAttribute("MaxTextureSize", 1024); + DriverAttributes->setAttribute("Version", 1); + + // create triangle renderers + + TriangleRenderers[ETR_FLAT] = createTriangleRendererFlat(ZBuffer); + TriangleRenderers[ETR_FLAT_WIRE] = createTriangleRendererFlatWire(ZBuffer); + TriangleRenderers[ETR_GOURAUD] = createTriangleRendererGouraud(ZBuffer); + TriangleRenderers[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire(ZBuffer); + TriangleRenderers[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat(ZBuffer); + TriangleRenderers[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire(ZBuffer); + TriangleRenderers[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud(ZBuffer); + TriangleRenderers[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire(ZBuffer); + TriangleRenderers[ETR_TEXTURE_GOURAUD_NOZ] = createTriangleRendererTextureGouraudNoZ(); + TriangleRenderers[ETR_TEXTURE_GOURAUD_ADD] = createTriangleRendererTextureGouraudAdd(ZBuffer); + + // select render target + + setRenderTarget(BackBuffer); + + // select the right renderer + + selectRightTriangleRenderer(); +} + + + +//! destructor +CSoftwareDriver::~CSoftwareDriver() +{ + // delete Backbuffer + if (BackBuffer) + BackBuffer->drop(); + + // delete triangle renderers + + for (s32 i=0; idrop(); + + // delete zbuffer + + if (ZBuffer) + ZBuffer->drop(); + + // delete current texture + + if (Texture) + Texture->drop(); + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + if (RenderTargetSurface) + RenderTargetSurface->drop(); +} + + + +//! switches to a triangle renderer +void CSoftwareDriver::switchToTriangleRenderer(ETriangleRenderer renderer) +{ + video::IImage* s = 0; + if (Texture) + s = ((CSoftwareTexture*)Texture)->getTexture(); + + CurrentTriangleRenderer = TriangleRenderers[renderer]; + CurrentTriangleRenderer->setBackfaceCulling(Material.BackfaceCulling == true); + CurrentTriangleRenderer->setTexture(s); + CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort); +} + + +//! void selects the right triangle renderer based on the render states. +void CSoftwareDriver::selectRightTriangleRenderer() +{ + + ETriangleRenderer renderer = ETR_FLAT; + + if (Texture) + { + if (!Material.GouraudShading) + renderer = (!Material.Wireframe) ? ETR_TEXTURE_FLAT : ETR_TEXTURE_FLAT_WIRE; + else + { + if (Material.Wireframe) + renderer = ETR_TEXTURE_GOURAUD_WIRE; + else + { + if (Material.MaterialType == EMT_TRANSPARENT_ADD_COLOR || + Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL || + Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA) + { + // simply draw all transparent stuff with the same renderer. at + // least it is transparent then. + renderer = ETR_TEXTURE_GOURAUD_ADD; + } + else + if ((Material.ZBuffer==ECFN_NEVER) && !Material.ZWriteEnable) + renderer = ETR_TEXTURE_GOURAUD_NOZ; + else + { + renderer = ETR_TEXTURE_GOURAUD; + } + } + } + } + else + { + if (!Material.GouraudShading) + renderer = (!Material.Wireframe) ? ETR_FLAT : ETR_FLAT_WIRE; + else + renderer = (!Material.Wireframe) ? ETR_GOURAUD : ETR_GOURAUD_WIRE; + } + + switchToTriangleRenderer(renderer); +} + + +//! queries the features of the driver, returns true if feature is available +bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + switch (feature) + { + case EVDF_RENDER_TO_TARGET: + case EVDF_TEXTURE_NSQUARE: + return FeatureEnabled[feature]; + default: + return false; + }; +} + + +//! sets transformation +void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + TransformationMatrix[state] = mat; +} + + +//! sets the current Texture +bool CSoftwareDriver::setActiveTexture(u32 stage, video::ITexture* texture) +{ + if (texture && texture->getDriverType() != EDT_SOFTWARE) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (Texture) + Texture->drop(); + + Texture = texture; + + if (Texture) + Texture->grab(); + + selectRightTriangleRenderer(); + return true; +} + + +//! sets a material +void CSoftwareDriver::setMaterial(const SMaterial& material) +{ + Material = material; + OverrideMaterial.apply(Material); + + for (u32 i = 0; i < 1; ++i) + { + setActiveTexture(i, Material.getTexture(i)); + setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), + material.getTextureMatrix(i)); + } +} + + +//! clears the zbuffer +bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, + const SExposedVideoData& videoData, core::rect* sourceRect) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); + WindowId=videoData.D3D9.HWnd; + SceneSourceRect = sourceRect; + + if (backBuffer && BackBuffer) + BackBuffer->fill(color); + + if (ZBuffer && zBuffer) + ZBuffer->clear(); + + return true; +} + + +//! presents the rendered scene on the screen, returns false if failed +bool CSoftwareDriver::endScene() +{ + CNullDriver::endScene(); + + return Presenter->present(BackBuffer, WindowId, SceneSourceRect); +} + + +//! returns a device dependent texture from a software surface (IImage) +//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES +ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) +{ + return new CSoftwareTexture(surface, name, false, mipmapData); +} + + +//! sets a render target +bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + if (texture && texture->getDriverType() != EDT_SOFTWARE) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + RenderTargetTexture = texture; + + if (RenderTargetTexture) + { + RenderTargetTexture->grab(); + setRenderTarget(((CSoftwareTexture*)RenderTargetTexture)->getTexture()); + } + else + { + setRenderTarget(BackBuffer); + } + + if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) + { + if (clearZBuffer) + ZBuffer->clear(); + + if (clearBackBuffer) + RenderTargetSurface->fill(color); + } + + return true; +} + + +//! sets a render target +void CSoftwareDriver::setRenderTarget(video::CImage* image) +{ + if (RenderTargetSurface) + RenderTargetSurface->drop(); + + RenderTargetSurface = image; + RenderTargetSize.Width = 0; + RenderTargetSize.Height = 0; + Render2DTranslation.X = 0; + Render2DTranslation.Y = 0; + + if (RenderTargetSurface) + { + RenderTargetSurface->grab(); + RenderTargetSize = RenderTargetSurface->getDimension(); + } + + setViewPort(core::rect(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); + + if (ZBuffer) + ZBuffer->setSize(RenderTargetSize); +} + + +//! sets a viewport +void CSoftwareDriver::setViewPort(const core::rect& area) +{ + ViewPort = area; + + //TODO: the clipping is not correct, because the projection is affected. + // to correct this, ViewPortSize and Render2DTranslation will have to be corrected. + core::rect rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); + ViewPort.clipAgainst(rendert); + + ViewPortSize = core::dimension2du(ViewPort.getSize()); + Render2DTranslation.X = (ViewPortSize.Width / 2) + ViewPort.UpperLeftCorner.X; + Render2DTranslation.Y = ViewPort.UpperLeftCorner.Y + ViewPortSize.Height - (ViewPortSize.Height / 2);// + ViewPort.UpperLeftCorner.Y; + + if (CurrentTriangleRenderer) + CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort); +} + + +void CSoftwareDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) + +{ + switch (iType) + { + case (EIT_16BIT): + { + drawVertexPrimitiveList16(vertices, vertexCount, (const u16*)indexList, primitiveCount, vType, pType); + break; + } + case (EIT_32BIT): + { + os::Printer::log("Software driver can not render 32bit buffers", ELL_ERROR); + break; + } + } +} + + +//! draws a vertex primitive list +void CSoftwareDriver::drawVertexPrimitiveList16(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) +{ + const u16* indexPointer=0; + core::array newBuffer; + switch (pType) + { + case scene::EPT_LINE_STRIP: + { + switch (vType) + { + case EVT_STANDARD: + { + for (u32 i=0; i < primitiveCount-1; ++i) + draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos, + ((S3DVertex*)vertices)[indexList[i+1]].Pos, + ((S3DVertex*)vertices)[indexList[i]].Color); + } + break; + case EVT_2TCOORDS: + { + for (u32 i=0; i < primitiveCount-1; ++i) + draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i]].Color); + } + break; + case EVT_TANGENTS: + { + for (u32 i=0; i < primitiveCount-1; ++i) + draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i]].Color); + } + break; + } + } + return; + case scene::EPT_LINE_LOOP: + drawVertexPrimitiveList16(vertices, vertexCount, indexList, primitiveCount-1, vType, scene::EPT_LINE_STRIP); + switch (vType) + { + case EVT_STANDARD: + draw3DLine(((S3DVertex*)vertices)[indexList[primitiveCount-1]].Pos, + ((S3DVertex*)vertices)[indexList[0]].Pos, + ((S3DVertex*)vertices)[indexList[primitiveCount-1]].Color); + break; + case EVT_2TCOORDS: + draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[0]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Color); + break; + case EVT_TANGENTS: + draw3DLine(((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Pos, + ((S3DVertexTangents*)vertices)[indexList[0]].Pos, + ((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Color); + break; + } + return; + case scene::EPT_LINES: + { + switch (vType) + { + case EVT_STANDARD: + { + for (u32 i=0; i < 2*primitiveCount; i+=2) + draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos, + ((S3DVertex*)vertices)[indexList[i+1]].Pos, + ((S3DVertex*)vertices)[indexList[i]].Color); + } + break; + case EVT_2TCOORDS: + { + for (u32 i=0; i < 2*primitiveCount; i+=2) + draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos, + ((S3DVertex2TCoords*)vertices)[indexList[i]].Color); + } + break; + case EVT_TANGENTS: + { + for (u32 i=0; i < 2*primitiveCount; i+=2) + draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos, + ((S3DVertexTangents*)vertices)[indexList[i]].Color); + } + break; + } + } + return; + case scene::EPT_TRIANGLE_FAN: + { + // TODO: don't convert fan to list + newBuffer.reallocate(primitiveCount*3); + for( u32 t=0; t +void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices, + s32 vertexCount, const u16* indexList, s32 triangleCount) +{ + if (!RenderTargetSurface || !ZBuffer || !triangleCount) + return; + + if (!checkPrimitiveCount(triangleCount)) + return; + + // arrays for storing clipped vertices + core::array clippedVertices; + core::array clippedIndices; + + // calculate inverse world transformation + core::matrix4 worldinv(TransformationMatrix[ETS_WORLD]); + worldinv.makeInverse(); + + // calculate view frustum planes + scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]); + + // copy and transform clipping planes ignoring far plane + core::plane3df planes[5]; // ordered by near, left, right, bottom, top + for (int p=0; p<5; ++p) + worldinv.transformPlane(frustum.planes[p+1], planes[p]); + + core::EIntersectionRelation3D inout[3]; // is point in front or back of plane? + + // temporary buffer for vertices to be clipped by all planes + core::array tClpBuf; + int t; + + int i; + for (i=0; i textureSize(0,0); + f32 zDiv; + + if (Texture) + textureSize = ((CSoftwareTexture*)Texture)->getTexture()->getDimension(); + + f32 transformedPos[4]; // transform all points in the list + + core::matrix4 matrix(TransformationMatrix[ETS_PROJECTION]); + matrix *= TransformationMatrix[ETS_VIEW]; + matrix *= TransformationMatrix[ETS_WORLD]; + + s32 ViewTransformWidth = (ViewPortSize.Width>>1); + s32 ViewTransformHeight = (ViewPortSize.Height>>1); + + for (i=0; i<(int)clippedVertices.size(); ++i) + { + transformedPos[0] = currentVertex->Pos.X; + transformedPos[1] = currentVertex->Pos.Y; + transformedPos[2] = currentVertex->Pos.Z; + transformedPos[3] = 1.0f; + + matrix.multiplyWith1x4Matrix(transformedPos); + zDiv = transformedPos[3] == 0.0f ? 1.0f : (1.0f / transformedPos[3]); + + tp->Pos.X = (s32)(ViewTransformWidth * (transformedPos[0] * zDiv) + (Render2DTranslation.X)); + tp->Pos.Y = (Render2DTranslation.Y - (s32)(ViewTransformHeight * (transformedPos[1] * zDiv))); + tp->Color = currentVertex->Color.toA1R5G5B5(); + tp->ZValue = (TZBufferType)(32767.0f * zDiv); + + tp->TCoords.X = (s32)(currentVertex->TCoords.X * textureSize.Width); + tp->TCoords.X <<= 8; + tp->TCoords.Y = (s32)(currentVertex->TCoords.Y * textureSize.Height); + tp->TCoords.Y <<= 8; + + ++currentVertex; + ++tp; + } + + // draw all transformed points from the index list + CurrentTriangleRenderer->drawIndexedTriangleList(&TransformedPoints[0], + clippedVertices.size(), clippedIndices.pointer(), clippedIndices.size()/3); +} + + +//! Draws a 3d line. +void CSoftwareDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + core::vector3df vect = start.crossProduct(end); + vect.normalize(); + vect *= Material.Thickness*0.3f; + + S3DVertex vtx[4]; + + vtx[0].Color = color; + vtx[1].Color = color; + vtx[2].Color = color; + vtx[3].Color = color; + + vtx[0].Pos = start; + vtx[1].Pos = end; + + vtx[2].Pos = start + vect; + vtx[3].Pos = end + vect; + + u16 idx[12] = {0,1,2, 0,2,1, 0,1,3, 0,3,1}; + + drawIndexedTriangleList(vtx, 4, idx, 4); +} + + +//! clips a triangle against the viewing frustum +void CSoftwareDriver::clipTriangle(f32* transformedPos) +{ +} + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void CSoftwareDriver::OnResize(const core::dimension2d& size) +{ + // make sure width and height are multiples of 2 + core::dimension2d realSize(size); + + if (realSize.Width % 2) + realSize.Width += 1; + + if (realSize.Height % 2) + realSize.Height += 1; + + if (ScreenSize != realSize) + { + if (ViewPort.getWidth() == (s32)ScreenSize.Width && + ViewPort.getHeight() == (s32)ScreenSize.Height) + { + ViewPort = core::rect(core::position2d(0,0), + core::dimension2di(realSize)); + } + + ScreenSize = realSize; + + bool resetRT = (RenderTargetSurface == BackBuffer); + + if (BackBuffer) + BackBuffer->drop(); + BackBuffer = new CImage(ECF_A1R5G5B5, realSize); + + if (resetRT) + setRenderTarget(BackBuffer); + } +} + +//! returns the current render target size +const core::dimension2d& CSoftwareDriver::getCurrentRenderTargetSize() const +{ + return RenderTargetSize; +} + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CSoftwareDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (texture) + { + if (texture->getDriverType() != EDT_SOFTWARE) + { + os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); + return; + } + + if (useAlphaChannelOfTexture) + ((CSoftwareTexture*)texture)->getImage()->copyToWithAlpha( + RenderTargetSurface, destPos, sourceRect, color, clipRect); + else + ((CSoftwareTexture*)texture)->getImage()->copyTo( + RenderTargetSurface, destPos, sourceRect, clipRect); + } +} + + + +//! Draws a 2d line. +void CSoftwareDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + drawLine(RenderTargetSurface, start, end, color ); +} + + +//! Draws a pixel +void CSoftwareDriver::drawPixel(u32 x, u32 y, const SColor & color) +{ + BackBuffer->setPixel(x, y, color, true); +} + + +//! draw a 2d rectangle +void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip) +{ + if (clip) + { + core::rect p(pos); + + p.clipAgainst(*clip); + + if(!p.isValid()) + return; + + drawRectangle(RenderTargetSurface, p, color); + } + else + { + if(!pos.isValid()) + return; + + drawRectangle(RenderTargetSurface, pos, color); + } +} + + +//!Draws an 2d rectangle with a gradient. +void CSoftwareDriver::draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ + // TODO: implement + draw2DRectangle(colorLeftUp, pos, clip); +} + + +//! \return Returns the name of the video driver. Example: In case of the Direct3D8 +//! driver, it would return "Direct3D8.1". +const wchar_t* CSoftwareDriver::getName() const +{ + return L"Irrlicht Software Driver 1.0"; +} + + +//! Returns type of video driver +E_DRIVER_TYPE CSoftwareDriver::getDriverType() const +{ + return EDT_SOFTWARE; +} + + +//! returns color format +ECOLOR_FORMAT CSoftwareDriver::getColorFormat() const +{ + if (BackBuffer) + return BackBuffer->getColorFormat(); + else + return CNullDriver::getColorFormat(); +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CSoftwareDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return TransformationMatrix[state]; +} + + +//! Creates a render target texture. +ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, + const ECOLOR_FORMAT format) +{ + IImage* img = createImage(video::ECF_A1R5G5B5, size); + ITexture* tex = new CSoftwareTexture(img, name, true); + img->drop(); + addTexture(tex); + tex->drop(); + return tex; +} + + +//! Clears the ZBuffer. +void CSoftwareDriver::clearZBuffer() +{ + if (ZBuffer) + ZBuffer->clear(); +} + + +//! Returns an image created from the last rendered frame. +IImage* CSoftwareDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) +{ + if (target != video::ERT_FRAME_BUFFER) + return 0; + + if (BackBuffer) + { + IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension()); + BackBuffer->copyTo(tmp); + return tmp; + } + else + return 0; +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CSoftwareDriver::getMaximalPrimitiveCount() const +{ + return 0x00800000; +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +//! creates a video driver +IVideoDriver* createSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CSoftwareDriver(windowSize, fullscreen, io, presenter); + #else + return 0; + #endif +} + + +} // end namespace video +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.h new file mode 100644 index 0000000..60b14c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver.h @@ -0,0 +1,180 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_SOFTWARE_H_INCLUDED__ +#define __C_VIDEO_SOFTWARE_H_INCLUDED__ + +#include "ITriangleRenderer.h" +#include "CNullDriver.h" +#include "SViewFrustum.h" +#include "CImage.h" + +namespace irr +{ +namespace video +{ + class CSoftwareDriver : public CNullDriver + { + public: + + //! constructor + CSoftwareDriver(const core::dimension2d& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter); + + //! destructor + virtual ~CSoftwareDriver(); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! clears the zbuffer + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect* sourceRect=0); + + //! presents the rendered scene on the screen, returns false if failed + virtual bool endScene(); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! returns size of the current render target + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + //! draws a vertex primitive list + void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a single pixel + virtual void drawPixel(u32 x, u32 y, const SColor & color); + + //! \return Returns the name of the video driver. Example: In case of the Direct3D8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! get color format of the current color buffer + virtual ECOLOR_FORMAT getColorFormat() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); + + //! Creates a render target texture. + virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! Clears the ZBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + protected: + + //! sets a render target + void setRenderTarget(video::CImage* image); + + //! sets the current Texture + bool setActiveTexture(u32 stage, video::ITexture* texture); + + //! switches to a triangle renderer + void switchToTriangleRenderer(ETriangleRenderer renderer); + + //! void selects the right triangle renderer based on the render states. + void selectRightTriangleRenderer(); + + //! clips a triangle agains the viewing frustum + void clipTriangle(f32* transformedPos); + + + //! draws a vertex primitive list + void drawVertexPrimitiveList16(const void* vertices, u32 vertexCount, + const u16* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); + + + template + void drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices, + s32 vertexCount, const u16* indexList, s32 triangleCount); + + video::CImage* BackBuffer; + video::IImagePresenter* Presenter; + void* WindowId; + core::rect* SceneSourceRect; + + core::array TransformedPoints; + + video::ITexture* RenderTargetTexture; + video::CImage* RenderTargetSurface; + core::position2d Render2DTranslation; + core::dimension2d RenderTargetSize; + core::dimension2d ViewPortSize; + + core::matrix4 TransformationMatrix[ETS_COUNT]; + + ITriangleRenderer* CurrentTriangleRenderer; + ITriangleRenderer* TriangleRenderers[ETR_COUNT]; + ETriangleRenderer CurrentRenderer; + + IZBuffer* ZBuffer; + + video::ITexture* Texture; + + SMaterial Material; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.cpp new file mode 100644 index 0000000..f90ede5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.cpp @@ -0,0 +1,2723 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CSoftwareDriver2.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +#include "SoftwareDriver2_helper.h" +#include "CSoftwareTexture2.h" +#include "CSoftware2MaterialRenderer.h" +#include "S3DVertex.h" +#include "S4DVertex.h" +#include "CBlit.h" + + +#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( tex ) ) + + +namespace irr +{ +namespace video +{ + +namespace glsl +{ + +typedef sVec4 vec4; +typedef sVec3 vec3; +typedef sVec2 vec2; + +#define in +#define uniform +#define attribute +#define varying + +#ifdef _MSC_VER +#pragma warning(disable:4244) +#endif + +struct mat4{ + float m[4][4]; + + vec4 operator* ( const vec4 &in ) const + { + vec4 out; + return out; + } + +}; + +struct mat3{ + float m[3][3]; + + vec3 operator* ( const vec3 &in ) const + { + vec3 out; + return out; + } +}; + +const int gl_MaxLights = 8; + + +inline float dot (float x, float y) { return x * y; } +inline float dot ( const vec2 &x, const vec2 &y) { return x.x * y.x + x.y * y.y; } +inline float dot ( const vec3 &x, const vec3 &y) { return x.x * y.x + x.y * y.y + x.z * y.z; } +inline float dot ( const vec4 &x, const vec4 &y) { return x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w; } + +inline float reflect (float I, float N) { return I - 2.0 * dot (N, I) * N; } +inline vec2 reflect (const vec2 &I, const vec2 &N) { return I - N * 2.0 * dot (N, I); } +inline vec3 reflect (const vec3 &I, const vec3 &N) { return I - N * 2.0 * dot (N, I); } +inline vec4 reflect (const vec4 &I, const vec4 &N) { return I - N * 2.0 * dot (N, I); } + + +inline float refract (float I, float N, float eta){ + const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); + if (k < 0.0) + return 0.0; + return eta * I - (eta * dot (N, I) + sqrt (k)) * N; +} + +inline vec2 refract (const vec2 &I, const vec2 &N, float eta){ + const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); + if (k < 0.0) + return vec2 (0.0); + return I * eta - N * (eta * dot (N, I) + sqrt (k)); +} + +inline vec3 refract (const vec3 &I, const vec3 &N, float eta) { + const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); + if (k < 0.0) + return vec3 (0.0); + return I * eta - N * (eta * dot (N, I) + sqrt (k)); +} + +inline vec4 refract (const vec4 &I, const vec4 &N, float eta) { + const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); + if (k < 0.0) + return vec4 (0.0); + return I * eta - N * (eta * dot (N, I) + sqrt (k)); +} + + +inline float length ( const vec3 &v ) { return sqrtf ( v.x * v.x + v.y * v.y + v.z * v.z ); } +vec3 normalize ( const vec3 &v ) { float l = 1.f / length ( v ); return vec3 ( v.x * l, v.y * l, v.z * l ); } +float max ( float a, float b ) { return a > b ? a : b; } +float min ( float a, float b ) { return a < b ? a : b; } +vec4 clamp ( const vec4 &a, f32 low, f32 high ) { return vec4 ( min (max(a.x,low), high), min (max(a.y,low), high), min (max(a.z,low), high), min (max(a.w,low), high) ); } + + + +typedef int sampler2D; +sampler2D texUnit0; + +vec4 texture2D (sampler2D sampler, const vec2 &coord) { return vec4 (0.0); } + +struct gl_LightSourceParameters { + vec4 ambient; // Acli + vec4 diffuse; // Dcli + vec4 specular; // Scli + vec4 position; // Ppli + vec4 halfVector; // Derived: Hi + vec3 spotDirection; // Sdli + float spotExponent; // Srli + float spotCutoff; // Crli + // (range: [0.0,90.0], 180.0) + float spotCosCutoff; // Derived: cos(Crli) + // (range: [1.0,0.0],-1.0) + float constantAttenuation; // K0 + float linearAttenuation; // K1 + float quadraticAttenuation;// K2 +}; + +uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; + +struct gl_LightModelParameters { + vec4 ambient; +}; +uniform gl_LightModelParameters gl_LightModel; + +struct gl_LightModelProducts { + vec4 sceneColor; +}; + +uniform gl_LightModelProducts gl_FrontLightModelProduct; +uniform gl_LightModelProducts gl_BackLightModelProduct; + +struct gl_LightProducts { + vec4 ambient; + vec4 diffuse; + vec4 specular; +}; + +uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; +uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; + +struct gl_MaterialParameters +{ + vec4 emission; // Ecm + vec4 ambient; // Acm + vec4 diffuse; // Dcm + vec4 specular; // Scm + float shininess; // Srm +}; +uniform gl_MaterialParameters gl_FrontMaterial; +uniform gl_MaterialParameters gl_BackMaterial; + +// GLSL has some built-in attributes in a vertex shader: +attribute vec4 gl_Vertex; // 4D vector representing the vertex position +attribute vec3 gl_Normal; // 3D vector representing the vertex normal +attribute vec4 gl_Color; // 4D vector representing the vertex color +attribute vec4 gl_MultiTexCoord0; // 4D vector representing the texture coordinate of texture unit X +attribute vec4 gl_MultiTexCoord1; // 4D vector representing the texture coordinate of texture unit X + +uniform mat4 gl_ModelViewMatrix; //4x4 Matrix representing the model-view matrix. +uniform mat4 gl_ModelViewProjectionMatrix; //4x4 Matrix representing the model-view-projection matrix. +uniform mat3 gl_NormalMatrix; //3x3 Matrix representing the inverse transpose model-view matrix. This matrix is used for normal transformation. + + +varying vec4 gl_FrontColor; // 4D vector representing the primitives front color +varying vec4 gl_FrontSecondaryColor; // 4D vector representing the primitives second front color +varying vec4 gl_BackColor; // 4D vector representing the primitives back color +varying vec4 gl_TexCoord[4]; // 4D vector representing the Xth texture coordinate + +// shader output +varying vec4 gl_Position; // 4D vector representing the final processed vertex position. Only available in vertex shader. +varying vec4 gl_FragColor; // 4D vector representing the final color which is written in the frame buffer. Only available in fragment shader. +varying float gl_FragDepth; // float representing the depth which is written in the depth buffer. Only available in fragment shader. + +varying vec4 gl_SecondaryColor; +varying float gl_FogFragCoord; + + +vec4 ftransform(void) +{ + return gl_ModelViewProjectionMatrix * gl_Vertex; +} + +vec3 fnormal(void) +{ + //Compute the normal + vec3 normal = gl_NormalMatrix * gl_Normal; + normal = normalize(normal); + return normal; +} + + +struct program1 +{ + vec4 Ambient; + vec4 Diffuse; + vec4 Specular; + + void pointLight(in int i, in vec3 normal, in vec3 eye, in vec3 ecPosition3) + { + float nDotVP; // normal . light direction + float nDotHV; // normal . light half vector + float pf; // power factor + float attenuation; // computed attenuation factor + float d; // distance from surface to light source + vec3 VP; // direction from surface to light position + vec3 halfVector; // direction of maximum highlights + + // Compute vector from surface to light position + VP = vec3 (gl_LightSource[i].position) - ecPosition3; + + // Compute distance between surface and light position + d = length(VP); + + // Normalize the vector from surface to light position + VP = normalize(VP); + + // Compute attenuation + attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + + gl_LightSource[i].linearAttenuation * d + + gl_LightSource[i].quadraticAttenuation * d * d); + + halfVector = normalize(VP + eye); + + nDotVP = max(0.0, dot(normal, VP)); + nDotHV = max(0.0, dot(normal, halfVector)); + + if (nDotVP == 0.0) + { + pf = 0.0; + } + else + { + pf = pow(nDotHV, gl_FrontMaterial.shininess); + + } + Ambient += gl_LightSource[i].ambient * attenuation; + Diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; + Specular += gl_LightSource[i].specular * pf * attenuation; + } + + vec3 fnormal(void) + { + //Compute the normal + vec3 normal = gl_NormalMatrix * gl_Normal; + normal = normalize(normal); + return normal; + } + + void ftexgen(in vec3 normal, in vec4 ecPosition) + { + + gl_TexCoord[0] = gl_MultiTexCoord0; + } + + void flight(in vec3 normal, in vec4 ecPosition, float alphaFade) + { + vec4 color; + vec3 ecPosition3; + vec3 eye; + + ecPosition3 = (vec3 (ecPosition)) / ecPosition.w; + eye = vec3 (0.0, 0.0, 1.0); + + // Clear the light intensity accumulators + Ambient = vec4 (0.0); + Diffuse = vec4 (0.0); + Specular = vec4 (0.0); + + pointLight(0, normal, eye, ecPosition3); + + pointLight(1, normal, eye, ecPosition3); + + color = gl_FrontLightModelProduct.sceneColor + + Ambient * gl_FrontMaterial.ambient + + Diffuse * gl_FrontMaterial.diffuse; + gl_FrontSecondaryColor = Specular * gl_FrontMaterial.specular; + color = clamp( color, 0.0, 1.0 ); + gl_FrontColor = color; + + gl_FrontColor.a *= alphaFade; + } + + + void vertexshader_main (void) + { + vec3 transformedNormal; + float alphaFade = 1.0; + + // Eye-coordinate position of vertex, needed in various calculations + vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; + + // Do fixed functionality vertex transform + gl_Position = ftransform(); + transformedNormal = fnormal(); + flight(transformedNormal, ecPosition, alphaFade); + ftexgen(transformedNormal, ecPosition); + } + + void fragmentshader_main (void) + { + vec4 color; + + color = gl_Color; + + color *= texture2D(texUnit0, vec2(gl_TexCoord[0].x, gl_TexCoord[0].y) ); + + color += gl_SecondaryColor; + color = clamp(color, 0.0, 1.0); + + gl_FragColor = color; + } +}; + +} + +//! constructor +CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) +: CNullDriver(io, params.WindowSize), BackBuffer(0), Presenter(presenter), + WindowId(0), SceneSourceRect(0), + RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0), + DepthBuffer(0), StencilBuffer ( 0 ), + CurrentOut ( 12 * 2, 128 ), Temp ( 12 * 2, 128 ) +{ + #ifdef _DEBUG + setDebugName("CBurningVideoDriver"); + #endif + + // create backbuffer + BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, params.WindowSize); + if (BackBuffer) + { + BackBuffer->fill(SColor(0)); + + // create z buffer + if ( params.ZBufferBits ) + DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension()); + + // create stencil buffer + if ( params.Stencilbuffer ) + StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension()); + } + + DriverAttributes->setAttribute("MaxTextures", 2); + DriverAttributes->setAttribute("MaxIndices", 1<<16); + DriverAttributes->setAttribute("MaxTextureSize", 1024); + DriverAttributes->setAttribute("MaxLights", glsl::gl_MaxLights); + DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); + DriverAttributes->setAttribute("Version", 47); + + // create triangle renderers + + irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) ); + //BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer); + //BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer); + BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(this); + BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this ); + BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this ); + //BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer); + //BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer); + //BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer); + BurningShader[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud2(this); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M1] = createTriangleRendererTextureLightMap2_M1(this); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M2] = createTriangleRendererTextureLightMap2_M2(this); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M4] = createTriangleRendererGTextureLightMap2_M4(this); + BurningShader[ETR_TEXTURE_LIGHTMAP_M4] = createTriangleRendererTextureLightMap2_M4(this); + BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD] = createTriangleRendererTextureLightMap2_Add(this); + BurningShader[ETR_TEXTURE_GOURAUD_DETAIL_MAP] = createTriangleRendererTextureDetailMap2(this); + + BurningShader[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire2(this); + BurningShader[ETR_TEXTURE_GOURAUD_NOZ] = createTRTextureGouraudNoZ2(this); + BurningShader[ETR_TEXTURE_GOURAUD_ADD] = createTRTextureGouraudAdd2(this); + BurningShader[ETR_TEXTURE_GOURAUD_ADD_NO_Z] = createTRTextureGouraudAddNoZ2(this); + BurningShader[ETR_TEXTURE_GOURAUD_VERTEX_ALPHA] = createTriangleRendererTextureVertexAlpha2 ( this ); + + BurningShader[ETR_TEXTURE_GOURAUD_ALPHA] = createTRTextureGouraudAlpha(this ); + BurningShader[ETR_TEXTURE_GOURAUD_ALPHA_NOZ] = createTRTextureGouraudAlphaNoZ( this ); + + BurningShader[ETR_NORMAL_MAP_SOLID] = createTRNormalMap ( this ); + BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this ); + BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this ); + + BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this ); + + + // add the same renderer for all solid types + CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID( this); + CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR( this); + CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this ); + + //!TODO: addMaterialRenderer depends on pushing order.... + addMaterialRenderer ( smr ); // EMT_SOLID + addMaterialRenderer ( smr ); // EMT_SOLID_2_LAYER, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP, + addMaterialRenderer ( tmr ); // EMT_LIGHTMAP_ADD, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M2, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_M4, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2, + addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4, + addMaterialRenderer ( smr ); // EMT_DETAIL_MAP, + addMaterialRenderer ( umr ); // EMT_SPHERE_MAP, + addMaterialRenderer ( smr ); // EMT_REFLECTION_2_LAYER, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ADD_COLOR, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL_REF, + addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA, + addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER, + addMaterialRenderer ( smr ); // EMT_NORMAL_MAP_SOLID, + addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, + addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, + addMaterialRenderer ( smr ); // EMT_PARALLAX_MAP_SOLID, + addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, + addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, + addMaterialRenderer ( tmr ); // EMT_ONETEXTURE_BLEND + + smr->drop (); + tmr->drop (); + umr->drop (); + + // select render target + setRenderTarget(BackBuffer); + + //reset Lightspace + LightSpace.reset (); + + // select the right renderer + setCurrentShader(); +} + + +//! destructor +CBurningVideoDriver::~CBurningVideoDriver() +{ + // delete Backbuffer + if (BackBuffer) + BackBuffer->drop(); + + // delete triangle renderers + + for (s32 i=0; idrop(); + } + + // delete Additional buffer + if (StencilBuffer) + StencilBuffer->drop(); + + if (DepthBuffer) + DepthBuffer->drop(); + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + if (RenderTargetSurface) + RenderTargetSurface->drop(); +} + + +/*! + selects the right triangle renderer based on the render states. +*/ +void CBurningVideoDriver::setCurrentShader() +{ + ITexture *texture0 = Material.org.getTexture(0); + ITexture *texture1 = Material.org.getTexture(1); + + bool zMaterialTest = Material.org.ZBuffer != ECFN_NEVER && + Material.org.ZWriteEnable && + ( AllowZWriteOnTransparent || !Material.org.isTransparent() ); + + EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; + + TransformationFlag[ ETS_TEXTURE_0] &= ~(ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION); + LightSpace.Flags &= ~VERTEXTRANSFORM; + + switch ( Material.org.MaterialType ) + { + case EMT_ONETEXTURE_BLEND: + shader = ETR_TEXTURE_BLEND; + break; + + case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: + Material.org.MaterialTypeParam = 0.5f; + // fall through + case EMT_TRANSPARENT_ALPHA_CHANNEL: + if ( texture0 && texture0->hasAlpha () ) + { + shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ; + break; + } + // fall through + + case EMT_TRANSPARENT_ADD_COLOR: + shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z; + break; + + case EMT_TRANSPARENT_VERTEX_ALPHA: + shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA; + break; + + case EMT_LIGHTMAP: + case EMT_LIGHTMAP_LIGHTING: + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1; + break; + + case EMT_LIGHTMAP_M2: + case EMT_LIGHTMAP_LIGHTING_M2: + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2; + break; + + case EMT_LIGHTMAP_LIGHTING_M4: + if ( texture1 ) + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4; + break; + case EMT_LIGHTMAP_M4: + if ( texture1 ) + shader = ETR_TEXTURE_LIGHTMAP_M4; + break; + + case EMT_LIGHTMAP_ADD: + if ( texture1 ) + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD; + break; + + case EMT_DETAIL_MAP: + if ( texture1 ) + shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP; + break; + + case EMT_SPHERE_MAP: + TransformationFlag[ ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_REFLECTION; // ETF_TEXGEN_CAMERA_NORMAL; + LightSpace.Flags |= VERTEXTRANSFORM; + break; + case EMT_REFLECTION_2_LAYER: + shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1; + TransformationFlag[ ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION; + LightSpace.Flags |= VERTEXTRANSFORM; + break; + + case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA: + case EMT_NORMAL_MAP_SOLID: + case EMT_PARALLAX_MAP_SOLID: + case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA: + shader = ETR_NORMAL_MAP_SOLID; + LightSpace.Flags |= VERTEXTRANSFORM; + break; + + default: + break; + + } + + if ( !texture0 ) + { + shader = ETR_GOURAUD; + } + + if ( Material.org.Wireframe ) + { + shader = ETR_TEXTURE_GOURAUD_WIRE; + } + + //shader = ETR_REFERENCE; + + // switchToTriangleRenderer + CurrentShader = BurningShader[shader]; + if ( CurrentShader ) + { + CurrentShader->setZCompareFunc ( Material.org.ZBuffer ); + CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); + CurrentShader->setMaterial ( Material ); + + switch ( shader ) + { + case ETR_TEXTURE_GOURAUD_ALPHA: + case ETR_TEXTURE_GOURAUD_ALPHA_NOZ: + case ETR_TEXTURE_BLEND: + CurrentShader->setParam ( 0, Material.org.MaterialTypeParam ); + break; + default: + break; + } + } + +} + + + +//! queries the features of the driver, returns true if feature is available +bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const +{ + if (!FeatureEnabled[feature]) + return false; + + switch (feature) + { +#ifdef SOFTWARE_DRIVER_2_BILINEAR + case EVDF_BILINEAR_FILTER: + return true; +#endif +#ifdef SOFTWARE_DRIVER_2_MIPMAPPING + case EVDF_MIP_MAP: + return true; +#endif + case EVDF_STENCIL_BUFFER: + case EVDF_RENDER_TO_TARGET: + case EVDF_MULTITEXTURE: + case EVDF_HARDWARE_TL: + case EVDF_TEXTURE_NSQUARE: + return true; + + default: + return false; + } +} + + + +//! sets transformation +void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) +{ + Transformation[state] = mat; + core::setbit_cond ( TransformationFlag[state], mat.isIdentity(), ETF_IDENTITY ); + + switch ( state ) + { + case ETS_VIEW: + Transformation[ETS_VIEW_PROJECTION].setbyproduct_nocheck ( + Transformation[ETS_PROJECTION], + Transformation[ETS_VIEW] + ); + getCameraPosWorldSpace (); + break; + + case ETS_WORLD: + if ( TransformationFlag[state] & ETF_IDENTITY ) + { + Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD]; + TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY; + Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION]; + } + else + { + //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] ); + Transformation[ETS_CURRENT].setbyproduct_nocheck ( + Transformation[ETS_VIEW_PROJECTION], + Transformation[ETS_WORLD] + ); + } + TransformationFlag[ETS_CURRENT] = 0; + //getLightPosObjectSpace (); + break; + case ETS_TEXTURE_0: + case ETS_TEXTURE_1: + case ETS_TEXTURE_2: + case ETS_TEXTURE_3: + if ( 0 == (TransformationFlag[state] & ETF_IDENTITY ) ) + LightSpace.Flags |= VERTEXTRANSFORM; + default: + break; + } +} + + +//! clears the zbuffer +bool CBurningVideoDriver::beginScene(bool backBuffer, bool zBuffer, + SColor color, const SExposedVideoData& videoData, + core::rect* sourceRect) +{ + CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); + WindowId = videoData.D3D9.HWnd; + SceneSourceRect = sourceRect; + + if (backBuffer && BackBuffer) + BackBuffer->fill(color); + + if (zBuffer && DepthBuffer) + DepthBuffer->clear(); + + memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) ); + return true; +} + + +//! presents the rendered scene on the screen, returns false if failed +bool CBurningVideoDriver::endScene() +{ + CNullDriver::endScene(); + + return Presenter->present(BackBuffer, WindowId, SceneSourceRect); +} + + +//! sets a render target +bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color) +{ + if (texture && texture->getDriverType() != EDT_BURNINGSVIDEO) + { + os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); + return false; + } + + if (RenderTargetTexture) + RenderTargetTexture->drop(); + + RenderTargetTexture = texture; + + if (RenderTargetTexture) + { + RenderTargetTexture->grab(); + setRenderTarget(((CSoftwareTexture2*)RenderTargetTexture)->getTexture()); + } + else + { + setRenderTarget(BackBuffer); + } + + if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) + { + if (clearZBuffer) + DepthBuffer->clear(); + + if (clearBackBuffer) + RenderTargetSurface->fill( color ); + } + + return true; +} + + +//! sets a render target +void CBurningVideoDriver::setRenderTarget(video::CImage* image) +{ + if (RenderTargetSurface) + RenderTargetSurface->drop(); + + RenderTargetSurface = image; + RenderTargetSize.Width = 0; + RenderTargetSize.Height = 0; + + if (RenderTargetSurface) + { + RenderTargetSurface->grab(); + RenderTargetSize = RenderTargetSurface->getDimension(); + } + + setViewPort(core::rect(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); + + if (DepthBuffer) + DepthBuffer->setSize(RenderTargetSize); + + if (StencilBuffer) + StencilBuffer->setSize(RenderTargetSize); +} + + + +//! sets a viewport +void CBurningVideoDriver::setViewPort(const core::rect& area) +{ + ViewPort = area; + + core::rect rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); + ViewPort.clipAgainst(rendert); + + Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 ); + + if (CurrentShader) + CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort); +} + +/* + generic plane clipping in homogenous coordinates + special case ndc frustum <-w,w>,<-w,w>,<-w,w> + can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w +*/ + +const sVec4 CBurningVideoDriver::NDCPlane[6] = +{ + sVec4( 0.f, 0.f, -1.f, -1.f ), // near + sVec4( 0.f, 0.f, 1.f, -1.f ), // far + sVec4( 1.f, 0.f, 0.f, -1.f ), // left + sVec4( -1.f, 0.f, 0.f, -1.f ), // right + sVec4( 0.f, 1.f, 0.f, -1.f ), // bottom + sVec4( 0.f, -1.f, 0.f, -1.f ) // top +}; + + + +/* + test a vertex if it's inside the standard frustum + + this is the generic one.. + + f32 dotPlane; + for ( u32 i = 0; i!= 6; ++i ) + { + dotPlane = v->Pos.dotProduct ( NDCPlane[i] ); + core::setbit_cond( flag, dotPlane <= 0.f, 1 << i ); + } + + // this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w> + core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 ); + core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 ); + core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 ); + core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 ); + core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 ); + core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 ); + +*/ +#ifdef IRRLICHT_FAST_MATH + +REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const +{ + f32 test[6]; + u32 flag; + const f32 w = - v->Pos.w; + + // a conditional move is needed....FCOMI ( but we don't have it ) + // so let the fpu calculate and write it back. + // cpu makes the compare, interleaving + + test[0] = v->Pos.z + w; + test[1] = -v->Pos.z + w; + test[2] = v->Pos.x + w; + test[3] = -v->Pos.x + w; + test[4] = v->Pos.y + w; + test[5] = -v->Pos.y + w; + + flag = (IR ( test[0] ) ) >> 31; + flag |= (IR ( test[1] ) & 0x80000000 ) >> 30; + flag |= (IR ( test[2] ) & 0x80000000 ) >> 29; + flag |= (IR ( test[3] ) & 0x80000000 ) >> 28; + flag |= (IR ( test[4] ) & 0x80000000 ) >> 27; + flag |= (IR ( test[5] ) & 0x80000000 ) >> 26; + +/* + flag = F32_LOWER_EQUAL_0 ( test[0] ); + flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1; + flag |= F32_LOWER_EQUAL_0 ( test[2] ) << 2; + flag |= F32_LOWER_EQUAL_0 ( test[3] ) << 3; + flag |= F32_LOWER_EQUAL_0 ( test[4] ) << 4; + flag |= F32_LOWER_EQUAL_0 ( test[5] ) << 5; +*/ + return flag; +} + +#else + + +REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const +{ + u32 flag = 0; + + if ( v->Pos.z <= v->Pos.w ) flag |= 1; + if (-v->Pos.z <= v->Pos.w ) flag |= 2; + + if ( v->Pos.x <= v->Pos.w ) flag |= 4; + if (-v->Pos.x <= v->Pos.w ) flag |= 8; + + if ( v->Pos.y <= v->Pos.w ) flag |= 16; + if (-v->Pos.y <= v->Pos.w ) flag |= 32; + +/* + for ( u32 i = 0; i!= 6; ++i ) + { + core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i ); + } +*/ + return flag; +} + +#endif // _MSC_VER + +u32 CBurningVideoDriver::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane ) +{ + u32 outCount = 0; + s4DVertex * out = dest; + + const s4DVertex * a; + const s4DVertex * b = source; + + f32 bDotPlane; + + bDotPlane = b->Pos.dotProduct ( plane ); + + for( u32 i = 1; i < inCount + 1; ++i) + { + const s32 condition = i - inCount; + const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1; + + a = &source[ index ]; + + // current point inside + if ( a->Pos.dotProduct ( plane ) <= 0.f ) + { + // last point outside + if ( F32_GREATER_0 ( bDotPlane ) ) + { + // intersect line segment with plane + out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); + out += 2; + outCount += 1; + } + + // copy current to out + //*out = *a; + irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 ); + b = out; + + out += 2; + outCount += 1; + } + else + { + // current point outside + + if ( F32_LOWER_EQUAL_0 ( bDotPlane ) ) + { + // previous was inside + // intersect line segment with plane + out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) ); + out += 2; + outCount += 1; + } + // pointer + b = a; + } + + bDotPlane = b->Pos.dotProduct ( plane ); + + } + + return outCount; +} + + +u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn ) +{ + u32 vOut = vIn; + + vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut; + vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[5] ); + return vOut; +} + +/*! + Part I: + apply Clip Scale matrix + From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC ) + + Part II: + Project homogeneous vector + homogeneous to non-homogenous coordinates ( dividebyW ) + + Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A ) + Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w ) + + + replace w/w by 1/w +*/ +inline void CBurningVideoDriver::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const +{ + u32 g; + + for ( g = 0; g != vIn; g += 2 ) + { + if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) + continue; + + dest[g].flag = source[g].flag | VERTEX4D_PROJECTED; + + const f32 w = source[g].Pos.w; + const f32 iw = core::reciprocal ( w ); + + // to device coordinates + dest[g].Pos.x = iw * ( source[g].Pos.x * Transformation [ ETS_CLIPSCALE ][ 0] + w * Transformation [ ETS_CLIPSCALE ][12] ); + dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ][ 5] + w * Transformation [ ETS_CLIPSCALE ][13] ); + +#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER + dest[g].Pos.z = iw * source[g].Pos.z; +#endif + + #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dest[g].Color[0] = source[g].Color[0] * iw; + #else + dest[g].Color[0] = source[g].Color[0]; + #endif + + #endif + dest[g].LightTangent[0] = source[g].LightTangent[0] * iw; + dest[g].Pos.w = iw; + } +} + + +inline void CBurningVideoDriver::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const +{ + u32 g; + + for ( g = 0; g != size; g += 1 ) + { + s4DVertex * a = (s4DVertex*) v[g]; + + if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED ) + continue; + + a[1].flag = a->flag | VERTEX4D_PROJECTED; + + // project homogenous vertex, store 1/w + const f32 w = a->Pos.w; + const f32 iw = core::reciprocal ( w ); + + // to device coordinates + const f32 * p = Transformation [ ETS_CLIPSCALE ].pointer(); + a[1].Pos.x = iw * ( a->Pos.x * p[ 0] + w * p[12] ); + a[1].Pos.y = iw * ( a->Pos.y * p[ 5] + w * p[13] ); + +#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER + a[1].Pos.z = a->Pos.z * iw; +#endif + + #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + a[1].Color[0] = a->Color[0] * iw; + #else + a[1].Color[0] = a->Color[0]; + #endif + #endif + + a[1].LightTangent[0] = a[0].LightTangent[0] * iw; + a[1].Pos.w = iw; + + } + +} + + +/*! + crossproduct in projected 2D -> screen area triangle +*/ +inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const +{ + return ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) - + ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) ); +} + + +/*! +*/ +inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const +{ + f32 z; + + z = ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) ) + - ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) ); + + return MAT_TEXTURE ( tex )->getLODFactor ( z ); +} + +/*! + crossproduct in projected 2D +*/ +inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const +{ + return ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) - + ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) ); +} + +/*! +*/ +inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const +{ + f32 z; + z = ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) ) + - ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) ); + + return MAT_TEXTURE ( tex )->getLODFactor ( z ); +} + + +/*! +*/ +inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, u32 tex, const core::dimension2du& texSize ) const +{ + f32 f[2]; + + f[0] = (f32) texSize.Width - 0.25f; + f[1] = (f32) texSize.Height - 0.25f; + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + for ( u32 g = 0; g != vIn; g += 2 ) + { + (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0]; + (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1]; + } +#else + for ( u32 g = 0; g != vIn; g += 2 ) + { + (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * f[0]; + (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * f[1]; + } +#endif +} + +inline void CBurningVideoDriver::select_polygon_mipmap2 ( s4DVertex **v, u32 tex, const core::dimension2du& texSize ) const +{ + f32 f[2]; + + f[0] = (f32) texSize.Width - 0.25f; + f[1] = (f32) texSize.Height - 0.25f; + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0]; + (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1]; + + (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0]; + (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1]; + + (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0]; + (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1]; + +#else + (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0]; + (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1]; + + (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0]; + (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1]; + + (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0]; + (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1]; +#endif +} + +// Vertex Cache +const SVSize CBurningVideoDriver::vSize[] = +{ + { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 }, + { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 }, + { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 }, + { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, // reflection map + { 0, sizeof(f32) * 3, 0 }, // core::vector3df* +}; + + + +/*! + fill a cache line with transformed, light and clipp test triangles +*/ +void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex) +{ + u8 * source; + s4DVertex *dest; + + source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch ); + + // it's a look ahead so we never hit it.. + // but give priority... + //VertexCache.info[ destIndex ].hit = hitCount; + + // store info + VertexCache.info[ destIndex ].index = sourceIndex; + VertexCache.info[ destIndex ].hit = 0; + + // destination Vertex + dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + + // transform Model * World * Camera * Projection * NDCSpace matrix + const S3DVertex *base = ((S3DVertex*) source ); + Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos ); + + //mhm ;-) maybe no goto + if ( VertexCache.vType == 4 ) goto clipandproject; + + +#if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) + + // vertex normal in light space + if ( Material.org.Lighting || (LightSpace.Flags & VERTEXTRANSFORM) ) + { + if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY ) + { + LightSpace.normal.set ( base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f ); + LightSpace.vertex.set ( base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f ); + } + else + { + Transformation[ETS_WORLD].rotateVect ( &LightSpace.normal.x, base->Normal ); + + // vertex in light space + if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR | VERTEXTRANSFORM) ) + Transformation[ETS_WORLD].transformVect ( &LightSpace.vertex.x, base->Pos ); + } + + if ( LightSpace.Flags & NORMALIZE ) + LightSpace.normal.normalize_xyz(); + + } + +#endif + +#if defined ( SOFTWARE_DRIVER_2_USE_VERTEX_COLOR ) + // apply lighting model + #if defined (SOFTWARE_DRIVER_2_LIGHTING) + if ( Material.org.Lighting ) + { + lightVertex ( dest, base->Color.color ); + } + else + { + dest->Color[0].setA8R8G8B8 ( base->Color.color ); + } + #else + dest->Color[0].setA8R8G8B8 ( base->Color.color ); + #endif +#endif + + // Texture Transform +#if !defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) + irr::memcpy32_small ( &dest->Tex[0],&base->TCoords, + vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 ) + ); +#else + + if ( 0 == (LightSpace.Flags & VERTEXTRANSFORM) ) + { + irr::memcpy32_small ( &dest->Tex[0],&base->TCoords, + vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 ) + ); + } + else + { + /* + Generate texture coordinates as linear functions so that: + u = Ux*x + Uy*y + Uz*z + Uw + v = Vx*x + Vy*y + Vz*z + Vw + The matrix M for this case is: + Ux Vx 0 0 + Uy Vy 0 0 + Uz Vz 0 0 + Uw Vw 0 0 + */ + + u32 t; + sVec4 n; + sVec2 srcT; + + for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t ) + { + const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ]; + + // texgen + if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & (ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION) ) + { + n.x = LightSpace.campos.x - LightSpace.vertex.x; + n.y = LightSpace.campos.x - LightSpace.vertex.y; + n.z = LightSpace.campos.x - LightSpace.vertex.z; + n.normalize_xyz(); + n.x += LightSpace.normal.x; + n.y += LightSpace.normal.y; + n.z += LightSpace.normal.z; + n.normalize_xyz(); + + const f32 *view = Transformation[ETS_VIEW].pointer(); + + if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & ETF_TEXGEN_CAMERA_REFLECTION ) + { + srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[4] + n.z * view[8] )); + srcT.y = 0.5f * ( 1.f + (n.x * view[1] + n.y * view[5] + n.z * view[9] )); + } + else + { + srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[1] + n.z * view[2] )); + srcT.y = 0.5f * ( 1.f + (n.x * view[4] + n.y * view[5] + n.z * view[6] )); + } + } + else + { + irr::memcpy32_small ( &srcT,(&base->TCoords) + t, + sizeof ( f32 ) * 2 ); + } + + switch ( Material.org.TextureLayer[t].TextureWrapU ) + { + case ETC_CLAMP: + case ETC_CLAMP_TO_EDGE: + case ETC_CLAMP_TO_BORDER: + dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f ); + break; + case ETC_MIRROR: + dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8]; + if (core::fract(dest->Tex[t].x)>0.5f) + dest->Tex[t].x=1.f-dest->Tex[t].x; + break; + case ETC_MIRROR_CLAMP: + case ETC_MIRROR_CLAMP_TO_EDGE: + case ETC_MIRROR_CLAMP_TO_BORDER: + dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f ); + if (core::fract(dest->Tex[t].x)>0.5f) + dest->Tex[t].x=1.f-dest->Tex[t].x; + break; + case ETC_REPEAT: + default: + dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8]; + break; + } + switch ( Material.org.TextureLayer[t].TextureWrapV ) + { + case ETC_CLAMP: + case ETC_CLAMP_TO_EDGE: + case ETC_CLAMP_TO_BORDER: + dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f ); + break; + case ETC_MIRROR: + dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9]; + if (core::fract(dest->Tex[t].y)>0.5f) + dest->Tex[t].y=1.f-dest->Tex[t].y; + break; + case ETC_MIRROR_CLAMP: + case ETC_MIRROR_CLAMP_TO_EDGE: + case ETC_MIRROR_CLAMP_TO_BORDER: + dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f ); + if (core::fract(dest->Tex[t].y)>0.5f) + dest->Tex[t].y=1.f-dest->Tex[t].y; + break; + case ETC_REPEAT: + default: + dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9]; + break; + } + } + } + +#if 0 + // tangent space light vector, emboss + if ( Lights.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) ) + { + const S3DVertexTangents *tangent = ((S3DVertexTangents*) source ); + const SBurningShaderLight &light = LightSpace.Light[0]; + + sVec4 vp; + + vp.x = light.pos.x - LightSpace.vertex.x; + vp.y = light.pos.y - LightSpace.vertex.y; + vp.z = light.pos.z - LightSpace.vertex.z; + + vp.normalize_xyz(); + + LightSpace.tangent.x = vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z; + LightSpace.tangent.y = vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z; + //LightSpace.tangent.z = vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z; + LightSpace.tangent.z = 0.f; + LightSpace.tangent.normalize_xyz(); + + f32 scale = 1.f / 128.f; + if ( Material.org.MaterialTypeParam > 0.f ) + scale = Material.org.MaterialTypeParam; + + // emboss, shift coordinates + dest->Tex[1].x = dest->Tex[0].x + LightSpace.tangent.x * scale; + dest->Tex[1].y = dest->Tex[0].y + LightSpace.tangent.y * scale; + //dest->Tex[1].z = LightSpace.tangent.z * scale; + } +#endif + + if ( LightSpace.Light.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) ) + { + const S3DVertexTangents *tangent = ((S3DVertexTangents*) source ); + + sVec4 vp; + + dest->LightTangent[0].x = 0.f; + dest->LightTangent[0].y = 0.f; + dest->LightTangent[0].z = 0.f; + for ( u32 i = 0; i < 2 && i < LightSpace.Light.size (); ++i ) + { + const SBurningShaderLight &light = LightSpace.Light[i]; + + if ( !light.LightIsOn ) + continue; + + vp.x = light.pos.x - LightSpace.vertex.x; + vp.y = light.pos.y - LightSpace.vertex.y; + vp.z = light.pos.z - LightSpace.vertex.z; + + /* + vp.x = light.pos_objectspace.x - base->Pos.X; + vp.y = light.pos_objectspace.y - base->Pos.Y; + vp.z = light.pos_objectspace.z - base->Pos.Z; + */ + + vp.normalize_xyz(); + + + // transform by tangent matrix + sVec3 l; + #if 1 + l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z ); + l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z ); + l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z ); + #else + l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X ); + l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y ); + l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z ); + #endif + + + /* + f32 scale = 1.f / 128.f; + scale /= dest->LightTangent[0].b; + + // emboss, shift coordinates + dest->Tex[1].x = dest->Tex[0].x + l.r * scale; + dest->Tex[1].y = dest->Tex[0].y + l.g * scale; + */ + dest->Tex[1].x = dest->Tex[0].x; + dest->Tex[1].y = dest->Tex[0].y; + + // scale bias + dest->LightTangent[0].x += l.x; + dest->LightTangent[0].y += l.y; + dest->LightTangent[0].z += l.z; + } + dest->LightTangent[0].setLength ( 0.5f ); + dest->LightTangent[0].x += 0.5f; + dest->LightTangent[0].y += 0.5f; + dest->LightTangent[0].z += 0.5f; + } + + +#endif + +clipandproject: + dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format; + + // test vertex + dest[0].flag |= clipToFrustumTest ( dest); + + // to DC Space, project homogenous vertex + if ( (dest[0].flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) + { + ndc_2_dc_and_project2 ( (const s4DVertex**) &dest, 1 ); + } + + //return dest; +} + +// + +REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex ) +{ + for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i ) + { + if ( VertexCache.info[ i ].index == sourceIndex ) + { + return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + } + } + return 0; +} + + +/* + Cache based on linear walk indices + fill blockwise on the next 16(Cache_Size) unique vertices in indexlist + merge the next 16 vertices with the current +*/ +REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face) +{ + SCacheInfo info[VERTEXCACHE_ELEMENT]; + + // next primitive must be complete in cache + if ( VertexCache.indicesIndex - VertexCache.indicesRun < 3 && + VertexCache.indicesIndex < VertexCache.indexCount + ) + { + // rewind to start of primitive + VertexCache.indicesIndex = VertexCache.indicesRun; + + irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) ); + + // get the next unique vertices cache line + u32 fillIndex = 0; + u32 dIndex; + u32 i; + u32 sourceIndex; + + while ( VertexCache.indicesIndex < VertexCache.indexCount && + fillIndex < VERTEXCACHE_ELEMENT + ) + { + switch ( VertexCache.iType ) + { + case 1: + sourceIndex = ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ]; + break; + case 2: + sourceIndex = ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ]; + break; + case 4: + sourceIndex = VertexCache.indicesIndex; + break; + } + + VertexCache.indicesIndex += 1; + + // if not exist, push back + s32 exist = 0; + for ( dIndex = 0; dIndex < fillIndex; ++dIndex ) + { + if ( info[ dIndex ].index == sourceIndex ) + { + exist = 1; + break; + } + } + + if ( 0 == exist ) + { + info[fillIndex++].index = sourceIndex; + } + } + + // clear marks + for ( i = 0; i!= VERTEXCACHE_ELEMENT; ++i ) + { + VertexCache.info[i].hit = 0; + } + + // mark all existing + for ( i = 0; i!= fillIndex; ++i ) + { + for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) + { + if ( VertexCache.info[ dIndex ].index == info[i].index ) + { + info[i].hit = dIndex; + VertexCache.info[ dIndex ].hit = 1; + break; + } + } + } + + // fill new + for ( i = 0; i!= fillIndex; ++i ) + { + if ( info[i].hit != VERTEXCACHE_MISS ) + continue; + + for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex ) + { + if ( 0 == VertexCache.info[dIndex].hit ) + { + VertexCache_fill ( info[i].index, dIndex ); + VertexCache.info[dIndex].hit += 1; + info[i].hit = dIndex; + break; + } + } + } + } + + const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); + + switch ( VertexCache.iType ) + { + case 1: + { + const u16 *p = (const u16 *) VertexCache.indices; + face[0] = VertexCache_getVertex ( p[ i0 ] ); + face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); + face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); + } + break; + + case 2: + { + const u32 *p = (const u32 *) VertexCache.indices; + face[0] = VertexCache_getVertex ( p[ i0 ] ); + face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); + face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); + } + break; + + case 4: + face[0] = VertexCache_getVertex ( VertexCache.indicesRun + 0 ); + face[1] = VertexCache_getVertex ( VertexCache.indicesRun + 1 ); + face[2] = VertexCache_getVertex ( VertexCache.indicesRun + 2 ); + break; + default: + face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0); + break; + } + + VertexCache.indicesRun += VertexCache.primitivePitch; +} + +/*! +*/ +REALINLINE void CBurningVideoDriver::VertexCache_getbypass ( s4DVertex ** face ) +{ + const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); + + if ( VertexCache.iType == 1 ) + { + const u16 *p = (const u16 *) VertexCache.indices; + VertexCache_fill ( p[ i0 ], 0 ); + VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 ); + VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 ); + } + else + { + const u32 *p = (const u32 *) VertexCache.indices; + VertexCache_fill ( p[ i0 ], 0 ); + VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 ); + VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 ); + } + + VertexCache.indicesRun += VertexCache.primitivePitch; + + face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ); + +} + +/*! +*/ +void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount, + const void* indices, u32 primitiveCount, + E_VERTEX_TYPE vType, + scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType) +{ + VertexCache.vertices = vertices; + VertexCache.vertexCount = vertexCount; + + VertexCache.indices = indices; + VertexCache.indicesIndex = 0; + VertexCache.indicesRun = 0; + + if ( Material.org.MaterialType == video::EMT_REFLECTION_2_LAYER ) + VertexCache.vType = 3; + else + VertexCache.vType = vType; + VertexCache.pType = pType; + + switch ( iType ) + { + case EIT_16BIT: VertexCache.iType = 1; break; + case EIT_32BIT: VertexCache.iType = 2; break; + default: + VertexCache.iType = iType; break; + } + + switch ( VertexCache.pType ) + { + // most types here will not work as expected, only triangles/triangle_fan + // is known to work. + case scene::EPT_POINTS: + VertexCache.indexCount = primitiveCount; + VertexCache.primitivePitch = 1; + break; + case scene::EPT_LINE_STRIP: + VertexCache.indexCount = primitiveCount+1; + VertexCache.primitivePitch = 1; + break; + case scene::EPT_LINE_LOOP: + VertexCache.indexCount = primitiveCount+1; + VertexCache.primitivePitch = 1; + break; + case scene::EPT_LINES: + VertexCache.indexCount = 2*primitiveCount; + VertexCache.primitivePitch = 2; + break; + case scene::EPT_TRIANGLE_STRIP: + VertexCache.indexCount = primitiveCount+2; + VertexCache.primitivePitch = 1; + break; + case scene::EPT_TRIANGLES: + VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount; + VertexCache.primitivePitch = 3; + break; + case scene::EPT_TRIANGLE_FAN: + VertexCache.indexCount = primitiveCount + 2; + VertexCache.primitivePitch = 1; + break; + case scene::EPT_QUAD_STRIP: + VertexCache.indexCount = 2*primitiveCount + 2; + VertexCache.primitivePitch = 2; + break; + case scene::EPT_QUADS: + VertexCache.indexCount = 4*primitiveCount; + VertexCache.primitivePitch = 4; + break; + case scene::EPT_POLYGON: + VertexCache.indexCount = primitiveCount+1; + VertexCache.primitivePitch = 1; + break; + case scene::EPT_POINT_SPRITES: + VertexCache.indexCount = primitiveCount; + VertexCache.primitivePitch = 1; + break; + } + + irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) ); +} + + +void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) + +{ + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + + // These calls would lead to crashes due to wrong index usage. + // The vertex cache needs to be rewritten for these primitives. + if (pType==scene::EPT_POINTS || pType==scene::EPT_LINE_STRIP || + pType==scene::EPT_LINE_LOOP || pType==scene::EPT_LINES || pType==scene::EPT_POLYGON || + pType==scene::EPT_POINT_SPRITES) + return; + + if ( 0 == CurrentShader ) + return; + + VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType, iType ); + + const s4DVertex * face[3]; + + f32 dc_area; + s32 lodLevel; + u32 i; + u32 g; + u32 m; + video::CSoftwareTexture2* tex; + + for ( i = 0; i < (u32) primitiveCount; ++i ) + { + VertexCache_get(face); + + // if fully outside or outside on same side + if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK ) + != VERTEX4D_INSIDE + ) + continue; + + // if fully inside + if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) + { + dc_area = screenarea2 ( face ); + if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) ) + continue; + else + if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) ) + continue; + + // select mipmap + dc_area = core::reciprocal ( dc_area ); + for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m ) + { + if ( 0 == (tex = MAT_TEXTURE ( m )) ) + { + CurrentShader->setTextureParam(m, 0, 0); + continue; + } + + lodLevel = s32_log2_f32 ( texelarea2 ( face, m ) * dc_area ); + CurrentShader->setTextureParam(m, tex, lodLevel ); + select_polygon_mipmap2 ( (s4DVertex**) face, m, tex->getSize() ); + } + + // rasterize + CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); + continue; + } + + // else if not complete inside clipping necessary + irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 ); + irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 ); + irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 ); + + const u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK; + + for ( g = 0; g != CurrentOut.ElementSize; ++g ) + { + CurrentOut.data[g].flag = flag; + Temp.data[g].flag = flag; + } + + u32 vOut; + vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); + if ( vOut < 3 ) + continue; + + vOut <<= 1; + + // to DC Space, project homogenous vertex + ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); + +/* + // TODO: don't stick on 32 Bit Pointer + #define PointerAsValue(x) ( (u32) (u32*) (x) ) + + // if not complete inside clipping necessary + if ( ( test & VERTEX4D_INSIDE ) != VERTEX4D_INSIDE ) + { + u32 v[2] = { PointerAsValue ( Temp ) , PointerAsValue ( CurrentOut ) }; + for ( g = 0; g != 6; ++g ) + { + vOut = clipToHyperPlane ( (s4DVertex*) v[0], (s4DVertex*) v[1], vOut, NDCPlane[g] ); + if ( vOut < 3 ) + break; + + v[0] ^= v[1]; + v[1] ^= v[0]; + v[0] ^= v[1]; + } + + if ( vOut < 3 ) + continue; + + } +*/ + + // check 2d backface culling on first + dc_area = screenarea ( CurrentOut.data ); + if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) ) + continue; + else if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) ) + continue; + + // select mipmap + dc_area = core::reciprocal ( dc_area ); + for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m ) + { + if ( 0 == (tex = MAT_TEXTURE ( m )) ) + { + CurrentShader->setTextureParam(m, 0, 0); + continue; + } + + lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, m ) * dc_area ); + CurrentShader->setTextureParam(m, tex, lodLevel ); + select_polygon_mipmap ( CurrentOut.data, vOut, m, tex->getSize() ); + } + + + // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) + for ( g = 0; g <= vOut - 6; g += 2 ) + { + // rasterize + CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1, + CurrentOut.data + g + 3, + CurrentOut.data + g + 5); + } + + } + + // dump statistics +/* + char buf [64]; + sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d", + vertexCount, primitiveCount, + VertexCache.CacheMiss + ); + os::Printer::log( buf ); +*/ + +} + + +//! Sets the dynamic ambient light color. The default color is +//! (0,0,0,0) which means it is dark. +//! \param color: New color of the ambient light. +void CBurningVideoDriver::setAmbientLight(const SColorf& color) +{ + LightSpace.Global_AmbientLight.setColorf ( color ); +} + + +//! adds a dynamic light +s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) +{ + (void) CNullDriver::addDynamicLight( dl ); + + SBurningShaderLight l; +// l.org = dl; + l.Type = dl.Type; + l.LightIsOn = true; + + l.AmbientColor.setColorf ( dl.AmbientColor ); + l.DiffuseColor.setColorf ( dl.DiffuseColor ); + l.SpecularColor.setColorf ( dl.SpecularColor ); + + switch ( dl.Type ) + { + case video::ELT_DIRECTIONAL: + l.pos.x = -dl.Direction.X; + l.pos.y = -dl.Direction.Y; + l.pos.z = -dl.Direction.Z; + l.pos.w = 1.f; + break; + case ELT_POINT: + case ELT_SPOT: + LightSpace.Flags |= POINTLIGHT; + l.pos.x = dl.Position.X; + l.pos.y = dl.Position.Y; + l.pos.z = dl.Position.Z; + l.pos.w = 1.f; +/* + l.radius = (1.f / dl.Attenuation.Y) * (1.f / dl.Attenuation.Y); + l.constantAttenuation = dl.Attenuation.X; + l.linearAttenuation = dl.Attenuation.Y; + l.quadraticAttenuation = dl.Attenuation.Z; +*/ + l.radius = dl.Radius * dl.Radius; + l.constantAttenuation = dl.Attenuation.X; + l.linearAttenuation = 1.f / dl.Radius; + l.quadraticAttenuation = dl.Attenuation.Z; + + break; + default: + break; + } + + LightSpace.Light.push_back ( l ); + return LightSpace.Light.size() - 1; +} + +//! Turns a dynamic light on or off +void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn) +{ + if(lightIndex > -1 && lightIndex < (s32)LightSpace.Light.size()) + { + LightSpace.Light[lightIndex].LightIsOn = turnOn; + } +} + +//! deletes all dynamic lights there are +void CBurningVideoDriver::deleteAllDynamicLights() +{ + LightSpace.reset (); + CNullDriver::deleteAllDynamicLights(); + +} + +//! returns the maximal amount of dynamic lights the device can handle +u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const +{ + return 8; +} + + +//! sets a material +void CBurningVideoDriver::setMaterial(const SMaterial& material) +{ + Material.org = material; + +#ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM + for (u32 i = 0; i < 2; ++i) + { + setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), + material.getTextureMatrix(i)); + } +#endif + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + Material.AmbientColor.setR8G8B8 ( Material.org.AmbientColor.color ); + Material.DiffuseColor.setR8G8B8 ( Material.org.DiffuseColor.color ); + Material.EmissiveColor.setR8G8B8 ( Material.org.EmissiveColor.color ); + Material.SpecularColor.setR8G8B8 ( Material.org.SpecularColor.color ); + + core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR ); + core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG ); + core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE ); +#endif + + setCurrentShader(); +} + + +/*! + Camera Position in World Space +*/ +void CBurningVideoDriver::getCameraPosWorldSpace () +{ + Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ]; + Transformation[ETS_VIEW_INVERSE].makeInverse (); + TransformationFlag[ETS_VIEW_INVERSE] = 0; + + const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer (); + + /* The viewpoint is at (0., 0., 0.) in eye space. + Turning this into a vector [0 0 0 1] and multiply it by + the inverse of the view matrix, the resulting vector is the + object space location of the camera. + */ + + LightSpace.campos.x = M[12]; + LightSpace.campos.y = M[13]; + LightSpace.campos.z = M[14]; + LightSpace.campos.w = 1.f; +} + +void CBurningVideoDriver::getLightPosObjectSpace () +{ + if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY ) + { + Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD]; + TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY; + } + else + { + Transformation[ETS_WORLD].getInverse ( Transformation[ETS_WORLD_INVERSE] ); + TransformationFlag[ETS_WORLD_INVERSE] &= ~ETF_IDENTITY; + } + + for ( u32 i = 0; i < 1 && i < LightSpace.Light.size(); ++i ) + { + SBurningShaderLight &l = LightSpace.Light[i]; + + Transformation[ETS_WORLD_INVERSE].transformVec3 ( &l.pos_objectspace.x, &l.pos.x ); + } +} + + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + +//! Sets the fog mode. +void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); + LightSpace.FogColor.setA8R8G8B8 ( color.color ); +} + +/*! + applies lighting model +*/ +void CBurningVideoDriver::lightVertex ( s4DVertex *dest, u32 vertexargb ) +{ + sVec3 dColor; + + dColor = LightSpace.Global_AmbientLight; + dColor.add ( Material.EmissiveColor ); + + if ( Lights.size () == 0 ) + { + dColor.saturate( dest->Color[0], vertexargb); + return; + } + + sVec3 ambient; + sVec3 diffuse; + sVec3 specular; + + + // the universe started in darkness.. + ambient.set ( 0.f, 0.f, 0.f ); + diffuse.set ( 0.f, 0.f, 0.f ); + specular.set ( 0.f, 0.f, 0.f ); + + + u32 i; + f32 dot; + f32 len; + f32 attenuation; + sVec4 vp; // unit vector vertex to light + sVec4 lightHalf; // blinn-phong reflection + + for ( i = 0; i!= LightSpace.Light.size (); ++i ) + { + const SBurningShaderLight &light = LightSpace.Light[i]; + + if ( !light.LightIsOn ) + continue; + + // accumulate ambient + ambient.add ( light.AmbientColor ); + + switch ( light.Type ) + { + case video::ELT_SPOT: + case video::ELT_POINT: + // surface to light + vp.x = light.pos.x - LightSpace.vertex.x; + vp.y = light.pos.y - LightSpace.vertex.y; + vp.z = light.pos.z - LightSpace.vertex.z; + //vp.x = light.pos_objectspace.x - LightSpace.vertex.x; + //vp.y = light.pos_objectspace.y - LightSpace.vertex.x; + //vp.z = light.pos_objectspace.z - LightSpace.vertex.x; + + len = vp.get_length_xyz_square(); + if ( light.radius < len ) + continue; + + len = core::reciprocal_squareroot ( len ); + + // build diffuse reflection + + //angle between normal and light vector + vp.mul ( len ); + dot = LightSpace.normal.dot_xyz ( vp ); + if ( dot < 0.f ) + continue; + + attenuation = light.constantAttenuation + ( 1.f - ( len * light.linearAttenuation ) ); + + // diffuse component + diffuse.mulAdd ( light.DiffuseColor, 3.f * dot * attenuation ); + + if ( !(LightSpace.Flags & SPECULAR) ) + continue; + + // build specular + // surface to view + lightHalf.x = LightSpace.campos.x - LightSpace.vertex.x; + lightHalf.y = LightSpace.campos.y - LightSpace.vertex.y; + lightHalf.z = LightSpace.campos.z - LightSpace.vertex.z; + lightHalf.normalize_xyz(); + lightHalf += vp; + lightHalf.normalize_xyz(); + + // specular + dot = LightSpace.normal.dot_xyz ( lightHalf ); + if ( dot < 0.f ) + continue; + + //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation ); + specular.mulAdd ( light.SpecularColor, dot * attenuation ); + break; + + case video::ELT_DIRECTIONAL: + + //angle between normal and light vector + dot = LightSpace.normal.dot_xyz ( light.pos ); + if ( dot < 0.f ) + continue; + + // diffuse component + diffuse.mulAdd ( light.DiffuseColor, dot ); + break; + default: + break; + } + + } + + // sum up lights + dColor.mulAdd (ambient, Material.AmbientColor ); + dColor.mulAdd (diffuse, Material.DiffuseColor); + dColor.mulAdd (specular, Material.SpecularColor); + + dColor.saturate ( dest->Color[0], vertexargb ); +} + +#endif + + +//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. +void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, + const core::rect* clipRect, SColor color, + bool useAlphaChannelOfTexture) +{ + if (texture) + { + if (texture->getDriverType() != EDT_BURNINGSVIDEO) + { + os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); + return; + } + +#if 0 + // 2d methods don't use viewPort + core::position2di dest = destPos; + core::recti clip=ViewPort; + if (ViewPort.getSize().Width != ScreenSize.Width) + { + dest.X=ViewPort.UpperLeftCorner.X+core::round32(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width); + dest.Y=ViewPort.UpperLeftCorner.Y+core::round32(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height); + if (clipRect) + { + clip.constrainTo(*clipRect); + } + clipRect = &clip; + } +#endif + if (useAlphaChannelOfTexture) + ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha( + RenderTargetSurface, destPos, sourceRect, color, clipRect); + else + ((CSoftwareTexture2*)texture)->getImage()->copyTo( + RenderTargetSurface, destPos, sourceRect, clipRect); + } +} + + +//! Draws a part of the texture into the rectangle. +void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + if (texture) + { + if (texture->getDriverType() != EDT_BURNINGSVIDEO) + { + os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); + return; + } + + if (useAlphaChannelOfTexture) + StretchBlit(BLITTER_TEXTURE_ALPHA_BLEND, RenderTargetSurface, &destRect, &sourceRect, + ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0)); + else + StretchBlit(BLITTER_TEXTURE, RenderTargetSurface, &destRect, &sourceRect, + ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0)); + } +} + +//! Draws a 2d line. +void CBurningVideoDriver::draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color) +{ + drawLine(BackBuffer, start, end, color ); +} + + +//! Draws a pixel +void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor & color) +{ + BackBuffer->setPixel(x, y, color, true); +} + + +//! draw an 2d rectangle +void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip) +{ + if (clip) + { + core::rect p(pos); + + p.clipAgainst(*clip); + + if(!p.isValid()) + return; + + drawRectangle(BackBuffer, p, color); + } + else + { + if(!pos.isValid()) + return; + + drawRectangle(BackBuffer, pos, color); + } +} + + +//! Only used by the internal engine. Used to notify the driver that +//! the window was resized. +void CBurningVideoDriver::OnResize(const core::dimension2d& size) +{ + // make sure width and height are multiples of 2 + core::dimension2d realSize(size); + + if (realSize.Width % 2) + realSize.Width += 1; + + if (realSize.Height % 2) + realSize.Height += 1; + + if (ScreenSize != realSize) + { + if (ViewPort.getWidth() == (s32)ScreenSize.Width && + ViewPort.getHeight() == (s32)ScreenSize.Height) + { + ViewPort.UpperLeftCorner.X = 0; + ViewPort.UpperLeftCorner.Y = 0; + ViewPort.LowerRightCorner.X = realSize.Width; + ViewPort.LowerRightCorner.X = realSize.Height; + } + + ScreenSize = realSize; + + bool resetRT = (RenderTargetSurface == BackBuffer); + + if (BackBuffer) + BackBuffer->drop(); + BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, realSize); + + if (resetRT) + setRenderTarget(BackBuffer); + } +} + + +//! returns the current render target size +const core::dimension2d& CBurningVideoDriver::getCurrentRenderTargetSize() const +{ + return RenderTargetSize; +} + + +//!Draws an 2d rectangle with a gradient. +void CBurningVideoDriver::draw2DRectangle(const core::rect& position, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip) +{ +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + + core::rect pos = position; + + if (clip) + pos.clipAgainst(*clip); + + if (!pos.isValid()) + return; + + const core::dimension2d renderTargetSize ( ViewPort.getSize() ); + + const s32 xPlus = -(renderTargetSize.Width>>1); + const f32 xFact = 1.0f / (renderTargetSize.Width>>1); + + const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); + const f32 yFact = 1.0f / (renderTargetSize.Height>>1); + + // fill VertexCache direct + s4DVertex *v; + + VertexCache.vertexCount = 4; + + VertexCache.info[0].index = 0; + VertexCache.info[1].index = 1; + VertexCache.info[2].index = 2; + VertexCache.info[3].index = 3; + + v = &VertexCache.mem.data [ 0 ]; + + v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); + v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color ); + + v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f ); + v[2].Color[0].setA8R8G8B8 ( colorRightUp.color ); + + v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f ); + v[4].Color[0].setA8R8G8B8 ( colorRightDown.color ); + + v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f ); + v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color ); + + s32 i; + u32 g; + + for ( i = 0; i!= 8; i += 2 ) + { + v[i + 0].flag = clipToFrustumTest ( v + i ); + v[i + 1].flag = 0; + if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE ) + { + ndc_2_dc_and_project ( v + i + 1, v + i, 2 ); + } + } + + + IBurningShader * render; + + render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ]; + render->setRenderTarget(RenderTargetSurface, ViewPort); + + static const s16 indexList[6] = {0,1,2,0,2,3}; + + s4DVertex * face[3]; + + for ( i = 0; i!= 6; i += 3 ) + { + face[0] = VertexCache_getVertex ( indexList [ i + 0 ] ); + face[1] = VertexCache_getVertex ( indexList [ i + 1 ] ); + face[2] = VertexCache_getVertex ( indexList [ i + 2 ] ); + + // test clipping + u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE; + + if ( test == VERTEX4D_INSIDE ) + { + render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 ); + continue; + } + // Todo: all vertices are clipped in 2d.. + // is this true ? + u32 vOut = 6; + memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 ); + memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 ); + memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 ); + + vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 ); + if ( vOut < 3 ) + continue; + + vOut <<= 1; + // to DC Space, project homogenous vertex + ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); + + // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) + for ( g = 0; g <= vOut - 6; g += 2 ) + { + // rasterize + render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] ); + } + + } +#else + draw2DRectangle ( colorLeftUp, position, clip ); +#endif +} + + +//! Draws a 3d line. +void CBurningVideoDriver::draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color) +{ + Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[0].Pos.x, start ); + Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[2].Pos.x, end ); + + u32 g; + u32 vOut; + + // no clipping flags + for ( g = 0; g != CurrentOut.ElementSize; ++g ) + { + CurrentOut.data[g].flag = 0; + Temp.data[g].flag = 0; + } + + // vertices count per line + vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 ); + if ( vOut < 2 ) + return; + + vOut <<= 1; + + IBurningShader * line; + line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ]; + line->setRenderTarget(RenderTargetSurface, ViewPort); + + // to DC Space, project homogenous vertex + ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut ); + + // unproject vertex color +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + for ( g = 0; g != vOut; g+= 2 ) + { + CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color ); + } +#endif + + + for ( g = 0; g <= vOut - 4; g += 2 ) + { + // rasterize + line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 ); + } +} + + +//! \return Returns the name of the video driver. Example: In case of the DirectX8 +//! driver, it would return "Direct3D8.1". +const wchar_t* CBurningVideoDriver::getName() const +{ +#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL + return L"Burning's Video 0.47 beautiful"; +#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) + return L"Burning's Video 0.47 ultra fast"; +#elif defined ( BURNINGVIDEO_RENDERER_FAST ) + return L"Burning's Video 0.47 fast"; +#else + return L"Burning's Video 0.47"; +#endif +} + +//! Returns the graphics card vendor name. +core::stringc CBurningVideoDriver::getVendorInfo() +{ + return "Burning's Video: Ing. Thomas Alten (c) 2006-2012"; +} + + +//! Returns type of video driver +E_DRIVER_TYPE CBurningVideoDriver::getDriverType() const +{ + return EDT_BURNINGSVIDEO; +} + + +//! returns color format +ECOLOR_FORMAT CBurningVideoDriver::getColorFormat() const +{ + return BURNINGSHADER_COLOR_FORMAT; +} + + +//! Returns the transformation set by setTransform +const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const +{ + return Transformation[state]; +} + + +//! Creates a render target texture. +ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format) +{ + IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size); + ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET ); + img->drop(); + addTexture(tex); + tex->drop(); + return tex; +} + + +//! Clears the DepthBuffer. +void CBurningVideoDriver::clearZBuffer() +{ + if (DepthBuffer) + DepthBuffer->clear(); +} + + +//! Returns an image created from the last rendered frame. +IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) +{ + if (target != video::ERT_FRAME_BUFFER) + return 0; + + if (BackBuffer) + { + IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension()); + BackBuffer->copyTo(tmp); + return tmp; + } + else + return 0; +} + + +//! returns a device dependent texture from a software surface (IImage) +//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES +ITexture* CBurningVideoDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) +{ + return new CSoftwareTexture2( + surface, name, + (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0 ) | + (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE ), mipmapData); + +} + + +//! Returns the maximum amount of primitives (mostly vertices) which +//! the device is able to render with one drawIndexedTriangleList +//! call. +u32 CBurningVideoDriver::getMaximalPrimitiveCount() const +{ + return 0xFFFFFFFF; +} + + +//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do +//! this: First, draw all geometry. Then use this method, to draw the shadow +//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow. +void CBurningVideoDriver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) +{ + const u32 count = triangles.size(); + IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ]; + + CurrentShader = shader; + shader->setRenderTarget(RenderTargetSurface, ViewPort); + + Material.org.MaterialType = video::EMT_SOLID; + Material.org.Lighting = false; + Material.org.ZWriteEnable = false; + Material.org.ZBuffer = ECFN_LESSEQUAL; + LightSpace.Flags &= ~VERTEXTRANSFORM; + + //glStencilMask(~0); + //glStencilFunc(GL_ALWAYS, 0, ~0); + + if (true)// zpass does not work yet + { + Material.org.BackfaceCulling = true; + Material.org.FrontfaceCulling = false; + shader->setParam ( 0, 0 ); + shader->setParam ( 1, 1 ); + shader->setParam ( 2, 0 ); + drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 ); + //glStencilOp(GL_KEEP, incr, GL_KEEP); + //glDrawArrays(GL_TRIANGLES,0,count); + + Material.org.BackfaceCulling = false; + Material.org.FrontfaceCulling = true; + shader->setParam ( 0, 0 ); + shader->setParam ( 1, 2 ); + shader->setParam ( 2, 0 ); + drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 ); + //glStencilOp(GL_KEEP, decr, GL_KEEP); + //glDrawArrays(GL_TRIANGLES,0,count); + } + else // zpass + { + Material.org.BackfaceCulling = true; + Material.org.FrontfaceCulling = false; + shader->setParam ( 0, 0 ); + shader->setParam ( 1, 0 ); + shader->setParam ( 2, 1 ); + //glStencilOp(GL_KEEP, GL_KEEP, incr); + //glDrawArrays(GL_TRIANGLES,0,count); + + Material.org.BackfaceCulling = false; + Material.org.FrontfaceCulling = true; + shader->setParam ( 0, 0 ); + shader->setParam ( 1, 0 ); + shader->setParam ( 2, 2 ); + //glStencilOp(GL_KEEP, GL_KEEP, decr); + //glDrawArrays(GL_TRIANGLES,0,count); + } +} + +//! Fills the stencil shadow with color. After the shadow volume has been drawn +//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this +//! to draw the color of the shadow. +void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, + video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) +{ + if (!StencilBuffer) + return; + // draw a shadow rectangle covering the entire screen using stencil buffer + const u32 h = RenderTargetSurface->getDimension().Height; + const u32 w = RenderTargetSurface->getDimension().Width; + tVideoSample *dst; + u32 *stencil; + u32* const stencilBase=(u32*) StencilBuffer->lock(); + + for ( u32 y = 0; y < h; ++y ) + { + dst = (tVideoSample*)RenderTargetSurface->lock() + ( y * w ); + stencil = stencilBase + ( y * w ); + + for ( u32 x = 0; x < w; ++x ) + { + if ( stencil[x] > 1 ) + { + dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color ); + } + } + } + + StencilBuffer->clear(); +} + + +core::dimension2du CBurningVideoDriver::getMaxTextureSize() const +{ + return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a video driver +IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CBurningVideoDriver(params, io, presenter); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + + +} // end namespace video +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.h new file mode 100644 index 0000000..120bad2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareDriver2.h @@ -0,0 +1,290 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_VIDEO_2_SOFTWARE_H_INCLUDED__ +#define __C_VIDEO_2_SOFTWARE_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "IBurningShader.h" +#include "CNullDriver.h" +#include "CImage.h" +#include "os.h" +#include "irrString.h" +#include "SIrrCreationParameters.h" + +namespace irr +{ +namespace video +{ + class CBurningVideoDriver : public CNullDriver + { + public: + + //! constructor + CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter); + + //! destructor + virtual ~CBurningVideoDriver(); + + //! queries the features of the driver, returns true if feature is available + virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; + + //! sets transformation + virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); + + //! sets a material + virtual void setMaterial(const SMaterial& material); + + virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, + bool clearZBuffer, SColor color); + + //! sets a viewport + virtual void setViewPort(const core::rect& area); + + //! clears the zbuffer + virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, + SColor color=SColor(255,0,0,0), + const SExposedVideoData& videoData=SExposedVideoData(), + core::rect* sourceRect=0); + + //! presents the rendered scene on the screen, returns false if failed + virtual bool endScene(); + + //! Only used by the internal engine. Used to notify the driver that + //! the window was resized. + virtual void OnResize(const core::dimension2d& size); + + //! returns size of the current render target + virtual const core::dimension2d& getCurrentRenderTargetSize() const; + + //! deletes all dynamic lights there are + virtual void deleteAllDynamicLights(); + + //! adds a dynamic light, returning an index to the light + //! \param light: the light data to use to create the light + //! \return An index to the light, or -1 if an error occurs + virtual s32 addDynamicLight(const SLight& light); + + //! Turns a dynamic light on or off + //! \param lightIndex: the index returned by addDynamicLight + //! \param turnOn: true to turn the light on, false to turn it off + virtual void turnLightOn(s32 lightIndex, bool turnOn); + + //! returns the maximal amount of dynamic lights the device can handle + virtual u32 getMaximalDynamicLightAmount() const; + + //! Sets the dynamic ambient light color. The default color is + //! (0,0,0,0) which means it is dark. + //! \param color: New color of the ambient light. + virtual void setAmbientLight(const SColorf& color); + + //! draws a vertex primitive list + void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType); + + //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. + virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, + const core::rect& sourceRect, const core::rect* clipRect = 0, + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + + //! Draws a part of the texture into the rectangle. + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect = 0, + const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); + + //! Draws a 3d line. + virtual void draw3DLine(const core::vector3df& start, + const core::vector3df& end, SColor color = SColor(255,255,255,255)); + + //! draw an 2d rectangle + virtual void draw2DRectangle(SColor color, const core::rect& pos, + const core::rect* clip = 0); + + //!Draws an 2d rectangle with a gradient. + virtual void draw2DRectangle(const core::rect& pos, + SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, + const core::rect* clip = 0); + + //! Draws a 2d line. + virtual void draw2DLine(const core::position2d& start, + const core::position2d& end, + SColor color=SColor(255,255,255,255)); + + //! Draws a single pixel + virtual void drawPixel(u32 x, u32 y, const SColor & color); + + //! \return Returns the name of the video driver. Example: In case of the DirectX8 + //! driver, it would return "Direct3D8.1". + virtual const wchar_t* getName() const; + + //! Returns type of video driver + virtual E_DRIVER_TYPE getDriverType() const; + + //! get color format of the current color buffer + virtual ECOLOR_FORMAT getColorFormat() const; + + //! Returns the transformation set by setTransform + virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; + + //! Creates a render target texture. + virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, + const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + + //! Clears the DepthBuffer. + virtual void clearZBuffer(); + + //! Returns an image created from the last rendered frame. + virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); + + //! Returns the maximum amount of primitives (mostly vertices) which + //! the device is able to render with one drawIndexedTriangleList + //! call. + virtual u32 getMaximalPrimitiveCount() const; + + //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do + //! this: First, draw all geometry. Then use this method, to draw the shadow + //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. + virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail=true, u32 debugDataVisible=0); + + //! Fills the stencil shadow with color. After the shadow volume has been drawn + //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this + //! to draw the color of the shadow. + virtual void drawStencilShadow(bool clearStencilBuffer=false, + video::SColor leftUpEdge = video::SColor(0,0,0,0), + video::SColor rightUpEdge = video::SColor(0,0,0,0), + video::SColor leftDownEdge = video::SColor(0,0,0,0), + video::SColor rightDownEdge = video::SColor(0,0,0,0)); + + //! Returns the graphics card vendor name. + virtual core::stringc getVendorInfo(); + + //! Returns the maximum texture size supported. + virtual core::dimension2du getMaxTextureSize() const; + + virtual IDepthBuffer * getDepthBuffer () { return DepthBuffer; } + virtual IStencilBuffer * getStencilBuffer () { return StencilBuffer; } + + protected: + + + //! sets a render target + void setRenderTarget(video::CImage* image); + + //! sets the current Texture + //bool setTexture(u32 stage, video::ITexture* texture); + + //! returns a device dependent texture from a software surface (IImage) + //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES + virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); + + video::CImage* BackBuffer; + video::IImagePresenter* Presenter; + + void* WindowId; + core::rect* SceneSourceRect; + + video::ITexture* RenderTargetTexture; + video::IImage* RenderTargetSurface; + core::dimension2d RenderTargetSize; + + //! selects the right triangle renderer based on the render states. + void setCurrentShader(); + + IBurningShader* CurrentShader; + IBurningShader* BurningShader[ETR2_COUNT]; + + IDepthBuffer* DepthBuffer; + IStencilBuffer* StencilBuffer; + + + /* + extend Matrix Stack + -> combined CameraProjection + -> combined CameraProjectionWorld + -> ClipScale from NDC to DC Space + */ + enum E_TRANSFORMATION_STATE_BURNING_VIDEO + { + ETS_VIEW_PROJECTION = ETS_COUNT, + ETS_CURRENT, + ETS_CLIPSCALE, + ETS_VIEW_INVERSE, + ETS_WORLD_INVERSE, + + ETS_COUNT_BURNING + }; + + enum E_TRANSFORMATION_FLAG + { + ETF_IDENTITY = 1, + ETF_TEXGEN_CAMERA_NORMAL = 2, + ETF_TEXGEN_CAMERA_REFLECTION = 4, + }; + u32 TransformationFlag[ETS_COUNT_BURNING]; + core::matrix4 Transformation[ETS_COUNT_BURNING]; + + void getCameraPosWorldSpace (); + void getLightPosObjectSpace (); + + + // Vertex Cache + static const SVSize vSize[]; + + SVertexCache VertexCache; + + void VertexCache_reset (const void* vertices, u32 vertexCount, + const void* indices, u32 indexCount, + E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType, + E_INDEX_TYPE iType); + void VertexCache_get ( const s4DVertex ** face ); + void VertexCache_getbypass ( s4DVertex ** face ); + + void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex ); + s4DVertex * VertexCache_getVertex ( const u32 sourceIndex ); + + + // culling & clipping + u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane ); + u32 clipToFrustumTest ( const s4DVertex * v ) const; + u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn ); + + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + + void lightVertex ( s4DVertex *dest, u32 vertexargb ); + //! Sets the fog mode. + virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); +#endif + + + // holds transformed, clipped vertices + SAlignedVertex CurrentOut; + SAlignedVertex Temp; + + void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const; + f32 screenarea ( const s4DVertex *v0 ) const; + void select_polygon_mipmap ( s4DVertex *source, u32 vIn, u32 tex, const core::dimension2du& texSize ) const; + f32 texelarea ( const s4DVertex *v0, int tex ) const; + + + void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const; + f32 screenarea2 ( const s4DVertex **v ) const; + f32 texelarea2 ( const s4DVertex **v, int tex ) const; + void select_polygon_mipmap2 ( s4DVertex **source, u32 tex, const core::dimension2du& texSize ) const; + + + SBurningShaderLightSpace LightSpace; + SBurningShaderMaterial Material; + + static const sVec4 NDCPlane[6]; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.cpp new file mode 100644 index 0000000..b446e7d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.cpp @@ -0,0 +1,151 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +#include "CSoftwareTexture.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CSoftwareTexture::CSoftwareTexture(IImage* image, const io::path& name, + bool renderTarget, void* mipmapData) +: ITexture(name), Texture(0), IsRenderTarget(renderTarget) +{ + #ifdef _DEBUG + setDebugName("CSoftwareTexture"); + #endif + + if (image) + { + OrigSize = image->getDimension(); + core::dimension2d optSize=OrigSize.getOptimalSize(); + + Image = new CImage(ECF_A1R5G5B5, OrigSize); + image->copyTo(Image); + + if (optSize == OrigSize) + { + Texture = Image; + Texture->grab(); + } + else + { + Texture = new CImage(ECF_A1R5G5B5, optSize); + Image->copyToScaling(Texture); + } + } +} + + + +//! destructor +CSoftwareTexture::~CSoftwareTexture() +{ + if (Image) + Image->drop(); + + if (Texture) + Texture->drop(); +} + + + +//! lock function +void* CSoftwareTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) +{ + return Image->lock(); +} + + + +//! unlock function +void CSoftwareTexture::unlock() +{ + if (Image != Texture) + { + os::Printer::log("Performance warning, slow unlock of non power of 2 texture.", ELL_WARNING); + Image->copyToScaling(Texture); + } + + Image->unlock(); +} + + +//! Returns original size of the texture. +const core::dimension2d& CSoftwareTexture::getOriginalSize() const +{ + return OrigSize; +} + + +//! Returns (=size) of the texture. +const core::dimension2d& CSoftwareTexture::getSize() const +{ + return Image->getDimension(); +} + + +//! returns unoptimized surface +CImage* CSoftwareTexture::getImage() +{ + return Image; +} + + + +//! returns texture surface +CImage* CSoftwareTexture::getTexture() +{ + return Texture; +} + + + +//! returns driver type of texture (=the driver, who created the texture) +E_DRIVER_TYPE CSoftwareTexture::getDriverType() const +{ + return EDT_SOFTWARE; +} + + + +//! returns color format of texture +ECOLOR_FORMAT CSoftwareTexture::getColorFormat() const +{ + return ECF_A1R5G5B5; +} + + + +//! returns pitch of texture (in bytes) +u32 CSoftwareTexture::getPitch() const +{ + return Image->getDimension().Width * 2; +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void CSoftwareTexture::regenerateMipMapLevels(void* mipmapData) +{ + // our software textures don't have mip maps +} + +bool CSoftwareTexture::isRenderTarget() const +{ + return IsRenderTarget; +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.h new file mode 100644 index 0000000..ff06e16 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture.h @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SOFTWARE_TEXTURE_H_INCLUDED__ +#define __C_SOFTWARE_TEXTURE_H_INCLUDED__ + +#include "ITexture.h" +#include "CImage.h" + +namespace irr +{ +namespace video +{ + +/*! + interface for a Video Driver dependent Texture. +*/ +class CSoftwareTexture : public ITexture +{ +public: + + //! constructor + CSoftwareTexture(IImage* surface, const io::path& name, + bool renderTarget=false, void* mipmapData=0); + + //! destructor + virtual ~CSoftwareTexture(); + + //! lock function + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); + + //! unlock function + virtual void unlock(); + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const; + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const; + + //! returns unoptimized surface + virtual CImage* getImage(); + + //! returns texture surface + virtual CImage* getTexture(); + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const; + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const; + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const; + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(void* mipmapData=0); + + //! is it a render target? + virtual bool isRenderTarget() const; + +private: + CImage* Image; + CImage* Texture; + core::dimension2d OrigSize; + bool IsRenderTarget; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.cpp new file mode 100644 index 0000000..32d150f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +#include "SoftwareDriver2_compile_config.h" +#include "SoftwareDriver2_helper.h" +#include "CSoftwareTexture2.h" +#include "os.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, + u32 flags, void* mipmapData) + : ITexture(name), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN) +{ + #ifdef _DEBUG + setDebugName("CSoftwareTexture2"); + #endif + + #ifndef SOFTWARE_DRIVER_2_MIPMAPPING + Flags &= ~GEN_MIPMAP; + #endif + + memset32 ( MipMap, 0, sizeof ( MipMap ) ); + + if (image) + { + OrigSize = image->getDimension(); + OriginalFormat = image->getColorFormat(); + + core::setbit_cond(Flags, + image->getColorFormat () == video::ECF_A8R8G8B8 || + image->getColorFormat () == video::ECF_A1R5G5B5, + HAS_ALPHA); + + core::dimension2d optSize( + OrigSize.getOptimalSize( 0 != ( Flags & NP2_SIZE ), + false, false, + ( Flags & NP2_SIZE ) ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 0) + ); + + if ( OrigSize == optSize ) + { + MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension()); + image->copyTo(MipMap[0]); + } + else + { + char buf[256]; + core::stringw showName ( name ); + snprintf ( buf, 256, "Burningvideo: Warning Texture %ls reformat %dx%d -> %dx%d,%d", + showName.c_str(), + OrigSize.Width, OrigSize.Height, optSize.Width, optSize.Height, + BURNINGSHADER_COLOR_FORMAT + ); + + OrigSize = optSize; + os::Printer::log ( buf, ELL_WARNING ); + MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize); + image->copyToScalingBoxFilter ( MipMap[0],0, false ); + } + + OrigImageDataSizeInPixels = (f32) 0.3f * MipMap[0]->getImageDataSizeInPixels(); + } + + regenerateMipMapLevels(mipmapData); +} + + +//! destructor +CSoftwareTexture2::~CSoftwareTexture2() +{ + for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) + { + if ( MipMap[i] ) + MipMap[i]->drop(); + } +} + + +//! Regenerates the mip map levels of the texture. Useful after locking and +//! modifying the texture +void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData) +{ + if ( !hasMipMaps () ) + return; + + s32 i; + + // release + for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) + { + if ( MipMap[i] ) + MipMap[i]->drop(); + } + + core::dimension2d newSize; + core::dimension2d origSize=OrigSize; + + for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) + { + newSize = MipMap[i-1]->getDimension(); + newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE ); + newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE ); + origSize.Width = core::s32_max(1, origSize.Width >> 1); + origSize.Height = core::s32_max(1, origSize.Height >> 1); + + if (mipmapData) + { + if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT) + { + IImage* tmpImage = new CImage(OriginalFormat, origSize, mipmapData, true, false); + MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); + if (origSize==newSize) + tmpImage->copyTo(MipMap[i]); + else + tmpImage->copyToScalingBoxFilter(MipMap[i]); + tmpImage->drop(); + } + else + { + if (origSize==newSize) + MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mipmapData, false); + else + { + MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); + IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mipmapData, true, false); + tmpImage->copyToScalingBoxFilter(MipMap[i]); + tmpImage->drop(); + } + } + mipmapData = (u8*)mipmapData+origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8; + } + else + { + MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); + + //static u32 color[] = { 0, 0xFFFF0000, 0xFF00FF00,0xFF0000FF,0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0xFF0F0F0F }; + MipMap[i]->fill ( 0 ); + MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false ); + } + } +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.h new file mode 100644 index 0000000..cc8adc6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSoftwareTexture2.h @@ -0,0 +1,141 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SOFTWARE_2_TEXTURE_H_INCLUDED__ +#define __C_SOFTWARE_2_TEXTURE_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" + +#include "ITexture.h" +#include "CImage.h" + +namespace irr +{ +namespace video +{ + +/*! + interface for a Video Driver dependent Texture. +*/ +class CSoftwareTexture2 : public ITexture +{ +public: + + //! constructor + enum eTex2Flags + { + GEN_MIPMAP = 1, + IS_RENDERTARGET = 2, + NP2_SIZE = 4, + HAS_ALPHA = 8 + }; + CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags, void* mipmapData=0); + + //! destructor + virtual ~CSoftwareTexture2(); + + //! lock function + virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) + { + if (Flags & GEN_MIPMAP) + MipMapLOD=mipmapLevel; + return MipMap[MipMapLOD]->lock(); + } + + //! unlock function + virtual void unlock() + { + MipMap[MipMapLOD]->unlock(); + } + + //! Returns original size of the texture. + virtual const core::dimension2d& getOriginalSize() const + { + //return MipMap[0]->getDimension(); + return OrigSize; + } + + //! Returns the size of the largest mipmap. + f32 getLODFactor( const f32 texArea ) const + { + return OrigImageDataSizeInPixels * texArea; + //return MipMap[0]->getImageDataSizeInPixels () * texArea; + } + + //! Returns (=size) of the texture. + virtual const core::dimension2d& getSize() const + { + return MipMap[MipMapLOD]->getDimension(); + } + + //! returns unoptimized surface + virtual CImage* getImage() const + { + return MipMap[0]; + } + + //! returns texture surface + virtual CImage* getTexture() const + { + return MipMap[MipMapLOD]; + } + + + //! returns driver type of texture (=the driver, who created the texture) + virtual E_DRIVER_TYPE getDriverType() const + { + return EDT_BURNINGSVIDEO; + } + + //! returns color format of texture + virtual ECOLOR_FORMAT getColorFormat() const + { + return BURNINGSHADER_COLOR_FORMAT; + } + + //! returns pitch of texture (in bytes) + virtual u32 getPitch() const + { + return MipMap[MipMapLOD]->getPitch(); + } + + //! Regenerates the mip map levels of the texture. Useful after locking and + //! modifying the texture + virtual void regenerateMipMapLevels(void* mipmapData=0); + + //! support mipmaps + virtual bool hasMipMaps() const + { + return (Flags & GEN_MIPMAP ) != 0; + } + + //! Returns if the texture has an alpha channel + virtual bool hasAlpha() const + { + return (Flags & HAS_ALPHA ) != 0; + } + + //! is a render target + virtual bool isRenderTarget() const + { + return (Flags & IS_RENDERTARGET) != 0; + } + +private: + f32 OrigImageDataSizeInPixels; + core::dimension2d OrigSize; + + CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; + + u32 MipMapLOD; + u32 Flags; + ECOLOR_FORMAT OriginalFormat; +}; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.cpp new file mode 100644 index 0000000..00b6528 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.cpp @@ -0,0 +1,199 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CSphereSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "os.h" +#include "CShadowVolumeSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) +: IMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), Shadow(0), + Radius(radius), PolyCountX(polyCountX), PolyCountY(polyCountY) +{ + #ifdef _DEBUG + setDebugName("CSphereSceneNode"); + #endif + + Mesh = SceneManager->getGeometryCreator()->createSphereMesh(radius, polyCountX, polyCountY); +} + + + +//! destructor +CSphereSceneNode::~CSphereSceneNode() +{ + if (Shadow) + Shadow->drop(); + if (Mesh) + Mesh->drop(); +} + + +//! renders the node. +void CSphereSceneNode::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + if (Mesh && driver) + { + driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial()); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + if (Shadow) + Shadow->updateShadowVolumes(); + + driver->drawMeshBuffer(Mesh->getMeshBuffer(0)); + if ( DebugDataVisible & scene::EDS_BBOX ) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(Mesh->getMeshBuffer(0)->getBoundingBox(), video::SColor(255,255,255,255)); + } + } +} + + +//! Removes a child from this scene node. +//! Implemented here, to be able to remove the shadow properly, if there is one, +//! or to remove attached childs. +bool CSphereSceneNode::removeChild(ISceneNode* child) +{ + if (child && Shadow == child) + { + Shadow->drop(); + Shadow = 0; + } + + return ISceneNode::removeChild(child); +} + + +//! Creates shadow volume scene node as child of this node +//! and returns a pointer to it. +IShadowVolumeSceneNode* CSphereSceneNode::addShadowVolumeSceneNode( + const IMesh* shadowMesh, s32 id, bool zfailmethod, f32 infinity) +{ + if (!SceneManager->getVideoDriver()->queryFeature(video::EVDF_STENCIL_BUFFER)) + return 0; + + if (!shadowMesh) + shadowMesh = Mesh; // if null is given, use the mesh of node + + if (Shadow) + Shadow->drop(); + + Shadow = new CShadowVolumeSceneNode(shadowMesh, this, SceneManager, id, zfailmethod, infinity); + return Shadow; +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CSphereSceneNode::getBoundingBox() const +{ + return Mesh ? Mesh->getBoundingBox() : Box; +} + + +void CSphereSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this); + + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CSphereSceneNode::getMaterial(u32 i) +{ + if (i>0 || !Mesh) + return ISceneNode::getMaterial(i); + else + return Mesh->getMeshBuffer(i)->getMaterial(); +} + + +//! returns amount of materials used by this scene node. +u32 CSphereSceneNode::getMaterialCount() const +{ + return 1; +} + + +//! Writes attributes of the scene node. +void CSphereSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addFloat("Radius", Radius); + out->addInt("PolyCountX", PolyCountX); + out->addInt("PolyCountY", PolyCountY); +} + + +//! Reads attributes of the scene node. +void CSphereSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + f32 oldRadius = Radius; + u32 oldPolyCountX = PolyCountX; + u32 oldPolyCountY = PolyCountY; + + Radius = in->getAttributeAsFloat("Radius"); + PolyCountX = in->getAttributeAsInt("PolyCountX"); + PolyCountY = in->getAttributeAsInt("PolyCountY"); + // legacy values read for compatibility with older versions + u32 polyCount = in->getAttributeAsInt("PolyCount"); + if (PolyCountX ==0 && PolyCountY == 0) + PolyCountX = PolyCountY = polyCount; + + Radius = core::max_(Radius, 0.0001f); + + if ( !core::equals(Radius, oldRadius) || PolyCountX != oldPolyCountX || PolyCountY != oldPolyCountY) + { + if (Mesh) + Mesh->drop(); + Mesh = SceneManager->getGeometryCreator()->createSphereMesh(Radius, PolyCountX, PolyCountY); + } + + ISceneNode::deserializeAttributes(in, options); +} + +//! Creates a clone of this scene node and its children. +ISceneNode* CSphereSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CSphereSceneNode* nb = new CSphereSceneNode(Radius, PolyCountX, PolyCountY, newParent, + newManager, ID, RelativeTranslation); + + nb->cloneMembers(this, newManager); + nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial(); + nb->Shadow = Shadow; + if ( nb->Shadow ) + nb->Shadow->grab(); + + if ( newParent ) + nb->drop(); + return nb; +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.h new file mode 100644 index 0000000..7dcc4c8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CSphereSceneNode.h @@ -0,0 +1,96 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_SHPERE_SCENE_NODE_H_INCLUDED__ +#define __C_SHPERE_SCENE_NODE_H_INCLUDED__ + +#include "IMeshSceneNode.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + class CSphereSceneNode : public IMeshSceneNode + { + public: + + //! constructor + CSphereSceneNode(f32 size, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CSphereSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. To get the amount + //! of materials used by this scene node, use getMaterialCount(). + //! This function is needed for inserting the node into the scene hirachy on a + //! optimal position for minimizing renderstate changes, but can also be used + //! to directly modify the material of a scene node. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_SPHERE; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + //! The mesh cannot be changed + virtual void setMesh(IMesh* mesh) {} + + //! Returns the current mesh + virtual IMesh* getMesh() { return Mesh; } + + //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. + /* In this way it is possible to change the materials a mesh causing all mesh scene nodes + referencing this mesh to change too. */ + virtual void setReadOnlyMaterials(bool readonly) {} + + //! Returns if the scene node should not copy the materials of the mesh but use them in a read only style + virtual bool isReadOnlyMaterials() const { return false; } + + //! Creates shadow volume scene node as child of this node + //! and returns a pointer to it. + virtual IShadowVolumeSceneNode* addShadowVolumeSceneNode(const IMesh* shadowMesh, + s32 id, bool zfailmethod=true, f32 infinity=10000.0f); + + //! Removes a child from this scene node. + //! Implemented here, to be able to remove the shadow properly, if there is one, + //! or to remove attached childs. + virtual bool removeChild(ISceneNode* child); + + private: + + IMesh* Mesh; + IShadowVolumeSceneNode* Shadow; + core::aabbox3d Box; + f32 Radius; + u32 PolyCountX; + u32 PolyCountY; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp new file mode 100644 index 0000000..216e1a1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlat.cpp @@ -0,0 +1,300 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRFlat : public CTRTextureGouraud +{ +public: + + CTRFlat(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRFlat"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + color = v1->Color; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + // TODO: clipping is not correct when leftx is clipped. + + if (leftxViewPortRect.LowerRightCorner.X) + leftx = ViewPortRect.LowerRightCorner.X; + + if (rightxViewPortRect.LowerRightCorner.X) + rightx = ViewPortRect.LowerRightCorner.X; + + // draw the span + + if (rightx - leftx != 0) + { + tmpDiv = 1.0f / (rightx - leftx); + spanZValue = leftZValue; + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + + hSpanBegin = targetSurface + leftx; + spanZTarget = zTarget + leftx; + hSpanEnd = targetSurface + rightx; + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + *hSpanBegin = color; + } + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererFlat(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRFlat(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlatWire.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlatWire.cpp new file mode 100644 index 0000000..4f0c5c7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRFlatWire.cpp @@ -0,0 +1,281 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRFlatWire : public CTRTextureGouraud +{ +public: + + CTRFlatWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + color = v1->Color; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + *(targetSurface + leftx) = color; + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + *(targetSurface + rightx) = color; + } + + } + + // draw the span + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererFlatWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRFlatWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud.cpp new file mode 100644 index 0000000..9edf908 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud.cpp @@ -0,0 +1,358 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +class CTRGouraud : public CTRTextureGouraud +{ +public: + + CTRGouraud(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRGouraud"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<11; + leftG = rightG = video::getGreen(v1->Color)<<11; + leftB = rightB = video::getBlue(v1->Color)<<11; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - leftB) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + // TODO: clipping is not correct when leftx is clipped. + + if (leftxViewPortRect.LowerRightCorner.X) + leftx = ViewPortRect.LowerRightCorner.X; + + if (rightxViewPortRect.LowerRightCorner.X) + rightx = ViewPortRect.LowerRightCorner.X; + + // draw the span + + if (rightx - leftx != 0) + { + tmpDiv = 1.0f / (rightx - leftx); + spanZValue = leftZValue; + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + + hSpanBegin = targetSurface + leftx; + spanZTarget = zTarget + leftx; + hSpanEnd = targetSurface + rightx; + + spanR = leftR; + spanG = leftG; + spanB = leftB; + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanStepB = (s32)((rightB - leftB) * tmpDiv); + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + *hSpanBegin = video::RGB16(spanR>>8, spanG>>8, spanB>>8); + } + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<11; + rightG = video::getGreen(v2->Color)<<11; + rightB = video::getBlue(v2->Color)<<11; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<11; + leftG = video::getGreen(v2->Color)<<11; + leftB = video::getBlue(v2->Color)<<11; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererGouraud(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRGouraud(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud2.cpp new file mode 100644 index 0000000..48ed4d1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraud2.cpp @@ -0,0 +1,645 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +//#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRGouraud2 : public IBurningShader +{ +public: + + //! constructor + CTRGouraud2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGouraud2::CTRGouraud2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRGouraud2"); + #endif +} + + + +/*! +*/ +void CTRGouraud2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + +#ifdef IPOL_C0 + tFixPoint r0, g0, b0; + +#ifdef INVERSE_W + f32 inversew; +#endif + +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef IPOL_C0 +#ifdef INVERSE_W + inversew = core::reciprocal ( line.w[0] ); + + getSample_color ( r0, g0, b0, line.c[0][0] * inversew ); +#else + getSample_color ( r0, g0, b0, line.c[0][0] ); +#endif + + dst[i] = fix_to_color ( r0, g0, b0 ); +#else + dst[i] = COLOR_BRIGHT_WHITE; +#endif + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b); + if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c); + if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGouraud2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlpha2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlpha2.cpp new file mode 100644 index 0000000..3c014f3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlpha2.cpp @@ -0,0 +1,657 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +//#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRGouraudAlpha2 : public IBurningShader +{ +public: + + //! constructor + CTRGouraudAlpha2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGouraudAlpha2::CTRGouraudAlpha2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRGouraudAlpha2"); + #endif +} + + + +/*! +*/ +void CTRGouraudAlpha2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[0]; +#endif +#ifdef IPOL_T1 + sVec2 slopeT[1]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + +#ifdef IPOL_C0 + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint a0; + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef IPOL_C0 +#ifdef INVERSE_W + inversew = core::reciprocal ( line.w[0] ); + + getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew ); +#else + getSample_color ( a0, r0, g0, b0, line.c[0][0] ); +#endif + + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + + dst[i] = fix_to_color ( r2, g2, b2 ); +#else + dst[i] = COLOR_BRIGHT_WHITE; +#endif +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGouraudAlpha2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp new file mode 100644 index 0000000..24b8779 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp @@ -0,0 +1,654 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +//#define INVERSE_W + +//#define USE_ZBUFFER +//#define IPOL_W +//#define CMP_W +//#define WRITE_W + +#define IPOL_C0 +//#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + //#define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRGouraudAlphaNoZ2 : public IBurningShader +{ +public: + + //! constructor + CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGouraudAlphaNoZ2::CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRGouraudAlphaNoZ2"); + #endif +} + + + +/*! +*/ +void CTRGouraudAlphaNoZ2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + +#ifdef IPOL_C0 + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint a0; + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef IPOL_C0 +#ifdef IPOL_W + inversew = core::reciprocal ( line.w[0] ); + + getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew ); +#else + getSample_color ( a0, r0, g0, b0, line.c[0][0] ); +#endif + + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + + dst[i] = fix_to_color ( r2, g2, b2 ); +#else + dst[i] = COLOR_BRIGHT_WHITE; +#endif + + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGouraudAlphaNoZ2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudWire.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudWire.cpp new file mode 100644 index 0000000..1d233a7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRGouraudWire.cpp @@ -0,0 +1,326 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRGouraudWire : public CTRTextureGouraud +{ +public: + + CTRGouraudWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRGouraudWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<11; + leftG = rightG = video::getGreen(v1->Color)<<11; + leftB = rightB = video::getBlue(v1->Color)<<11; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - leftB) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + *(targetSurface + leftx) = video::RGB16(leftR>>8, leftG>>8, leftB>>8); + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + *(targetSurface + rightx) = video::RGB16(rightR, rightG, rightB); + } + + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<11; + rightG = video::getGreen(v2->Color)<<11; + rightB = video::getBlue(v2->Color)<<11; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<11; + leftG = video::getGreen(v2->Color)<<11; + leftB = video::getBlue(v2->Color)<<11; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererGouraudWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRGouraudWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRNormalMap.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRNormalMap.cpp new file mode 100644 index 0000000..94c0962 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRNormalMap.cpp @@ -0,0 +1,848 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 +#undef IPOL_T2 +#undef IPOL_L0 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 +#define IPOL_L0 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + + +class CTRNormalMap : public IBurningShader +{ +public: + + //! constructor + CTRNormalMap(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRNormalMap"); + #endif +} + + + +/*! +*/ +void CTRNormalMap::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif +#ifdef IPOL_L0 + sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif +#ifdef IPOL_T2 + slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX; +#endif +#ifdef IPOL_L0 + slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#ifdef IPOL_T2 + line.t[2][0] += slopeT[2] * subPixel; +#endif +#ifdef IPOL_L0 + line.l[0][0] += slopeL[0] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0, tx1; + tFixPoint ty0, ty1; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + tFixPoint lx, ly, lz; + tFixPoint ndotl; + + sVec3 light; + + +#ifdef IPOL_C0 + tFixPoint r3, g3, b3; +#endif + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); + tx1 = tofix ( line.t[1][0].x,inversew); + ty1 = tofix ( line.t[1][0].y,inversew); + + +#ifdef IPOL_C0 + r3 = tofix ( line.c[0][0].y ,inversew ); + g3 = tofix ( line.c[0][0].z ,inversew ); + b3 = tofix ( line.c[0][0].w ,inversew ); +#endif + +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); + tx1 = tofix ( line.t[1][0].x ); + ty1 = tofix ( line.t[1][0].y ); + +#ifdef IPOL_C0 + r3 = tofix ( line.c[0][0].y ); + g3 = tofix ( line.c[0][0].z ); + b3 = tofix ( line.c[0][0].w ); +#endif + +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + + // normal map + getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 ); + + r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); + g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); + b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); + +/* + sVec3 l = line.l[0][0] * inversew; + l.setLength( 2.f ); + + lx = tofix ( l.x - 0.5f ); + ly = tofix ( l.y - 0.5f ); + lz = tofix ( l.z - 0.5f ); +*/ + + lx = tofix ( line.l[0][0].x, inversew ); + ly = tofix ( line.l[0][0].y, inversew ); + lz = tofix ( line.l[0][0].z, inversew ); + + // DOT 3 Normal Map light in tangent space + ndotl = saturateFix ( FIX_POINT_HALF_COLOR + (( imulFix ( r1, lx ) + imulFix ( g1, ly ) + imulFix ( b1, lz ) ) << (COLOR_MAX_LOG2-1)) ); + +#ifdef IPOL_C0 + + // N . L + r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 ); + g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 ); + b2 = imulFix ( imulFix_tex1 ( b0, ndotl ), b3 ); + +/* + // heightmap: (1 - neu ) + alt - 0.5, on_minus_srcalpha + add signed + // emboss bump map + a4 -= a1; + r2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( r0 + a4, r3 ) ) ); + g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) ); + b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) ); +*/ + +/* + r2 = clampfix_maxcolor ( imulFix_tex1 ( r2, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex1 ( g2, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex1 ( b2, b1 ) ); +*/ +#else + r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ); +#endif + + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif +#ifdef IPOL_T2 + line.t[2][0] += slopeT[2]; +#endif +#ifdef IPOL_L0 + line.l[0][0] += slopeL[0]; +#endif + } + +} + +void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + +#ifdef IPOL_T2 + scan.slopeT[2][0] = (c->Tex[2] - a->Tex[2]) * scan.invDeltaY[0]; + scan.t[2][0] = a->Tex[2]; +#endif + +#ifdef IPOL_L0 + scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0]; + scan.l[0][0] = a->LightTangent[0]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + + // rasterize upper sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + +#ifdef IPOL_T2 + scan.slopeT[2][1] = (b->Tex[2] - a->Tex[2]) * scan.invDeltaY[1]; + scan.t[2][1] = a->Tex[2]; +#endif + +#ifdef IPOL_L0 + scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1]; + scan.l[0][1] = a->LightTangent[0]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0] * subPixel; + scan.t[2][1] += scan.slopeT[2][1] * subPixel; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0] * subPixel; + scan.l[0][1] += scan.slopeL[0][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + +#ifdef IPOL_T2 + line.t[2][scan.left] = scan.t[2][0]; + line.t[2][scan.right] = scan.t[2][1]; +#endif + +#ifdef IPOL_L0 + line.l[0][scan.left] = scan.l[0][0]; + line.l[0][scan.right] = scan.l[0][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0]; + scan.t[2][1] += scan.slopeT[2][1]; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0]; + scan.l[0][1] += scan.slopeL[0][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + //if( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif +#ifdef IPOL_T2 + scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0]; +#endif +#ifdef IPOL_L0 + scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + +#ifdef IPOL_T2 + scan.slopeT[2][1] = (c->Tex[2] - b->Tex[2]) * scan.invDeltaY[2]; + scan.t[2][1] = b->Tex[2]; +#endif + +#ifdef IPOL_L0 + scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2]; + scan.l[0][1] = b->LightTangent[0]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0] * subPixel; + scan.t[2][1] += scan.slopeT[2][1] * subPixel; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0] * subPixel; + scan.l[0][1] += scan.slopeL[0][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + +#ifdef IPOL_T2 + line.t[2][scan.left] = scan.t[2][0]; + line.t[2][scan.right] = scan.t[2][1]; +#endif + +#ifdef IPOL_L0 + line.l[0][scan.left] = scan.l[0][0]; + line.l[0][scan.right] = scan.l[0][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0]; + scan.t[2][1] += scan.slopeT[2][1]; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0]; + scan.l[0][1] += scan.slopeL[0][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a triangle renderer +IBurningShader* createTRNormalMap(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRNormalMap(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRStencilShadow.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRStencilShadow.cpp new file mode 100644 index 0000000..be974b6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRStencilShadow.cpp @@ -0,0 +1,930 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef USE_SBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 +#undef IPOL_T2 +#undef IPOL_L0 + +// define render case +#define SUBTEXEL +//#define INVERSE_W + +#define USE_ZBUFFER +#define USE_SBUFFER +#define IPOL_W +#define CMP_W +//#define WRITE_W + + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRStencilShadow : public IBurningShader +{ +public: + + //! constructor + CTRStencilShadow(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + virtual void setParam ( u32 index, f32 value); + +private: + // fragment shader + typedef void (CTRStencilShadow::*tFragmentShader) (); + void fragment_zfail_decr (); + void fragment_zfail_incr (); + + tFragmentShader fragmentShader; + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRStencilShadow"); + #endif +} + + +/*! +*/ +void CTRStencilShadow::setParam ( u32 index, f32 value) +{ + u32 val = (u32) value; + + // glStencilOp (fail,zfail,zpass + if ( index == 1 && val == 1 ) + { + fragmentShader = &CTRStencilShadow::fragment_zfail_incr; + } + else + if ( index == 1 && val == 2 ) + { + fragmentShader = &CTRStencilShadow::fragment_zfail_decr; + } +} + +/*! +*/ +void CTRStencilShadow::fragment_zfail_decr () +{ + if (!Stencil) + return; + //tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + +#ifdef USE_SBUFFER + u32 *stencil; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif +#ifdef IPOL_L0 + sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif +#ifdef IPOL_T2 + slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX; +#endif +#ifdef IPOL_L0 + slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#ifdef IPOL_T2 + line.t[2][0] += slopeT[2] * subPixel; +#endif +#ifdef IPOL_L0 + line.l[0][0] += slopeL[0] * subPixel; +#endif +#endif + + //dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + +#ifdef USE_SBUFFER + stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + +#ifdef IPOL_C0 + tFixPoint r3, g3, b3; +#endif + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] < z[i] ) +#endif + { + // zfail + stencil[i] -= 1; + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif +#ifdef IPOL_T2 + line.t[2][0] += slopeT[2]; +#endif +#ifdef IPOL_L0 + line.l[0][0] += slopeL[0]; +#endif + } +} + +/*! +*/ +void CTRStencilShadow::fragment_zfail_incr() +{ + if (!Stencil) + return; + //tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + +#ifdef USE_SBUFFER + u32 *stencil; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif +#ifdef IPOL_L0 + sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif +#ifdef IPOL_T2 + slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX; +#endif +#ifdef IPOL_L0 + slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#ifdef IPOL_T2 + line.t[2][0] += slopeT[2] * subPixel; +#endif +#ifdef IPOL_L0 + line.l[0][0] += slopeL[0] * subPixel; +#endif +#endif + + //dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + +#ifdef USE_SBUFFER + stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + +#ifdef INVERSE_W + f32 inversew; +#endif + +#ifdef IPOL_C0 + tFixPoint r3, g3, b3; +#endif + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] < z[i] ) +#endif + { + // zfail + stencil[i] += 1; + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif +#ifdef IPOL_T2 + line.t[2][0] += slopeT[2]; +#endif +#ifdef IPOL_L0 + line.l[0][0] += slopeL[0]; +#endif + } +} + +void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + +#ifdef IPOL_T2 + scan.slopeT[2][0] = (c->Tex[2] - a->Tex[2]) * scan.invDeltaY[0]; + scan.t[2][0] = a->Tex[2]; +#endif + +#ifdef IPOL_L0 + scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0]; + scan.l[0][0] = a->LightTangent[0]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + +#ifdef IPOL_T2 + scan.slopeT[2][1] = (b->Tex[2] - a->Tex[2]) * scan.invDeltaY[1]; + scan.t[2][1] = a->Tex[2]; +#endif + +#ifdef IPOL_L0 + scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1]; + scan.l[0][1] = a->LightTangent[0]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0] * subPixel; + scan.t[2][1] += scan.slopeT[2][1] * subPixel; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0] * subPixel; + scan.l[0][1] += scan.slopeL[0][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + +#ifdef IPOL_T2 + line.t[2][scan.left] = scan.t[2][0]; + line.t[2][scan.right] = scan.t[2][1]; +#endif + +#ifdef IPOL_L0 + line.l[0][scan.left] = scan.l[0][0]; + line.l[0][scan.right] = scan.l[0][1]; +#endif + + // render a scanline + (this->*fragmentShader) (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0]; + scan.t[2][1] += scan.slopeT[2][1]; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0]; + scan.l[0][1] += scan.slopeL[0][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + //if( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif +#ifdef IPOL_T2 + scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0]; +#endif +#ifdef IPOL_L0 + scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + +#ifdef IPOL_T2 + scan.slopeT[2][1] = (c->Tex[2] - b->Tex[2]) * scan.invDeltaY[2]; + scan.t[2][1] = b->Tex[2]; +#endif + +#ifdef IPOL_L0 + scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2]; + scan.l[0][1] = b->LightTangent[0]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0] * subPixel; + scan.t[2][1] += scan.slopeT[2][1] * subPixel; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0] * subPixel; + scan.l[0][1] += scan.slopeL[0][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + +#ifdef IPOL_T2 + line.t[2][scan.left] = scan.t[2][0]; + line.t[2][scan.right] = scan.t[2][1]; +#endif + +#ifdef IPOL_L0 + line.l[0][scan.left] = scan.l[0][0]; + line.l[0][scan.right] = scan.l[0][1]; +#endif + + // render a scanline + (this->*fragmentShader) (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif +#ifdef IPOL_T2 + scan.t[2][0] += scan.slopeT[2][0]; + scan.t[2][1] += scan.slopeT[2][1]; +#endif + +#ifdef IPOL_L0 + scan.l[0][0] += scan.slopeL[0][0]; + scan.l[0][1] += scan.slopeL[0][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a triangle renderer +IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRStencilShadow(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureBlend.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureBlend.cpp new file mode 100644 index 0000000..82372e8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureBlend.cpp @@ -0,0 +1,2385 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureBlend : public IBurningShader +{ +public: + + //! constructor + CTRTextureBlend(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setZCompareFunc ( u32 func); + virtual void setParam ( u32 index, f32 value); + + +private: + // fragment shader + typedef void (CTRTextureBlend::*tFragmentShader) (); + void fragment_dst_color_zero (); + void fragment_dst_color_one (); + void fragment_dst_color_src_alpha (); + void fragment_dst_color_one_minus_dst_alpha (); + void fragment_zero_one_minus_scr_color (); + void fragment_src_color_src_alpha (); + void fragment_one_one_minus_src_alpha (); + void fragment_one_minus_dst_alpha_one(); + void fragment_src_alpha_one(); + + tFragmentShader fragmentShader; + sScanConvertData scan; + sScanLineData line; + + u32 ZCompare; +}; + +//! constructor +CTRTextureBlend::CTRTextureBlend(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureBlend"); + #endif + + ZCompare = 1; +} + +/*! +*/ +void CTRTextureBlend::setZCompareFunc ( u32 func) +{ + ZCompare = func; +} + +/*! +*/ +void CTRTextureBlend::setParam ( u32 index, f32 value) +{ + u8 showname = 0; + + E_BLEND_FACTOR srcFact,dstFact; + E_MODULATE_FUNC modulate; + u32 alphaSrc; + unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, value ); + + fragmentShader = 0; + + if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ZERO ) + { + fragmentShader = &CTRTextureBlend::fragment_dst_color_zero; + } + else + if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE ) + { + fragmentShader = &CTRTextureBlend::fragment_dst_color_one; + } + else + if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA) + { + fragmentShader = &CTRTextureBlend::fragment_dst_color_src_alpha; + } + else + if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA) + { + fragmentShader = &CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha; + } + else + if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR ) + { + fragmentShader = &CTRTextureBlend::fragment_zero_one_minus_scr_color; + } + else + if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA) + { + fragmentShader = &CTRTextureBlend::fragment_one_one_minus_src_alpha; + } + else + if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE ) + { + fragmentShader = &CTRTextureBlend::fragment_one_minus_dst_alpha_one; + } + else + if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE ) + { + fragmentShader = &CTRTextureBlend::fragment_src_alpha_one; + } + else + if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA ) + { + fragmentShader = &CTRTextureBlend::fragment_src_color_src_alpha; + } + else + { + showname = 1; + fragmentShader = &CTRTextureBlend::fragment_dst_color_zero; + } + + static const c8 *n[] = + { + "gl_zero", + "gl_one", + "gl_dst_color", + "gl_one_minus_dst_color", + "gl_src_color", + "gl_one_minus_src_color", + "gl_src_alpha", + "gl_one_minus_src_alpha", + "gl_dst_alpha", + "gl_one_minus_dst_alpha", + "gl_src_alpha_saturate" + }; + + static E_BLEND_FACTOR lsrcFact = EBF_ZERO; + static E_BLEND_FACTOR ldstFact = EBF_ZERO; + + if ( showname && ( lsrcFact != srcFact || ldstFact != dstFact ) ) + { + char buf[128]; + snprintf ( buf, 128, "missing shader: %s %s",n[srcFact], n[dstFact] ); + os::Printer::log( buf, ELL_INFORMATION ); + + lsrcFact = srcFact; + ldstFact = dstFact; + } + +} + + +/*! +*/ +void CTRTextureBlend::fragment_dst_color_src_alpha () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint a0, r0, g0, b0; + tFixPoint r1, g1, b1; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0,r0,g0,b0, + &IT[0], + tofix ( line.t[0][0].x,iw), + tofix ( line.t[0][0].y,iw) + ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0,r0,g0,b0, + &IT[0], + tofix ( line.t[0][0].x,iw), + tofix ( line.t[0][0].y,iw) + ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + ); + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_src_color_src_alpha () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint a0, r0, g0, b0; + tFixPoint r1, g1, b1; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0, r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,iw), tofix ( line.t[0][0].y,iw) ); + color_to_fix ( r1, g1, b1, dst[i] ); + +// u32 check = imulFix_tex1( r0, r1 ); + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1( r0, r1 ) + imulFix_tex1( r1, a0 ) ), + clampfix_maxcolor ( imulFix_tex1( g0, g1 ) + imulFix_tex1( g1, a0 ) ), + clampfix_maxcolor ( imulFix_tex1( b0, b1 ) + imulFix_tex1( b1, a0 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0,r0,g0,b0, + &IT[0], + tofix ( line.t[0][0].x,iw), + tofix ( line.t[0][0].y,iw) + ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + ); + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_one_one_minus_src_alpha() +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint a0,r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + a0 = FIX_POINT_ONE - a0; + + color_to_fix1 ( r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ), + imulFix ( g0 + imulFix ( g1, a0 ), g2 ), + imulFix ( b0 + imulFix ( b1, a0 ), b2 ) + ); +#else + dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ), + g0 + imulFix ( g1, a0 ), + b0 + imulFix ( b1, a0 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + a0 = FIX_POINT_ONE - a0; + + color_to_fix1 ( r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ), + imulFix ( g0 + imulFix ( g1, a0 ), g2 ), + imulFix ( b0 + imulFix ( b1, a0 ), b2 ) + ); +#else + dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ), + g0 + imulFix ( g1, a0 ), + b0 + imulFix ( b1, a0 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_one_minus_dst_alpha_one () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint r0, g0, b0; + tFixPoint a1, r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( a1, r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + a1 = FIX_POINT_ONE - a1; + dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ), + imulFix ( imulFix ( g0, a1 ) + g1, g2 ), + imulFix ( imulFix ( b0, a1 ) + b1, b2 ) + ); +#else + dst[i] = fix_to_color ( imulFix ( r0, a1) + r0, + imulFix ( g0, a1) + g0, + imulFix ( b0, a1) + b0 + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( a1, r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + a1 = FIX_POINT_ONE - a1; + dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ), + imulFix ( imulFix ( g0, a1 ) + g1, g2 ), + imulFix ( imulFix ( b0, a1 ) + b1, b2 ) + ); +#else + dst[i] = fix_to_color ( imulFix ( r0, a1) + r0, + imulFix ( g0, a1) + g0, + imulFix ( b0, a1) + b0 + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_src_alpha_one () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint a0, r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + if ( a0 > 0 ) + { + a0 >>= 8; + + color_to_fix ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix4_to_color ( a0, + clampfix_maxcolor ( imulFix (r0,a0 ) + r1), + clampfix_maxcolor ( imulFix (g0,a0 ) + g1), + clampfix_maxcolor ( imulFix (b0,a0 ) + b1) + ); + +/* + a0 >>= 8; + dst[i] = fix4_to_color ( a0, + imulFix ( imulFix ( r0, a0 ) + r1, r2 ), + imulFix ( imulFix ( g0, a0 ) + g1, g2 ), + imulFix ( imulFix ( b0, a0 ) + b1, b2 ) + ); +*/ +#else + dst[i] = fix4_to_color ( a0, + clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ), + clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ), + clampfix_maxcolor ( imulFix (b0,a0 ) + b1 ) + ); + +#endif + +#ifdef WRITE_W + //z[i] = line.w[0]; +#endif + } + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + { + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + if ( a0 > 0 ) + { + a0 >>= 8; + + color_to_fix ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix4_to_color ( a0, + clampfix_maxcolor ( imulFix ( imulFix (r0,a0 ) + r1, r2 ) ), + clampfix_maxcolor ( imulFix ( imulFix (g0,a0 ) + g1, g2 ) ), + clampfix_maxcolor ( imulFix ( imulFix (b0,a0 ) + b1, b2 ) ) + ); + +/* + a0 >>= 8; + dst[i] = fix4_to_color ( a0, + imulFix ( imulFix ( r0, a0 ) + r1, r2 ), + imulFix ( imulFix ( g0, a0 ) + g1, g2 ), + imulFix ( imulFix ( b0, a0 ) + b1, b2 ) + ); +*/ +#else + dst[i] = fix4_to_color ( a0, + clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ), + clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ), + clampfix_maxcolor ( imulFix (b0,a0 ) + b1 ) + ); + +#endif + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + } + } +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + + +/*! +*/ +void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint r0, g0, b0; + tFixPoint a1, r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( a1, r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + a1 = FIX_POINT_ONE - a1; + dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ), + imulFix ( imulFix ( g1, g0 + a1 ), g2 ), + imulFix ( imulFix ( b1, b0 + a1 ), b2 ) + ); +#else + dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ), + imulFix ( g1, g0 + a1 ), + imulFix ( b1, b0 + a1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( a1, r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + a1 = FIX_POINT_ONE - a1; + dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ), + imulFix ( imulFix ( g1, g0 + a1 ), g2 ), + imulFix ( imulFix ( b1, b0 + a1 ), b2 ) + ); +#else + dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ), + imulFix ( g1, g0 + a1 ), + imulFix ( b1, b0 + a1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_dst_color_zero () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ), + imulFix ( imulFix ( g0, g1 ), g2 ), + imulFix ( imulFix ( b0, b1 ), b2 ) ); +#else + dst[i] = fix_to_color ( imulFix ( r0, r1 ), + imulFix ( g0, g1 ), + imulFix ( b0, b1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ), + imulFix ( imulFix ( g0, g1 ), g2 ), + imulFix ( imulFix ( b0, b1 ), b2 ) + ); +#else + dst[i] = fix_to_color ( imulFix ( r0, r1 ), + imulFix ( g0, g1 ), + imulFix ( b0, b1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_dst_color_one () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix ( r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ), + clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ), + clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 ) + ); + +#else + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ), + clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ), + clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ), + clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ), + clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 ) + ); + +#else + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ), + clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ), + clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 ) + ); + +#endif + + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + +/*! +*/ +void CTRTextureBlend::fragment_zero_one_minus_scr_color () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + f32 iw = FIX_POINT_F32_MUL; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + s32 i; + + switch ( ZCompare ) + { + case 1: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ), + imulFix ( FIX_POINT_ONE - g0, g1 ), + imulFix ( FIX_POINT_ONE - b0, b1 ) + ); + +#else + dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ), + imulFix ( FIX_POINT_ONE - g0, g1 ), + imulFix ( FIX_POINT_ONE - b0, b1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + } + break; + + case 2: + for ( i = 0; i <= dx; ++i ) + { +#ifdef CMP_W + if ( line.w[0] == z[i] ) +#endif + + { + +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + iw = fix_inverse32 ( line.w[0] ); +#endif + getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) ); + color_to_fix1 ( r1, g1, b1, dst[i] ); +#ifdef IPOL_C0 + getSample_color ( r2, g2, b2, line.c[0][0],iw ); + + dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ), + imulFix ( FIX_POINT_ONE - g0, g1 ), + imulFix ( FIX_POINT_ONE - b0, b1 ) + ); + +#else + dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ), + imulFix ( FIX_POINT_ONE - g0, g1 ), + imulFix ( FIX_POINT_ONE - b0, b1 ) + ); + +#endif + + } + +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif + }break; + } // zcompare + +} + + + +void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + if ( 0 == fragmentShader ) + return; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + (this->*fragmentShader) (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + (this->*fragmentShader) (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureBlend(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureDetailMap2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureDetailMap2.cpp new file mode 100644 index 0000000..514383f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureDetailMap2.cpp @@ -0,0 +1,659 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureDetailMap2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureDetailMap2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureDetailMap2::CTRTextureDetailMap2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureDetailMap2"); + #endif +} + + + +/*! +*/ +void CTRTextureDetailMap2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0, tx1; + tFixPoint ty0, ty1; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); + tx1 = tofix ( line.t[1][0].x,inversew); + ty1 = tofix ( line.t[1][0].y,inversew); + +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); + tx1 = tofix ( line.t[1][0].x ); + ty1 = tofix ( line.t[1][0].y ); +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 ); + + // bias half color + r1 += -FIX_POINT_HALF_COLOR; + g1 += -FIX_POINT_HALF_COLOR; + b1 += -FIX_POINT_HALF_COLOR; + + r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) ); + g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) ); + b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) ); + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureDetailMap2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlat.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlat.cpp new file mode 100644 index 0000000..d1c0c54 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlat.cpp @@ -0,0 +1,339 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureFlat : public CTRTextureGouraud +{ +public: + + CTRTextureFlat(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRTextureFlat"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + // TODO: clipping is not correct when leftx is clipped. + + if (leftxViewPortRect.LowerRightCorner.X) + leftx = ViewPortRect.LowerRightCorner.X; + + if (rightxViewPortRect.LowerRightCorner.X) + rightx = ViewPortRect.LowerRightCorner.X; + + // draw the span + + if (rightx - leftx != 0) + { + tmpDiv = 1.0f / (rightx - leftx); + spanZValue = leftZValue; + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + + hSpanBegin = targetSurface + leftx; + spanZTarget = zTarget + leftx; + hSpanEnd = targetSurface + rightx; + + spanTx = leftTx; + spanTy = leftTy; + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + *hSpanBegin = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + } + + spanTx += spanTxStep; + spanTy += spanTyStep; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); + + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureFlat(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureFlat(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp new file mode 100644 index 0000000..d15ba04 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureFlatWire.cpp @@ -0,0 +1,313 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureFlatWire : public CTRTextureGouraud +{ +public: + + CTRTextureFlatWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRTextureFlatWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + *(targetSurface + leftx) = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)]; + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + *(targetSurface + rightx) = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)]; + } + + } + + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); + + } +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureFlatWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureFlatWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.cpp new file mode 100644 index 0000000..3b2795d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.cpp @@ -0,0 +1,468 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! constructor +CTRTextureGouraud::CTRTextureGouraud(IZBuffer* zbuffer) + : RenderTarget(0), ZBuffer(zbuffer), SurfaceWidth(0), SurfaceHeight(0), + BackFaceCullingEnabled(true), lockedZBuffer(0), + lockedSurface(0), lockedTexture(0), lockedTextureWidth(0), + textureXMask(0), textureYMask(0), Texture(0) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraud"); + #endif + + if (ZBuffer) + zbuffer->grab(); +} + + + +//! destructor +CTRTextureGouraud::~CTRTextureGouraud() +{ + if (RenderTarget) + RenderTarget->drop(); + + if (ZBuffer) + ZBuffer->drop(); + + if (Texture) + Texture->drop(); +} + + + +//! sets the Texture +void CTRTextureGouraud::setTexture(video::IImage* texture) +{ + if (Texture) + Texture->drop(); + + Texture = texture; + + if (Texture) + { + Texture->grab(); + lockedTextureWidth = Texture->getDimension().Width; + + textureXMask = lockedTextureWidth-1; + textureYMask = Texture->getDimension().Height-1; + } +} + + + + +//! en or disables the backface culling +void CTRTextureGouraud::setBackfaceCulling(bool enabled) +{ + BackFaceCullingEnabled = enabled; +} + + + +//! sets a render target +void CTRTextureGouraud::setRenderTarget(video::IImage* surface, const core::rect& viewPort) +{ + if (RenderTarget) + RenderTarget->drop(); + + RenderTarget = surface; + + if (RenderTarget) + { + SurfaceWidth = RenderTarget->getDimension().Width; + SurfaceHeight = RenderTarget->getDimension().Height; + RenderTarget->grab(); + ViewPortRect = viewPort; + } +} + + + +//! draws an indexed triangle list +void CTRTextureGouraud::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) +{ + const S2DVertex *v1, *v2, *v3; + + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + // thanks to a correction by hybrid + // calculations delayed to correctly propagate to textures etc. + s32 tDiffLeft=0, tDiffRight=0; + if (leftxViewPortRect.LowerRightCorner.X) + tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; + + if (rightxViewPortRect.LowerRightCorner.X) + tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; + + // draw the span + if (rightx + tDiffRight - leftx - tDiffLeft) + { + tmpDiv = 1.0f / (f32)(rightx - leftx); + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + spanZValue = leftZValue+tDiffLeft*spanZStep; + + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanR = leftR+tDiffLeft*spanStepR; + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanG = leftG+tDiffLeft*spanStepG; + spanStepB = (s32)((rightB - leftB) * tmpDiv); + spanB = leftB+tDiffLeft*spanStepB; + + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTx = leftTx + tDiffLeft*spanTxStep; + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + spanTy = leftTy+tDiffLeft*spanTyStep; + + hSpanBegin = targetSurface + leftx+tDiffLeft; + spanZTarget = zTarget + leftx+tDiffLeft; + hSpanEnd = targetSurface + rightx+tDiffRight; + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + *spanZTarget = spanZValue; + u16 color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + *hSpanBegin = video::RGB16(video::getRed(color) * (spanR>>8) >>2, + video::getGreen(color) * (spanG>>8) >>2, + video::getBlue(color) * (spanB>>8) >>2); + } + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanTx += spanTxStep; + spanTy += spanTyStep; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureGouraud(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraud(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.h new file mode 100644 index 0000000..0885363 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud.h @@ -0,0 +1,85 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TRIANGLE_RENDERER_TEXTURE_GOURAUD_H_INCLUDED__ +#define __C_TRIANGLE_RENDERER_TEXTURE_GOURAUD_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifndef _IRR_COMPILE_WITH_SOFTWARE_ +// forward declarations for create methods +namespace irr +{ +namespace video +{ + class ITriangleRenderer; + class IZBuffer; +} // end namespace video +} // end namespace irr + +#else + +#include "ITriangleRenderer.h" +#include "IImage.h" + +namespace irr +{ +namespace video +{ + //! CTRTextureGouraud class + class CTRTextureGouraud : public ITriangleRenderer + { + public: + + //! constructor + CTRTextureGouraud(IZBuffer* zbuffer); + + //! destructor + virtual ~CTRTextureGouraud(); + + //! sets a render target + virtual void setRenderTarget(video::IImage* surface, const core::rect& viewPort); + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount); + + //! en or disables the backface culling + virtual void setBackfaceCulling(bool enabled = true); + + //! sets the Texture + virtual void setTexture(video::IImage* texture); + + protected: + + //! vertauscht zwei vertizen + inline void swapVertices(const S2DVertex** v1, const S2DVertex** v2) + { + const S2DVertex* b = *v1; + *v1 = *v2; + *v2 = b; + } + + video::IImage* RenderTarget; + core::rect ViewPortRect; + + IZBuffer* ZBuffer; + + s32 SurfaceWidth; + s32 SurfaceHeight; + bool BackFaceCullingEnabled; + TZBufferType* lockedZBuffer; + u16* lockedSurface; + u16* lockedTexture; + s32 lockedTextureWidth; + s32 textureXMask, textureYMask; + video::IImage* Texture; + }; + +} // end namespace video +} // end namespace irr + +#endif + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud2.cpp new file mode 100644 index 0000000..b4e8178 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraud2.cpp @@ -0,0 +1,674 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraud2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraud2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraud2::CTRTextureGouraud2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraud2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraud2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + +#ifdef IPOL_C0 + tFixPoint r1, g1, b1; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + tx0 = tofix ( line.t[0][0].x, inversew); + ty0 = tofix ( line.t[0][0].y, inversew); + +#ifdef IPOL_C0 + r1 = tofix ( line.c[0][0].y ,inversew ); + g1 = tofix ( line.c[0][0].z ,inversew ); + b1 = tofix ( line.c[0][0].w ,inversew ); +#endif + +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); +#ifdef IPOL_C0 + getTexel_plain2 ( r1, g1, b1, line.c[0][0] ); +#endif +#endif + +#ifdef IPOL_C0 + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + + dst[i] = fix_to_color ( imulFix ( r0, r1 ), + imulFix ( g0, g1 ), + imulFix ( b0, b1 ) + ); +#else + +#ifdef BURNINGVIDEO_RENDERER_FAST + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 ); +#else + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + dst[i] = fix_to_color ( r0, g0, b0 ); +#endif + +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraud2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd.cpp new file mode 100644 index 0000000..557bb48 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd.cpp @@ -0,0 +1,419 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureGouraudAdd : public CTRTextureGouraud +{ +public: + + //! constructor + CTRTextureGouraudAdd(IZBuffer* zbuffer); + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount); + +protected: + +}; + +//! constructor +CTRTextureGouraudAdd::CTRTextureGouraudAdd(IZBuffer* zbuffer) +: CTRTextureGouraud(zbuffer) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAdd"); + #endif +} + + +//! draws an indexed triangle list +void CTRTextureGouraudAdd::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) +{ + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + s32 spanZValue, spanZStep; // ZValues when drawing a span + TZBufferType* zTarget, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + // thanks to a correction by hybrid + // calculations delayed to correctly propagate to textures etc. + s32 tDiffLeft=0, tDiffRight=0; + if (leftxViewPortRect.LowerRightCorner.X) + tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; + + if (rightxViewPortRect.LowerRightCorner.X) + tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; + + // draw the span + if (rightx + tDiffRight - leftx - tDiffLeft) + { + tmpDiv = 1.0f / (f32)(rightx - leftx); + spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv); + spanZValue = leftZValue+tDiffLeft*spanZStep; + + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanR = leftR+tDiffLeft*spanStepR; + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanG = leftG+tDiffLeft*spanStepG; + spanStepB = (s32)((rightB - leftB) * tmpDiv); + spanB = leftB+tDiffLeft*spanStepB; + + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTx = leftTx + tDiffLeft*spanTxStep; + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + spanTy = leftTy+tDiffLeft*spanTyStep; + + hSpanBegin = targetSurface + leftx+tDiffLeft; + spanZTarget = zTarget + leftx+tDiffLeft; + hSpanEnd = targetSurface + rightx+tDiffRight; + + while (hSpanBegin < hSpanEnd) + { + if (spanZValue > *spanZTarget) + { + //*spanZTarget = spanZValue; + color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + + s32 basis = *hSpanBegin; + s32 r = (video::getRed(basis)<<3) + (video::getRed(color)<<3); + if (r > 255) r = 255; + s32 g = (video::getGreen(basis)<<3) + (video::getGreen(color)<<3); + if (g > 255) g = 255; + s32 b = (video::getBlue(basis)<<3) + (video::getBlue(color)<<3); + if (b > 255) b = 255; + + *hSpanBegin = video::RGB16(r, g, b); + } + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanTx += spanTxStep; + spanTy += spanTyStep; + + spanZValue += spanZStep; + ++hSpanBegin; + ++spanZTarget; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraudAdd(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp new file mode 100644 index 0000000..1738f33 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAdd2.cpp @@ -0,0 +1,680 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAdd2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAdd2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraudAdd2::CTRTextureGouraudAdd2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAdd2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraudAdd2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[1] - line.c[0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + dst[i] = PixelAdd32 ( + dst[i], + getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew), + d + tofix ( line.t[0][0].y,inversew) ) + ); +#else + dst[i] = PixelAdd32 ( + dst[i], + getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x), + d + tofix ( line.t[0][0].y) ) + ); + +#endif +#else + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ), + clampfix_maxcolor ( g1 + g0 ), + clampfix_maxcolor ( b1 + b0 ) + ); +#endif + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAdd2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp new file mode 100644 index 0000000..58b6d71 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp @@ -0,0 +1,645 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +//#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAddNoZ2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraudAddNoZ2::CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAddNoZ2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraudAddNoZ2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[1] - line.c[0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef IPOL_W + f32 inversew; +#endif + + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef IPOL_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); +#endif + + getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + (r0 >> 1 ) ), + clampfix_maxcolor ( g1 + (g0 >> 1 ) ), + clampfix_maxcolor ( b1 + (b0 >> 1) ) + ); + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAddNoZ2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlpha.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlpha.cpp new file mode 100644 index 0000000..62a7c9a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlpha.cpp @@ -0,0 +1,744 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAlpha2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAlpha2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setParam ( u32 index, f32 value); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + + u32 AlphaRef; +}; + +//! constructor +CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAlpha2"); + #endif + + AlphaRef = 0; +} + + +/*! +*/ +void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value) +{ +#ifdef BURNINGVIDEO_RENDERER_FAST + AlphaRef = core::floor32 ( value * 256.f ); +#else + AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) ); +#endif +} + +/*! +*/ +void CTRTextureGouraudAlpha2::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + tFixPoint a0; + tFixPoint r0, g0, b0; +#endif + +#ifdef IPOL_C0 + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + +#ifdef INVERSE_W + + inversew = fix_inverse32 ( line.w[0] ); + + u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew), + d + tofix ( line.t[0][0].y,inversew) + ); + +#else + + u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x), + d + tofix ( line.t[0][0].y) + ); + +#endif + + const u32 alpha = ( argb >> 24 ); + if ( alpha > AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + dst[i] = PixelBlend32 ( dst[i], argb, alpha ); + } + + +#else + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + getSample_texture ( a0,r0,g0,b0, + &IT[0], + tofix ( line.t[0][0].x,inversew), + tofix ( line.t[0][0].y,inversew) + ); +#else + getSample_texture ( a0,r0,g0,b0, + &IT[0], + tofix ( line.t[0][0].x), + tofix ( line.t[0][0].y) + ); +#endif + if ( (tFixPointu) a0 > AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + getSample_color ( r2, g2, b2, line.c[0][0], inversew ); +#else + getSample_color ( r2, g2, b2, line.c[0][0] ); +#endif + r0 = imulFix ( r0, r2 ); + g0 = imulFix ( g0, g2 ); + b0 = imulFix ( b0, b2 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + a0 >>= 8; + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + dst[i] = fix4_to_color ( a0, r2, g2, b2 ); + +/* + dst[i] = PixelBlend32 ( dst[i], + fix_to_color ( r0,g0, b0 ), + fixPointu_to_u32 ( a0 ) + ); +*/ +/* + getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX ); + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r0 + imulFix ( a0, r1 - r0 ); + g2 = g0 + imulFix ( a0, g1 - g0 ); + b2 = b0 + imulFix ( a0, b1 - b0 ); + dst[i] = fix_to_color ( r2, g2, b2 ); +*/ + + } +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAlpha2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp new file mode 100644 index 0000000..96e1519 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp @@ -0,0 +1,745 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +//#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudAlphaNoZ : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + virtual void setParam ( u32 index, f32 value); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + + u32 AlphaRef; +}; + +//! constructor +CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudAlphaNoZ"); + #endif + + AlphaRef = 0; +} + + +/*! +*/ +void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value) +{ +#ifdef BURNINGVIDEO_RENDERER_FAST + AlphaRef = core::floor32 ( value * 256.f ); +#else + AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) ); +#endif +} + +/*! +*/ +void CTRTextureGouraudAlphaNoZ::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC[MATERIAL_MAX_COLORS]; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0] * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + +#else + tFixPoint a0; + tFixPoint r0, g0, b0; +#endif + +#ifdef IPOL_C0 + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + +#ifdef INVERSE_W + + inversew = fix_inverse32 ( line.w[0] ); + + u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew), + d + tofix ( line.t[0][0].y,inversew) + ); + +#else + + u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x), + d + tofix ( line.t[0][0].y) + ); + +#endif + + const u32 alpha = ( argb >> 24 ); + if ( alpha > AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + + dst[i] = PixelBlend32 ( dst[i], argb, alpha ); + } + + +#else + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + getSample_texture ( a0, r0, g0, b0, + &IT[0], + tofix ( line.t[0][0].x,inversew), + tofix ( line.t[0][0].y,inversew) + ); +#else + getSample_texture ( a0, r0, g0,b0, + &IT[0], + tofix ( line.t[0][0].x), + tofix ( line.t[0][0].y) + ); +#endif + if ( (tFixPointu) a0 > AlphaRef ) + { +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef INVERSE_W + getSample_color ( r2, g2, b2, line.c[0][0], inversew ); +#else + getSample_color ( r2, g2, b2, line.c[0][0] ); +#endif + r0 = imulFix ( r0, r2 ); + g0 = imulFix ( g0, g2 ); + b0 = imulFix ( b0, b2 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + a0 >>= 8; + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + dst[i] = fix4_to_color ( a0, r2, g2, b2 ); + +/* + dst[i] = PixelBlend32 ( dst[i], + fix_to_color ( r0,g0, b0 ), + fixPointu_to_u32 ( a0 ) + ); +*/ +/* + getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX ); + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r0 + imulFix ( a0, r1 - r0 ); + g2 = g0 + imulFix ( a0, g1 - g0 ); + b2 = b0 + imulFix ( a0, b1 - b0 ); + dst[i] = fix_to_color ( r2, g2, b2 ); +*/ + + } +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC[0]; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudAlphaNoZ(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ.cpp new file mode 100644 index 0000000..ea47277 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ.cpp @@ -0,0 +1,367 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" +#include "SColor.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureGouraudNoZ : public CTRTextureGouraud +{ +public: + + CTRTextureGouraudNoZ() + : CTRTextureGouraud(0) + { + #ifdef _DEBUG + setDebugName("CTRGouraudWireNoZ"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span. + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span + core::rect TriangleRect; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + // thanks to a correction by hybrid + // calculations delayed to correctly propagate to textures etc. + s32 tDiffLeft=0, tDiffRight=0; + if (leftxViewPortRect.LowerRightCorner.X) + tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx; + + if (rightxViewPortRect.LowerRightCorner.X) + tDiffRight=ViewPortRect.LowerRightCorner.X-rightx; + + // draw the span + if (rightx + tDiffRight - leftx - tDiffLeft) + { + tmpDiv = 1.0f / (f32)(rightx - leftx); + + spanStepR = (s32)((rightR - leftR) * tmpDiv); + spanR = leftR+tDiffLeft*spanStepR; + spanStepG = (s32)((rightG - leftG) * tmpDiv); + spanG = leftG+tDiffLeft*spanStepG; + spanStepB = (s32)((rightB - leftB) * tmpDiv); + spanB = leftB+tDiffLeft*spanStepB; + + spanTxStep = (s32)((rightTx - leftTx) * tmpDiv); + spanTx = leftTx + tDiffLeft*spanTxStep; + spanTyStep = (s32)((rightTy - leftTy) * tmpDiv); + spanTy = leftTy+tDiffLeft*spanTyStep; + + hSpanBegin = targetSurface + leftx+tDiffLeft; + hSpanEnd = targetSurface + rightx+tDiffRight; + + while (hSpanBegin < hSpanEnd) + { + color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)]; + *hSpanBegin = video::RGB16(video::getRed(color) * (spanR>>8) >>2, + video::getGreen(color) * (spanG>>8) >>2, + video::getBlue(color) * (spanB>>8) >>2); + + spanR += spanStepR; + spanG += spanStepG; + spanB += spanStepB; + + spanTx += spanTxStep; + spanTy += spanTyStep; + + ++hSpanBegin; + } + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + Texture->unlock(); + } + +}; + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureGouraudNoZ() +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraudNoZ(); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ2.cpp new file mode 100644 index 0000000..e9eeee0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudNoZ2.cpp @@ -0,0 +1,647 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#ifdef BURNINGVIDEO_RENDERER_FAST + #define SUBTEXEL + #define INVERSE_W +#else + #define SUBTEXEL + #define INVERSE_W +#endif + +//#define USE_ZBUFFER +#define IPOL_W +//#define CMP_W +//#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureGouraudNoZ2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureGouraudNoZ2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureGouraudNoZ2"); + #endif +} + + + +/*! +*/ +void CTRTextureGouraudNoZ2::scanline_bilinear ( ) +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[1] - line.c[0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0; + tFixPoint ty0; + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); +#endif + dst[i] = getTexel_plain ( &IT[0], tx0, ty0 ); + +/* + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + dst[i] = fix_to_color ( r0, g0, b0 ); +*/ +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear ( ); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureGouraudNoZ2( driver ); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp new file mode 100644 index 0000000..5dad045 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp @@ -0,0 +1,690 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +//#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureVertexAlpha2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureVertexAlpha2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureVertexAlpha2::CTRTextureVertexAlpha2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureVertexAlpha2"); + #endif +} + + + +/*! +*/ +void CTRTextureVertexAlpha2::scanline_bilinear ( ) +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + +//#define __TEST_THIS + +#ifdef __TEST_THIS + +#else + tFixPoint tx0; + tFixPoint ty0; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif + + +#ifdef IPOL_C0 + tFixPoint a3; +#endif + + + for ( s32 i = 0; i <= dx; ++i ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + + { +#ifdef __TEST_THIS + + inversew = fix_inverse32 ( line.w[0] ); + + dst[i] = PixelAdd32 ( + dst[i], + getTexel_plain ( &IT[0], tofix ( line.t[0][0].x,inversew), + tofix ( line.t[0][0].y,inversew) ) + ); + +#else + +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); + +#ifdef IPOL_C0 + a3 = tofix ( line.c[0][0].y,inversew ); +#endif + +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); + +#ifdef IPOL_C0 + a3 = tofix ( line.c[0][0].y ); +#endif + + +#endif + + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + color_to_fix ( r1, g1, b1, dst[i] ); + +#ifdef IPOL_C0 + r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) ); + g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) ); + b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) ); +#else + r2 = clampfix_maxcolor ( r1 + r0 ); + g2 = clampfix_maxcolor ( g1 + g0 ); + b2 = clampfix_maxcolor ( b1 + b0 ); +#endif + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif +#endif + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureVertexAlpha2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudWire.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudWire.cpp new file mode 100644 index 0000000..8a07e43 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureGouraudWire.cpp @@ -0,0 +1,364 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CTRTextureGouraud.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +class CTRTextureGouraudWire : public CTRTextureGouraud +{ +public: + + CTRTextureGouraudWire(IZBuffer* zbuffer) + : CTRTextureGouraud(zbuffer) + { + #ifdef _DEBUG + setDebugName("CTRGouraudWire"); + #endif + } + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) + { + const S2DVertex *v1, *v2, *v3; + + u16 color; + f32 tmpDiv; // temporary division factor + f32 longest; // saves the longest span + s32 height; // saves height of triangle + u16* targetSurface; // target pointer where to plot pixels + s32 spanEnd; // saves end of spans + f32 leftdeltaxf; // amount of pixels to increase on left side of triangle + f32 rightdeltaxf; // amount of pixels to increase on right side of triangle + s32 leftx, rightx; // position where we are + f32 leftxf, rightxf; // same as above, but as f32 values + s32 span; // current span + s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values + s32 leftStepR, leftStepG, leftStepB, + rightStepR, rightStepG, rightStepB; // color steps + s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values + s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values + core::rect TriangleRect; + + s32 leftZValue, rightZValue; + s32 leftZStep, rightZStep; + TZBufferType* zTarget;//, *spanZTarget; // target of ZBuffer; + + lockedSurface = (u16*)RenderTarget->lock(); + lockedZBuffer = ZBuffer->lock(); + lockedTexture = (u16*)Texture->lock(); + + for (s32 i=0; iPos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) - + ((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X)); + + if (z < 0) + continue; + } + + //near plane clipping + + if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0) + continue; + + // sort for width for inscreen clipping + + if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2); + if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3); + if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3); + + if ((v1->Pos.X - v3->Pos.X) == 0) + continue; + + TriangleRect.UpperLeftCorner.X = v1->Pos.X; + TriangleRect.LowerRightCorner.X = v3->Pos.X; + + // sort for height for faster drawing. + + if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2); + if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3); + if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3); + + TriangleRect.UpperLeftCorner.Y = v1->Pos.Y; + TriangleRect.LowerRightCorner.Y = v3->Pos.Y; + + if (!TriangleRect.isRectCollided(ViewPortRect)) + continue; + + // calculate height of triangle + height = v3->Pos.Y - v1->Pos.Y; + if (!height) + continue; + + // calculate longest span + + longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X); + + spanEnd = v2->Pos.Y; + span = v1->Pos.Y; + leftxf = (f32)v1->Pos.X; + rightxf = (f32)v1->Pos.X; + + leftZValue = v1->ZValue; + rightZValue = v1->ZValue; + + leftR = rightR = video::getRed(v1->Color)<<8; + leftG = rightG = video::getGreen(v1->Color)<<8; + leftB = rightB = video::getBlue(v1->Color)<<8; + leftTx = rightTx = v1->TCoords.X; + leftTy = rightTy = v1->TCoords.Y; + + targetSurface = lockedSurface + span * SurfaceWidth; + zTarget = lockedZBuffer + span * SurfaceWidth; + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)height; + leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (f32)height; + rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv; + rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv); + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + + tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y); + leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv; + leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv); + leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv); + leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv); + } + + + // do it twice, once for the first half of the triangle, + // end then for the second half. + + for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf) + { + if (spanEnd > ViewPortRect.LowerRightCorner.Y) + spanEnd = ViewPortRect.LowerRightCorner.Y; + + // if the span <0, than we can skip these spans, + // and proceed to the next spans which are really on the screen. + if (span < ViewPortRect.UpperLeftCorner.Y) + { + // we'll use leftx as temp variable + if (spanEnd < ViewPortRect.UpperLeftCorner.Y) + { + leftx = spanEnd - span; + span = spanEnd; + } + else + { + leftx = ViewPortRect.UpperLeftCorner.Y - span; + span = ViewPortRect.UpperLeftCorner.Y; + } + + leftxf += leftdeltaxf*leftx; + rightxf += rightdeltaxf*leftx; + targetSurface += SurfaceWidth*leftx; + zTarget += SurfaceWidth*leftx; + leftZValue += leftZStep*leftx; + rightZValue += rightZStep*leftx; + + leftR += leftStepR*leftx; + leftG += leftStepG*leftx; + leftB += leftStepB*leftx; + rightR += rightStepR*leftx; + rightG += rightStepG*leftx; + rightB += rightStepB*leftx; + + leftTx += leftTxStep*leftx; + leftTy += leftTyStep*leftx; + rightTx += rightTxStep*leftx; + rightTy += rightTyStep*leftx; + } + + + // the main loop. Go through every span and draw it. + + while (span < spanEnd) + { + leftx = (s32)(leftxf); + rightx = (s32)(rightxf + 0.5f); + + // perform some clipping + + if (leftx>=ViewPortRect.UpperLeftCorner.X && + leftx<=ViewPortRect.LowerRightCorner.X) + { + if (leftZValue > *(zTarget + leftx)) + { + *(zTarget + leftx) = leftZValue; + color = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((leftTx>>8)&textureXMask)]; + *(targetSurface + leftx) = video::RGB16(video::getRed(color) * (leftR>>8) >>2, + video::getGreen(color) * (leftG>>8) >>2, + video::getBlue(color) * (leftR>>8) >>2); + } + } + + + if (rightx>=ViewPortRect.UpperLeftCorner.X && + rightx<=ViewPortRect.LowerRightCorner.X) + { + if (rightZValue > *(zTarget + rightx)) + { + *(zTarget + rightx) = rightZValue; + color = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)]; + *(targetSurface + rightx) = video::RGB16(video::getRed(color) * (rightR>>8) >>2, + video::getGreen(color) * (rightG>>8) >>2, + video::getBlue(color) * (rightR>>8) >>2); + } + + } + + leftxf += leftdeltaxf; + rightxf += rightdeltaxf; + ++span; + targetSurface += SurfaceWidth; + zTarget += SurfaceWidth; + leftZValue += leftZStep; + rightZValue += rightZStep; + + leftR += leftStepR; + leftG += leftStepG; + leftB += leftStepB; + rightR += rightStepR; + rightG += rightStepG; + rightB += rightStepB; + + leftTx += leftTxStep; + leftTy += leftTyStep; + rightTx += rightTxStep; + rightTy += rightTyStep; + } + + if (triangleHalf>0) // break, we've gout only two halves + break; + + + // setup variables for second half of the triangle. + + if (longest < 0.0f) + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + rightxf = (f32)v2->Pos.X; + + rightZValue = v2->ZValue; + rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + rightR = video::getRed(v2->Color)<<8; + rightG = video::getGreen(v2->Color)<<8; + rightB = video::getBlue(v2->Color)<<8; + rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv); + rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv); + rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv); + + rightTx = v2->TCoords.X; + rightTy = v2->TCoords.Y; + rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv); + rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv); + } + else + { + tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y); + + leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv; + leftxf = (f32)v2->Pos.X; + + leftZValue = v2->ZValue; + leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv); + + leftR = video::getRed(v2->Color)<<8; + leftG = video::getGreen(v2->Color)<<8; + leftB = video::getBlue(v2->Color)<<8; + leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv); + leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv); + leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv); + + leftTx = v2->TCoords.X; + leftTy = v2->TCoords.Y; + leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv); + leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv); + } + + + spanEnd = v3->Pos.Y; + } + + } + + RenderTarget->unlock(); + ZBuffer->unlock(); + Texture->unlock(); + } +}; + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +ITriangleRenderer* createTriangleRendererTextureGouraudWire(IZBuffer* zbuffer) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CTRTextureGouraudWire(zbuffer); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + +} // end namespace video +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_Add.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_Add.cpp new file mode 100644 index 0000000..82f39f3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_Add.cpp @@ -0,0 +1,672 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_Add : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_Add(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_Add::CTRTextureLightMap2_Add(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_Add"); + #endif +} + + + +/*! +*/ +REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[1] - line.c[0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + +#ifdef INVERSE_W + + const f32 inversew = fix_inverse32 ( line.w[0] ); + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + dst[i] = PixelAdd32 ( + getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew), + d + tofix ( line.t[0][0].y,inversew) ), + getTexel_plain ( &IT[1], d + tofix ( line.t[1][0].x,inversew), + d + tofix ( line.t[1][0].y,inversew) ) + ); +#else + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + dst[i] = PixelAdd32 ( + getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x), + d + tofix ( line.t[0][0].y) ), + getTexel_plain ( &IT[1], d + tofix ( line.t[1][0].x), + d + tofix ( line.t[1][0].y) ) + ); + +#endif + +#else + const f32 inversew = fix_inverse32 ( line.w[0] ); + + getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[0][1].x,inversew), tofix ( line.t[0][1].y,inversew) ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ), + clampfix_maxcolor ( g0 + g1 ), + clampfix_maxcolor ( b0 + b1 ) + ); +#endif + + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[1] ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + if ( (f32) 0.0 != scan.invDeltaY[2] ) + { + // advance to middle point + if( (f32) 0.0 != scan.invDeltaY[1] ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_Add(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M1.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M1.cpp new file mode 100644 index 0000000..59a13b1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M1.cpp @@ -0,0 +1,644 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_M1 : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_M1(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear2 (); + + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_M1::CTRTextureLightMap2_M1(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M1"); + #endif +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + + a = (f32) i + subPixel; + + line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX; + line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; + + line.t[0][0] += line.t[0][1] * a; + line.t[1][0] += line.t[1][1] * a; + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + getSample_texture ( r0, g0, b0, &IT[0], d + tofix ( line.t[0][0].x,inversew), d + tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], d + tofix ( line.t[1][0].x,inversew), d + tofix ( line.t[1][0].y,inversew) ); +#else + getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) ); + +#endif + + dst[i] = fix_to_color ( imulFix_tex1 ( r0, r1 ), + imulFix_tex1 ( g0, g1 ), + imulFix_tex1 ( b0, b1 ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t[0][0] += line.t[0][1]; + line.t[1][0] += line.t[1][1]; + } + +} + + + +void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_M1(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M2.cpp new file mode 100644 index 0000000..40da966 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M2.cpp @@ -0,0 +1,644 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_M2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_M2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear2 (); + + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_M2::CTRTextureLightMap2_M2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M2"); + #endif +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + + a = (f32) i + subPixel; + + line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX; + line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; + + line.t[0][0] += line.t[0][1] * a; + line.t[1][0] += line.t[1][1] * a; + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + getSample_texture ( r0, g0, b0, &IT[0], d + tofix ( line.t[0][0].x,inversew), d + tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], d + tofix ( line.t[1][0].x,inversew), d + tofix ( line.t[1][0].y,inversew) ); +#else + getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) ); + +#endif + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t[0][0] += line.t[0][1]; + line.t[1][0] += line.t[1][1]; + } + +} + + + +void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2 (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_M2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp new file mode 100644 index 0000000..989a915 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMap2_M4.cpp @@ -0,0 +1,1154 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +//#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRTextureLightMap2_M4 : public IBurningShader +{ +public: + + //! constructor + CTRTextureLightMap2_M4(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + + void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + void scanline_bilinear (); + void scanline_bilinear2_mag (); + void scanline_bilinear2_min (); + + sScanLineData line; + +}; + +//! constructor +CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureLightMap2_M4"); + #endif +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag () +{ + tVideoSample *dst; + fp24 *z; + + // apply top-left fill-convention, left + const s32 xStart = irr::core::ceil32( line.x[0] ); + const s32 xEnd = irr::core::ceil32( line.x[1] ) - 1; + s32 dx; + s32 i; + + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + i = ( line.y * RenderTarget->getDimension().Width ) + xStart; + z = (fp24*) DepthBuffer->lock() + i; + dst = (tVideoSample*)RenderTarget->lock() + i; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const fp24 b = (line.w[1] - line.w[0]) * invDeltaX; + fp24 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a < z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + + a = (f32) i + subPixel; + + line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX; + line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; + + line.t[0][0] += line.t[0][1] * a; + line.t[1][0] += line.t[1][1] * a; + + +#ifdef BURNINGVIDEO_RENDERER_FAST + u32 dIndex = ( line.y & 3 ) << 2; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + +#else + // + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; +#endif + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + +#ifdef BURNINGVIDEO_RENDERER_FAST + + const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; + + getSample_texture ( r0, g0, b0, &IT[0], d + tofix ( line.t[0][0].x,inversew), d + tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], d + tofix ( line.t[1][0].x,inversew), d + tofix ( line.t[1][0].y,inversew) ); +#else + getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); + getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) ); + +#endif + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t[0][0] += line.t[0][1]; + line.t[1][0] += line.t[1][1]; + } + +} + +/*! +*/ +REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min () +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; + + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + + // search z-buffer for first not occulled pixel + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + + // subTexel + const f32 subPixel = ( (f32) xStart ) - line.x[0]; + +#ifdef IPOL_W + const f32 b = (line.w[1] - line.w[0]) * invDeltaX; + f32 a = line.w[0] + ( b * subPixel ); + + i = 0; + + while ( a <= z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.w[0] = a; + line.w[1] = b; +#else + const f32 b = (line.z[1] - line.z[0]) * invDeltaX; + f32 a = line.z[0] + ( b * subPixel ); + + i = 0; + + while ( a > z[i] ) + { + a += b; + + i += 1; + if ( i > dx ) + return; + + } + + // lazy setup rest of scanline + + line.z[0] = a; + line.z[1] = b; +#endif + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + + a = (f32) i + subPixel; + + line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX; + line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; + + line.t[0][0] += line.t[0][1] * a; + line.t[1][0] += line.t[1][1] * a; + + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + + + for ( ;i <= dx; i++ ) + { +#ifdef IPOL_W + if ( line.w[0] >= z[i] ) + { + z[i] = line.w[0]; +#else + if ( line.z[0] < z[i] ) + { + z[i] = line.z[0]; +#endif + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + f32 inversew = fix_inverse32 ( line.w[0] ); +#else + f32 inversew = FIX_POINT_F32_MUL; +#endif + + + getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); + getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) ); + + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ), + clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ) + ); + } + +#ifdef IPOL_W + line.w[0] += line.w[1]; +#else + line.z[0] += line.z[1]; +#endif + line.t[0][0] += line.t[0][1]; + line.t[1][0] += line.t[1][1]; + } + +} + +//#ifdef BURNINGVIDEO_RENDERER_FAST +#if 1 + +void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + if ( IT[0].lodLevel <= 2 ) + drawTriangle_Mag ( a, b, c ); + else + drawTriangle_Min ( a, b, c ); +} + +void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2_min (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2_min (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) + +#else + +void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) + +#endif + +{ + sScanConvertData scan; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + + // rasterize upper sub-triangle + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2_mag (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0] * subPixel; + scan.c[1] += scan.slopeC[1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[scan.left] = scan.c[0]; + line.c[scan.right] = scan.c[1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear2_mag (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0] += scan.slopeC[0]; + scan.c[1] += scan.slopeC[1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureLightMap2_M4(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp new file mode 100644 index 0000000..d7397f4 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp @@ -0,0 +1,690 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + +#define IPOL_C0 +#define IPOL_T0 +#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #undef IPOL_C0 +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + +namespace irr +{ + +namespace video +{ + +class CTRGTextureLightMap2_M4 : public IBurningShader +{ +public: + + //! constructor + CTRGTextureLightMap2_M4(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + + +private: + void scanline_bilinear (); + + sScanConvertData scan; + sScanLineData line; + +}; + +//! constructor +CTRGTextureLightMap2_M4::CTRGTextureLightMap2_M4(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRGTextureLightMap2_M4"); + #endif +} + + + +/*! +*/ +void CTRGTextureLightMap2_M4::scanline_bilinear () +{ + tVideoSample *dst; + +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + s32 xStart; + s32 xEnd; + s32 dx; + + +#ifdef SUBTEXEL + f32 subPixel; +#endif + +#ifdef IPOL_Z + f32 slopeZ; +#endif +#ifdef IPOL_W + fp24 slopeW; +#endif +#ifdef IPOL_C0 + sVec4 slopeC; +#endif +#ifdef IPOL_T0 + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; +#endif + + // apply top-left fill-convention, left + xStart = core::ceil32( line.x[0] ); + xEnd = core::ceil32( line.x[1] ) - 1; + + dx = xEnd - xStart; + + if ( dx < 0 ) + return; + + // slopes + const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] ); + +#ifdef IPOL_Z + slopeZ = (line.z[1] - line.z[0]) * invDeltaX; +#endif +#ifdef IPOL_W + slopeW = (line.w[1] - line.w[0]) * invDeltaX; +#endif +#ifdef IPOL_C0 + slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T0 + slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; +#endif +#ifdef IPOL_T1 + slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; +#endif + +#ifdef SUBTEXEL + subPixel = ( (f32) xStart ) - line.x[0]; +#ifdef IPOL_Z + line.z[0] += slopeZ * subPixel; +#endif +#ifdef IPOL_W + line.w[0] += slopeW * subPixel; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC * subPixel; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0] * subPixel; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1] * subPixel; +#endif +#endif + + dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; + +#ifdef USE_ZBUFFER + z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; +#endif + + +#ifdef INVERSE_W + f32 inversew; +#endif + + tFixPoint tx0, tx1; + tFixPoint ty0, ty1; + + tFixPoint r0, g0, b0; + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; + +#ifdef IPOL_C0 + tFixPoint r3, g3, b3; +#endif + + for ( s32 i = 0; i <= dx; i++ ) + { +#ifdef CMP_Z + if ( line.z[0] < z[i] ) +#endif +#ifdef CMP_W + if ( line.w[0] >= z[i] ) +#endif + { +#ifdef INVERSE_W + inversew = fix_inverse32 ( line.w[0] ); + + tx0 = tofix ( line.t[0][0].x,inversew); + ty0 = tofix ( line.t[0][0].y,inversew); + tx1 = tofix ( line.t[1][0].x,inversew); + ty1 = tofix ( line.t[1][0].y,inversew); + +#ifdef IPOL_C0 + r3 = tofix ( line.c[0][0].y ,inversew ); + g3 = tofix ( line.c[0][0].z ,inversew ); + b3 = tofix ( line.c[0][0].w ,inversew ); +#endif + +#else + tx0 = tofix ( line.t[0][0].x ); + ty0 = tofix ( line.t[0][0].y ); + tx1 = tofix ( line.t[1][0].x ); + ty1 = tofix ( line.t[1][0].y ); + +#ifdef IPOL_C0 + r3 = tofix ( line.c[0][0].y ); + g3 = tofix ( line.c[0][0].z ); + b3 = tofix ( line.c[0][0].w ); +#endif + +#endif + getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); + getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 ); + +#ifdef IPOL_C0 + r2 = imulFix ( r0, r3 ); + g2 = imulFix ( g0, g3 ); + b2 = imulFix ( b0, b3 ); + + r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) ); +/* + r2 = r3 << 8; + g2 = g3 << 8; + b2 = b3 << 8; +*/ +#else + r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ); + g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ); + b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) ); +#endif + + + dst[i] = fix_to_color ( r2, g2, b2 ); + +#ifdef WRITE_Z + z[i] = line.z[0]; +#endif +#ifdef WRITE_W + z[i] = line.w[0]; +#endif + } + +#ifdef IPOL_Z + line.z[0] += slopeZ; +#endif +#ifdef IPOL_W + line.w[0] += slopeW; +#endif +#ifdef IPOL_C0 + line.c[0][0] += slopeC; +#endif +#ifdef IPOL_T0 + line.t[0][0] += slopeT[0]; +#endif +#ifdef IPOL_T1 + line.t[1][0] += slopeT[1]; +#endif + } + +} + +void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + const f32 ca = c->Pos.y - a->Pos.y; + const f32 ba = b->Pos.y - a->Pos.y; + const f32 cb = c->Pos.y - b->Pos.y; + // calculate delta y of the edges + scan.invDeltaY[0] = core::reciprocal( ca ); + scan.invDeltaY[1] = core::reciprocal( ba ); + scan.invDeltaY[2] = core::reciprocal( cb ); + + if ( F32_LOWER_0 ( scan.invDeltaY[0] ) ) + return; + + // find if the major edge is left or right aligned + f32 temp[4]; + + temp[0] = a->Pos.x - c->Pos.x; + temp[1] = -ca; + temp[2] = b->Pos.x - a->Pos.x; + temp[3] = ba; + + scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; + scan.right = 1 - scan.left; + + // calculate slopes for the major edge + scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0]; + scan.x[0] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0]; + scan.z[0] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0]; + scan.w[0] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; + scan.t[0][0] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0]; + scan.t[1][0] = a->Tex[1]; +#endif + + // top left fill convention y run + s32 yStart; + s32 yEnd; + +#ifdef SUBTEXEL + f32 subPixel; +#endif + + + // rasterize upper sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + // calculate slopes for top edge + scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; + scan.x[1] = a->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1]; + scan.z[1] = a->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1]; + scan.w[1] = a->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; + scan.t[0][1] = a->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1]; + scan.t[1][1] = a->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( a->Pos.y ); + yEnd = core::ceil32( b->Pos.y ) - 1; + +#ifdef SUBTEXEL + subPixel = ( (f32) yStart ) - a->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + + // rasterize lower sub-triangle + //if ( (f32) 0.0 != scan.invDeltaY[2] ) + if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) + { + // advance to middle point + //if( (f32) 0.0 != scan.invDeltaY[1] ) + if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) + { + temp[0] = b->Pos.y - a->Pos.y; // dy + + scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; +#ifdef IPOL_Z + scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; +#endif +#ifdef IPOL_W + scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; +#endif +#ifdef IPOL_C0 + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; +#endif +#ifdef IPOL_T0 + scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; +#endif +#ifdef IPOL_T1 + scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; +#endif + + } + + // calculate slopes for bottom edge + scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2]; + scan.x[1] = b->Pos.x; + +#ifdef IPOL_Z + scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2]; + scan.z[1] = b->Pos.z; +#endif + +#ifdef IPOL_W + scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2]; + scan.w[1] = b->Pos.w; +#endif + +#ifdef IPOL_C0 + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; +#endif + +#ifdef IPOL_T0 + scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; + scan.t[0][1] = b->Tex[0]; +#endif + +#ifdef IPOL_T1 + scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2]; + scan.t[1][1] = b->Tex[1]; +#endif + + // apply top-left fill convention, top part + yStart = core::ceil32( b->Pos.y ); + yEnd = core::ceil32( c->Pos.y ) - 1; + +#ifdef SUBTEXEL + + subPixel = ( (f32) yStart ) - b->Pos.y; + + // correct to pixel center + scan.x[0] += scan.slopeX[0] * subPixel; + scan.x[1] += scan.slopeX[1] * subPixel; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0] * subPixel; + scan.z[1] += scan.slopeZ[1] * subPixel; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0] * subPixel; + scan.w[1] += scan.slopeW[1] * subPixel; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0] * subPixel; + scan.t[0][1] += scan.slopeT[0][1] * subPixel; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0] * subPixel; + scan.t[1][1] += scan.slopeT[1][1] * subPixel; +#endif + +#endif + + // rasterize the edge scanlines + for( line.y = yStart; line.y <= yEnd; ++line.y) + { + line.x[scan.left] = scan.x[0]; + line.x[scan.right] = scan.x[1]; + +#ifdef IPOL_Z + line.z[scan.left] = scan.z[0]; + line.z[scan.right] = scan.z[1]; +#endif + +#ifdef IPOL_W + line.w[scan.left] = scan.w[0]; + line.w[scan.right] = scan.w[1]; +#endif + +#ifdef IPOL_C0 + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; +#endif + +#ifdef IPOL_T0 + line.t[0][scan.left] = scan.t[0][0]; + line.t[0][scan.right] = scan.t[0][1]; +#endif + +#ifdef IPOL_T1 + line.t[1][scan.left] = scan.t[1][0]; + line.t[1][scan.right] = scan.t[1][1]; +#endif + + // render a scanline + scanline_bilinear (); + + scan.x[0] += scan.slopeX[0]; + scan.x[1] += scan.slopeX[1]; + +#ifdef IPOL_Z + scan.z[0] += scan.slopeZ[0]; + scan.z[1] += scan.slopeZ[1]; +#endif + +#ifdef IPOL_W + scan.w[0] += scan.slopeW[0]; + scan.w[1] += scan.slopeW[1]; +#endif + +#ifdef IPOL_C0 + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; +#endif + +#ifdef IPOL_T0 + scan.t[0][0] += scan.slopeT[0][0]; + scan.t[0][1] += scan.slopeT[0][1]; +#endif + +#ifdef IPOL_T1 + scan.t[1][0] += scan.slopeT[1][0]; + scan.t[1][1] += scan.slopeT[1][1]; +#endif + + } + } + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRGTextureLightMap2_M4(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureWire2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureWire2.cpp new file mode 100644 index 0000000..5cf8b3c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTRTextureWire2.cpp @@ -0,0 +1,298 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "IBurningShader.h" + +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +// compile flag for this file +#undef USE_ZBUFFER +#undef IPOL_Z +#undef CMP_Z +#undef WRITE_Z + +#undef IPOL_W +#undef CMP_W +#undef WRITE_W + +#undef SUBTEXEL +#undef INVERSE_W + +#undef IPOL_C0 +#undef IPOL_T0 +#undef IPOL_T1 + +// define render case +#define SUBTEXEL +#define INVERSE_W + +#define USE_ZBUFFER +#define IPOL_W +#define CMP_W +#define WRITE_W + + +//#define IPOL_C0 +#define IPOL_T0 +//#define IPOL_T1 + +// apply global override +#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef INVERSE_W +#endif + +#ifndef SOFTWARE_DRIVER_2_SUBTEXEL + #undef SUBTEXEL +#endif + +#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) + #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #undef IPOL_W + #endif + #define IPOL_Z + + #ifdef CMP_W + #undef CMP_W + #define CMP_Z + #endif + + #ifdef WRITE_W + #undef WRITE_W + #define WRITE_Z + #endif + +#endif + + +namespace irr +{ + +namespace video +{ + +class CTRTextureWire2 : public IBurningShader +{ +public: + + //! constructor + CTRTextureWire2(CBurningVideoDriver* driver); + + //! draws an indexed triangle list + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); + virtual void drawLine ( const s4DVertex *a,const s4DVertex *b); + + + +private: + void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const; + void renderLine ( const s4DVertex *a,const s4DVertex *b ) const; + +}; + +//! constructor +CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver) +: IBurningShader(driver) +{ + #ifdef _DEBUG + setDebugName("CTRTextureWire2"); + #endif +} + + +// swap integer with xor +static inline void swap_xor ( s32 &a, s32 &b ) +{ + a ^= b; + b ^= a; + a ^= b; +} + + +/*! +*/ +void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const +{ + + int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY; + int pitch1 = RenderTarget->getDimension().Width << 2; + + int aposx = (int) a->Pos.x; + int aposy = (int) a->Pos.y; + int bposx = (int) b->Pos.x; + int bposy = (int) b->Pos.y; + + int dx = bposx - aposx; + int dy = bposy - aposy; + + int c; + int m; + int d = 0; + int run; + + tVideoSample *dst; +#ifdef USE_ZBUFFER + fp24 *z; +#endif + + int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY; + int yInc0 = pitch0; + + int xInc1 = 4; + int yInc1 = pitch1; + + tVideoSample color; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + tFixPoint r0, g0, b0; + getSample_color ( r0, g0, b0, a->Color[0] ); + color = fix_to_color ( r0, g0, b0 ); +#else + color = (tVideoSample) 0xFFFFFFFF; +#endif + + if ( dx < 0 ) + { + xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY); + xInc1 = -4; + dx = -dx; + } + + if ( dy > dx ) + { + swap_xor ( dx, dy ); + swap_xor ( xInc0, yInc0 ); + swap_xor ( xInc1, yInc1 ); + } + + if ( 0 == dx ) + return; + + dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->lock() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) ); +#ifdef USE_ZBUFFER + z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) ); +#endif + + c = dx << 1; + m = dy << 1; + +#ifdef IPOL_Z + f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx); + f32 dataZ = a->Pos.z; +#endif + +#ifdef IPOL_W + fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx ); + fp24 dataW = a->Pos.w; +#endif + + run = dx; + while ( run ) + { +#ifdef CMP_Z + if ( *z >= dataZ ) +#endif +#ifdef CMP_W + if ( dataW >= *z ) +#endif + { +#ifdef WRITE_Z + *z = dataZ; +#endif +#ifdef WRITE_W + *z = dataW; +#endif + + *dst = color; + + } + + dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc +#ifdef IPOL_Z + z = (fp24*) ( (u8*) z + xInc1 ); +#endif +#ifdef IPOL_W + z = (fp24*) ( (u8*) z + xInc1 ); +#endif + + d += m; + if ( d > dx ) + { + dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc +#ifdef IPOL_Z + z = (fp24*) ( (u8*) z + yInc1 ); +#endif +#ifdef IPOL_W + z = (fp24*) ( (u8*) z + yInc1 ); +#endif + + d -= c; + } + run -= 1; +#ifdef IPOL_Z + dataZ += slopeZ; +#endif +#ifdef IPOL_W + dataW += slopeW; +#endif + + } + +} + +void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) +{ + sScanLineData line; + + // sort on height, y + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); + if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); + + renderLine ( a, b ); + renderLine ( b, c ); + renderLine ( a, c ); + +} + + +void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b) +{ + + // query access to TexMaps + + // sort on height, y + if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b); + + renderLine ( a, b ); + +} + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +namespace irr +{ +namespace video +{ + + +//! creates a flat triangle renderer +IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver) +{ + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + return new CTRTextureWire2(driver); + #else + return 0; + #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ +} + + +} // end namespace video +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.cpp new file mode 100644 index 0000000..bbc9a8c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.cpp @@ -0,0 +1,258 @@ +// Copyright (C) 2009-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTarReader.h" + +#ifdef __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ + +#include "CFileList.h" +#include "CLimitReadFile.h" +#include "os.h" +#include "coreutil.h" +#if !defined(_IRR_WINDOWS_CE_PLATFORM_) +#include "errno.h" +#endif + +namespace irr +{ +namespace io +{ + +//! Constructor +CArchiveLoaderTAR::CArchiveLoaderTAR(io::IFileSystem* fs) +: FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("CArchiveLoaderTAR"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CArchiveLoaderTAR::isALoadableFileFormat(const io::path& filename) const +{ + return core::hasFileExtension(filename, "tar"); +} + +//! Check to see if the loader can create archives of this type. +bool CArchiveLoaderTAR::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const +{ + return fileType == EFAT_TAR; +} + +//! Creates an archive from the filename +/** \param file File handle to check. +\return Pointer to newly created archive, or 0 upon error. */ +IFileArchive* CArchiveLoaderTAR::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + archive = createArchive(file, ignoreCase, ignorePaths); + file->drop(); + } + + return archive; +} + + +//! creates/loads an archive from the file. +//! \return Pointer to the created archive. Returns 0 if loading failed. +IFileArchive* CArchiveLoaderTAR::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + if (file) + { + file->seek(0); + archive = new CTarReader(file, ignoreCase, ignorePaths); + } + return archive; +} + +//! Check if the file might be loaded by this class +/** Check might look into the file. +\param file File handle to check. +\return True if file seems to be loadable. */ +bool CArchiveLoaderTAR::isALoadableFileFormat(io::IReadFile* file) const +{ + // TAR files consist of blocks of 512 bytes + // if it isn't a multiple of 512 then it's not a TAR file. + if (file->getSize() % 512) + return false; + + file->seek(0); + + // read header of first file + STarHeader fHead; + file->read(&fHead, sizeof(STarHeader)); + + u32 checksum = 0; + sscanf(fHead.Checksum, "%o", &checksum); + + // verify checksum + + // some old TAR writers assume that chars are signed, others assume unsigned + // USTAR archives have a longer header, old TAR archives end after linkname + + u32 checksum1=0; + s32 checksum2=0; + + // remember to blank the checksum field! + memset(fHead.Checksum, ' ', 8); + + // old header + for (u8* p = (u8*)(&fHead); p < (u8*)(&fHead.Magic[0]); ++p) + { + checksum1 += *p; + checksum2 += c8(*p); + } + + if (!strncmp(fHead.Magic, "ustar", 5)) + { + for (u8* p = (u8*)(&fHead.Magic[0]); p < (u8*)(&fHead) + sizeof(fHead); ++p) + { + checksum1 += *p; + checksum2 += c8(*p); + } + } + return checksum1 == checksum || checksum2 == (s32)checksum; +} + +/* + TAR Archive +*/ +CTarReader::CTarReader(IReadFile* file, bool ignoreCase, bool ignorePaths) + : CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file) +{ + #ifdef _DEBUG + setDebugName("CTarReader"); + #endif + + if (File) + { + File->grab(); + + // fill the file list + populateFileList(); + + sort(); + } +} + + +CTarReader::~CTarReader() +{ + if (File) + File->drop(); +} + +const IFileList* CTarReader::getFileList() const +{ + return this; +} + + +u32 CTarReader::populateFileList() +{ + STarHeader fHead; + Files.clear(); + + u32 pos = 0; + while ( s32(pos + sizeof(STarHeader)) < File->getSize()) + { + // seek to next file header + File->seek(pos); + + // read the header + File->read(&fHead, sizeof(fHead)); + + // only add standard files for now + if (fHead.Link == ETLI_REGULAR_FILE || ETLI_REGULAR_FILE_OLD) + { + io::path fullPath = ""; + fullPath.reserve(255); + + // USTAR archives have a filename prefix + // may not be null terminated, copy carefully! + if (!strncmp(fHead.Magic, "ustar", 5)) + { + c8* np = fHead.FileNamePrefix; + while(*np && (np - fHead.FileNamePrefix) < 155) + fullPath.append(*np); + np++; + } + + // append the file name + c8* np = fHead.FileName; + while(*np && (np - fHead.FileName) < 100) + { + fullPath.append(*np); + np++; + } + + // get size + core::stringc sSize = ""; + sSize.reserve(12); + np = fHead.Size; + while(*np && (np - fHead.Size) < 12) + { + sSize.append(*np); + np++; + } + + u32 size = strtoul(sSize.c_str(), NULL, 8); +#if !defined(_IRR_WINDOWS_CE_PLATFORM_) + if (errno == ERANGE) + os::Printer::log("File too large", fullPath, ELL_WARNING); +#endif + + // save start position + u32 offset = pos + 512; + + // move to next file header block + pos = offset + (size / 512) * 512 + ((size % 512) ? 512 : 0); + + // add file to list + addItem(fullPath, offset, size, false ); + } + else + { + // todo: ETLI_DIRECTORY, ETLI_LINK_TO_ARCHIVED_FILE + + // move to next block + pos += 512; + } + + } + + return Files.size(); +} + +//! opens a file by file name +IReadFile* CTarReader::createAndOpenFile(const io::path& filename) +{ + const s32 index = findFile(filename, false); + + if (index != -1) + return createAndOpenFile(index); + + return 0; +} + +//! opens a file by index +IReadFile* CTarReader::createAndOpenFile(u32 index) +{ + if (index >= Files.size() ) + return 0; + + const SFileListEntry &entry = Files[index]; + return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size ); +} + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.h new file mode 100644 index 0000000..e2e59c7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTarReader.h @@ -0,0 +1,133 @@ +// Copyright (C) 2009-2012 Gaz Davidson +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TAR_READER_H_INCLUDED__ +#define __C_TAR_READER_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ + +#include "IReferenceCounted.h" +#include "IReadFile.h" +#include "irrArray.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "CFileList.h" + +namespace irr +{ +namespace io +{ + + enum E_TAR_LINK_INDICATOR + { + ETLI_REGULAR_FILE_OLD = 0 , + ETLI_REGULAR_FILE = '0', + ETLI_LINK_TO_ARCHIVED_FILE = '1', // Hard link + ETLI_SYMBOLIC_LINK = '2', + ETLI_CHAR_SPECIAL_DEVICE = '3', + ETLI_BLOCK_SPECIAL_DEVICE = '4', + ETLI_DIRECTORY = '5', + ETLI_FIFO_SPECIAL_FILE = '6', + ETLI_CONTIGUOUS_FILE = '7' + }; + +// byte-align structures +#include "irrpack.h" + + struct STarHeader + { + c8 FileName[100]; + c8 FileMode[8]; + c8 UserID[8]; + c8 GroupID[8]; + c8 Size[12]; + c8 ModifiedTime[12]; + c8 Checksum[8]; + c8 Link; + c8 LinkName[100]; + c8 Magic[6]; + c8 USTARVersion[2]; + c8 UserName[32]; + c8 GroupName[32]; + c8 DeviceMajor[8]; + c8 DeviceMinor[8]; + c8 FileNamePrefix[155]; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + //! Archiveloader capable of loading ZIP Archives + class CArchiveLoaderTAR : public IArchiveLoader + { + public: + + //! Constructor + CArchiveLoaderTAR(io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".tar") + virtual bool isALoadableFileFormat(const io::path& filename) const; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const; + + //! Creates an archive from the filename + /** \param file File handle to check. + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const; + + //! creates/loads an archive from the file. + //! \return Pointer to the created archive. Returns 0 if loading failed. + virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const; + + private: + io::IFileSystem* FileSystem; + }; + + + + class CTarReader : public virtual IFileArchive, virtual CFileList + { + public: + + CTarReader(IReadFile* file, bool ignoreCase, bool ignorePaths); + + virtual ~CTarReader(); + + //! opens a file by file name + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! opens a file by index + virtual IReadFile* createAndOpenFile(u32 index); + + //! returns the list of files + virtual const IFileList* getFileList() const; + + //! get the class Type + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_TAR; } + + private: + + u32 populateFileList(); + + IReadFile* File; + }; + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_TAR_ARCHIVE_LOADER_ +#endif // __C_TAR_READER_H_INCLUDED__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.cpp new file mode 100644 index 0000000..35e9211 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.cpp @@ -0,0 +1,1502 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// The code for the TerrainSceneNode is based on the GeoMipMapSceneNode +// developed by Spintz. He made it available for Irrlicht and allowed it to be +// distributed under this licence. I only modified some parts. A lot of thanks +// go to him. + +#include "CTerrainSceneNode.h" +#include "CTerrainTriangleSelector.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "SViewFrustum.h" +#include "irrMath.h" +#include "os.h" +#include "IGUIFont.h" +#include "IFileSystem.h" +#include "IReadFile.h" +#include "ITextSceneNode.h" +#include "IAnimatedMesh.h" +#include "SMesh.h" +#include "CDynamicMeshBuffer.h" + +namespace irr +{ +namespace scene +{ + + //! constructor + CTerrainSceneNode::CTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, + io::IFileSystem* fs, s32 id, s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) + : ITerrainSceneNode(parent, mgr, id, position, rotation, scale), + TerrainData(patchSize, maxLOD, position, rotation, scale), RenderBuffer(0), + VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false), + OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(true), + CameraMovementDelta(10.0f), CameraRotationDelta(1.0f),CameraFOVDelta(0.1f), + TCoordScale1(1.0f), TCoordScale2(1.0f), SmoothFactor(0), FileSystem(fs) + { + #ifdef _DEBUG + setDebugName("CTerrainSceneNode"); + #endif + + Mesh = new SMesh(); + RenderBuffer = new CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT); + RenderBuffer->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_VERTEX); + RenderBuffer->setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_INDEX); + + if (FileSystem) + FileSystem->grab(); + + setAutomaticCulling(scene::EAC_OFF); + } + + + //! destructor + CTerrainSceneNode::~CTerrainSceneNode() + { + delete [] TerrainData.Patches; + + if (FileSystem) + FileSystem->drop(); + + if (Mesh) + Mesh->drop(); + + if (RenderBuffer) + RenderBuffer->drop(); + } + + + //! Initializes the terrain data. Loads the vertices from the heightMapFile + bool CTerrainSceneNode::loadHeightMap(io::IReadFile* file, video::SColor vertexColor, + s32 smoothFactor) + { + if (!file) + return false; + + Mesh->MeshBuffers.clear(); + const u32 startTime = os::Timer::getRealTime(); + video::IImage* heightMap = SceneManager->getVideoDriver()->createImageFromFile(file); + + if (!heightMap) + { + os::Printer::log("Unable to load heightmap."); + return false; + } + + HeightmapFile = file->getFileName(); + SmoothFactor = smoothFactor; + + // Get the dimension of the heightmap data + TerrainData.Size = heightMap->getDimension().Width; + + switch (TerrainData.PatchSize) + { + case ETPS_9: + if (TerrainData.MaxLOD > 3) + { + TerrainData.MaxLOD = 3; + } + break; + case ETPS_17: + if (TerrainData.MaxLOD > 4) + { + TerrainData.MaxLOD = 4; + } + break; + case ETPS_33: + if (TerrainData.MaxLOD > 5) + { + TerrainData.MaxLOD = 5; + } + break; + case ETPS_65: + if (TerrainData.MaxLOD > 6) + { + TerrainData.MaxLOD = 6; + } + break; + case ETPS_129: + if (TerrainData.MaxLOD > 7) + { + TerrainData.MaxLOD = 7; + } + break; + } + + // --- Generate vertex data from heightmap ---- + // resize the vertex array for the mesh buffer one time (makes loading faster) + scene::CDynamicMeshBuffer *mb=0; + + const u32 numVertices = TerrainData.Size * TerrainData.Size; + if (numVertices <= 65536) + { + //small enough for 16bit buffers + mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT); + RenderBuffer->getIndexBuffer().setType(video::EIT_16BIT); + } + else + { + //we need 32bit buffers + mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_32BIT); + RenderBuffer->getIndexBuffer().setType(video::EIT_32BIT); + } + + mb->getVertexBuffer().set_used(numVertices); + + // Read the heightmap to get the vertex data + // Apply positions changes, scaling changes + const f32 tdSize = 1.0f/(f32)(TerrainData.Size-1); + s32 index = 0; + float fx=0.f; + float fx2=0.f; + for (s32 x = 0; x < TerrainData.Size; ++x) + { + float fz=0.f; + float fz2=0.f; + for (s32 z = 0; z < TerrainData.Size; ++z) + { + video::S3DVertex2TCoords& vertex= static_cast(mb->getVertexBuffer().pointer())[index++]; + vertex.Normal.set(0.0f, 1.0f, 0.0f); + vertex.Color = vertexColor; + vertex.Pos.X = fx; + vertex.Pos.Y = (f32) heightMap->getPixel(TerrainData.Size-x-1,z).getLightness(); + vertex.Pos.Z = fz; + + vertex.TCoords.X = vertex.TCoords2.X = 1.f-fx2; + vertex.TCoords.Y = vertex.TCoords2.Y = fz2; + + ++fz; + fz2 += tdSize; + } + ++fx; + fx2 += tdSize; + } + + // drop heightMap, no longer needed + heightMap->drop(); + + smoothTerrain(mb, smoothFactor); + + // calculate smooth normals for the vertices + calculateNormals(mb); + + // add the MeshBuffer to the mesh + Mesh->addMeshBuffer(mb); + + // We copy the data to the renderBuffer, after the normals have been calculated. + RenderBuffer->getVertexBuffer().set_used(numVertices); + + for (u32 i = 0; i < numVertices; ++i) + { + RenderBuffer->getVertexBuffer()[i] = mb->getVertexBuffer()[i]; + RenderBuffer->getVertexBuffer()[i].Pos *= TerrainData.Scale; + RenderBuffer->getVertexBuffer()[i].Pos += TerrainData.Position; + } + + // We no longer need the mb + mb->drop(); + + // calculate all the necessary data for the patches and the terrain + calculateDistanceThresholds(); + createPatches(); + calculatePatchData(); + + // set the default rotation pivot point to the terrain nodes center + TerrainData.RotationPivot = TerrainData.Center; + + // Rotate the vertices of the terrain by the rotation + // specified. Must be done after calculating the terrain data, + // so we know what the current center of the terrain is. + setRotation(TerrainData.Rotation); + + // Pre-allocate memory for indices + + RenderBuffer->getIndexBuffer().set_used( + TerrainData.PatchCount * TerrainData.PatchCount * + TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6); + + RenderBuffer->setDirty(); + + const u32 endTime = os::Timer::getRealTime(); + + c8 tmp[255]; + snprintf(tmp, 255, "Generated terrain data (%dx%d) in %.4f seconds", + TerrainData.Size, TerrainData.Size, (endTime - startTime) / 1000.0f ); + os::Printer::log(tmp); + + return true; + } + + + //! Initializes the terrain data. Loads the vertices from the heightMapFile + bool CTerrainSceneNode::loadHeightMapRAW(io::IReadFile* file, + s32 bitsPerPixel, bool signedData, bool floatVals, + s32 width, video::SColor vertexColor, s32 smoothFactor) + { + if (!file) + return false; + if (floatVals && bitsPerPixel != 32) + return false; + + // start reading + const u32 startTime = os::Timer::getTime(); + + Mesh->MeshBuffers.clear(); + + const s32 bytesPerPixel = bitsPerPixel / 8; + + // Get the dimension of the heightmap data + const s32 filesize = file->getSize(); + if (!width) + TerrainData.Size = core::floor32(sqrtf((f32)(filesize / bytesPerPixel))); + else + { + if ((filesize-file->getPos())/bytesPerPixel>width*width) + { + os::Printer::log("Error reading heightmap RAW file", "File is too small."); + return false; + } + TerrainData.Size = width; + } + + switch (TerrainData.PatchSize) + { + case ETPS_9: + if (TerrainData.MaxLOD > 3) + { + TerrainData.MaxLOD = 3; + } + break; + case ETPS_17: + if (TerrainData.MaxLOD > 4) + { + TerrainData.MaxLOD = 4; + } + break; + case ETPS_33: + if (TerrainData.MaxLOD > 5) + { + TerrainData.MaxLOD = 5; + } + break; + case ETPS_65: + if (TerrainData.MaxLOD > 6) + { + TerrainData.MaxLOD = 6; + } + break; + case ETPS_129: + if (TerrainData.MaxLOD > 7) + { + TerrainData.MaxLOD = 7; + } + break; + } + + // --- Generate vertex data from heightmap ---- + // resize the vertex array for the mesh buffer one time (makes loading faster) + scene::CDynamicMeshBuffer *mb=0; + const u32 numVertices = TerrainData.Size * TerrainData.Size; + if (numVertices <= 65536) + { + //small enough for 16bit buffers + mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_16BIT); + RenderBuffer->getIndexBuffer().setType(video::EIT_16BIT); + } + else + { + //we need 32bit buffers + mb=new scene::CDynamicMeshBuffer(video::EVT_2TCOORDS, video::EIT_32BIT); + RenderBuffer->getIndexBuffer().setType(video::EIT_32BIT); + } + + mb->getVertexBuffer().reallocate(numVertices); + + video::S3DVertex2TCoords vertex; + vertex.Normal.set(0.0f, 1.0f, 0.0f); + vertex.Color = vertexColor; + + // Read the heightmap to get the vertex data + // Apply positions changes, scaling changes + const f32 tdSize = 1.0f/(f32)(TerrainData.Size-1); + float fx=0.f; + float fx2=0.f; + for (s32 x = 0; x < TerrainData.Size; ++x) + { + float fz=0.f; + float fz2=0.f; + for (s32 z = 0; z < TerrainData.Size; ++z) + { + bool failure=false; + vertex.Pos.X = fx; + if (floatVals) + { + if (file->read(&vertex.Pos.Y, bytesPerPixel) != bytesPerPixel) + failure=true; + } + else if (signedData) + { + switch (bytesPerPixel) + { + case 1: + { + s8 val; + if (file->read(&val, bytesPerPixel) != bytesPerPixel) + failure=true; + vertex.Pos.Y=val; + } + break; + case 2: + { + s16 val; + if (file->read(&val, bytesPerPixel) != bytesPerPixel) + failure=true; + vertex.Pos.Y=val/256.f; + } + break; + case 4: + { + s32 val; + if (file->read(&val, bytesPerPixel) != bytesPerPixel) + failure=true; + vertex.Pos.Y=val/16777216.f; + } + break; + } + } + else + { + switch (bytesPerPixel) + { + case 1: + { + u8 val; + if (file->read(&val, bytesPerPixel) != bytesPerPixel) + failure=true; + vertex.Pos.Y=val; + } + break; + case 2: + { + u16 val; + if (file->read(&val, bytesPerPixel) != bytesPerPixel) + failure=true; + vertex.Pos.Y=val/256.f; + } + break; + case 4: + { + u32 val; + if (file->read(&val, bytesPerPixel) != bytesPerPixel) + failure=true; + vertex.Pos.Y=val/16777216.f; + } + break; + } + } + if (failure) + { + os::Printer::log("Error reading heightmap RAW file."); + mb->drop(); + return false; + } + vertex.Pos.Z = fz; + + vertex.TCoords.X = vertex.TCoords2.X = 1.f-fx2; + vertex.TCoords.Y = vertex.TCoords2.Y = fz2; + + mb->getVertexBuffer().push_back(vertex); + ++fz; + fz2 += tdSize; + } + ++fx; + fx2 += tdSize; + } + + smoothTerrain(mb, smoothFactor); + + // calculate smooth normals for the vertices + calculateNormals(mb); + + // add the MeshBuffer to the mesh + Mesh->addMeshBuffer(mb); + const u32 vertexCount = mb->getVertexCount(); + + // We copy the data to the renderBuffer, after the normals have been calculated. + RenderBuffer->getVertexBuffer().set_used(vertexCount); + + for (u32 i = 0; i < vertexCount; i++) + { + RenderBuffer->getVertexBuffer()[i] = mb->getVertexBuffer()[i]; + RenderBuffer->getVertexBuffer()[i].Pos *= TerrainData.Scale; + RenderBuffer->getVertexBuffer()[i].Pos += TerrainData.Position; + } + + // We no longer need the mb + mb->drop(); + + // calculate all the necessary data for the patches and the terrain + calculateDistanceThresholds(); + createPatches(); + calculatePatchData(); + + // set the default rotation pivot point to the terrain nodes center + TerrainData.RotationPivot = TerrainData.Center; + + // Rotate the vertices of the terrain by the rotation specified. Must be done + // after calculating the terrain data, so we know what the current center of the + // terrain is. + setRotation(TerrainData.Rotation); + + // Pre-allocate memory for indices + RenderBuffer->getIndexBuffer().set_used( + TerrainData.PatchCount*TerrainData.PatchCount* + TerrainData.CalcPatchSize*TerrainData.CalcPatchSize*6); + + const u32 endTime = os::Timer::getTime(); + + c8 tmp[255]; + snprintf(tmp, 255, "Generated terrain data (%dx%d) in %.4f seconds", + TerrainData.Size, TerrainData.Size, (endTime - startTime) / 1000.0f); + os::Printer::log(tmp); + + return true; + } + + + //! Returns the mesh + IMesh* CTerrainSceneNode::getMesh() { return Mesh; } + + + //! Returns the material based on the zero based index i. + video::SMaterial& CTerrainSceneNode::getMaterial(u32 i) + { + return Mesh->getMeshBuffer(i)->getMaterial(); + } + + + //! Returns amount of materials used by this scene node ( always 1 ) + u32 CTerrainSceneNode::getMaterialCount() const + { + return Mesh->getMeshBufferCount(); + } + + + //! Sets the scale of the scene node. + //! \param scale: New scale of the node + void CTerrainSceneNode::setScale(const core::vector3df& scale) + { + TerrainData.Scale = scale; + applyTransformation(); + calculateNormals(RenderBuffer); + ForceRecalculation = true; + } + + + //! Sets the rotation of the node. This only modifies + //! the relative rotation of the node. + //! \param rotation: New rotation of the node in degrees. + void CTerrainSceneNode::setRotation(const core::vector3df& rotation) + { + TerrainData.Rotation = rotation; + applyTransformation(); + ForceRecalculation = true; + } + + + //! Sets the pivot point for rotation of this node. This is useful for the TiledTerrainManager to + //! rotate all terrain tiles around a global world point. + //! NOTE: The default for the RotationPivot will be the center of the individual tile. + void CTerrainSceneNode::setRotationPivot(const core::vector3df& pivot) + { + UseDefaultRotationPivot = false; + TerrainData.RotationPivot = pivot; + } + + + //! Sets the position of the node. + //! \param newpos: New postition of the scene node. + void CTerrainSceneNode::setPosition(const core::vector3df& newpos) + { + TerrainData.Position = newpos; + applyTransformation(); + ForceRecalculation = true; + } + + + //! Apply transformation changes(scale, position, rotation) + void CTerrainSceneNode::applyTransformation() + { + if (!Mesh->getMeshBufferCount()) + return; + + core::matrix4 rotMatrix; + rotMatrix.setRotationDegrees(TerrainData.Rotation); + + const s32 vtxCount = Mesh->getMeshBuffer(0)->getVertexCount(); + for (s32 i = 0; i < vtxCount; ++i) + { + RenderBuffer->getVertexBuffer()[i].Pos = Mesh->getMeshBuffer(0)->getPosition(i) * TerrainData.Scale + TerrainData.Position; + + RenderBuffer->getVertexBuffer()[i].Pos -= TerrainData.RotationPivot; + rotMatrix.inverseRotateVect(RenderBuffer->getVertexBuffer()[i].Pos); + RenderBuffer->getVertexBuffer()[i].Pos += TerrainData.RotationPivot; + } + + calculateDistanceThresholds(true); + calculatePatchData(); + + RenderBuffer->setDirty(EBT_VERTEX); + } + + + //! Updates the scene nodes indices if the camera has moved or rotated by a certain + //! threshold, which can be changed using the SetCameraMovementDeltaThreshold and + //! SetCameraRotationDeltaThreshold functions. This also determines if a given patch + //! for the scene node is within the view frustum and if it's not the indices are not + //! generated for that patch. + void CTerrainSceneNode::OnRegisterSceneNode() + { + if (!IsVisible || !SceneManager->getActiveCamera()) + return; + + SceneManager->registerNodeForRendering(this); + + preRenderCalculationsIfNeeded(); + + // Do Not call ISceneNode::OnRegisterSceneNode(), this node should have no children (luke: is this comment still true, as ISceneNode::OnRegisterSceneNode() is called?) + + ISceneNode::OnRegisterSceneNode(); + ForceRecalculation = false; + } + + void CTerrainSceneNode::preRenderCalculationsIfNeeded() + { + scene::ICameraSceneNode * camera = SceneManager->getActiveCamera(); + if (!camera) + return; + + // Determine the camera rotation, based on the camera direction. + const core::vector3df cameraPosition = camera->getAbsolutePosition(); + const core::vector3df cameraRotation = core::line3d(cameraPosition, camera->getTarget()).getVector().getHorizontalAngle(); + core::vector3df cameraUp = camera->getUpVector(); + cameraUp.normalize(); + const f32 CameraFOV = SceneManager->getActiveCamera()->getFOV(); + + // Only check on the Camera's Y Rotation + if (!ForceRecalculation) + { + if ((fabsf(cameraRotation.X - OldCameraRotation.X) < CameraRotationDelta) && + (fabsf(cameraRotation.Y - OldCameraRotation.Y) < CameraRotationDelta)) + { + if ((fabs(cameraPosition.X - OldCameraPosition.X) < CameraMovementDelta) && + (fabs(cameraPosition.Y - OldCameraPosition.Y) < CameraMovementDelta) && + (fabs(cameraPosition.Z - OldCameraPosition.Z) < CameraMovementDelta)) + { + if (fabs(CameraFOV-OldCameraFOV) < CameraFOVDelta && + cameraUp.dotProduct(OldCameraUp) > (1.f - (cos(core::DEGTORAD * CameraRotationDelta)))) + { + return; + } + } + } + } + + //we need to redo calculations... + + OldCameraPosition = cameraPosition; + OldCameraRotation = cameraRotation; + OldCameraUp = cameraUp; + OldCameraFOV = CameraFOV; + + preRenderLODCalculations(); + preRenderIndicesCalculations(); + } + + void CTerrainSceneNode::preRenderLODCalculations() + { + scene::ICameraSceneNode * camera = SceneManager->getActiveCamera(); + + if (!camera) + return; + + const core::vector3df cameraPosition = camera->getAbsolutePosition(); + + const SViewFrustum* frustum = camera->getViewFrustum(); + + // Determine each patches LOD based on distance from camera (and whether or not they are in + // the view frustum). + const s32 count = TerrainData.PatchCount * TerrainData.PatchCount; + for (s32 j = 0; j < count; ++j) + { + if (frustum->getBoundingBox().intersectsWithBox(TerrainData.Patches[j].BoundingBox)) + { + const f32 distance = cameraPosition.getDistanceFromSQ(TerrainData.Patches[j].Center); + + TerrainData.Patches[j].CurrentLOD = 0; + for (s32 i = TerrainData.MaxLOD - 1; i>0; --i) + { + if (distance >= TerrainData.LODDistanceThreshold[i]) + { + TerrainData.Patches[j].CurrentLOD = i; + break; + } + } + } + else + { + TerrainData.Patches[j].CurrentLOD = -1; + } + } + } + + + void CTerrainSceneNode::preRenderIndicesCalculations() + { + scene::IIndexBuffer& indexBuffer = RenderBuffer->getIndexBuffer(); + IndicesToRender = 0; + indexBuffer.set_used(0); + + s32 index = 0; + // Then generate the indices for all patches that are visible. + for (s32 i = 0; i < TerrainData.PatchCount; ++i) + { + for (s32 j = 0; j < TerrainData.PatchCount; ++j) + { + if (TerrainData.Patches[index].CurrentLOD >= 0) + { + s32 x = 0; + s32 z = 0; + + // calculate the step we take this patch, based on the patches current LOD + const s32 step = 1 << TerrainData.Patches[index].CurrentLOD; + + // Loop through patch and generate indices + while (z < TerrainData.CalcPatchSize) + { + const s32 index11 = getIndex(j, i, index, x, z); + const s32 index21 = getIndex(j, i, index, x + step, z); + const s32 index12 = getIndex(j, i, index, x, z + step); + const s32 index22 = getIndex(j, i, index, x + step, z + step); + + indexBuffer.push_back(index12); + indexBuffer.push_back(index11); + indexBuffer.push_back(index22); + indexBuffer.push_back(index22); + indexBuffer.push_back(index11); + indexBuffer.push_back(index21); + IndicesToRender+=6; + + // increment index position horizontally + x += step; + + // we've hit an edge + if (x >= TerrainData.CalcPatchSize) + { + x = 0; + z += step; + } + } + } + ++index; + } + } + + RenderBuffer->setDirty(EBT_INDEX); + + if (DynamicSelectorUpdate && TriangleSelector) + { + CTerrainTriangleSelector* selector = (CTerrainTriangleSelector*)TriangleSelector; + selector->setTriangleData(this, -1); + } + } + + + //! Render the scene node + void CTerrainSceneNode::render() + { + if (!IsVisible || !SceneManager->getActiveCamera()) + return; + + if (!Mesh->getMeshBufferCount()) + return; + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + driver->setTransform (video::ETS_WORLD, core::IdentityMatrix); + driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial()); + + RenderBuffer->getIndexBuffer().set_used(IndicesToRender); + + // For use with geomorphing + driver->drawMeshBuffer(RenderBuffer); + + RenderBuffer->getIndexBuffer().set_used(RenderBuffer->getIndexBuffer().allocated_size()); + + // for debug purposes only: + if (DebugDataVisible) + { + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + if (DebugDataVisible & scene::EDS_BBOX) + driver->draw3DBox(TerrainData.BoundingBox, video::SColor(255,255,255,255)); + + const s32 count = TerrainData.PatchCount * TerrainData.PatchCount; + s32 visible = 0; + if (DebugDataVisible & scene::EDS_BBOX_BUFFERS) + { + for (s32 j = 0; j < count; ++j) + { + driver->draw3DBox(TerrainData.Patches[j].BoundingBox, video::SColor(255,255,0,0)); + visible += (TerrainData.Patches[j].CurrentLOD >= 0); + } + } + + if (DebugDataVisible & scene::EDS_NORMALS) + { + // draw normals + const f32 debugNormalLength = SceneManager->getParameters()->getAttributeAsFloat(DEBUG_NORMAL_LENGTH); + const video::SColor debugNormalColor = SceneManager->getParameters()->getAttributeAsColor(DEBUG_NORMAL_COLOR); + driver->drawMeshBufferNormals(RenderBuffer, debugNormalLength, debugNormalColor); + } + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + static u32 lastTime = 0; + + const u32 now = os::Timer::getRealTime(); + if (now - lastTime > 1000) + { + char buf[64]; + snprintf(buf, 64, "Count: %d, Visible: %d", count, visible); + os::Printer::log(buf); + + lastTime = now; + } + } + } + + + //! Return the bounding box of the entire terrain. + const core::aabbox3d& CTerrainSceneNode::getBoundingBox() const + { + return TerrainData.BoundingBox; + } + + + //! Return the bounding box of a patch + const core::aabbox3d& CTerrainSceneNode::getBoundingBox(s32 patchX, s32 patchZ) const + { + return TerrainData.Patches[patchX * TerrainData.PatchCount + patchZ].BoundingBox; + } + + + //! Gets the meshbuffer data based on a specified Level of Detail. + //! \param mb: A reference to an SMeshBuffer object + //! \param LOD: The Level Of Detail you want the indices from. + void CTerrainSceneNode::getMeshBufferForLOD(IDynamicMeshBuffer& mb, s32 LOD ) const + { + if (!Mesh->getMeshBufferCount()) + return; + + LOD = core::clamp(LOD, 0, TerrainData.MaxLOD - 1); + + const u32 numVertices = Mesh->getMeshBuffer(0)->getVertexCount(); + mb.getVertexBuffer().reallocate(numVertices); + video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)Mesh->getMeshBuffer(0)->getVertices(); + + for (u32 n=0; ngetIndexBuffer().getType()); + + // calculate the step we take for all patches, since LOD is the same + const s32 step = 1 << LOD; + + // Generate the indices for all patches at the specified LOD + s32 index = 0; + for (s32 i=0; i= TerrainData.CalcPatchSize) // we've hit an edge + { + x = 0; + z += step; + } + } + ++index; + } + } + } + + + //! Gets the indices for a specified patch at a specified Level of Detail. + //! \param mb: A reference to an array of u32 indices. + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \param LOD: The level of detail to get for that patch. If -1, then get + //! the CurrentLOD. If the CurrentLOD is set to -1, meaning it's not shown, + //! then it will retrieve the triangles at the highest LOD (0). + //! \return: Number if indices put into the buffer. + s32 CTerrainSceneNode::getIndicesForPatch(core::array& indices, s32 patchX, s32 patchZ, s32 LOD) + { + if (patchX < 0 || patchX > TerrainData.PatchCount-1 || + patchZ < 0 || patchZ > TerrainData.PatchCount-1) + return -1; + + if (LOD < -1 || LOD > TerrainData.MaxLOD - 1) + return -1; + + core::array cLODs; + bool setLODs = false; + + // If LOD of -1 was passed in, use the CurrentLOD of the patch specified + if (LOD == -1) + { + LOD = TerrainData.Patches[patchX * TerrainData.PatchCount + patchZ].CurrentLOD; + } + else + { + getCurrentLODOfPatches(cLODs); + setCurrentLODOfPatches(LOD); + setLODs = true; + } + + if (LOD < 0) + return -2; // Patch not visible, don't generate indices. + + // calculate the step we take for this LOD + const s32 step = 1 << LOD; + + // Generate the indices for the specified patch at the specified LOD + const s32 index = patchX * TerrainData.PatchCount + patchZ; + + s32 x = 0; + s32 z = 0; + + indices.set_used(TerrainData.PatchSize * TerrainData.PatchSize * 6); + + // Loop through patch and generate indices + s32 rv=0; + while (z= TerrainData.CalcPatchSize) // we've hit an edge + { + x = 0; + z += step; + } + } + + if (setLODs) + setCurrentLODOfPatches(cLODs); + + return rv; + } + + + //! Populates an array with the CurrentLOD of each patch. + //! \param LODs: A reference to a core::array to hold the values + //! \return Returns the number of elements in the array + s32 CTerrainSceneNode::getCurrentLODOfPatches(core::array& LODs) const + { + s32 numLODs; + LODs.clear(); + + const s32 count = TerrainData.PatchCount * TerrainData.PatchCount; + for (numLODs = 0; numLODs < count; numLODs++) + LODs.push_back(TerrainData.Patches[numLODs].CurrentLOD); + + return LODs.size(); + } + + + //! Manually sets the LOD of a patch + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \param LOD: The level of detail to set the patch to. + void CTerrainSceneNode::setLODOfPatch(s32 patchX, s32 patchZ, s32 LOD) + { + TerrainData.Patches[patchX * TerrainData.PatchCount + patchZ].CurrentLOD = LOD; + } + + + //! Override the default generation of distance thresholds for determining the LOD a patch + //! is rendered at. + bool CTerrainSceneNode::overrideLODDistance(s32 LOD, f64 newDistance) + { + OverrideDistanceThreshold = true; + + if (LOD < 0 || LOD > TerrainData.MaxLOD - 1) + return false; + + TerrainData.LODDistanceThreshold[LOD] = newDistance * newDistance; + + return true; + } + + + //! Creates a planar texture mapping on the terrain + //! \param resolution: resolution of the planar mapping. This is the value + //! specifying the relation between world space and texture coordinate space. + void CTerrainSceneNode::scaleTexture(f32 resolution, f32 resolution2) + { + TCoordScale1 = resolution; + TCoordScale2 = resolution2; + + const f32 resBySize = resolution / (f32)(TerrainData.Size-1); + const f32 res2BySize = resolution2 / (f32)(TerrainData.Size-1); + u32 index = 0; + f32 xval = 0.f; + f32 x2val = 0.f; + for (s32 x=0; xgetVertexBuffer()[index].TCoords.X = 1.f-xval; + RenderBuffer->getVertexBuffer()[index].TCoords.Y = zval; + + if (RenderBuffer->getVertexType()==video::EVT_2TCOORDS) + { + if (resolution2 == 0) + { + ((video::S3DVertex2TCoords&)RenderBuffer->getVertexBuffer()[index]).TCoords2 = RenderBuffer->getVertexBuffer()[index].TCoords; + } + else + { + ((video::S3DVertex2TCoords&)RenderBuffer->getVertexBuffer()[index]).TCoords2.X = 1.f-x2val; + ((video::S3DVertex2TCoords&)RenderBuffer->getVertexBuffer()[index]).TCoords2.Y = z2val; + } + } + + ++index; + zval += resBySize; + z2val += res2BySize; + } + xval += resBySize; + x2val += res2BySize; + } + + RenderBuffer->setDirty(EBT_VERTEX); + } + + + //! used to get the indices when generating index data for patches at varying levels of detail. + u32 CTerrainSceneNode::getIndex(const s32 PatchX, const s32 PatchZ, + const s32 PatchIndex, u32 vX, u32 vZ) const + { + // top border + if (vZ == 0) + { + if (TerrainData.Patches[PatchIndex].Top && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Top->CurrentLOD && + (vX % (1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD)) != 0 ) + { + vX -= vX % (1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD); + } + } + else + if (vZ == (u32)TerrainData.CalcPatchSize) // bottom border + { + if (TerrainData.Patches[PatchIndex].Bottom && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Bottom->CurrentLOD && + (vX % (1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD)) != 0) + { + vX -= vX % (1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD); + } + } + + // left border + if (vX == 0) + { + if (TerrainData.Patches[PatchIndex].Left && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Left->CurrentLOD && + (vZ % (1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD)) != 0) + { + vZ -= vZ % (1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD); + } + } + else + if (vX == (u32)TerrainData.CalcPatchSize) // right border + { + if (TerrainData.Patches[PatchIndex].Right && + TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Right->CurrentLOD && + (vZ % (1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD)) != 0) + { + vZ -= vZ % (1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD); + } + } + + if (vZ >= (u32)TerrainData.PatchSize) + vZ = TerrainData.CalcPatchSize; + + if (vX >= (u32)TerrainData.PatchSize) + vX = TerrainData.CalcPatchSize; + + return (vZ + ((TerrainData.CalcPatchSize) * PatchZ)) * TerrainData.Size + + (vX + ((TerrainData.CalcPatchSize) * PatchX)); + } + + + //! smooth the terrain + void CTerrainSceneNode::smoothTerrain(IDynamicMeshBuffer* mb, s32 smoothFactor) + { + for (s32 run = 0; run < smoothFactor; ++run) + { + s32 yd = TerrainData.Size; + for (s32 y = 1; y < TerrainData.Size - 1; ++y) + { + for (s32 x = 1; x < TerrainData.Size - 1; ++x) + { + mb->getVertexBuffer()[x + yd].Pos.Y = + (mb->getVertexBuffer()[x-1 + yd].Pos.Y + //left + mb->getVertexBuffer()[x+1 + yd].Pos.Y + //right + mb->getVertexBuffer()[x + yd - TerrainData.Size].Pos.Y + //above + mb->getVertexBuffer()[x + yd + TerrainData.Size].Pos.Y) * 0.25f; //below + } + yd += TerrainData.Size; + } + } + } + + + //! calculate smooth normals + void CTerrainSceneNode::calculateNormals(IDynamicMeshBuffer* mb) + { + s32 count; + core::vector3df a, b, c, t; + + for (s32 x=0; x0 && z>0) + { + a = mb->getVertexBuffer()[(x-1)*TerrainData.Size+z-1].Pos; + b = mb->getVertexBuffer()[(x-1)*TerrainData.Size+z].Pos; + c = mb->getVertexBuffer()[x*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + a = mb->getVertexBuffer()[(x-1)*TerrainData.Size+z-1].Pos; + b = mb->getVertexBuffer()[x*TerrainData.Size+z-1].Pos; + c = mb->getVertexBuffer()[x*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + count += 2; + } + + // top right + if (x>0 && zgetVertexBuffer()[(x-1)*TerrainData.Size+z].Pos; + b = mb->getVertexBuffer()[(x-1)*TerrainData.Size+z+1].Pos; + c = mb->getVertexBuffer()[x*TerrainData.Size+z+1].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + a = mb->getVertexBuffer()[(x-1)*TerrainData.Size+z].Pos; + b = mb->getVertexBuffer()[x*TerrainData.Size+z+1].Pos; + c = mb->getVertexBuffer()[x*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + count += 2; + } + + // bottom right + if (xgetVertexBuffer()[x*TerrainData.Size+z+1].Pos; + b = mb->getVertexBuffer()[x*TerrainData.Size+z].Pos; + c = mb->getVertexBuffer()[(x+1)*TerrainData.Size+z+1].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + a = mb->getVertexBuffer()[x*TerrainData.Size+z+1].Pos; + b = mb->getVertexBuffer()[(x+1)*TerrainData.Size+z+1].Pos; + c = mb->getVertexBuffer()[(x+1)*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + count += 2; + } + + // bottom left + if (x0) + { + a = mb->getVertexBuffer()[x*TerrainData.Size+z-1].Pos; + b = mb->getVertexBuffer()[x*TerrainData.Size+z].Pos; + c = mb->getVertexBuffer()[(x+1)*TerrainData.Size+z].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + a = mb->getVertexBuffer()[x*TerrainData.Size+z-1].Pos; + b = mb->getVertexBuffer()[(x+1)*TerrainData.Size+z].Pos; + c = mb->getVertexBuffer()[(x+1)*TerrainData.Size+z-1].Pos; + b -= a; + c -= a; + t = b.crossProduct(c); + t.normalize(); + normal += t; + + count += 2; + } + + if (count != 0) + { + normal.normalize(); + } + else + { + normal.set(0.0f, 1.0f, 0.0f); + } + + mb->getVertexBuffer()[x * TerrainData.Size + z].Normal = normal; + } + } + } + + + //! create patches, stuff that needs to be done only once for patches goes here. + void CTerrainSceneNode::createPatches() + { + TerrainData.PatchCount = (TerrainData.Size - 1) / (TerrainData.CalcPatchSize); + + if (TerrainData.Patches) + delete [] TerrainData.Patches; + + TerrainData.Patches = new SPatch[TerrainData.PatchCount * TerrainData.PatchCount]; + } + + + //! used to calculate the internal STerrainData structure both at creation and after scaling/position calls. + void CTerrainSceneNode::calculatePatchData() + { + // Reset the Terrains Bounding Box for re-calculation + TerrainData.BoundingBox.reset(RenderBuffer->getPosition(0)); + + for (s32 x = 0; x < TerrainData.PatchCount; ++x) + { + for (s32 z = 0; z < TerrainData.PatchCount; ++z) + { + const s32 index = x * TerrainData.PatchCount + z; + SPatch& patch = TerrainData.Patches[index]; + patch.CurrentLOD = 0; + + const s32 xstart = x*TerrainData.CalcPatchSize; + const s32 xend = xstart+TerrainData.CalcPatchSize; + const s32 zstart = z*TerrainData.CalcPatchSize; + const s32 zend = zstart+TerrainData.CalcPatchSize; + // For each patch, calculate the bounding box (mins and maxes) + patch.BoundingBox.reset(RenderBuffer->getPosition(xstart*TerrainData.Size + zstart)); + + for (s32 xx = xstart; xx <= xend; ++xx) + for (s32 zz = zstart; zz <= zend; ++zz) + patch.BoundingBox.addInternalPoint(RenderBuffer->getVertexBuffer()[xx * TerrainData.Size + zz].Pos); + + // Reconfigure the bounding box of the terrain as a whole + TerrainData.BoundingBox.addInternalBox(patch.BoundingBox); + + // get center of Patch + patch.Center = patch.BoundingBox.getCenter(); + + // Assign Neighbours + // Top + if (x > 0) + patch.Top = &TerrainData.Patches[(x-1) * TerrainData.PatchCount + z]; + else + patch.Top = 0; + + // Bottom + if (x < TerrainData.PatchCount - 1) + patch.Bottom = &TerrainData.Patches[(x+1) * TerrainData.PatchCount + z]; + else + patch.Bottom = 0; + + // Left + if (z > 0) + patch.Left = &TerrainData.Patches[x * TerrainData.PatchCount + z - 1]; + else + patch.Left = 0; + + // Right + if (z < TerrainData.PatchCount - 1) + patch.Right = &TerrainData.Patches[x * TerrainData.PatchCount + z + 1]; + else + patch.Right = 0; + } + } + + // get center of Terrain + TerrainData.Center = TerrainData.BoundingBox.getCenter(); + + // if the default rotation pivot is still being used, update it. + if (UseDefaultRotationPivot) + { + TerrainData.RotationPivot = TerrainData.Center; + } + } + + + //! used to calculate or recalculate the distance thresholds + void CTerrainSceneNode::calculateDistanceThresholds(bool scalechanged) + { + // Only update the LODDistanceThreshold if it's not manually changed + if (!OverrideDistanceThreshold) + { + TerrainData.LODDistanceThreshold.set_used(0); + // Determine new distance threshold for determining what LOD to draw patches at + TerrainData.LODDistanceThreshold.reallocate(TerrainData.MaxLOD); + + const f64 size = TerrainData.PatchSize * TerrainData.PatchSize * + TerrainData.Scale.X * TerrainData.Scale.Z; + for (s32 i=0; i& lodarray) + { + const s32 count = TerrainData.PatchCount * TerrainData.PatchCount; + for (s32 i=0; igetMeshBufferCount()) + return 0; + + core::matrix4 rotMatrix; + rotMatrix.setRotationDegrees(TerrainData.Rotation); + core::vector3df pos(x, 0.0f, z); + rotMatrix.rotateVect(pos); + pos -= TerrainData.Position; + pos /= TerrainData.Scale; + + s32 X(core::floor32(pos.X)); + s32 Z(core::floor32(pos.Z)); + + f32 height = -FLT_MAX; + if (X >= 0 && X < TerrainData.Size-1 && + Z >= 0 && Z < TerrainData.Size-1) + { + const video::S3DVertex2TCoords* Vertices = (const video::S3DVertex2TCoords*)Mesh->getMeshBuffer(0)->getVertices(); + const core::vector3df& a = Vertices[X * TerrainData.Size + Z].Pos; + const core::vector3df& b = Vertices[(X + 1) * TerrainData.Size + Z].Pos; + const core::vector3df& c = Vertices[X * TerrainData.Size + (Z + 1)].Pos; + const core::vector3df& d = Vertices[(X + 1) * TerrainData.Size + (Z + 1)].Pos; + + // offset from integer position + const f32 dx = pos.X - X; + const f32 dz = pos.Z - Z; + + if (dx > dz) + height = a.Y + (d.Y - b.Y)*dz + (b.Y - a.Y)*dx; + else + height = a.Y + (d.Y - c.Y)*dx + (c.Y - a.Y)*dz; + + height *= TerrainData.Scale.Y; + height += TerrainData.Position.Y; + } + + return height; + } + + + //! Writes attributes of the scene node. + void CTerrainSceneNode::serializeAttributes(io::IAttributes* out, + io::SAttributeReadWriteOptions* options) const + { + ISceneNode::serializeAttributes(out, options); + + out->addString("Heightmap", HeightmapFile.c_str()); + out->addFloat("TextureScale1", TCoordScale1); + out->addFloat("TextureScale2", TCoordScale2); + out->addInt("SmoothFactor", SmoothFactor); + } + + + //! Reads attributes of the scene node. + void CTerrainSceneNode::deserializeAttributes(io::IAttributes* in, + io::SAttributeReadWriteOptions* options) + { + io::path newHeightmap = in->getAttributeAsString("Heightmap"); + f32 tcoordScale1 = in->getAttributeAsFloat("TextureScale1"); + f32 tcoordScale2 = in->getAttributeAsFloat("TextureScale2"); + s32 smoothFactor = in->getAttributeAsInt("SmoothFactor"); + + // set possible new heightmap + + if (newHeightmap.size() != 0 && newHeightmap != HeightmapFile) + { + io::IReadFile* file = FileSystem->createAndOpenFile(newHeightmap.c_str()); + if (file) + { + loadHeightMap(file, video::SColor(255,255,255,255), smoothFactor); + file->drop(); + } + else + os::Printer::log("could not open heightmap", newHeightmap.c_str()); + } + + // set possible new scale + + if (core::equals(tcoordScale1, 0.f)) + tcoordScale1 = 1.0f; + + if (core::equals(tcoordScale2, 0.f)) + tcoordScale2 = 1.0f; + + if (!core::equals(tcoordScale1, TCoordScale1) || + !core::equals(tcoordScale2, TCoordScale2)) + { + scaleTexture(tcoordScale1, tcoordScale2); + } + + ISceneNode::deserializeAttributes(in, options); + } + + + //! Creates a clone of this scene node and its children. + ISceneNode* CTerrainSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) + { + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CTerrainSceneNode* nb = new CTerrainSceneNode( + newParent, newManager, FileSystem, ID, + 4, ETPS_17, getPosition(), getRotation(), getScale()); + + nb->cloneMembers(this, newManager); + + // instead of cloning the data structures, recreate the terrain. + // (temporary solution) + + // load file + + io::IReadFile* file = FileSystem->createAndOpenFile(HeightmapFile.c_str()); + if (file) + { + nb->loadHeightMap(file, video::SColor(255,255,255,255), 0); + file->drop(); + } + + // scale textures + + nb->scaleTexture(TCoordScale1, TCoordScale2); + + // copy materials + + for (unsigned int m = 0; mgetMeshBufferCount(); ++m) + { + if (nb->Mesh->getMeshBufferCount()>m && + nb->Mesh->getMeshBuffer(m) && + Mesh->getMeshBuffer(m)) + { + nb->Mesh->getMeshBuffer(m)->getMaterial() = + Mesh->getMeshBuffer(m)->getMaterial(); + } + } + + nb->RenderBuffer->getMaterial() = RenderBuffer->getMaterial(); + + // finish + + if ( newParent ) + nb->drop(); + return nb; + } + +} // end namespace scene +} // end namespace irr + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.h new file mode 100644 index 0000000..1d92f66 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainSceneNode.h @@ -0,0 +1,330 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +// The code for the TerrainSceneNode is based on the GeoMipMapSceneNode +// developed by Spintz. He made it available for Irrlicht and allowed it to be +// distributed under this licence. I only modified some parts. A lot of thanks go to him. + +#ifndef __C_TERRAIN_SCENE_NODE_H__ +#define __C_TERRAIN_SCENE_NODE_H__ + +#include "ITerrainSceneNode.h" +#include "IDynamicMeshBuffer.h" +#include "path.h" + +namespace irr +{ +namespace io +{ + class IFileSystem; + class IReadFile; +} +namespace scene +{ + struct SMesh; + class ITextSceneNode; + + //! A scene node for displaying terrain using the geo mip map algorithm. + class CTerrainSceneNode : public ITerrainSceneNode + { + public: + + //! constructor + //! \param parent: The node which this node is a child of. Making this node a child of another node, or + //! making it a parent of another node is yet untested and most likely does not work properly. + //! \param mgr: Pointer to the scene manager. + //! \param id: The id of the node + //! \param maxLOD: The maximum LOD ( Level of Detail ) for the node. + //! \param patchSize: An E_GEOMIPMAP_PATCH_SIZE enumeration defining the size of each patch of the terrain. + //! \param position: The absolute position of this node. + //! \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED ) + //! \param scale: The scale factor for the terrain. If you're using a heightmap of size 128x128 and would like + //! your terrain to be 12800x12800 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ). + //! If you use a Y scaling factor of 0.0f, then your terrain will be flat. + CTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, io::IFileSystem* fs, s32 id, + s32 maxLOD = 4, E_TERRAIN_PATCH_SIZE patchSize = ETPS_17, + const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + virtual ~CTerrainSceneNode(); + + //! Initializes the terrain data. Loads the vertices from the heightMapFile. + virtual bool loadHeightMap(io::IReadFile* file, + video::SColor vertexColor = video::SColor ( 255, 255, 255, 255 ), s32 smoothFactor = 0 ); + + //! Initializes the terrain data. Loads the vertices from the heightMapFile. + virtual bool loadHeightMapRAW(io::IReadFile* file, s32 bitsPerPixel = 16, + bool signedData=true, bool floatVals=false, s32 width=0, video::SColor vertexColor = video::SColor ( 255, 255, 255, 255 ), s32 smoothFactor = 0 ); + + //! Returns the material based on the zero based index i. This scene node only uses + //! 1 material. + //! \param i: Zero based index i. UNUSED, left in for virtual purposes. + //! \return Returns the single material this scene node uses. + virtual video::SMaterial& getMaterial(u32 i); + + //! Returns amount of materials used by this scene node ( always 1 ) + //! \return Returns current count of materials used by this scene node ( always 1 ) + virtual u32 getMaterialCount() const; + + //! Gets the last scaling factor applied to the scene node. This value only represents the + //! last scaling factor presented to the node. For instance, if you make create the node + //! with a scale factor of ( 1.0f, 1.0f, 1.0f ) then call setScale ( 50.0f, 5.0f, 50.0f ), + //! then make another call to setScale with the values ( 2.0f, 2.0f, 2.0f ), this will return + //! core::vector3df ( 2.0f, 2.0f, 2.0f ), although the total scaling of the scene node is + //! core::vector3df ( 100.0f, 10.0f, 100.0f ). + //! \return Returns the last scaling factor passed to the scene node. + virtual const core::vector3df& getScale() const + { + return TerrainData.Scale; + } + + //! Scales the scene nodes vertices by the vector specified. + //! \param scale: Scaling factor to apply to the node. + virtual void setScale(const core::vector3df& scale); + + //! Gets the last rotation factor applied to the scene node. + //! \return Returns the last rotation factor applied to the scene node. + virtual const core::vector3df& getRotation() const + { + return TerrainData.Rotation; + } + + //! Rotates the node. This only modifies the relative rotation of the node. + //! \param rotation: New rotation of the node in degrees. + virtual void setRotation(const core::vector3df& rotation); + + //! Sets the pivot point for rotation of this node. + //! NOTE: The default for the RotationPivot will be the center of the individual tile. + virtual void setRotationPivot( const core::vector3df& pivot ); + + //! Gets the last positioning vector applied to the scene node. + //! \return Returns the last position vector applied to the scene node. + virtual const core::vector3df& getPosition() const + { + return TerrainData.Position; + } + + //! Moves the scene nodes vertices by the vector specified. + //! \param newpos: Vector specifying how much to move each vertex of the scene node. + virtual void setPosition(const core::vector3df& newpos); + + //! Updates the scene nodes indices if the camera has moved or rotated by a certain + //! threshold, which can be changed using the SetCameraMovementDeltaThreshold and + //! SetCameraRotationDeltaThreshold functions. This also determines if a given patch + //! for the scene node is within the view frustum and if it's not the indices are not + //! generated for that patch. + virtual void OnRegisterSceneNode(); + + //! Render the scene node + virtual void render(); + + //! Return the bounding box of the entire terrain. + virtual const core::aabbox3d& getBoundingBox() const; + + //! Return the bounding box of a patch + virtual const core::aabbox3d& getBoundingBox(s32 patchX, s32 patchZ) const; + + //! Return the number of indices currently used to draw the scene node. + virtual u32 getIndexCount() const { return IndicesToRender; } + + //! Returns the mesh + virtual IMesh* getMesh(); + + //! Returns a pointer to the buffer used by the terrain (most users will not need this) + virtual IMeshBuffer* getRenderBuffer() { return RenderBuffer; } + + //! Gets the meshbuffer data based on a specified Level of Detail. + //! \param mb: A reference to an IDynamicMeshBuffer object + //! \param LOD: The Level Of Detail you want the indices from. + virtual void getMeshBufferForLOD(IDynamicMeshBuffer& mb, s32 LOD=0) const; + + //! Gets the indices for a specified patch at a specified Level of Detail. + //! \param indices: A reference to an array of u32 indices. + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \param LOD: The level of detail to get for that patch. If -1, then get + //! the CurrentLOD. If the CurrentLOD is set to -1, meaning it's not shown, + //! then it will retrieve the triangles at the highest LOD (0). + //! \return: Number of indices put into the buffer. + virtual s32 getIndicesForPatch(core::array& indices, + s32 patchX, s32 patchZ, s32 LOD=0); + + //! Populates an array with the CurrentLOD of each patch. + //! \param LODs: A reference to a core::array to hold the values + //! \return Returns the number of elements in the array + virtual s32 getCurrentLODOfPatches(core::array& LODs) const; + + //! Manually sets the LOD of a patch + //! \param patchX: Patch x coordinate. + //! \param patchZ: Patch z coordinate. + //! \param LOD: The level of detail to set the patch to. + virtual void setLODOfPatch(s32 patchX, s32 patchZ, s32 LOD=0); + + //! Returns center of terrain. + virtual const core::vector3df& getTerrainCenter() const + { + return TerrainData.Center; + } + + //! Returns center of terrain. + virtual f32 getHeight( f32 x, f32 y ) const; + + //! Sets the movement camera threshold which is used to determine when to recalculate + //! indices for the scene node. The default value is 10.0f. + virtual void setCameraMovementDelta(f32 delta) + { + CameraMovementDelta = delta; + } + + //! Sets the rotation camera threshold which is used to determine when to recalculate + //! indices for the scene node. The default value is 1.0f. + virtual void setCameraRotationDelta(f32 delta) + { + CameraRotationDelta = delta; + } + + //! Sets whether or not the node should dynamically update it its associated selector when + //! the geomipmap data changes. + //! param bVal: Boolean value representing whether or not to update selector dynamically. + //! NOTE: Temporarily disabled while working out issues with DynamicSelectorUpdate + virtual void setDynamicSelectorUpdate(bool bVal ) { DynamicSelectorUpdate = false; } + + //! Override the default generation of distance thresholds for determining the LOD a patch + //! is rendered at. If any LOD is overridden, then the scene node will no longer apply + //! scaling factors to these values. If you override these distances and then apply + //! a scale to the scene node, it is your responsibility to update the new distances to + //! work best with your new terrain size. + virtual bool overrideLODDistance( s32 LOD, f64 newDistance ); + + //! Scales the two textures + virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const {return ESNT_TERRAIN;} + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, + io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, + io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent, + ISceneManager* newManager); + + private: + friend class CTerrainTriangleSelector; + + struct SPatch + { + SPatch() + : Top(0), Bottom(0), Right(0), Left(0), CurrentLOD(-1) + { + } + + SPatch* Top; + SPatch* Bottom; + SPatch* Right; + SPatch* Left; + s32 CurrentLOD; + core::aabbox3df BoundingBox; + core::vector3df Center; + }; + + struct STerrainData + { + STerrainData(s32 patchSize, s32 maxLOD, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) + : Patches(0), Size(0), Position(position), Rotation(rotation), + Scale(scale), PatchSize(patchSize), CalcPatchSize(patchSize-1), + PatchCount(0), MaxLOD(maxLOD) + { + } + + SPatch* Patches; + s32 Size; + core::vector3df Position; + core::vector3df Rotation; + core::vector3df RotationPivot; + core::vector3df Scale; + core::vector3df Center; + s32 PatchSize; + s32 CalcPatchSize; + s32 PatchCount; + s32 MaxLOD; + core::aabbox3df BoundingBox; + core::array LODDistanceThreshold; + }; + + + virtual void preRenderCalculationsIfNeeded(); + + virtual void preRenderLODCalculations(); + virtual void preRenderIndicesCalculations(); + + //! get indices when generating index data for patches at varying levels of detail. + u32 getIndex(const s32 PatchX, const s32 PatchZ, const s32 PatchIndex, u32 vX, u32 vZ) const; + + //! smooth the terrain + void smoothTerrain(IDynamicMeshBuffer* mb, s32 smoothFactor); + + //! calculate smooth normals + void calculateNormals(IDynamicMeshBuffer* mb); + + //! create patches, stuff that needs to only be done once for patches goes here. + void createPatches(); + + //! calculate the internal STerrainData structure + void calculatePatchData(); + + //! calculate or recalculate the distance thresholds + void calculateDistanceThresholds(bool scalechanged = false); + + //! sets the CurrentLOD of all patches to the specified LOD + void setCurrentLODOfPatches(s32 i); + + //! sets the CurrentLOD of TerrainData patches to the LODs specified in the array + void setCurrentLODOfPatches(const core::array& lodarray); + + //! Apply transformation changes( scale, position, rotation ) + void applyTransformation(); + + STerrainData TerrainData; + SMesh* Mesh; + + IDynamicMeshBuffer *RenderBuffer; + + u32 VerticesToRender; + u32 IndicesToRender; + + bool DynamicSelectorUpdate; + bool OverrideDistanceThreshold; + bool UseDefaultRotationPivot; + bool ForceRecalculation; + + core::vector3df OldCameraPosition; + core::vector3df OldCameraRotation; + core::vector3df OldCameraUp; + f32 OldCameraFOV; + f32 CameraMovementDelta; + f32 CameraRotationDelta; + f32 CameraFOVDelta; + + // needed for (de)serialization + f32 TCoordScale1; + f32 TCoordScale2; + s32 SmoothFactor; + io::path HeightmapFile; + io::IFileSystem* FileSystem; + }; + + +} // end namespace scene +} // end namespace irr + +#endif // __C_TERRAIN_SCENE_NODE_H__ + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainTriangleSelector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainTriangleSelector.cpp new file mode 100644 index 0000000..91820ce --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTerrainTriangleSelector.cpp @@ -0,0 +1,234 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTerrainTriangleSelector.h" +#include "CTerrainSceneNode.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + + +//! constructor +CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s32 LOD ) + : SceneNode(node) +{ + #ifdef _DEBUG + setDebugName ("CTerrainTriangleSelector"); + #endif + + setTriangleData(node, LOD); +} + + +//! destructor +CTerrainTriangleSelector::~CTerrainTriangleSelector() +{ + TrianglePatches.TrianglePatchArray.clear(); +} + + +//! Clears and sets triangle data +void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD) +{ + // Get pointer to the GeoMipMaps vertices + const video::S3DVertex2TCoords* vertices = static_cast(node->getRenderBuffer()->getVertices()); + + // Clear current data + const s32 count = (static_cast(node))->TerrainData.PatchCount; + TrianglePatches.TotalTriangles = 0; + TrianglePatches.NumPatches = count*count; + + TrianglePatches.TrianglePatchArray.reallocate(TrianglePatches.NumPatches); + for (s32 o=0; o indices; + s32 tIndex = 0; + for(s32 x = 0; x < count; ++x ) + { + for(s32 z = 0; z < count; ++z ) + { + TrianglePatches.TrianglePatchArray[tIndex].NumTriangles = 0; + TrianglePatches.TrianglePatchArray[tIndex].Box = node->getBoundingBox( x, z ); + u32 indexCount = node->getIndicesForPatch( indices, x, z, LOD ); + + TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3); + for(u32 i = 0; i < indexCount; i += 3 ) + { + tri.pointA = vertices[indices[i+0]].Pos; + tri.pointB = vertices[indices[i+1]].Pos; + tri.pointC = vertices[indices[i+2]].Pos; + TrianglePatches.TrianglePatchArray[tIndex].Triangles.push_back(tri); + ++TrianglePatches.TrianglePatchArray[tIndex].NumTriangles; + } + + TrianglePatches.TotalTriangles += TrianglePatches.TrianglePatchArray[tIndex].NumTriangles; + ++tIndex; + } + } +} + + +//! Gets all triangles. +void CTerrainTriangleSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform) const +{ + s32 count = TrianglePatches.TotalTriangles; + + if (count > arraySize) + count = arraySize; + + core::matrix4 mat; + + if (transform) + mat = (*transform); + + s32 tIndex = 0; + + for (s32 i=0; i& box, const core::matrix4* transform) const +{ + s32 count = TrianglePatches.TotalTriangles; + + if (count > arraySize) + count = arraySize; + + core::matrix4 mat; + + if (transform) + mat = (*transform); + + s32 tIndex = 0; + + for (s32 i=0; i& line, + const core::matrix4* transform) const +{ + const s32 count = core::min_((s32)TrianglePatches.TotalTriangles, arraySize); + + core::matrix4 mat; + + if (transform) + mat = (*transform); + + s32 tIndex = 0; + + for (s32 i=0; i& box, const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + + //! Returns amount of all available triangles in this selector + virtual s32 getTriangleCount() const; + + //! Return the scene node associated with a given triangle. + virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const; + + // Get the number of TriangleSelectors that are part of this one + virtual u32 getSelectorCount() const; + + // Get the TriangleSelector based on index based on getSelectorCount + virtual ITriangleSelector* getSelector(u32 index); + + // Get the TriangleSelector based on index based on getSelectorCount + virtual const ITriangleSelector* getSelector(u32 index) const; + +private: + + friend class CTerrainSceneNode; + + struct SGeoMipMapTrianglePatch + { + core::array Triangles; + s32 NumTriangles; + core::aabbox3df Box; + }; + + struct SGeoMipMapTrianglePatches + { + SGeoMipMapTrianglePatches() : + NumPatches(0), TotalTriangles(0) + { + } + + core::array TrianglePatchArray; + s32 NumPatches; + u32 TotalTriangles; + }; + + ITerrainSceneNode* SceneNode; + SGeoMipMapTrianglePatches TrianglePatches; +}; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_TERRAIN_TRIANGLE_SELECTOR_H__ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.cpp new file mode 100644 index 0000000..7edf2f5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.cpp @@ -0,0 +1,471 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTextSceneNode.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "ICameraSceneNode.h" +#include "IGUISpriteBank.h" +#include "SMeshBuffer.h" +#include "os.h" + + +namespace irr +{ +namespace scene +{ + + +//! constructor +CTextSceneNode::CTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font, scene::ISceneCollisionManager* coll, + const core::vector3df& position, const wchar_t* text, + video::SColor color) + : ITextSceneNode(parent, mgr, id, position), Text(text), Color(color), + Font(font), Coll(coll) + +{ + #ifdef _DEBUG + setDebugName("CTextSceneNode"); + #endif + + if (Font) + Font->grab(); + + setAutomaticCulling(scene::EAC_OFF); +} + +//! destructor +CTextSceneNode::~CTextSceneNode() +{ + if (Font) + Font->drop(); +} + +void CTextSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); + + ISceneNode::OnRegisterSceneNode(); +} + +//! renders the node. +void CTextSceneNode::render() +{ + if (!Font || !Coll) + return; + + core::position2d pos = Coll->getScreenCoordinatesFrom3DPosition(getAbsolutePosition(), + SceneManager->getActiveCamera()); + + core::rect r(pos, core::dimension2d(1,1)); + Font->draw(Text.c_str(), r, Color, true, true); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CTextSceneNode::getBoundingBox() const +{ + return Box; +} + +//! sets the text string +void CTextSceneNode::setText(const wchar_t* text) +{ + Text = text; +} + + +//! sets the color of the text +void CTextSceneNode::setTextColor(video::SColor color) +{ + Color = color; +} + + +//!--------------------------------- CBillboardTextSceneNode ---------------------------------------------- + + +//! constructor +CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font,const wchar_t* text, + const core::vector3df& position, const core::dimension2d& size, + video::SColor colorTop,video::SColor shade_bottom ) +: IBillboardTextSceneNode(parent, mgr, id, position), + Font(0), ColorTop(colorTop), ColorBottom(shade_bottom), Mesh(0) +{ + #ifdef _DEBUG + setDebugName("CBillboardTextSceneNode"); + #endif + + Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + Material.MaterialTypeParam = 1.f / 255.f; + Material.BackfaceCulling = false; + Material.Lighting = false; + Material.ZBuffer = video::ECFN_LESSEQUAL; + Material.ZWriteEnable = false; + + if (font) + { + // doesn't support other font types + if (font->getType() == gui::EGFT_BITMAP) + { + Font = (gui::IGUIFontBitmap*)font; + Font->grab(); + + // mesh with one buffer per texture + Mesh = new SMesh(); + for (u32 i=0; igetSpriteBank()->getTextureCount(); ++i) + { + SMeshBuffer *mb = new SMeshBuffer(); + mb->Material = Material; + mb->Material.setTexture(0, Font->getSpriteBank()->getTexture(i)); + Mesh->addMeshBuffer(mb); + mb->drop(); + } + } + else + { + os::Printer::log("Sorry, CBillboardTextSceneNode does not support this font type", ELL_INFORMATION); + } + } + + setText(text); + setSize(size); + + setAutomaticCulling ( scene::EAC_BOX ); +} + + + +CBillboardTextSceneNode::~CBillboardTextSceneNode() +{ + if (Font) + Font->drop(); + + if (Mesh) + Mesh->drop(); + +} + + +//! sets the text string +void CBillboardTextSceneNode::setText(const wchar_t* text) +{ + if ( !Mesh ) + return; + + Text = text; + + Symbol.clear(); + + // clear mesh + for (u32 j=0; j < Mesh->getMeshBufferCount(); ++j) + { + ((SMeshBuffer*)Mesh->getMeshBuffer(j))->Indices.clear(); + ((SMeshBuffer*)Mesh->getMeshBuffer(j))->Vertices.clear(); + } + + if (!Font) + return; + + const core::array< core::rect > &sourceRects = Font->getSpriteBank()->getPositions(); + const core::array< gui::SGUISprite > &sprites = Font->getSpriteBank()->getSprites(); + + f32 dim[2]; + f32 tex[4]; + + u32 i; + for ( i = 0; i != Text.size (); ++i ) + { + SSymbolInfo info; + + u32 spriteno = Font->getSpriteNoFromChar( &text[i] ); + u32 rectno = sprites[spriteno].Frames[0].rectNumber; + u32 texno = sprites[spriteno].Frames[0].textureNumber; + + dim[0] = core::reciprocal ( (f32) Font->getSpriteBank()->getTexture(texno)->getSize().Width ); + dim[1] = core::reciprocal ( (f32) Font->getSpriteBank()->getTexture(texno)->getSize().Height ); + + const core::rect& s = sourceRects[rectno]; + + // add space for letter to buffer + SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(texno); + u32 firstInd = buf->Indices.size(); + u32 firstVert = buf->Vertices.size(); + buf->Indices.set_used(firstInd + 6); + buf->Vertices.set_used(firstVert + 4); + + tex[0] = (s.LowerRightCorner.X * dim[0]) + 0.5f*dim[0]; // half pixel + tex[1] = (s.LowerRightCorner.Y * dim[1]) + 0.5f*dim[1]; + tex[2] = (s.UpperLeftCorner.Y * dim[1]) - 0.5f*dim[1]; + tex[3] = (s.UpperLeftCorner.X * dim[0]) - 0.5f*dim[0]; + + buf->Vertices[firstVert+0].TCoords.set(tex[0], tex[1]); + buf->Vertices[firstVert+1].TCoords.set(tex[0], tex[2]); + buf->Vertices[firstVert+2].TCoords.set(tex[3], tex[2]); + buf->Vertices[firstVert+3].TCoords.set(tex[3], tex[1]); + + buf->Vertices[firstVert+0].Color = ColorBottom; + buf->Vertices[firstVert+3].Color = ColorBottom; + buf->Vertices[firstVert+1].Color = ColorTop; + buf->Vertices[firstVert+2].Color = ColorTop; + + buf->Indices[firstInd+0] = (u16)firstVert+0; + buf->Indices[firstInd+1] = (u16)firstVert+2; + buf->Indices[firstInd+2] = (u16)firstVert+1; + buf->Indices[firstInd+3] = (u16)firstVert+0; + buf->Indices[firstInd+4] = (u16)firstVert+3; + buf->Indices[firstInd+5] = (u16)firstVert+2; + + wchar_t *tp = 0; + if (i>0) + tp = &Text[i-1]; + + info.Width = (f32)s.getWidth(); + info.bufNo = texno; + info.Kerning = (f32)Font->getKerningWidth(&Text[i], tp); + info.firstInd = firstInd; + info.firstVert = firstVert; + + Symbol.push_back(info); + } +} + + +//! pre render event +void CBillboardTextSceneNode::OnAnimate(u32 timeMs) +{ + ISceneNode::OnAnimate(timeMs); + + if (!IsVisible || !Font || !Mesh) + return; + + ICameraSceneNode* camera = SceneManager->getActiveCamera(); + if (!camera) + return; + + // get text width + f32 textLength = 0.f; + u32 i; + for(i=0; i!=Symbol.size(); ++i) + { + SSymbolInfo &info = Symbol[i]; + textLength += info.Kerning + info.Width; + } + if (textLength<0.0f) + textLength=1.0f; + + //const core::matrix4 &m = camera->getViewFrustum()->Matrices[ video::ETS_VIEW ]; + + // make billboard look to camera + core::vector3df pos = getAbsolutePosition(); + + core::vector3df campos = camera->getAbsolutePosition(); + core::vector3df target = camera->getTarget(); + core::vector3df up = camera->getUpVector(); + core::vector3df view = target - campos; + view.normalize(); + + core::vector3df horizontal = up.crossProduct(view); + if ( horizontal.getLength() == 0 ) + { + horizontal.set(up.Y,up.X,up.Z); + } + + horizontal.normalize(); + core::vector3df space = horizontal; + + horizontal *= 0.5f * Size.Width; + + core::vector3df vertical = horizontal.crossProduct(view); + vertical.normalize(); + vertical *= 0.5f * Size.Height; + + view *= -1.0f; + + // center text + pos += space * (Size.Width * -0.5f); + + for ( i = 0; i!= Symbol.size(); ++i ) + { + SSymbolInfo &info = Symbol[i]; + f32 infw = info.Width / textLength; + f32 infk = info.Kerning / textLength; + f32 w = (Size.Width * infw * 0.5f); + pos += space * w; + + SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo); + + buf->Vertices[info.firstVert+0].Normal = view; + buf->Vertices[info.firstVert+1].Normal = view; + buf->Vertices[info.firstVert+2].Normal = view; + buf->Vertices[info.firstVert+3].Normal = view; + + buf->Vertices[info.firstVert+0].Pos = pos + (space * w) + vertical; + buf->Vertices[info.firstVert+1].Pos = pos + (space * w) - vertical; + buf->Vertices[info.firstVert+2].Pos = pos - (space * w) - vertical; + buf->Vertices[info.firstVert+3].Pos = pos - (space * w) + vertical; + + pos += space * (Size.Width*infk + w); + } + + // make bounding box + + for (i=0; i< Mesh->getMeshBufferCount() ; ++i) + Mesh->getMeshBuffer(i)->recalculateBoundingBox(); + Mesh->recalculateBoundingBox(); + + BBox = Mesh->getBoundingBox(); + core::matrix4 mat( getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE ); + mat.transformBoxEx(BBox); +} + +void CBillboardTextSceneNode::OnRegisterSceneNode() +{ + SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); + ISceneNode::OnRegisterSceneNode(); +} + + +//! render +void CBillboardTextSceneNode::render() +{ + if ( !Mesh ) + return; + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + // draw + core::matrix4 mat; + driver->setTransform(video::ETS_WORLD, mat); + + for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) + { + driver->setMaterial(Mesh->getMeshBuffer(i)->getMaterial()); + driver->drawMeshBuffer(Mesh->getMeshBuffer(i)); + } + + if ( DebugDataVisible & scene::EDS_BBOX ) + { + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + video::SMaterial m; + m.Lighting = false; + driver->setMaterial(m); + driver->draw3DBox(BBox, video::SColor(0,208,195,152)); + } +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CBillboardTextSceneNode::getBoundingBox() const +{ + return BBox; +} + + +//! sets the size of the billboard +void CBillboardTextSceneNode::setSize(const core::dimension2d& size) +{ + Size = size; + + if (Size.Width == 0.0f) + Size.Width = 1.0f; + + if (Size.Height == 0.0f ) + Size.Height = 1.0f; + + //f32 avg = (size.Width + size.Height)/6; + //BBox.MinEdge.set(-avg,-avg,-avg); + //BBox.MaxEdge.set(avg,avg,avg); +} + + +video::SMaterial& CBillboardTextSceneNode::getMaterial(u32 i) +{ + if (Mesh && Mesh->getMeshBufferCount() > i ) + return Mesh->getMeshBuffer(i)->getMaterial(); + else + return Material; +} + + +//! returns amount of materials used by this scene node. +u32 CBillboardTextSceneNode::getMaterialCount() const +{ + if (Mesh) + return Mesh->getMeshBufferCount(); + else + return 0; +} + + +//! gets the size of the billboard +const core::dimension2d& CBillboardTextSceneNode::getSize() const +{ + return Size; +} + + +//! sets the color of the text +void CBillboardTextSceneNode::setTextColor(video::SColor color) +{ + Color = color; +} + +//! Set the color of all vertices of the billboard +//! \param overallColor: the color to set +void CBillboardTextSceneNode::setColor(const video::SColor & overallColor) +{ + if ( !Mesh ) + return; + + for ( u32 i = 0; i != Text.size (); ++i ) + { + const SSymbolInfo &info = Symbol[i]; + SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo); + buf->Vertices[info.firstVert+0].Color = overallColor; + buf->Vertices[info.firstVert+1].Color = overallColor; + buf->Vertices[info.firstVert+2].Color = overallColor; + buf->Vertices[info.firstVert+3].Color = overallColor; + } +} + + +//! Set the color of the top and bottom vertices of the billboard +//! \param topColor: the color to set the top vertices +//! \param bottomColor: the color to set the bottom vertices +void CBillboardTextSceneNode::setColor(const video::SColor & topColor, const video::SColor & bottomColor) +{ + if ( !Mesh ) + return; + + ColorBottom = bottomColor; + ColorTop = topColor; + for ( u32 i = 0; i != Text.size (); ++i ) + { + const SSymbolInfo &info = Symbol[i]; + SMeshBuffer* buf = (SMeshBuffer*)Mesh->getMeshBuffer(info.bufNo); + buf->Vertices[info.firstVert+0].Color = ColorBottom; + buf->Vertices[info.firstVert+3].Color = ColorBottom; + buf->Vertices[info.firstVert+1].Color = ColorTop; + buf->Vertices[info.firstVert+2].Color = ColorTop; + } +} + + +//! Gets the color of the top and bottom vertices of the billboard +//! \param topColor: stores the color of the top vertices +//! \param bottomColor: stores the color of the bottom vertices +void CBillboardTextSceneNode::getColor(video::SColor & topColor, video::SColor & bottomColor) const +{ + topColor = ColorTop; + bottomColor = ColorBottom; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.h new file mode 100644 index 0000000..5c2e55e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTextSceneNode.h @@ -0,0 +1,160 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TEXT_SCENE_NODE_H_INCLUDED__ +#define __C_TEXT_SCENE_NODE_H_INCLUDED__ + +#include "ITextSceneNode.h" +#include "IBillboardTextSceneNode.h" +#include "IGUIFont.h" +#include "IGUIFontBitmap.h" +#include "ISceneCollisionManager.h" +#include "SMesh.h" + +namespace irr +{ +namespace scene +{ + + + class CTextSceneNode : public ITextSceneNode + { + public: + + //! constructor + CTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font, scene::ISceneCollisionManager* coll, + const core::vector3df& position = core::vector3df(0,0,0), const wchar_t* text=0, + video::SColor color=video::SColor(100,0,0,0)); + + //! destructor + virtual ~CTextSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the text string + virtual void setText(const wchar_t* text); + + //! sets the color of the text + virtual void setTextColor(video::SColor color); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_TEXT; } + + private: + + core::stringw Text; + video::SColor Color; + gui::IGUIFont* Font; + scene::ISceneCollisionManager* Coll; + core::aabbox3d Box; + }; + + class CBillboardTextSceneNode : public IBillboardTextSceneNode + { + public: + + CBillboardTextSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + gui::IGUIFont* font,const wchar_t* text, + const core::vector3df& position, const core::dimension2d& size, + video::SColor colorTop, video::SColor shade_bottom); + + //! destructor + virtual ~CBillboardTextSceneNode(); + + //! sets the vertex positions etc + virtual void OnAnimate(u32 timeMs); + + //! registers the node into the transparent pass + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! sets the text string + virtual void setText(const wchar_t* text); + + //! sets the color of the text + virtual void setTextColor(video::SColor color); + + //! sets the size of the billboard + virtual void setSize(const core::dimension2d& size); + + //! gets the size of the billboard + virtual const core::dimension2d& getSize() const; + + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_TEXT; } + + //! Set the color of all vertices of the billboard + //! \param overallColor: the color to set + virtual void setColor(const video::SColor & overallColor); + + //! Set the color of the top and bottom vertices of the billboard + //! \param topColor: the color to set the top vertices + //! \param bottomColor: the color to set the bottom vertices + virtual void setColor(const video::SColor & topColor, const video::SColor & bottomColor); + + //! Gets the color of the top and bottom vertices of the billboard + //! \param topColor: stores the color of the top vertices + //! \param bottomColor: stores the color of the bottom vertices + virtual void getColor(video::SColor & topColor, video::SColor & bottomColor) const; + + virtual void setSize(f32 height, f32 bottomEdgeWidth, f32 topEdgeWidth) + { + setSize(core::dimension2df(bottomEdgeWidth, height)); + } + + virtual void getSize(f32& height, f32& bottomEdgeWidth, f32& topEdgeWidth) const + { + height = Size.Height; + bottomEdgeWidth = Size.Width; + topEdgeWidth = Size.Width; + } + + private: + + core::stringw Text; + video::SColor Color; + gui::IGUIFontBitmap* Font; + + core::dimension2d Size; + core::aabbox3d BBox; + video::SMaterial Material; + + video::SColor ColorTop; + video::SColor ColorBottom; + struct SSymbolInfo + { + u32 bufNo; + f32 Width; + f32 Kerning; + u32 firstInd; + u32 firstVert; + }; + + core::array < SSymbolInfo > Symbol; + + SMesh *Mesh; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTimer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTimer.h new file mode 100644 index 0000000..8d8b8b8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTimer.h @@ -0,0 +1,108 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_IRR_C_TIMER_H_INCLUDED__ +#define __C_IRR_C_TIMER_H_INCLUDED__ + +#include "ITimer.h" +#include "os.h" + +namespace irr +{ + //! Device independent implementation of the timer + class CTimer : public ITimer + { + public: + + CTimer(bool usePerformanceTimer=true) + { + os::Timer::initTimer(usePerformanceTimer); + } + + //! Returns current real time in milliseconds of the system. + /** This value does not start with 0 when the application starts. + For example in one implementation the value returned could be the + amount of milliseconds which have elapsed since the system was started. */ + virtual u32 getRealTime() const + { + return os::Timer::getRealTime(); + } + + //! Get current time and date in calendar form + virtual RealTimeDate getRealTimeAndDate() const + { + return os::Timer::getRealTimeAndDate(); + } + + //! Returns current virtual time in milliseconds. + /** This value starts with 0 and can be manipulated using setTime(), stopTimer(), + startTimer(), etc. This value depends on the set speed of the timer if the timer + is stopped, etc. If you need the system time, use getRealTime() */ + virtual u32 getTime() const + { + return os::Timer::getTime(); + } + + //! sets current virtual time + virtual void setTime(u32 time) + { + os::Timer::setTime(time); + } + + //! Stops the game timer. + /** The timer is reference counted, which means everything which calls + stopTimer() will also have to call startTimer(), otherwise the timer may not start/stop + corretly again. */ + virtual void stop() + { + os::Timer::stopTimer(); + } + + //! Starts the game timer. + /** The timer is reference counted, which means everything which calls + stopTimer() will also have to call startTimer(), otherwise the timer may not start/stop + corretly again. */ + virtual void start() + { + os::Timer::startTimer(); + } + + //! Sets the speed of the timer + /** The speed is the factor with which the time is running faster or slower then the + real system time. */ + virtual void setSpeed(f32 speed = 1.0f) + { + os::Timer::setSpeed(speed); + } + + //! Returns current speed of the timer + /** The speed is the factor with which the time is running faster or slower then the + real system time. */ + virtual f32 getSpeed() const + { + return os::Timer::getSpeed(); + } + + //! Returns if game timer is currently stopped + virtual bool isStopped() const + { + bool ret = os::Timer::isStopped(); + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return ret; + } + + //! Advances the virtual time + /** Makes the virtual timer update the time value based on the real time. This is + called automaticly when calling IrrlichtDevice::run(), but you can call it manually + if you don't use this method. */ + virtual void tick() + { + os::Timer::tick(); + } + }; + +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.cpp new file mode 100644 index 0000000..547b249 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTriangleBBSelector.h" +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CTriangleBBSelector::CTriangleBBSelector(ISceneNode* node) +: CTriangleSelector(node) +{ + #ifdef _DEBUG + setDebugName("CTriangleBBSelector"); + #endif + + Triangles.set_used(12); // a box has 12 triangles. +} + + + +//! Gets all triangles. +void CTriangleBBSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform) const +{ + if (!SceneNode) + return; + + // construct triangles + const core::aabbox3d& box = SceneNode->getBoundingBox(); + core::vector3df edges[8]; + box.getEdges(edges); + + Triangles[0].set( edges[3], edges[0], edges[2]); + Triangles[1].set( edges[3], edges[1], edges[0]); + + Triangles[2].set( edges[3], edges[2], edges[7]); + Triangles[3].set( edges[7], edges[2], edges[6]); + + Triangles[4].set( edges[7], edges[6], edges[4]); + Triangles[5].set( edges[5], edges[7], edges[4]); + + Triangles[6].set( edges[5], edges[4], edges[0]); + Triangles[7].set( edges[5], edges[0], edges[1]); + + Triangles[8].set( edges[1], edges[3], edges[7]); + Triangles[9].set( edges[1], edges[7], edges[5]); + + Triangles[10].set(edges[0], edges[6], edges[2]); + Triangles[11].set(edges[0], edges[4], edges[6]); + + // call parent + CTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount, transform); +} + +void CTriangleBBSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, + const core::matrix4* transform) const +{ + return getTriangles(triangles, arraySize, outTriangleCount, transform); +} + +void CTriangleBBSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::line3d& line, + const core::matrix4* transform) const +{ + return getTriangles(triangles, arraySize, outTriangleCount, transform); +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.h new file mode 100644 index 0000000..c34f57d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleBBSelector.h @@ -0,0 +1,43 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TRIANGLE_BB_SELECTOR_H_INCLUDED__ +#define __C_TRIANGLE_BB_SELECTOR_H_INCLUDED__ + +#include "CTriangleSelector.h" + +namespace irr +{ +namespace scene +{ + +//! Stupid triangle selector without optimization +class CTriangleBBSelector : public CTriangleSelector +{ +public: + + //! Constructs a selector based on a mesh + CTriangleBBSelector(ISceneNode* node); + + //! Gets all triangles. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform=0) const; + + //! Gets all triangles which lie within a specific bounding box. + void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp new file mode 100644 index 0000000..7b30882 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.cpp @@ -0,0 +1,298 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CTriangleSelector.h" +#include "ISceneNode.h" +#include "IMeshBuffer.h" +#include "IAnimatedMeshSceneNode.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CTriangleSelector::CTriangleSelector(ISceneNode* node) +: SceneNode(node), AnimatedNode(0), LastMeshFrame(0) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif + + BoundingBox.reset(0.f, 0.f, 0.f); +} + + +//! constructor +CTriangleSelector::CTriangleSelector(const core::aabbox3d& box, ISceneNode* node) +: SceneNode(node), AnimatedNode(0), LastMeshFrame(0) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif + + BoundingBox=box; + // TODO +} + + +//! constructor +CTriangleSelector::CTriangleSelector(const IMesh* mesh, ISceneNode* node) +: SceneNode(node), AnimatedNode(0), LastMeshFrame(0) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif + + createFromMesh(mesh); +} + + +CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node) +: SceneNode(node), AnimatedNode(node), LastMeshFrame(0) +{ + #ifdef _DEBUG + setDebugName("CTriangleSelector"); + #endif + + if (!AnimatedNode) + return; + + IAnimatedMesh* animatedMesh = AnimatedNode->getMesh(); + if (!animatedMesh) + return; + + LastMeshFrame = (u32)AnimatedNode->getFrameNr(); + IMesh* mesh = animatedMesh->getMesh(LastMeshFrame); + + if (mesh) + createFromMesh(mesh); +} + + +void CTriangleSelector::createFromMesh(const IMesh* mesh) +{ + const u32 cnt = mesh->getMeshBufferCount(); + u32 totalFaceCount = 0; + for (u32 j=0; jgetMeshBuffer(j)->getIndexCount(); + totalFaceCount /= 3; + Triangles.reallocate(totalFaceCount); + BoundingBox.reset(0.f, 0.f, 0.f); + + for (u32 i=0; igetMeshBuffer(i); + + const u32 idxCnt = buf->getIndexCount(); + const u16* const indices = buf->getIndices(); + + for (u32 j=0; jgetPosition(indices[j+0]), + buf->getPosition(indices[j+1]), + buf->getPosition(indices[j+2]))); + const core::triangle3df& tri = Triangles.getLast(); + BoundingBox.addInternalPoint(tri.pointA); + BoundingBox.addInternalPoint(tri.pointB); + BoundingBox.addInternalPoint(tri.pointC); + } + } +} + + +void CTriangleSelector::updateFromMesh(const IMesh* mesh) const +{ + if (!mesh) + return; + + u32 meshBuffers = mesh->getMeshBufferCount(); + u32 triangleCount = 0; + + BoundingBox.reset(0.f, 0.f, 0.f); + for (u32 i = 0; i < meshBuffers; ++i) + { + IMeshBuffer* buf = mesh->getMeshBuffer(i); + u32 idxCnt = buf->getIndexCount(); + const u16* indices = buf->getIndices(); + + for (u32 index = 0; index < idxCnt; index += 3) + { + core::triangle3df& tri = Triangles[triangleCount++]; + tri.pointA = buf->getPosition(indices[index + 0]); + tri.pointB = buf->getPosition(indices[index + 1]); + tri.pointC = buf->getPosition(indices[index + 2]); + BoundingBox.addInternalPoint(tri.pointA); + BoundingBox.addInternalPoint(tri.pointB); + BoundingBox.addInternalPoint(tri.pointC); + } + } +} + + +void CTriangleSelector::update(void) const +{ + if (!AnimatedNode) + return; //< harmless no-op + + const u32 currentFrame = (u32)AnimatedNode->getFrameNr(); + if (currentFrame == LastMeshFrame) + return; //< Nothing to do + + LastMeshFrame = currentFrame; + IAnimatedMesh * animatedMesh = AnimatedNode->getMesh(); + + if (animatedMesh) + { + IMesh * mesh = animatedMesh->getMesh(LastMeshFrame); + + if (mesh) + updateFromMesh(mesh); + } +} + + +//! Gets all triangles. +void CTriangleSelector::getTriangles(core::triangle3df* triangles, + s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform) const +{ + // Update my triangles if necessary + update(); + + u32 cnt = Triangles.size(); + if (cnt > (u32)arraySize) + cnt = (u32)arraySize; + + core::matrix4 mat; + if (transform) + mat = *transform; + if (SceneNode) + mat *= SceneNode->getAbsoluteTransformation(); + + for (u32 i=0; i& box, + const core::matrix4* transform) const +{ + // Update my triangles if necessary + update(); + + core::matrix4 mat(core::matrix4::EM4CONST_NOTHING); + core::aabbox3df tBox(box); + + if (SceneNode) + { + SceneNode->getAbsoluteTransformation().getInverse(mat); + mat.transformBoxEx(tBox); + } + if (transform) + mat = *transform; + else + mat.makeIdentity(); + if (SceneNode) + mat *= SceneNode->getAbsoluteTransformation(); + + outTriangleCount = 0; + + if (!tBox.intersectsWithBox(BoundingBox)) + return; + + s32 triangleCount = 0; + const u32 cnt = Triangles.size(); + for (u32 i=0; i& line, + const core::matrix4* transform) const +{ + // Update my triangles if necessary + update(); + + core::aabbox3d box(line.start); + box.addInternalPoint(line.end); + + // TODO: Could be optimized for line a little bit more. + getTriangles(triangles, arraySize, outTriangleCount, + box, transform); +} + + +//! Returns amount of all available triangles in this selector +s32 CTriangleSelector::getTriangleCount() const +{ + return Triangles.size(); +} + + +/* Get the number of TriangleSelectors that are part of this one. +Only useful for MetaTriangleSelector others return 1 +*/ +u32 CTriangleSelector::getSelectorCount() const +{ + return 1; +} + + +/* Get the TriangleSelector based on index based on getSelectorCount. +Only useful for MetaTriangleSelector others return 'this' or 0 +*/ +ITriangleSelector* CTriangleSelector::getSelector(u32 index) +{ + if (index) + return 0; + else + return this; +} + + +/* Get the TriangleSelector based on index based on getSelectorCount. +Only useful for MetaTriangleSelector others return 'this' or 0 +*/ +const ITriangleSelector* CTriangleSelector::getSelector(u32 index) const +{ + if (index) + return 0; + else + return this; +} + + +} // end namespace scene +} // end namespace irr diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.h new file mode 100644 index 0000000..3d3b5f7 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CTriangleSelector.h @@ -0,0 +1,92 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_TRIANGLE_SELECTOR_H_INCLUDED__ +#define __C_TRIANGLE_SELECTOR_H_INCLUDED__ + +#include "ITriangleSelector.h" +#include "IMesh.h" +#include "irrArray.h" +#include "aabbox3d.h" + +namespace irr +{ +namespace scene +{ + +class ISceneNode; +class IAnimatedMeshSceneNode; + +//! Stupid triangle selector without optimization +class CTriangleSelector : public ITriangleSelector +{ +public: + + //! Constructs a selector based on a mesh + CTriangleSelector(ISceneNode* node); + + //! Constructs a selector based on a mesh + CTriangleSelector(const IMesh* mesh, ISceneNode* node); + + //! Constructs a selector based on an animated mesh scene node + //!\param node An animated mesh scene node, which must have a valid mesh + CTriangleSelector(IAnimatedMeshSceneNode* node); + + //! Constructs a selector based on a bounding box + CTriangleSelector(const core::aabbox3d& box, ISceneNode* node); + + //! Gets all triangles. + void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::matrix4* transform=0) const; + + //! Gets all triangles which lie within a specific bounding box. + void getTriangles(core::triangle3df* triangles, s32 arraySize, s32& outTriangleCount, + const core::aabbox3d& box, const core::matrix4* transform=0) const; + + //! Gets all triangles which have or may have contact with a 3d line. + virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, + s32& outTriangleCount, const core::line3d& line, + const core::matrix4* transform=0) const; + + //! Returns amount of all available triangles in this selector + virtual s32 getTriangleCount() const; + + //! Return the scene node associated with a given triangle. + virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const { return SceneNode; } + + // Get the number of TriangleSelectors that are part of this one + virtual u32 getSelectorCount() const; + + // Get the TriangleSelector based on index based on getSelectorCount + virtual ITriangleSelector* getSelector(u32 index); + + // Get the TriangleSelector based on index based on getSelectorCount + virtual const ITriangleSelector* getSelector(u32 index) const; + +protected: + //! Create from a mesh + virtual void createFromMesh(const IMesh* mesh); + + //! Update when the mesh has changed + virtual void updateFromMesh(const IMesh* mesh) const; + + //! Update the triangle selector, which will only have an effect if it + //! was built from an animated mesh and that mesh's frame has changed + //! since the last time it was updated. + virtual void update(void) const; + + ISceneNode* SceneNode; + mutable core::array Triangles; // (mutable for CTriangleBBSelector) + mutable core::aabbox3df BoundingBox; // Allows for trivial rejection + + IAnimatedMeshSceneNode* AnimatedNode; + mutable u32 LastMeshFrame; +}; + +} // end namespace scene +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CVideoModeList.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CVideoModeList.cpp new file mode 100644 index 0000000..9ae7fb2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CVideoModeList.cpp @@ -0,0 +1,132 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CVideoModeList.h" +#include "irrMath.h" + +namespace irr +{ +namespace video +{ + +//! constructor +CVideoModeList::CVideoModeList() +{ + #ifdef _DEBUG + setDebugName("CVideoModeList"); + #endif + + Desktop.depth = 0; + Desktop.size = core::dimension2d(0,0); +} + + +void CVideoModeList::setDesktop(s32 desktopDepth, const core::dimension2d& desktopSize) +{ + Desktop.depth = desktopDepth; + Desktop.size = desktopSize; +} + + +//! Gets amount of video modes in the list. +s32 CVideoModeList::getVideoModeCount() const +{ + return (s32)VideoModes.size(); +} + + +//! Returns the screen size of a video mode in pixels. +core::dimension2d CVideoModeList::getVideoModeResolution(s32 modeNumber) const +{ + if (modeNumber < 0 || modeNumber > (s32)VideoModes.size()) + return core::dimension2d(0,0); + + return VideoModes[modeNumber].size; +} + + +core::dimension2d CVideoModeList::getVideoModeResolution( + const core::dimension2d& minSize, + const core::dimension2d& maxSize) const +{ + u32 best=VideoModes.size(); + // if only one or no mode + if (best<2) + return getVideoModeResolution(0); + + u32 i; + for (i=0; i=minSize.Width && + VideoModes[i].size.Height>=minSize.Height && + VideoModes[i].size.Width<=maxSize.Width && + VideoModes[i].size.Height<=maxSize.Height) + best=i; + } + // we take the last one found, the largest one fitting + if (best (s32)VideoModes.size()) + return 0; + + return VideoModes[modeNumber].depth; +} + + +//! Returns current desktop screen resolution. +const core::dimension2d& CVideoModeList::getDesktopResolution() const +{ + return Desktop.size; +} + + +//! Returns the pixel depth of a video mode in bits. +s32 CVideoModeList::getDesktopDepth() const +{ + return Desktop.depth; +} + + +//! adds a new mode to the list +void CVideoModeList::addMode(const core::dimension2d& size, s32 depth) +{ + SVideoMode m; + m.depth = depth; + m.size = size; + + for (u32 i=0; i getVideoModeResolution(s32 modeNumber) const; + + //! Returns the screen size of an optimal video mode in pixels. + virtual core::dimension2d getVideoModeResolution(const core::dimension2d& minSize, const core::dimension2d& maxSize) const; + + //! Returns the pixel depth of a video mode in bits. + virtual s32 getVideoModeDepth(s32 modeNumber) const; + + //! Returns current desktop screen resolution. + virtual const core::dimension2d& getDesktopResolution() const; + + //! Returns the pixel depth of a video mode in bits. + virtual s32 getDesktopDepth() const; + + //! adds a new mode to the list + void addMode(const core::dimension2d& size, s32 depth); + + void setDesktop(s32 desktopDepth, const core::dimension2d& desktopSize); + + private: + + struct SVideoMode + { + core::dimension2d size; + s32 depth; + + bool operator==(const SVideoMode& other) const + { + return size == other.size && depth == other.depth; + } + + bool operator <(const SVideoMode& other) const + { + return (size.Width < other.size.Width || + (size.Width == other.size.Width && + size.Height < other.size.Height) || + (size.Width == other.size.Width && + size.Height == other.size.Height && + depth < other.depth)); + } + }; + + core::array VideoModes; + SVideoMode Desktop; + }; + +} // end namespace video +} // end namespace irr + + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.cpp new file mode 100644 index 0000000..966e823 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.cpp @@ -0,0 +1,202 @@ +// Copyright (C) 2007-2012 Dean Wadsworth +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CVolumeLightSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "S3DVertex.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager* mgr, + s32 id, const u32 subdivU, const u32 subdivV, + const video::SColor foot, + const video::SColor tail, + const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale) + : IVolumeLightSceneNode(parent, mgr, id, position, rotation, scale), + Mesh(0), LPDistance(8.0f), + SubdivideU(subdivU), SubdivideV(subdivV), + FootColor(foot), TailColor(tail), + LightDimensions(core::vector3df(1.0f, 1.2f, 1.0f)) +{ + #ifdef _DEBUG + setDebugName("CVolumeLightSceneNode"); + #endif + + constructLight(); +} + + +CVolumeLightSceneNode::~CVolumeLightSceneNode() +{ + if (Mesh) + Mesh->drop(); +} + + +void CVolumeLightSceneNode::constructLight() +{ + if (Mesh) + Mesh->drop(); + Mesh = SceneManager->getGeometryCreator()->createVolumeLightMesh(SubdivideU, SubdivideV, FootColor, TailColor, LPDistance, LightDimensions); +} + + +//! renders the node. +void CVolumeLightSceneNode::render() +{ + if (!Mesh) + return; + + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + + driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial()); + driver->drawMeshBuffer(Mesh->getMeshBuffer(0)); +} + + +//! returns the axis aligned bounding box of this node +const core::aabbox3d& CVolumeLightSceneNode::getBoundingBox() const +{ + return Mesh->getBoundingBox(); +} + + +void CVolumeLightSceneNode::OnRegisterSceneNode() +{ + if (IsVisible) + { + SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); + } + ISceneNode::OnRegisterSceneNode(); +} + + +//! returns the material based on the zero based index i. To get the amount +//! of materials used by this scene node, use getMaterialCount(). +//! This function is needed for inserting the node into the scene hirachy on a +//! optimal position for minimizing renderstate changes, but can also be used +//! to directly modify the material of a scene node. +video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i) +{ + return Mesh->getMeshBuffer(i)->getMaterial(); +} + + +//! returns amount of materials used by this scene node. +u32 CVolumeLightSceneNode::getMaterialCount() const +{ + return 1; +} + + +void CVolumeLightSceneNode::setSubDivideU (const u32 inU) +{ + if (inU != SubdivideU) + { + SubdivideU = inU; + constructLight(); + } +} + + +void CVolumeLightSceneNode::setSubDivideV (const u32 inV) +{ + if (inV != SubdivideV) + { + SubdivideV = inV; + constructLight(); + } +} + + +void CVolumeLightSceneNode::setFootColor(const video::SColor inColor) +{ + if (inColor != FootColor) + { + FootColor = inColor; + constructLight(); + } +} + + +void CVolumeLightSceneNode::setTailColor(const video::SColor inColor) +{ + if (inColor != TailColor) + { + TailColor = inColor; + constructLight(); + } +} + + +//! Writes attributes of the scene node. +void CVolumeLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + ISceneNode::serializeAttributes(out, options); + + out->addFloat("lpDistance", LPDistance); + out->addInt("subDivideU", SubdivideU); + out->addInt("subDivideV", SubdivideV); + + out->addColor("footColor", FootColor); + out->addColor("tailColor", TailColor); + + out->addVector3d("lightDimension", LightDimensions); +} + + +//! Reads attributes of the scene node. +void CVolumeLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + LPDistance = in->getAttributeAsFloat("lpDistance"); + LPDistance = core::max_(LPDistance, 8.0f); + + SubdivideU = in->getAttributeAsInt("subDivideU"); + SubdivideU = core::max_(SubdivideU, 1u); + + SubdivideV = in->getAttributeAsInt("subDivideV"); + SubdivideV = core::max_(SubdivideV, 1u); + + FootColor = in->getAttributeAsColor("footColor"); + TailColor = in->getAttributeAsColor("tailColor"); + + LightDimensions = in->getAttributeAsVector3d("lightDimension"); + + constructLight(); + + ISceneNode::deserializeAttributes(in, options); +} + + +//! Creates a clone of this scene node and its children. +ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) +{ + if (!newParent) + newParent = Parent; + if (!newManager) + newManager = SceneManager; + + CVolumeLightSceneNode* nb = new CVolumeLightSceneNode(newParent, + newManager, ID, SubdivideU, SubdivideV, FootColor, TailColor, RelativeTranslation); + + nb->cloneMembers(this, newManager); + nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial(); + + if ( newParent ) + nb->drop(); + return nb; +} + + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.h new file mode 100644 index 0000000..7ee9e3c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CVolumeLightSceneNode.h @@ -0,0 +1,93 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// +// created by Dean Wadsworth aka Varmint Dec 31 2007 + +#ifndef __VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__ +#define __VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__ + +#include "IVolumeLightSceneNode.h" +#include "IMesh.h" + +namespace irr +{ +namespace scene +{ + class CVolumeLightSceneNode : public IVolumeLightSceneNode + { + public: + + //! constructor + CVolumeLightSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, + const u32 subdivU = 32, const u32 subdivV = 32, + const video::SColor foot = video::SColor(51, 0, 230, 180), + const video::SColor tail = video::SColor(0, 0, 0, 0), + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + virtual ~CVolumeLightSceneNode(); + + virtual void OnRegisterSceneNode(); + + //! renders the node. + virtual void render(); + + //! returns the axis aligned bounding box of this node + virtual const core::aabbox3d& getBoundingBox() const; + + //! returns the material based on the zero based index i. + virtual video::SMaterial& getMaterial(u32 i); + + //! returns amount of materials used by this scene node. + virtual u32 getMaterialCount() const; + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_VOLUME_LIGHT; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + + //! Creates a clone of this scene node and its children. + virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); + + virtual void setSubDivideU(const u32 inU); + virtual void setSubDivideV(const u32 inV); + + virtual u32 getSubDivideU() const { return SubdivideU; } + virtual u32 getSubDivideV() const { return SubdivideV; } + + virtual void setFootColor(const video::SColor inColor); + virtual void setTailColor(const video::SColor inColor); + + virtual video::SColor getFootColor() const { return FootColor; } + virtual video::SColor getTailColor() const { return TailColor; } + + private: + void constructLight(); + + IMesh* Mesh; + + f32 LPDistance; // Distance to hypothetical lightsource point -- affects fov angle + + u32 SubdivideU; // Number of subdivisions in U and V space. + u32 SubdivideV; // Controls the number of "slices" in the volume. + // NOTE : Total number of polygons = 2 + ((SubdivideU + 1) + (SubdivideV + 1)) * 2 + // Each slice being a quad plus the rectangular plane at the bottom. + + video::SColor FootColor; // Color at the source + video::SColor TailColor; // Color at the end. + + core::vector3df LightDimensions; // LightDimensions.Y Distance of shooting -- Length of beams + // LightDimensions.X and LightDimensions.Z determine the size/dimension of the plane + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp new file mode 100644 index 0000000..9945fc8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.cpp @@ -0,0 +1,263 @@ +// Copyright (C) 2002-2012 Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h +// Code contributed by skreamz + +#include "IrrCompileConfig.h" + +#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ + +#include "CWADReader.h" +#include "os.h" +#include "coreutil.h" + +namespace irr +{ +namespace io +{ + +//! Constructor +CArchiveLoaderWAD::CArchiveLoaderWAD( io::IFileSystem* fs) +: FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("CArchiveLoaderWAD"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +bool CArchiveLoaderWAD::isALoadableFileFormat(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "wad" ); +} + + +//! Creates an archive from the filename +/** \param file File handle to check. +\return Pointer to newly created archive, or 0 upon error. */ +IFileArchive* CArchiveLoaderWAD::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + archive = createArchive ( file, ignoreCase, ignorePaths ); + file->drop (); + } + + return archive; +} + +//! creates/loads an archive from the file. +//! \return Pointer to the created archive. Returns 0 if loading failed. +IFileArchive* CArchiveLoaderWAD::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + if ( file ) + { + file->seek ( 0 ); + archive = new CWADReader(file, ignoreCase, ignorePaths); + } + return archive; +} + + +//! Check if the file might be loaded by this class +/** Check might look into the file. +\param file File handle to check. +\return True if file seems to be loadable. */ +bool CArchiveLoaderWAD::isALoadableFileFormat(io::IReadFile* file) const +{ + SWADFileHeader header; + memset(&header, 0, sizeof(header)); + + file->read( &header.tag, 4 ); + + return !strncmp ( header.tag, "WAD2", 4 ) || !strncmp ( header.tag, "WAD3", 4 ); +} + +//! Check to see if the loader can create archives of this type. +bool CArchiveLoaderWAD::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const +{ + return fileType == EFAT_WAD; +} + +void createDir ( const c8 *full ); + + +/*! + WAD Reader +*/ +CWADReader::CWADReader(IReadFile* file, bool ignoreCase, bool ignorePaths) +: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file) +{ + #ifdef _DEBUG + setDebugName("CWADReader"); + #endif + + if (File) + { + File->grab(); + + Base = File->getFileName(); + Base.replace ( '\\', '/' ); + + // scan local headers + scanLocalHeader(); + + sort(); + } + +#if 0 + for ( u32 i = 0; i < FileList.size(); ++i ) + { + SWADFileEntry &e = FileList[i]; + char buf[128]; + snprintf ( buf, 128, "c:\\h2\\%s", e.wadFileName.c_str() ); + + createDir ( buf ); + FILE * f = fopen ( buf, "wb" ); + if ( 0 == f ) + continue; + + u8 * mem = new u8 [ e.header.disksize ]; + File->seek ( e.header.filepos ); + File->read ( mem, e.header.disksize ); + fwrite ( mem, e.header.disksize, 1, f ); + delete [] mem; + fclose ( f ); + } +#endif + +} + + +CWADReader::~CWADReader() +{ + if (File) + File->drop(); +} + + +//! return the id of the file Archive +const io::path& CWADReader::getArchiveName () const +{ + return Base; +} + +const IFileList* CWADReader::getFileList() const +{ + return this; +} + + +//! scans for a local header, returns false if there is no more local file header. +bool CWADReader::scanLocalHeader() +{ + SWADFileEntryOriginal entry; + SWADFileEntry save; + + memset(&Header, 0, sizeof(SWADFileHeader)); + File->read(&Header, sizeof(SWADFileHeader)); + + if ( 0 == strncmp ( Header.tag, "WAD2", 4 ) ) + WadType = WAD_FORMAT_QUAKE2; + else + if ( 0 == strncmp ( Header.tag, "WAD3", 4 ) ) + WadType = WAD_FORMAT_HALFLIFE; + else + WadType = WAD_FORMAT_UNKNOWN; + + if ( WadType == WAD_FORMAT_UNKNOWN ) + return false; + +#ifdef __BIG_ENDIAN__ + Header.numlumps = os::Byteswap::byteswap(Header.numlumps); + Header.infotableofs = os::Byteswap::byteswap(Header.infotableofs); +#endif + + File->seek ( Header.infotableofs ); + + c8 buf[16]; + for ( u32 i = 0; i < Header.numlumps; ++i ) + { + // read entry + File->read(&entry, sizeof ( SWADFileEntryOriginal )); + entry.name[ sizeof ( entry.name ) - 1 ] = 0; + + save.header = entry; + save.wadFileName = "/"; + save.wadFileName += entry.name; + + if ( WadType == WAD_FORMAT_HALFLIFE ) + { + // don't know about the types! i'm guessing + switch ( entry.type ) + { + case WAD_TYP_MIPTEX_HALFLIFE: + save.wadFileName += ".wal2"; + break; + default: + snprintf ( buf, 16, ".%02d", entry.type ); + save.wadFileName += buf; + break; + } + } + else + if ( WadType == WAD_FORMAT_QUAKE2 ) + { + switch ( entry.type ) + { + case WAD_TYP_MIPTEX: save.wadFileName += ".miptex"; break; + case WAD_TYP_SOUND: save.wadFileName += ".sound"; break; + case WAD_TYP_PALETTE: save.wadFileName += ".palette"; break; + case WAD_TYP_QTEX: save.wadFileName += ".qtex"; break; + case WAD_TYP_QPIC: save.wadFileName += ".qpic"; break; + case WAD_TYP_FONT: save.wadFileName += ".font"; break; + default: + snprintf ( buf, 16, ".%02d", entry.type ); + save.wadFileName += buf; + break; + } + } + + // add file to list + addItem(save.wadFileName,save.header.filepos, save.header.disksize, false ); + //FileInfo.push_back(save); + } + return true; +} + + +//! opens a file by file name +IReadFile* CWADReader::createAndOpenFile(const io::path& filename) +{ + s32 index = findFile(filename, false); + + if (index != -1) + return createAndOpenFile(index); + + return 0; +} + + +//! opens a file by index +IReadFile* CWADReader::createAndOpenFile(u32 index) +{ + if (index >= Files.size() ) + return 0; + + const SFileListEntry &entry = Files[index]; + return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size ); +} + + + +} // end namespace io +} // end namespace irr + + +#endif // __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.h new file mode 100644 index 0000000..2d51902 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWADReader.h @@ -0,0 +1,177 @@ +// Copyright (C) 2002-2012 Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_WAD_READER_H_INCLUDED__ +#define __C_WAD_READER_H_INCLUDED__ + +#include "IrrCompileConfig.h" +#ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ + +#include "IReferenceCounted.h" +#include "IReadFile.h" +#include "irrArray.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "CFileList.h" + + +namespace irr +{ +namespace io +{ + + enum eWADFileTypes + { + WAD_FORMAT_UNKNOWN = 0, + WAD_FORMAT_QUAKE2 = 1, + WAD_FORMAT_HALFLIFE = 2, + + WAD_CMP_NONE = 0, + WAD_CMP_LZSS = 1, + + WAD_TYP_NONE = 0, + WAD_TYP_LABEL = 1, + + WAD_TYP_LUMPY = 64, // 64 + grab command number + WAD_TYP_PALETTE = 64, + WAD_TYP_QTEX = 65, + WAD_TYP_QPIC = 66, + WAD_TYP_SOUND = 67, + WAD_TYP_MIPTEX = 68, + WAD_TYP_MIPTEX_HALFLIFE = 67, + WAD_TYP_FONT = 70, + }; + +// byte-align structures +#include "irrpack.h" + + struct SWADFileHeader + { + c8 tag[4]; // type of WAD format WAD2 = quake2, WAD3 = halflife + u32 numlumps; + u32 infotableofs; + } PACK_STRUCT; + + struct SWADFileEntryOriginal + { + u32 filepos; + u32 disksize; + u32 size; // uncompressed + u8 type; + u8 compression; + u8 pad[2]; + u8 name[16]; // must be null terminated + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + struct SWADFileEntry + { + io::path simpleFileName; + bool operator < (const SWADFileEntry& other) const + { + return simpleFileName < other.simpleFileName; + } + + io::path wadFileName; + SWADFileEntryOriginal header; + }; + + //! Archiveloader capable of loading WAD Archives + class CArchiveLoaderWAD : public IArchiveLoader + { + public: + + //! Constructor + CArchiveLoaderWAD(io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".zip") + virtual bool isALoadableFileFormat(const io::path& filename) const; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const; + + //! Creates an archive from the filename + /** \param file File handle to check. + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const; + + //! creates/loads an archive from the file. + //! \return Pointer to the created archive. Returns 0 if loading failed. + virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const; + + private: + io::IFileSystem* FileSystem; + }; + + + //! reads from WAD + class CWADReader : public IFileArchive, virtual CFileList + { + public: + + CWADReader(IReadFile* file, bool ignoreCase, bool ignorePaths); + virtual ~CWADReader(); + + // file archive methods + + //! return the id of the file Archive + virtual const io::path& getArchiveName() const; + + //! opens a file by file name + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! opens a file by index + virtual IReadFile* createAndOpenFile(u32 index); + + //! returns the list of files + virtual const IFileList* getFileList() const; + + //! get the class Type + virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_WAD; } + + + private: + + io::path Type; + + //! scans for a local header, returns false if there is no more local file header. + bool scanLocalHeader(); + + //! splits filename from zip file into useful filenames and paths + void extractFilename(SWADFileEntry* entry); + + + io::path Base; + io::path MountPoint; + + IReadFile* File; + + eWADFileTypes WadType; + SWADFileHeader Header; + + //core::array FileInfo; + + io::IFileSystem* FileSystem; + }; + +} // end namespace io +} // end namespace irr + +#endif + + +#endif // #ifdef __IRR_COMPILE_WITH_WAD_ARCHIVE_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.cpp new file mode 100644 index 0000000..12d20c2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.cpp @@ -0,0 +1,137 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CWaterSurfaceSceneNode.h" +#include "ISceneManager.h" +#include "IMeshManipulator.h" +#include "IMeshCache.h" +#include "S3DVertex.h" +#include "SMesh.h" +#include "os.h" + +namespace irr +{ +namespace scene +{ + +//! constructor +CWaterSurfaceSceneNode::CWaterSurfaceSceneNode(f32 waveHeight, f32 waveSpeed, f32 waveLength, + IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale) + : CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale), + WaveLength(waveLength), WaveSpeed(waveSpeed), WaveHeight(waveHeight), + OriginalMesh(0) +{ + #ifdef _DEBUG + setDebugName("CWaterSurfaceSceneNode"); + #endif + + setMesh(mesh); +} + + +//! destructor +CWaterSurfaceSceneNode::~CWaterSurfaceSceneNode() +{ + // Mesh is dropped in CMeshSceneNode destructor + if (OriginalMesh) + OriginalMesh->drop(); +} + + +//! frame +void CWaterSurfaceSceneNode::OnRegisterSceneNode() +{ + CMeshSceneNode::OnRegisterSceneNode(); +} + + +void CWaterSurfaceSceneNode::OnAnimate(u32 timeMs) +{ + if (Mesh && IsVisible) + { + const u32 meshBufferCount = Mesh->getMeshBufferCount(); + const f32 time = timeMs / WaveSpeed; + + for (u32 b=0; bgetMeshBuffer(b)->getVertexCount(); + + for (u32 i=0; igetMeshBuffer(b)->getPosition(i).Y = addWave( + OriginalMesh->getMeshBuffer(b)->getPosition(i), + time); + }// end for all mesh buffers + Mesh->setDirty(scene::EBT_VERTEX); + + SceneManager->getMeshManipulator()->recalculateNormals(Mesh); + } + CMeshSceneNode::OnAnimate(timeMs); +} + + +void CWaterSurfaceSceneNode::setMesh(IMesh* mesh) +{ + CMeshSceneNode::setMesh(mesh); + if (!mesh) + return; + if (OriginalMesh) + OriginalMesh->drop(); + IMesh* clone = SceneManager->getMeshManipulator()->createMeshCopy(mesh); + OriginalMesh = mesh; + Mesh = clone; + Mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX); +// Mesh->setHardwareMappingHint(scene::EHM_STREAM, scene::EBT_VERTEX); +} + + +//! Writes attributes of the scene node. +void CWaterSurfaceSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const +{ + out->addFloat("WaveLength", WaveLength); + out->addFloat("WaveSpeed", WaveSpeed); + out->addFloat("WaveHeight", WaveHeight); + + CMeshSceneNode::serializeAttributes(out, options); + // serialize original mesh + out->setAttribute("Mesh", SceneManager->getMeshCache()->getMeshName(OriginalMesh).getPath().c_str()); +} + + +//! Reads attributes of the scene node. +void CWaterSurfaceSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) +{ + WaveLength = in->getAttributeAsFloat("WaveLength"); + WaveSpeed = in->getAttributeAsFloat("WaveSpeed"); + WaveHeight = in->getAttributeAsFloat("WaveHeight"); + + if (Mesh) + { + Mesh->drop(); + Mesh = OriginalMesh; + OriginalMesh = 0; + } + // deserialize original mesh + CMeshSceneNode::deserializeAttributes(in, options); + + if (Mesh) + { + IMesh* clone = SceneManager->getMeshManipulator()->createMeshCopy(Mesh); + OriginalMesh = Mesh; + Mesh = clone; + } +} + + +f32 CWaterSurfaceSceneNode::addWave(const core::vector3df &source, f32 time) const +{ + return source.Y + + (sinf(((source.X/WaveLength) + time)) * WaveHeight) + + (cosf(((source.Z/WaveLength) + time)) * WaveHeight); +} + +} // end namespace scene +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.h new file mode 100644 index 0000000..f8ce2d0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWaterSurfaceSceneNode.h @@ -0,0 +1,61 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_WATER_SURFACE_SCENE_NODE_H_INCLUDED__ +#define __C_WATER_SURFACE_SCENE_NODE_H_INCLUDED__ + +#include "CMeshSceneNode.h" + +namespace irr +{ +namespace scene +{ + + class CWaterSurfaceSceneNode : public CMeshSceneNode + { + public: + + //! constructor + CWaterSurfaceSceneNode(f32 waveHeight, f32 waveSpeed, f32 waveLength, + IMesh* mesh, ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0,0,0), + const core::vector3df& rotation = core::vector3df(0,0,0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + //! destructor + virtual ~CWaterSurfaceSceneNode(); + + //! frame registration + virtual void OnRegisterSceneNode(); + + //! animated update + virtual void OnAnimate(u32 timeMs); + + //! Update mesh + virtual void setMesh(IMesh* mesh); + + //! Returns type of the scene node + virtual ESCENE_NODE_TYPE getType() const { return ESNT_WATER_SURFACE; } + + //! Writes attributes of the scene node. + virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; + + //! Reads attributes of the scene node. + virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); + + private: + + inline f32 addWave(const core::vector3df &source, f32 time) const; + + f32 WaveLength; + f32 WaveSpeed; + f32 WaveHeight; + IMesh* OriginalMesh; + }; + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.cpp new file mode 100644 index 0000000..f72ef38 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.cpp @@ -0,0 +1,123 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CWriteFile.h" +#include + +namespace irr +{ +namespace io +{ + + +CWriteFile::CWriteFile(const io::path& fileName, bool append) +: FileSize(0) +{ + #ifdef _DEBUG + setDebugName("CWriteFile"); + #endif + + Filename = fileName; + openFile(append); +} + + + +CWriteFile::~CWriteFile() +{ + if (File) + fclose(File); +} + + + +//! returns if file is open +inline bool CWriteFile::isOpen() const +{ + return File != 0; +} + + + +//! returns how much was read +s32 CWriteFile::write(const void* buffer, u32 sizeToWrite) +{ + if (!isOpen()) + return 0; + + return (s32)fwrite(buffer, 1, sizeToWrite, File); +} + + + +//! changes position in file, returns true if successful +//! if relativeMovement==true, the pos is changed relative to current pos, +//! otherwise from begin of file +bool CWriteFile::seek(long finalPos, bool relativeMovement) +{ + if (!isOpen()) + return false; + + return fseek(File, finalPos, relativeMovement ? SEEK_CUR : SEEK_SET) == 0; +} + + + +//! returns where in the file we are. +long CWriteFile::getPos() const +{ + return ftell(File); +} + + + +//! opens the file +void CWriteFile::openFile(bool append) +{ + if (Filename.size() == 0) + { + File = 0; + return; + } + +#if defined(_IRR_WCHAR_FILESYSTEM) + File = _wfopen(Filename.c_str(), append ? L"ab" : L"wb"); +#else + File = fopen(Filename.c_str(), append ? "ab" : "wb"); +#endif + + if (File) + { + // get FileSize + + fseek(File, 0, SEEK_END); + FileSize = ftell(File); + fseek(File, 0, SEEK_SET); + } +} + + + +//! returns name of file +const io::path& CWriteFile::getFileName() const +{ + return Filename; +} + + + +IWriteFile* createWriteFile(const io::path& fileName, bool append) +{ + CWriteFile* file = new CWriteFile(fileName, append); + if (file->isOpen()) + return file; + + file->drop(); + return 0; +} + + +} // end namespace io +} // end namespace irr + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.h new file mode 100644 index 0000000..b3203ce --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CWriteFile.h @@ -0,0 +1,58 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_WRITE_FILE_H_INCLUDED__ +#define __C_WRITE_FILE_H_INCLUDED__ + +#include +#include "IWriteFile.h" +#include "irrString.h" + +namespace irr +{ + +namespace io +{ + + /*! + Class for writing a real file to disk. + */ + class CWriteFile : public IWriteFile + { + public: + + CWriteFile(const io::path& fileName, bool append); + + virtual ~CWriteFile(); + + //! Reads an amount of bytes from the file. + virtual s32 write(const void* buffer, u32 sizeToWrite); + + //! Changes position in file, returns true if successful. + virtual bool seek(long finalPos, bool relativeMovement = false); + + //! Returns the current position in the file. + virtual long getPos() const; + + //! Returns name of file. + virtual const io::path& getFileName() const; + + //! returns if file is open + bool isOpen() const; + + private: + + //! opens the file + void openFile(bool append); + + io::path Filename; + FILE* File; + long FileSize; + }; + +} // end namespace io +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.cpp new file mode 100644 index 0000000..bb42800 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CXMLReaderImpl.h" +#include "CXMLReader.h" +#include "IReadFile.h" + +namespace irr +{ +namespace io +{ + //! Irrlicht implementation of the file read callback for the xml parser + class CIrrXMLFileReadCallBack : public IFileReadCallBack + { + public: + + //! construct from FILE pointer + CIrrXMLFileReadCallBack(IReadFile* file) + : ReadFile(file) + { + ReadFile->grab(); + } + + //! destructor + virtual ~CIrrXMLFileReadCallBack() + { + ReadFile->drop(); + } + + //! Reads an amount of bytes from the file. + virtual int read(void* buffer, int sizeToRead) + { + return ReadFile->read(buffer, sizeToRead); + } + + //! Returns size of file in bytes + virtual long getSize() const + { + return ReadFile->getSize(); + } + + private: + + IReadFile* ReadFile; + }; // end class CMyXMLFileReadCallBack + + + // now create an implementation for IXMLReader using irrXML. + + //! Creates an instance of a wide character xml parser. + IXMLReader* createIXMLReader(IReadFile* file) + { + if (!file) + return 0; + + return new CXMLReaderImpl(new CIrrXMLFileReadCallBack(file)); + } + + //! Creates an instance of an UFT-8 or ASCII character xml parser. + IXMLReaderUTF8* createIXMLReaderUTF8(IReadFile* file) + { + if (!file) + return 0; + + return new CXMLReaderImpl(new CIrrXMLFileReadCallBack(file)); + } + +} // end namespace +} // end namespace diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.h new file mode 100644 index 0000000..f2764f0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReader.h @@ -0,0 +1,26 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_XML_READER_H_INCLUDED__ +#define __C_XML_READER_H_INCLUDED__ + +#include "IXMLReader.h" + +namespace irr +{ +namespace io +{ + class IReadFile; + + //! creates an IXMLReader + IXMLReader* createIXMLReader(IReadFile* file); + + //! creates an IXMLReader + IXMLReaderUTF8* createIXMLReaderUTF8(IReadFile* file); + +} // end namespace irr +} // end namespace io + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReaderImpl.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReaderImpl.h new file mode 100644 index 0000000..cfd89b0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLReaderImpl.h @@ -0,0 +1,821 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine" and the "irrXML" project. +// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h + +#ifndef __ICXML_READER_IMPL_H_INCLUDED__ +#define __ICXML_READER_IMPL_H_INCLUDED__ + +#include "irrXML.h" +#include "irrString.h" +#include "irrArray.h" +#include "fast_atof.h" + +#ifdef _DEBUG +#define IRR_DEBUGPRINT(x) printf((x)); +#else // _DEBUG +#define IRR_DEBUGPRINT(x) +#endif // _DEBUG + + +namespace irr +{ +namespace io +{ + + +//! implementation of the IrrXMLReader +template +class CXMLReaderImpl : public IIrrXMLReader +{ +public: + + //! Constructor + CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true) + : IgnoreWhitespaceText(true), TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE), + SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII), IsEmptyElement(false) + { + if (!callback) + return; + + storeTargetFormat(); + + // read whole xml file + + readFile(callback); + + // clean up + + if (deleteCallBack) + delete callback; + + // create list with special characters + + createSpecialCharacterList(); + + // set pointer to text begin + P = TextBegin; + } + + + //! Destructor + virtual ~CXMLReaderImpl() + { + delete [] TextData; + } + + + //! Reads forward to the next xml node. + //! \return Returns false, if there was no further node. + virtual bool read() + { + // if not end reached, parse the node + if (P && ((unsigned int)(P - TextBegin) < TextSize - 1) && (*P != 0)) + { + return parseCurrentNode(); + } + + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return false; + } + + + //! Returns the type of the current XML node. + virtual EXML_NODE getNodeType() const + { + return CurrentNodeType; + } + + + //! Returns attribute count of the current XML node. + virtual unsigned int getAttributeCount() const + { + return Attributes.size(); + } + + + //! Returns name of an attribute. + virtual const char_type* getAttributeName(int idx) const + { + if ((u32)idx >= Attributes.size()) + return 0; + + return Attributes[idx].Name.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(int idx) const + { + if ((unsigned int)idx >= Attributes.size()) + return 0; + + return Attributes[idx].Value.c_str(); + } + + + //! Returns the value of an attribute. + virtual const char_type* getAttributeValue(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + return attr->Value.c_str(); + } + + + //! Returns the value of an attribute + virtual const char_type* getAttributeValueSafe(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return EmptyString.c_str(); + + return attr->Value.c_str(); + } + + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + core::stringc c(attr->Value.c_str()); + return core::strtol10(c.c_str()); + } + + + //! Returns the value of an attribute as integer. + int getAttributeValueAsInt(int idx) const + { + const char_type* attrvalue = getAttributeValue(idx); + if (!attrvalue) + return 0; + + core::stringc c(attrvalue); + return core::strtol10(c.c_str()); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(const char_type* name) const + { + const SAttribute* attr = getAttributeByName(name); + if (!attr) + return 0; + + core::stringc c = attr->Value.c_str(); + return core::fast_atof(c.c_str()); + } + + + //! Returns the value of an attribute as float. + float getAttributeValueAsFloat(int idx) const + { + const char_type* attrvalue = getAttributeValue(idx); + if (!attrvalue) + return 0; + + core::stringc c = attrvalue; + return core::fast_atof(c.c_str()); + } + + + //! Returns the name of the current node. + virtual const char_type* getNodeName() const + { + return NodeName.c_str(); + } + + + //! Returns data of the current node. + virtual const char_type* getNodeData() const + { + return NodeName.c_str(); + } + + + //! Returns if an element is an empty element, like + virtual bool isEmptyElement() const + { + return IsEmptyElement; + } + + //! Returns format of the source xml file. + virtual ETEXT_FORMAT getSourceFormat() const + { + return SourceFormat; + } + + //! Returns format of the strings returned by the parser. + virtual ETEXT_FORMAT getParserFormat() const + { + return TargetFormat; + } + +private: + + // Reads the current xml node + // return false if no further node is found + bool parseCurrentNode() + { + char_type* start = P; + + // more forward until '<' found + while(*P != L'<' && *P) + ++P; + + // not a node, so return false + if (!*P) + return false; + + if (P - start > 0) + { + // we found some text, store it + if (setText(start, P)) + return true; + } + + ++P; + + // based on current token, parse and report next element + switch(*P) + { + case L'/': + parseClosingXMLElement(); + break; + case L'?': + ignoreDefinition(); + break; + case L'!': + if (!parseCDATA()) + parseComment(); + break; + default: + parseOpeningXMLElement(); + break; + } + return true; + } + + + //! sets the state that text was found. Returns true if set should be set + bool setText(char_type* start, char_type* end) + { + // By default xml preserves all whitespace. But Irrlicht dropped some whitespace by default + // in the past which did lead to OS dependent behavior. We just ignore all whitespace for now + // as it's the closest to fixing behavior without breaking downward compatibility too much. + if ( IgnoreWhitespaceText ) + { + char_type* p = start; + for(; p != end; ++p) + if (!isWhiteSpace(*p)) + break; + + if (p == end) + return false; + } + + // set current text to the parsed text, and replace xml special characters + core::string s(start, (int)(end - start)); + NodeName = replaceSpecialCharacters(s); + + // current XML node type is text + CurrentNodeType = EXN_TEXT; + + return true; + } + + + + //! ignores an xml definition like + void ignoreDefinition() + { + CurrentNodeType = EXN_UNKNOWN; + + // move until end marked with '>' reached + while(*P != L'>') + ++P; + + ++P; + } + + + //! parses a comment + void parseComment() + { + CurrentNodeType = EXN_COMMENT; + P += 1; + + char_type *pCommentBegin = P; + + int count = 1; + + // move until end of comment reached + while(count) + { + if (*P == L'>') + --count; + else + if (*P == L'<') + ++count; + + ++P; + } + + P -= 3; + NodeName = core::string(pCommentBegin+2, (int)(P - pCommentBegin-2)); + P += 3; + } + + + //! parses an opening xml element and reads attributes + void parseOpeningXMLElement() + { + CurrentNodeType = EXN_ELEMENT; + IsEmptyElement = false; + Attributes.clear(); + + // find name + const char_type* startName = P; + + // find end of element + while(*P != L'>' && !isWhiteSpace(*P)) + ++P; + + const char_type* endName = P; + + // find Attributes + while(*P != L'>') + { + if (isWhiteSpace(*P)) + ++P; + else + { + if (*P != L'/') + { + // we've got an attribute + + // read the attribute names + const char_type* attributeNameBegin = P; + + while(!isWhiteSpace(*P) && *P != L'=') + ++P; + + const char_type* attributeNameEnd = P; + ++P; + + // read the attribute value + // check for quotes and single quotes, thx to murphy + while( (*P != L'\"') && (*P != L'\'') && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type attributeQuoteChar = *P; + + ++P; + const char_type* attributeValueBegin = P; + + while(*P != attributeQuoteChar && *P) + ++P; + + if (!*P) // malformatted xml file + return; + + const char_type* attributeValueEnd = P; + ++P; + + SAttribute attr; + attr.Name = core::string(attributeNameBegin, + (int)(attributeNameEnd - attributeNameBegin)); + + core::string s(attributeValueBegin, + (int)(attributeValueEnd - attributeValueBegin)); + + attr.Value = replaceSpecialCharacters(s); + Attributes.push_back(attr); + } + else + { + // tag is closed directly + ++P; + IsEmptyElement = true; + break; + } + } + } + + // check if this tag is closing directly + if (endName > startName && *(endName-1) == L'/') + { + // directly closing tag + IsEmptyElement = true; + endName--; + } + + NodeName = core::string(startName, (int)(endName - startName)); + + ++P; + } + + + //! parses an closing xml tag + void parseClosingXMLElement() + { + CurrentNodeType = EXN_ELEMENT_END; + IsEmptyElement = false; + Attributes.clear(); + + ++P; + const char_type* pBeginClose = P; + + while(*P != L'>') + ++P; + + NodeName = core::string(pBeginClose, (int)(P - pBeginClose)); + ++P; + } + + //! parses a possible CDATA section, returns false if begin was not a CDATA section + bool parseCDATA() + { + if (*(P+1) != L'[') + return false; + + CurrentNodeType = EXN_CDATA; + + // skip '' && + (*(P-1) == L']') && + (*(P-2) == L']')) + { + cDataEnd = P - 2; + } + + ++P; + } + + if ( cDataEnd ) + NodeName = core::string(cDataBegin, (int)(cDataEnd - cDataBegin)); + else + NodeName = ""; + + return true; + } + + + // structure for storing attribute-name pairs + struct SAttribute + { + core::string Name; + core::string Value; + }; + + // finds a current attribute by name, returns 0 if not found + const SAttribute* getAttributeByName(const char_type* name) const + { + if (!name) + return 0; + + core::string n = name; + + for (int i=0; i<(int)Attributes.size(); ++i) + if (Attributes[i].Name == n) + return &Attributes[i]; + + return 0; + } + + // replaces xml special characters in a string and creates a new one + core::string replaceSpecialCharacters( + core::string& origstr) + { + int pos = origstr.findFirst(L'&'); + int oldPos = 0; + + if (pos == -1) + return origstr; + + core::string newstr; + + while(pos != -1 && pos < (int)origstr.size()-2) + { + // check if it is one of the special characters + + int specialChar = -1; + for (int i=0; i<(int)SpecialCharacters.size(); ++i) + { + const char_type* p = &origstr.c_str()[pos]+1; + + if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1)) + { + specialChar = i; + break; + } + } + + if (specialChar != -1) + { + newstr.append(origstr.subString(oldPos, pos - oldPos)); + newstr.append(SpecialCharacters[specialChar][0]); + pos += SpecialCharacters[specialChar].size(); + } + else + { + newstr.append(origstr.subString(oldPos, pos - oldPos + 1)); + pos += 1; + } + + // find next & + oldPos = pos; + pos = origstr.findNext(L'&', pos); + } + + if (oldPos < (int)origstr.size()-1) + newstr.append(origstr.subString(oldPos, origstr.size()-oldPos)); + + return newstr; + } + + + + //! reads the xml file and converts it into the wanted character format. + bool readFile(IFileReadCallBack* callback) + { + long size = callback->getSize(); + if (size<0) + return false; + size += 4; // We need four terminating 0's at the end. + // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4. + + char* data8 = new char[size]; + + if (!callback->read(data8, size-4)) + { + delete [] data8; + return false; + } + + // add zeros at end + + memset(data8+size-4, 0, 4); + + char16* data16 = reinterpret_cast(data8); + char32* data32 = reinterpret_cast(data8); + + // now we need to convert the data to the desired target format + // based on the byte order mark. + + const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF; + const u16 UTF16_BE = 0xFFFE; + const u16 UTF16_LE = 0xFEFF; + const u32 UTF32_BE = 0xFFFE0000; + const u32 UTF32_LE = 0x0000FEFF; + + // check source for all utf versions and convert to target data format + + if (size >= 4 && data32[0] + == static_cast(UTF32_BE)) + { + // UTF-32, big endian + SourceFormat = ETF_UTF32_BE; + convertTextData(data32+1, data8, (size/4)-1); // data32+1 because we need to skip the header + } + else + if (size >= 4 && data32[0] == static_cast(UTF32_LE)) + { + // UTF-32, little endian + SourceFormat = ETF_UTF32_LE; + convertTextData(data32+1, data8, (size/4)-1); // data32+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_BE) + { + // UTF-16, big endian + SourceFormat = ETF_UTF16_BE; + convertTextData(data16+1, data8, (size/2)-1); // data16+1 because we need to skip the header + } + else + if (size >= 2 && data16[0] == UTF16_LE) + { + // UTF-16, little endian + SourceFormat = ETF_UTF16_LE; + convertTextData(data16+1, data8, (size/2)-1); // data16+1 because we need to skip the header + } + else + if (size >= 3 && memcmp(data8,UTF8,3)==0) + { + // UTF-8 + SourceFormat = ETF_UTF8; + convertTextData(data8+3, data8, size-3); // data8+3 because we need to skip the header + } + else + { + // ASCII + SourceFormat = ETF_ASCII; + convertTextData(data8, data8, size); + } + + return true; + } + + + //! converts the text file into the desired format. + /** \param source: begin of the text (without byte order mark) + \param pointerToStore: pointer to text data block which can be + stored or deleted based on the nesessary conversion. + \param sizeWithoutHeader: Text size in characters without header + */ + template + void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader) + { + // convert little to big endian if necessary + if (sizeof(src_char_type) > 1 && + isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat)) + convertToLittleEndian(source); + + // check if conversion is necessary: + if (sizeof(src_char_type) == sizeof(char_type)) + { + // no need to convert + TextBegin = (char_type*)source; + TextData = (char_type*)pointerToStore; + TextSize = sizeWithoutHeader; + } + else + { + // convert source into target data format. + // TODO: implement a real conversion. This one just + // copies bytes. This is a problem when there are + // unicode symbols using more than one character. + + TextData = new char_type[sizeWithoutHeader]; + + if ( sizeof(src_char_type) == 1 ) + { + // we have to cast away negative numbers or results might add the sign instead of just doing a copy + for (int i=0; i(static_cast(source[i])); + } + } + else + { + for (int i=0; i(source[i]); + } + TextBegin = TextData; + TextSize = sizeWithoutHeader; + + // delete original data because no longer needed + delete [] pointerToStore; + } + } + + //! converts whole text buffer to little endian + template + void convertToLittleEndian(src_char_type* t) + { + if (sizeof(src_char_type) == 4) + { + // 32 bit + + while(*t) + { + *t = ((*t & 0xff000000) >> 24) | + ((*t & 0x00ff0000) >> 8) | + ((*t & 0x0000ff00) << 8) | + ((*t & 0x000000ff) << 24); + ++t; + } + } + else + { + // 16 bit + + while(*t) + { + *t = (*t >> 8) | (*t << 8); + ++t; + } + } + } + + //! returns if a format is little endian + inline bool isLittleEndian(ETEXT_FORMAT f) + { + return f == ETF_ASCII || + f == ETF_UTF8 || + f == ETF_UTF16_LE || + f == ETF_UTF32_LE; + } + + + //! returns true if a character is whitespace + inline bool isWhiteSpace(char_type c) + { + return (c==' ' || c=='\t' || c=='\n' || c=='\r'); + } + + + //! generates a list with xml special characters + void createSpecialCharacterList() + { + // list of strings containing special symbols, + // the first character is the special character, + // the following is the symbol string without trailing &. + + SpecialCharacters.push_back("&"); + SpecialCharacters.push_back("gt;"); + SpecialCharacters.push_back("\"quot;"); + SpecialCharacters.push_back("'apos;"); + + } + + + //! compares the first n characters of the strings + bool equalsn(const char_type* str1, const char_type* str2, int len) + { + int i; + for(i=0; str1[i] && str2[i] && i < len; ++i) + if (str1[i] != str2[i]) + return false; + + // if one (or both) of the strings was smaller then they + // are only equal if they have the same lenght + return (i == len) || (str1[i] == 0 && str2[i] == 0); + } + + + //! stores the target text format + void storeTargetFormat() + { + // get target format. We could have done this using template specialization, + // but VisualStudio 6 don't like it and we want to support it. + + switch(sizeof(char_type)) + { + case 1: + TargetFormat = ETF_UTF8; + break; + case 2: + TargetFormat = ETF_UTF16_LE; + break; + case 4: + TargetFormat = ETF_UTF32_LE; + break; + default: + TargetFormat = ETF_ASCII; // should never happen. + } + } + + + // instance variables: + bool IgnoreWhitespaceText; // do not return EXN_TEXT nodes for pure whitespace + char_type* TextData; // data block of the text file + char_type* P; // current point in text to parse + char_type* TextBegin; // start of text to parse + unsigned int TextSize; // size of text to parse in characters, not bytes + + EXML_NODE CurrentNodeType; // type of the currently parsed node + ETEXT_FORMAT SourceFormat; // source format of the xml file + ETEXT_FORMAT TargetFormat; // output format of this parser + + core::string NodeName; // name of the node currently in - also used for text + core::string EmptyString; // empty string to be returned by getSafe() methods + + bool IsEmptyElement; // is the currently parsed node empty? + + core::array< core::string > SpecialCharacters; // see createSpecialCharacterList() + + core::array Attributes; // attributes of current element + +}; // end CXMLReaderImpl + + +} // end namespace +} // end namespace + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.cpp new file mode 100644 index 0000000..cc294c5 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.cpp @@ -0,0 +1,257 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CXMLWriter.h" +#include +#include "irrString.h" +#include "IrrCompileConfig.h" + +namespace irr +{ +namespace io +{ + + +//! Constructor +CXMLWriter::CXMLWriter(IWriteFile* file) +: File(file), Tabs(0), TextWrittenLast(false) +{ + #ifdef _DEBUG + setDebugName("CXMLWriter"); + #endif + + if (File) + File->grab(); +} + + + +//! Destructor +CXMLWriter::~CXMLWriter() +{ + if (File) + File->drop(); +} + + + +//! Writes a xml 1.0 header like +void CXMLWriter::writeXMLHeader() +{ + if (!File) + return; + + if (sizeof(wchar_t)==2) + { + const u16 h = 0xFEFF; + File->write(&h, 2); + } + else + { + const u32 h = 0x0000FEFF; + File->write(&h, sizeof(wchar_t)); + } + + const wchar_t* const p = L""; + File->write(p, wcslen(p)*sizeof(wchar_t)); + + writeLineBreak(); + TextWrittenLast = false; +} + + + +//! Writes an xml element with maximal 5 attributes +void CXMLWriter::writeElement(const wchar_t* name, bool empty, + const wchar_t* attr1Name, const wchar_t* attr1Value, + const wchar_t* attr2Name, const wchar_t* attr2Value, + const wchar_t* attr3Name, const wchar_t* attr3Value, + const wchar_t* attr4Name, const wchar_t* attr4Value, + const wchar_t* attr5Name, const wchar_t* attr5Value) +{ + if (!File || !name) + return; + + if (Tabs > 0) + { + for (int i=0; iwrite(L"\t", sizeof(wchar_t)); + } + + // write name + + File->write(L"<", sizeof(wchar_t)); + File->write(name, wcslen(name)*sizeof(wchar_t)); + + // write attributes + + writeAttribute(attr1Name, attr1Value); + writeAttribute(attr2Name, attr2Value); + writeAttribute(attr3Name, attr3Value); + writeAttribute(attr4Name, attr4Value); + writeAttribute(attr5Name, attr5Value); + + // write closing tag + if (empty) + File->write(L" />", 3*sizeof(wchar_t)); + else + { + File->write(L">", sizeof(wchar_t)); + ++Tabs; + } + + TextWrittenLast = false; +} + +//! Writes an xml element with any number of attributes +void CXMLWriter::writeElement(const wchar_t* name, bool empty, + core::array &names, + core::array &values) +{ + if (!File || !name) + return; + + if (Tabs > 0) + { + for (int i=0; iwrite(L"\t", sizeof(wchar_t)); + } + + // write name + + File->write(L"<", sizeof(wchar_t)); + File->write(name, wcslen(name)*sizeof(wchar_t)); + + // write attributes + u32 i=0; + for (; i < names.size() && i < values.size(); ++i) + writeAttribute(names[i].c_str(), values[i].c_str()); + + // write closing tag + if (empty) + File->write(L" />", 3*sizeof(wchar_t)); + else + { + File->write(L">", sizeof(wchar_t)); + ++Tabs; + } + + TextWrittenLast = false; +} + + +void CXMLWriter::writeAttribute(const wchar_t* name, const wchar_t* value) +{ + if (!name || !value) + return; + + File->write(L" ", sizeof(wchar_t)); + File->write(name, wcslen(name)*sizeof(wchar_t)); + File->write(L"=\"", 2*sizeof(wchar_t)); + writeText(value); + File->write(L"\"", sizeof(wchar_t)); +} + + +//! Writes a comment into the xml file +void CXMLWriter::writeComment(const wchar_t* comment) +{ + if (!File || !comment) + return; + + File->write(L"", 3*sizeof(wchar_t)); +} + + +//! Writes the closing tag for an element. Like +void CXMLWriter::writeClosingTag(const wchar_t* name) +{ + if (!File || !name) + return; + + --Tabs; + + if (Tabs > 0 && !TextWrittenLast) + { + for (int i=0; iwrite(L"\t", sizeof(wchar_t)); + } + + File->write(L"write(name, wcslen(name)*sizeof(wchar_t)); + File->write(L">", sizeof(wchar_t)); + TextWrittenLast = false; +} + + + +const CXMLWriter::XMLSpecialCharacters XMLWSChar[] = +{ + { L'&', L"&" }, + { L'<', L"<" }, + { L'>', L">" }, + { L'"', L""" }, + { L'\0', 0 } +}; + + +//! Writes a text into the file. All occurrences of special characters like +//! & (&), < (<), > (>), and " (") are automaticly replaced. +void CXMLWriter::writeText(const wchar_t* text) +{ + if (!File || !text) + return; + + // TODO: we have to get rid of that reserve call as well as it slows down xml-writing seriously. + // Making a member-variable would work, but a lot of memory would stay around after writing. + // So the correct solution is probably using fixed block here and always write when that is full. + core::stringw s; + s.reserve(wcslen(text)+1); + const wchar_t* p = text; + + while(*p) + { + // check if it is matching + bool found = false; + for (s32 i=0; XMLWSChar[i].Character != '\0'; ++i) + if (*p == XMLWSChar[i].Character) + { + s.append(XMLWSChar[i].Symbol); + found = true; + break; + } + + if (!found) + s.append(*p); + ++p; + } + + // write new string + File->write(s.c_str(), s.size()*sizeof(wchar_t)); + TextWrittenLast = true; +} + + +//! Writes a line break +void CXMLWriter::writeLineBreak() +{ + if (!File) + return; + +#if defined(_IRR_OSX_PLATFORM_) + File->write(L"\r", sizeof(wchar_t)); +#elif defined(_IRR_WINDOWS_API_) + File->write(L"\r\n", 2*sizeof(wchar_t)); +#else + File->write(L"\n", sizeof(wchar_t)); +#endif + +} + + +} // end namespace irr +} // end namespace io + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.h new file mode 100644 index 0000000..9a69e71 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMLWriter.h @@ -0,0 +1,76 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_XML_WRITER_H_INCLUDED__ +#define __C_XML_WRITER_H_INCLUDED__ + +#include +#include "IXMLWriter.h" +#include "IWriteFile.h" + +namespace irr +{ +namespace io +{ + + //! Interface providing methods for making it easier to write XML files. + class CXMLWriter : public IXMLWriter + { + public: + + //! Constructor + CXMLWriter(IWriteFile* file); + + //! Destructor + virtual ~CXMLWriter(); + + //! Writes a xml 1.0 header like + virtual void writeXMLHeader(); + + //! Writes an xml element with maximal 5 attributes + virtual void writeElement(const wchar_t* name, bool empty=false, + const wchar_t* attr1Name = 0, const wchar_t* attr1Value = 0, + const wchar_t* attr2Name = 0, const wchar_t* attr2Value = 0, + const wchar_t* attr3Name = 0, const wchar_t* attr3Value = 0, + const wchar_t* attr4Name = 0, const wchar_t* attr4Value = 0, + const wchar_t* attr5Name = 0, const wchar_t* attr5Value = 0); + + //! Writes an xml element with any number of attributes + virtual void writeElement(const wchar_t* name, bool empty, + core::array &names, core::array &values); + + //! Writes a comment into the xml file + virtual void writeComment(const wchar_t* comment); + + //! Writes the closing tag for an element. Like + virtual void writeClosingTag(const wchar_t* name); + + //! Writes a text into the file. All occurrences of special characters like + //! & (&), < (<), > (>), and " (") are automaticly replaced. + virtual void writeText(const wchar_t* text); + + //! Writes a line break + virtual void writeLineBreak(); + + struct XMLSpecialCharacters + { + wchar_t Character; + const wchar_t* Symbol; + }; + + private: + + void writeAttribute(const wchar_t* att, const wchar_t* name); + + IWriteFile* File; + s32 Tabs; + + bool TextWrittenLast; + }; + +} // end namespace irr +} // end namespace io + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.cpp new file mode 100644 index 0000000..0c4922a --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.cpp @@ -0,0 +1,2423 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_X_LOADER_ + +#include "CXMeshFileLoader.h" +#include "os.h" + +#include "fast_atof.h" +#include "coreutil.h" +#include "ISceneManager.h" +#include "IVideoDriver.h" +#include "IFileSystem.h" +#include "IReadFile.h" + +#ifdef _DEBUG +#define _XREADER_DEBUG +#endif +//#define BETTER_MESHBUFFER_SPLITTING_FOR_X + +namespace irr +{ +namespace scene +{ + +//! Constructor +CXMeshFileLoader::CXMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs) +: SceneManager(smgr), FileSystem(fs), AllJoints(0), AnimatedMesh(0), + Buffer(0), P(0), End(0), BinaryNumCount(0), Line(0), + CurFrame(0), MajorVersion(0), MinorVersion(0), BinaryFormat(false), FloatSize(0) +{ + #ifdef _DEBUG + setDebugName("CXMeshFileLoader"); + #endif +} + + +//! returns true if the file maybe is able to be loaded by this class +//! based on the file extension (e.g. ".bsp") +bool CXMeshFileLoader::isALoadableFileExtension(const io::path& filename) const +{ + return core::hasFileExtension ( filename, "x" ); +} + + +//! creates/loads an animated mesh from the file. +//! \return Pointer to the created mesh. Returns 0 if loading failed. +//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). +//! See IReferenceCounted::drop() for more information. +IAnimatedMesh* CXMeshFileLoader::createMesh(io::IReadFile* f) +{ + if (!f) + return 0; + +#ifdef _XREADER_DEBUG + u32 time = os::Timer::getRealTime(); +#endif + + AnimatedMesh = new CSkinnedMesh(); + + if (load(f)) + { + AnimatedMesh->finalize(); + } + else + { + AnimatedMesh->drop(); + AnimatedMesh = 0; + } +#ifdef _XREADER_DEBUG + time = os::Timer::getRealTime() - time; + core::stringc tmpString = "Time to load "; + tmpString += BinaryFormat ? "binary" : "ascii"; + tmpString += " X file: "; + tmpString += time; + tmpString += "ms"; + os::Printer::log(tmpString.c_str()); +#endif + //Clear up + + MajorVersion=0; + MinorVersion=0; + BinaryFormat=0; + BinaryNumCount=0; + FloatSize=0; + P=0; + End=0; + CurFrame=0; + TemplateMaterials.clear(); + + delete [] Buffer; + Buffer = 0; + + for (u32 i=0; iMaterials.size()) + { + mesh->Materials.push_back(video::SMaterial()); + mesh->Materials[0].DiffuseColor.set(0xff777777); + mesh->Materials[0].Shininess=0.f; + mesh->Materials[0].SpecularColor.set(0xff777777); + mesh->Materials[0].EmissiveColor.set(0xff000000); + } + + u32 i; + + mesh->Buffers.reallocate(mesh->Materials.size()); +#ifndef BETTER_MESHBUFFER_SPLITTING_FOR_X + const u32 bufferOffset = AnimatedMesh->getMeshBufferCount(); +#endif + for (i=0; iMaterials.size(); ++i) + { + mesh->Buffers.push_back( AnimatedMesh->addMeshBuffer() ); + mesh->Buffers.getLast()->Material = mesh->Materials[i]; + + if (!mesh->HasSkinning) + { + //Set up rigid animation + if (mesh->AttachedJointID!=-1) + { + AnimatedMesh->getAllJoints()[mesh->AttachedJointID]->AttachedMeshes.push_back( AnimatedMesh->getMeshBuffers().size()-1 ); + } + } + } + + if (!mesh->FaceMaterialIndices.size()) + { + mesh->FaceMaterialIndices.set_used(mesh->Indices.size() / 3); + for (i=0; iFaceMaterialIndices.size(); ++i) + mesh->FaceMaterialIndices[i]=0; + } + + if (!mesh->HasVertexColors) + { + for (u32 j=0;jFaceMaterialIndices.size();++j) + { + for (u32 id=j*3+0;id<=j*3+2;++id) + { + mesh->Vertices[ mesh->Indices[id] ].Color = mesh->Buffers[mesh->FaceMaterialIndices[j]]->Material.DiffuseColor; + } + } + } + + #ifdef BETTER_MESHBUFFER_SPLITTING_FOR_X + { + //the same vertex can be used in many different meshbuffers, but it's slow to work out + + core::array< core::array< u32 > > verticesLinkIndex; + verticesLinkIndex.reallocate(mesh->Vertices.size()); + core::array< core::array< u16 > > verticesLinkBuffer; + verticesLinkBuffer.reallocate(mesh->Vertices.size()); + + for (i=0;iVertices.size();++i) + { + verticesLinkIndex.push_back( core::array< u32 >() ); + verticesLinkBuffer.push_back( core::array< u16 >() ); + } + + for (i=0;iFaceMaterialIndices.size();++i) + { + for (u32 id=i*3+0;id<=i*3+2;++id) + { + core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; + bool found=false; + + for (u32 j=0; j < Array.size(); ++j) + { + if (Array[j]==mesh->FaceMaterialIndices[i]) + { + found=true; + break; + } + } + + if (!found) + Array.push_back( mesh->FaceMaterialIndices[i] ); + } + } + + for (i=0;iVertices.size();++i) + { + core::array< u16 > &Array = verticesLinkBuffer[i]; + verticesLinkIndex[i].reallocate(Array.size()); + for (u32 j=0; j < Array.size(); ++j) + { + scene::SSkinMeshBuffer *buffer = mesh->Buffers[ Array[j] ]; + verticesLinkIndex[i].push_back( buffer->Vertices_Standard.size() ); + buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); + } + } + + for (i=0;iFaceMaterialIndices.size();++i) + { + scene::SSkinMeshBuffer *buffer=mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; + + for (u32 id=i*3+0;id<=i*3+2;++id) + { + core::array< u16 > &Array=verticesLinkBuffer[ mesh->Indices[id] ]; + + for (u32 j=0;j< Array.size() ;++j) + { + if ( Array[j]== mesh->FaceMaterialIndices[i] ) + buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ][j] ); + } + } + } + + for (u32 j=0;jWeightJoint.size();++j) + { + ISkinnedMesh::SJoint* joint = AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]; + ISkinnedMesh::SWeight& weight = joint->Weights[mesh->WeightNum[j]]; + + u32 id = weight.vertex_id; + + if (id>=verticesLinkIndex.size()) + { + os::Printer::log("X loader: Weight id out of range", ELL_WARNING); + id=0; + weight.strength=0.f; + } + + if (verticesLinkBuffer[id].size()==1) + { + weight.vertex_id=verticesLinkIndex[id][0]; + weight.buffer_id=verticesLinkBuffer[id][0]; + } + else if (verticesLinkBuffer[id].size() != 0) + { + for (u32 k=1; k < verticesLinkBuffer[id].size(); ++k) + { + ISkinnedMesh::SWeight* WeightClone = AnimatedMesh->addWeight(joint); + WeightClone->strength = weight.strength; + WeightClone->vertex_id = verticesLinkIndex[id][k]; + WeightClone->buffer_id = verticesLinkBuffer[id][k]; + } + } + } + } + #else + { + core::array< u32 > verticesLinkIndex; + core::array< s16 > verticesLinkBuffer; + verticesLinkBuffer.set_used(mesh->Vertices.size()); + + // init with 0 + for (i=0;iVertices.size();++i) + { + // watch out for vertices which are not part of the mesh + // they will keep the -1 and can lead to out-of-bounds access + verticesLinkBuffer[i]=-1; + } + + bool warned = false; + // store meshbuffer number per vertex + for (i=0;iFaceMaterialIndices.size();++i) + { + for (u32 id=i*3+0;id<=i*3+2;++id) + { + if ((verticesLinkBuffer[mesh->Indices[id]] != -1) && (verticesLinkBuffer[mesh->Indices[id]] != (s16)mesh->FaceMaterialIndices[i])) + { + if (!warned) + { + os::Printer::log("X loader", "Duplicated vertex, animation might be corrupted.", ELL_WARNING); + warned=true; + } + const u32 tmp = mesh->Vertices.size(); + mesh->Vertices.push_back(mesh->Vertices[ mesh->Indices[id] ]); + mesh->Indices[id] = tmp; + verticesLinkBuffer.set_used(mesh->Vertices.size()); + } + verticesLinkBuffer[ mesh->Indices[id] ] = mesh->FaceMaterialIndices[i]; + } + } + + if (mesh->FaceMaterialIndices.size() != 0) + { + // store vertices in buffers and remember relation in verticesLinkIndex + u32* vCountArray = new u32[mesh->Buffers.size()]; + memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); + // count vertices in each buffer and reallocate + for (i=0; iVertices.size(); ++i) + { + if (verticesLinkBuffer[i] != -1) + ++vCountArray[verticesLinkBuffer[i]]; + } + if (mesh->TCoords2.size()) + { + for (i=0; i!=mesh->Buffers.size(); ++i) + { + mesh->Buffers[i]->Vertices_2TCoords.reallocate(vCountArray[i]); + mesh->Buffers[i]->VertexType=video::EVT_2TCOORDS; + } + } + else + { + for (i=0; i!=mesh->Buffers.size(); ++i) + mesh->Buffers[i]->Vertices_Standard.reallocate(vCountArray[i]); + } + + verticesLinkIndex.set_used(mesh->Vertices.size()); + // actually store vertices + for (i=0; iVertices.size(); ++i) + { + // if a vertex is missing for some reason, just skip it + if (verticesLinkBuffer[i]==-1) + continue; + scene::SSkinMeshBuffer *buffer = mesh->Buffers[ verticesLinkBuffer[i] ]; + + if (mesh->TCoords2.size()) + { + verticesLinkIndex[i] = buffer->Vertices_2TCoords.size(); + buffer->Vertices_2TCoords.push_back( mesh->Vertices[i] ); + // We have a problem with correct tcoord2 handling here + // crash fixed for now by checking the values + buffer->Vertices_2TCoords.getLast().TCoords2=(iTCoords2.size())?mesh->TCoords2[i]:mesh->Vertices[i].TCoords; + } + else + { + verticesLinkIndex[i] = buffer->Vertices_Standard.size(); + buffer->Vertices_Standard.push_back( mesh->Vertices[i] ); + } + } + + // count indices per buffer and reallocate + memset(vCountArray, 0, mesh->Buffers.size()*sizeof(u32)); + for (i=0; iFaceMaterialIndices.size(); ++i) + ++vCountArray[ mesh->FaceMaterialIndices[i] ]; + for (i=0; i!=mesh->Buffers.size(); ++i) + mesh->Buffers[i]->Indices.reallocate(vCountArray[i]); + delete [] vCountArray; + // create indices per buffer + for (i=0; iFaceMaterialIndices.size(); ++i) + { + scene::SSkinMeshBuffer *buffer = mesh->Buffers[ mesh->FaceMaterialIndices[i] ]; + for (u32 id=i*3+0; id!=i*3+3; ++id) + { + buffer->Indices.push_back( verticesLinkIndex[ mesh->Indices[id] ] ); + } + } + } + + for (u32 j=0; jWeightJoint.size(); ++j) + { + ISkinnedMesh::SWeight& weight = (AnimatedMesh->getAllJoints()[mesh->WeightJoint[j]]->Weights[mesh->WeightNum[j]]); + + u32 id = weight.vertex_id; + + if (id>=verticesLinkIndex.size()) + { + os::Printer::log("X loader: Weight id out of range", ELL_WARNING); + id=0; + weight.strength=0.f; + } + + weight.vertex_id=verticesLinkIndex[id]; + weight.buffer_id=verticesLinkBuffer[id] + bufferOffset; + } + } + #endif + + } + + return true; +} + + +//! Reads file into memory +bool CXMeshFileLoader::readFileIntoMemory(io::IReadFile* file) +{ + const long size = file->getSize(); + if (size < 12) + { + os::Printer::log("X File is too small.", ELL_WARNING); + return false; + } + + Buffer = new c8[size]; + + //! read all into memory + if (file->read(Buffer, size) != size) + { + os::Printer::log("Could not read from x file.", ELL_WARNING); + return false; + } + + Line = 1; + End = Buffer + size; + + //! check header "xof " + if (strncmp(Buffer, "xof ", 4)!=0) + { + os::Printer::log("Not an x file, wrong header.", ELL_WARNING); + return false; + } + + //! read minor and major version, e.g. 0302 or 0303 + c8 tmp[3]; + tmp[0] = Buffer[4]; + tmp[1] = Buffer[5]; + tmp[2] = 0x0; + MajorVersion = core::strtoul10(tmp); + + tmp[0] = Buffer[6]; + tmp[1] = Buffer[7]; + MinorVersion = core::strtoul10(tmp); + + //! read format + if (strncmp(&Buffer[8], "txt ", 4) ==0) + BinaryFormat = false; + else if (strncmp(&Buffer[8], "bin ", 4) ==0) + BinaryFormat = true; + else + { + os::Printer::log("Only uncompressed x files currently supported.", ELL_WARNING); + return false; + } + BinaryNumCount=0; + + //! read float size + if (strncmp(&Buffer[12], "0032", 4) ==0) + FloatSize = 4; + else if (strncmp(&Buffer[12], "0064", 4) ==0) + FloatSize = 8; + else + { + os::Printer::log("Float size not supported.", ELL_WARNING); + return false; + } + + P = &Buffer[16]; + + readUntilEndOfLine(); + FilePath = FileSystem->getFileDir(file->getFileName()) + "/"; + + return true; +} + + +//! Parses the file +bool CXMeshFileLoader::parseFile() +{ + while(parseDataObject()) + { + // loop + } + + return true; +} + + +//! Parses the next Data object in the file +bool CXMeshFileLoader::parseDataObject() +{ + core::stringc objectName = getNextToken(); + + if (objectName.size() == 0) + return false; + + // parse specific object +#ifdef _XREADER_DEBUG + os::Printer::log("debug DataObject:", objectName.c_str(), ELL_DEBUG); +#endif + + if (objectName == "template") + return parseDataObjectTemplate(); + else + if (objectName == "Frame") + { + return parseDataObjectFrame( 0 ); + } + else + if (objectName == "Mesh") + { + // some meshes have no frames at all + //CurFrame = AnimatedMesh->addJoint(0); + + SXMesh *mesh=new SXMesh; + + //mesh->Buffer=AnimatedMesh->addMeshBuffer(); + Meshes.push_back(mesh); + + return parseDataObjectMesh(*mesh); + } + else + if (objectName == "AnimationSet") + { + return parseDataObjectAnimationSet(); + } + else + if (objectName == "Material") + { + // template materials now available thanks to joeWright + TemplateMaterials.push_back(SXTemplateMaterial()); + TemplateMaterials.getLast().Name = getNextToken(); + return parseDataObjectMaterial(TemplateMaterials.getLast().Material); + } + else + if (objectName == "}") + { + os::Printer::log("} found in dataObject", ELL_WARNING); + return true; + } + + os::Printer::log("Unknown data object in animation of .x file", objectName.c_str(), ELL_WARNING); + + return parseUnknownDataObject(); +} + + +bool CXMeshFileLoader::parseDataObjectTemplate() +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading template", ELL_DEBUG); +#endif + + // parse a template data object. Currently not stored. + core::stringc name; + + if (!readHeadOfDataObject(&name)) + { + os::Printer::log("Left delimiter in template data object missing.", + name.c_str(), ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + // read GUID + getNextToken(); + + // read and ignore data members + while(true) + { + core::stringc s = getNextToken(); + + if (s == "}") + break; + + if (s.size() == 0) + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectFrame(CSkinnedMesh::SJoint *Parent) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading frame", ELL_DEBUG); +#endif + + // A coordinate frame, or "frame of reference." The Frame template + // is open and can contain any object. The Direct3D extensions (D3DX) + // mesh-loading functions recognize Mesh, FrameTransformMatrix, and + // Frame template instances as child objects when loading a Frame + // instance. + + u32 JointID=0; + + core::stringc name; + + if (!readHeadOfDataObject(&name)) + { + os::Printer::log("No opening brace in Frame found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + CSkinnedMesh::SJoint *joint=0; + + if (name.size()) + { + for (u32 n=0; n < AnimatedMesh->getAllJoints().size(); ++n) + { + if (AnimatedMesh->getAllJoints()[n]->Name==name) + { + joint=AnimatedMesh->getAllJoints()[n]; + JointID=n; + break; + } + } + } + + if (!joint) + { +#ifdef _XREADER_DEBUG + os::Printer::log("creating joint ", name.c_str(), ELL_DEBUG); +#endif + joint=AnimatedMesh->addJoint(Parent); + joint->Name=name; + JointID=AnimatedMesh->getAllJoints().size()-1; + } + else + { +#ifdef _XREADER_DEBUG + os::Printer::log("using joint ", name.c_str(), ELL_DEBUG); +#endif + if (Parent) + Parent->Children.push_back(joint); + } + + // Now inside a frame. + // read tokens until closing brace is reached. + + while(true) + { + core::stringc objectName = getNextToken(); + +#ifdef _XREADER_DEBUG + os::Printer::log("debug DataObject in frame:", objectName.c_str(), ELL_DEBUG); +#endif + + if (objectName.size() == 0) + { + os::Printer::log("Unexpected ending found in Frame in x file.", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + else + if (objectName == "}") + { + break; // frame finished + } + else + if (objectName == "Frame") + { + + if (!parseDataObjectFrame(joint)) + return false; + } + else + if (objectName == "FrameTransformMatrix") + { + if (!parseDataObjectTransformationMatrix(joint->LocalMatrix)) + return false; + + //joint->LocalAnimatedMatrix + //joint->LocalAnimatedMatrix.makeInverse(); + //joint->LocalMatrix=tmp*joint->LocalAnimatedMatrix; + } + else + if (objectName == "Mesh") + { + /* + frame.Meshes.push_back(SXMesh()); + if (!parseDataObjectMesh(frame.Meshes.getLast())) + return false; + */ + SXMesh *mesh=new SXMesh; + + mesh->AttachedJointID=JointID; + + Meshes.push_back(mesh); + + if (!parseDataObjectMesh(*mesh)) + return false; + } + else + { + os::Printer::log("Unknown data object in frame in x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectTransformationMatrix(core::matrix4 &mat) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading Transformation Matrix", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Transformation Matrix found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + readMatrix(mat); + + if (!checkForOneFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon in Transformation Matrix found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Transformation Matrix found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh) +{ + core::stringc name; + + if (!readHeadOfDataObject(&name)) + { +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading mesh", ELL_DEBUG); +#endif + os::Printer::log("No opening brace in Mesh found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading mesh", name.c_str(), ELL_DEBUG); +#endif + + // read vertex count + const u32 nVertices = readInt(); + + // read vertices + mesh.Vertices.set_used(nVertices); + for (u32 n=0; n polygonfaces; + u32 currentIndex = 0; + + for (u32 k=0; k>8)&0xf)*sizeof(core::vector2df); + for (u32 j=0; jgetAllJoints().size(); ++n) + { + if (AnimatedMesh->getAllJoints()[n]->Name==TransformNodeName) + { + joint=AnimatedMesh->getAllJoints()[n]; + break; + } + } + + if (!joint) + { +#ifdef _XREADER_DEBUG + os::Printer::log("creating joint for skinning ", TransformNodeName.c_str(), ELL_DEBUG); +#endif + n = AnimatedMesh->getAllJoints().size(); + joint=AnimatedMesh->addJoint(0); + joint->Name=TransformNodeName; + } + + // read vertex weights + const u32 nWeights = readInt(); + + // read vertex indices + u32 i; + + const u32 jointStart = joint->Weights.size(); + joint->Weights.reallocate(jointStart+nWeights); + + mesh.WeightJoint.reallocate( mesh.WeightJoint.size() + nWeights ); + mesh.WeightNum.reallocate( mesh.WeightNum.size() + nWeights ); + + for (i=0; iWeights.size()); + + CSkinnedMesh::SWeight *weight=AnimatedMesh->addWeight(joint); + + weight->buffer_id=0; + weight->vertex_id=readInt(); + } + + // read vertex weights + + for (i=jointStart; iWeights[i].strength = readFloat(); + + // read matrix offset + + // transforms the mesh vertices to the space of the bone + // When concatenated to the bone's transform, this provides the + // world space coordinates of the mesh as affected by the bone + core::matrix4& MatrixOffset = joint->GlobalInversedMatrix; + + readMatrix(MatrixOffset); + + if (!checkForOneFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon in Skin Weights found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Skin Weights found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectSkinMeshHeader(SXMesh& mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading skin mesh header", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Skin Mesh header found in .x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + mesh.MaxSkinWeightsPerVertex = readInt(); + mesh.MaxSkinWeightsPerFace = readInt(); + mesh.BoneCount = readInt(); + + if (!BinaryFormat) + getNextToken(); // skip semicolon + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in skin mesh header in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectMeshNormals(SXMesh &mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading mesh normals", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Mesh Normals found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + // read count + const u32 nNormals = readInt(); + core::array normals; + normals.set_used(nNormals); + + // read normals + for (u32 i=0; i normalIndices; + normalIndices.set_used(mesh.Indices.size()); + + // read face normal indices + const u32 nFNormals = readInt(); + + u32 normalidx = 0; + core::array polygonfaces; + for (u32 k=0; k=mesh.Vertices.size()) + { + os::Printer::log("index value in parseDataObjectMeshVertexColors out of bounds", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + readRGBA(mesh.Vertices[Index].Color); + checkForOneFollowingSemicolons(); + } + + if (!checkForOneFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon in Mesh Vertex Colors Array found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Mesh Texture Coordinates Array found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectMeshMaterialList(SXMesh &mesh) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading mesh material list", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Mesh Material List found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + // read material count + mesh.Materials.reallocate(readInt()); + + // read non triangulated face material index count + const u32 nFaceIndices = readInt(); + + // There seems to be a compact representation of "all faces the same material" + // being represented as 1;1;0;; which means 1 material, 1 face with first material + // all the other faces have to obey then, so check is disabled + //if (nFaceIndices != mesh.IndexCountPerFace.size()) + // os::Printer::log("Index count per face not equal to face material index count in x file.", ELL_WARNING); + + // read non triangulated face indices and create triangulated ones + mesh.FaceMaterialIndices.set_used( mesh.Indices.size() / 3); + u32 triangulatedindex = 0; + u32 ind = 0; + for (u32 tfi=0; tfiexistFile(TextureFileName)) + material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName)); + // mesh path + else + { + TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName); + if (FileSystem->existFile(TextureFileName)) + material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(TextureFileName)); + // working directory + else + material.setTexture(textureLayer, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName))); + } + ++textureLayer; + if (textureLayer==2) + material.MaterialType=video::EMT_LIGHTMAP; + } + else + if (objectName.equals_ignore_case("NormalmapFilename")) + { + // some exporters write "NormalmapFileName" instead. + core::stringc TextureFileName; + if (!parseDataObjectTextureFilename(TextureFileName)) + return false; + + // original name + if (FileSystem->existFile(TextureFileName)) + material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName)); + // mesh path + else + { + TextureFileName=FilePath + FileSystem->getFileBasename(TextureFileName); + if (FileSystem->existFile(TextureFileName)) + material.setTexture(1, SceneManager->getVideoDriver()->getTexture(TextureFileName)); + // working directory + else + material.setTexture(1, SceneManager->getVideoDriver()->getTexture(FileSystem->getFileBasename(TextureFileName))); + } + if (textureLayer==1) + ++textureLayer; + } + else + { + os::Printer::log("Unknown data object in material in .x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectAnimationSet() +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: Reading animation set", ELL_DEBUG); +#endif + + core::stringc AnimationName; + + if (!readHeadOfDataObject(&AnimationName)) + { + os::Printer::log("No opening brace in Animation Set found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + os::Printer::log("Reading animationset ", AnimationName, ELL_DEBUG); + + while(true) + { + core::stringc objectName = getNextToken(); + + if (objectName.size() == 0) + { + os::Printer::log("Unexpected ending found in Animation set in x file.", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + else + if (objectName == "}") + { + break; // animation set finished + } + else + if (objectName == "Animation") + { + if (!parseDataObjectAnimation()) + return false; + } + else + { + os::Printer::log("Unknown data object in animation set in x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + return true; +} + + +bool CXMeshFileLoader::parseDataObjectAnimation() +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading animation", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Animation found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + //anim.closed = true; + //anim.linearPositionQuality = true; + CSkinnedMesh::SJoint animationDump; + + core::stringc FrameName; + + while(true) + { + core::stringc objectName = getNextToken(); + + if (objectName.size() == 0) + { + os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + else + if (objectName == "}") + { + break; // animation finished + } + else + if (objectName == "AnimationKey") + { + if (!parseDataObjectAnimationKey(&animationDump)) + return false; + } + else + if (objectName == "AnimationOptions") + { + //TODO: parse options. + if (!parseUnknownDataObject()) + return false; + } + else + if (objectName == "{") + { + // read frame name + FrameName = getNextToken(); + + if (!checkForClosingBrace()) + { + os::Printer::log("Unexpected ending found in Animation in x file.", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + } + else + { + os::Printer::log("Unknown data object in animation in x file", objectName.c_str(), ELL_WARNING); + if (!parseUnknownDataObject()) + return false; + } + } + + if (FrameName.size() != 0) + { +#ifdef _XREADER_DEBUG + os::Printer::log("frame name", FrameName.c_str(), ELL_DEBUG); +#endif + CSkinnedMesh::SJoint *joint=0; + + u32 n; + for (n=0; n < AnimatedMesh->getAllJoints().size(); ++n) + { + if (AnimatedMesh->getAllJoints()[n]->Name==FrameName) + { + joint=AnimatedMesh->getAllJoints()[n]; + break; + } + } + + if (!joint) + { +#ifdef _XREADER_DEBUG + os::Printer::log("creating joint for animation ", FrameName.c_str(), ELL_DEBUG); +#endif + joint=AnimatedMesh->addJoint(0); + joint->Name=FrameName; + } + + joint->PositionKeys.reallocate(joint->PositionKeys.size()+animationDump.PositionKeys.size()); + for (n=0; nPositionKeys.push_back(animationDump.PositionKeys[n]); + } + + joint->ScaleKeys.reallocate(joint->ScaleKeys.size()+animationDump.ScaleKeys.size()); + for (n=0; nScaleKeys.push_back(animationDump.ScaleKeys[n]); + } + + joint->RotationKeys.reallocate(joint->RotationKeys.size()+animationDump.RotationKeys.size()); + for (n=0; nRotationKeys.push_back(animationDump.RotationKeys[n]); + } + } + else + os::Printer::log("joint name was never given", ELL_WARNING); + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading animation key", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Animation Key found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + // read key type + + const u32 keyType = readInt(); + + if (keyType > 4) + { + os::Printer::log("Unknown key type found in Animation Key in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + // read number of keys + const u32 numberOfKeys = readInt(); + + // eat the semicolon after the "0". if there are keys present, readInt() + // does this for us. If there aren't, we need to do it explicitly + if (numberOfKeys == 0) + checkForOneFollowingSemicolons(); + + for (u32 i=0; iaddRotationKey(joint); + key->frame=time; + key->rotation.set(X,Y,Z,W); + } + break; + case 1: //scale + case 2: //position + { + // read vectors + + // read count + if (readInt() != 3) + { + os::Printer::log("Expected 3 numbers in animation key in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + core::vector3df vector; + readVector3(vector); + + if (!checkForTwoFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon after vector animation key in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + } + + if (keyType==2) + { + ISkinnedMesh::SPositionKey *key=AnimatedMesh->addPositionKey(joint); + key->frame=time; + key->position=vector; + } + else + { + ISkinnedMesh::SScaleKey *key=AnimatedMesh->addScaleKey(joint); + key->frame=time; + key->scale=vector; + } + } + break; + case 3: + case 4: + { + // read matrix + + // read count + if (readInt() != 16) + { + os::Printer::log("Expected 16 numbers in animation key in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + // read matrix + core::matrix4 mat(core::matrix4::EM4CONST_NOTHING); + readMatrix(mat); + + //mat=joint->LocalMatrix*mat; + + if (!checkForOneFollowingSemicolons()) + { + os::Printer::log("No finishing semicolon after matrix animation key in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + } + + //core::vector3df rotation = mat.getRotationDegrees(); + + ISkinnedMesh::SRotationKey *keyR=AnimatedMesh->addRotationKey(joint); + keyR->frame=time; + + // IRR_TEST_BROKEN_QUATERNION_USE: TODO - switched from mat to mat.getTransposed() for downward compatibility. + // Not tested so far if this was correct or wrong before quaternion fix! + keyR->rotation= core::quaternion(mat.getTransposed()); + + ISkinnedMesh::SPositionKey *keyP=AnimatedMesh->addPositionKey(joint); + keyP->frame=time; + keyP->position=mat.getTranslation(); + +/* + core::vector3df scale=mat.getScale(); + + if (scale.X==0) + scale.X=1; + if (scale.Y==0) + scale.Y=1; + if (scale.Z==0) + scale.Z=1; + ISkinnedMesh::SScaleKey *keyS=AnimatedMesh->addScaleKey(joint); + keyS->frame=time; + keyS->scale=scale; +*/ + } + break; + } // end switch + } + + if (!checkForOneFollowingSemicolons()) + --P; + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in animation key in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseDataObjectTextureFilename(core::stringc& texturename) +{ +#ifdef _XREADER_DEBUG + os::Printer::log("CXFileReader: reading texture filename", ELL_DEBUG); +#endif + + if (!readHeadOfDataObject()) + { + os::Printer::log("No opening brace in Texture filename found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + if (!getNextTokenAsString(texturename)) + { + os::Printer::log("Unknown syntax while reading texture filename string in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + if (!checkForClosingBrace()) + { + os::Printer::log("No closing brace in Texture filename found in x file", ELL_WARNING); + os::Printer::log("Line", core::stringc(Line).c_str(), ELL_WARNING); + return false; + } + + return true; +} + + +bool CXMeshFileLoader::parseUnknownDataObject() +{ + // find opening delimiter + while(true) + { + core::stringc t = getNextToken(); + + if (t.size() == 0) + return false; + + if (t == "{") + break; + } + + u32 counter = 1; + + // parse until closing delimiter + + while(counter) + { + core::stringc t = getNextToken(); + + if (t.size() == 0) + return false; + + if (t == "{") + ++counter; + else + if (t == "}") + --counter; + } + + return true; +} + + +//! checks for closing curly brace, returns false if not there +bool CXMeshFileLoader::checkForClosingBrace() +{ + return (getNextToken() == "}"); +} + + +//! checks for one following semicolon, returns false if not there +bool CXMeshFileLoader::checkForOneFollowingSemicolons() +{ + if (BinaryFormat) + return true; + + if (getNextToken() == ";") + return true; + else + { + --P; + return false; + } +} + + +//! checks for two following semicolons, returns false if they are not there +bool CXMeshFileLoader::checkForTwoFollowingSemicolons() +{ + if (BinaryFormat) + return true; + + for (u32 k=0; k<2; ++k) + { + if (getNextToken() != ";") + { + --P; + return false; + } + } + + return true; +} + + +//! reads header of dataobject including the opening brace. +//! returns false if error happened, and writes name of object +//! if there is one +bool CXMeshFileLoader::readHeadOfDataObject(core::stringc* outname) +{ + core::stringc nameOrBrace = getNextToken(); + if (nameOrBrace != "{") + { + if (outname) + (*outname) = nameOrBrace; + + if (getNextToken() != "{") + return false; + } + + return true; +} + + +//! returns next parseable token. Returns empty string if no token there +core::stringc CXMeshFileLoader::getNextToken() +{ + core::stringc s; + + // process binary-formatted file + if (BinaryFormat) + { + // in binary mode it will only return NAME and STRING token + // and (correctly) skip over other tokens. + + s16 tok = readBinWord(); + u32 len; + + // standalone tokens + switch (tok) { + case 1: + // name token + len = readBinDWord(); + s = core::stringc(P, len); + P += len; + return s; + case 2: + // string token + len = readBinDWord(); + s = core::stringc(P, len); + P += (len + 2); + return s; + case 3: + // integer token + P += 4; + return ""; + case 5: + // GUID token + P += 16; + return ""; + case 6: + len = readBinDWord(); + P += (len * 4); + return ""; + case 7: + len = readBinDWord(); + P += (len * FloatSize); + return ""; + case 0x0a: + return "{"; + case 0x0b: + return "}"; + case 0x0c: + return "("; + case 0x0d: + return ")"; + case 0x0e: + return "["; + case 0x0f: + return "]"; + case 0x10: + return "<"; + case 0x11: + return ">"; + case 0x12: + return "."; + case 0x13: + return ","; + case 0x14: + return ";"; + case 0x1f: + return "template"; + case 0x28: + return "WORD"; + case 0x29: + return "DWORD"; + case 0x2a: + return "FLOAT"; + case 0x2b: + return "DOUBLE"; + case 0x2c: + return "CHAR"; + case 0x2d: + return "UCHAR"; + case 0x2e: + return "SWORD"; + case 0x2f: + return "SDWORD"; + case 0x30: + return "void"; + case 0x31: + return "string"; + case 0x32: + return "unicode"; + case 0x33: + return "cstring"; + case 0x34: + return "array"; + } + } + // process text-formatted file + else + { + findNextNoneWhiteSpace(); + + if (P >= End) + return s; + + while((P < End) && !core::isspace(P[0])) + { + // either keep token delimiters when already holding a token, or return if first valid char + if (P[0]==';' || P[0]=='}' || P[0]=='{' || P[0]==',') + { + if (!s.size()) + { + s.append(P[0]); + ++P; + } + break; // stop for delimiter + } + s.append(P[0]); + ++P; + } + } + return s; +} + + +//! places pointer to next begin of a token, which must be a number, +// and ignores comments +void CXMeshFileLoader::findNextNoneWhiteSpaceNumber() +{ + if (BinaryFormat) + return; + + while((P < End) && (P[0] != '-') && (P[0] != '.') && + !( core::isdigit(P[0]))) + { + // check if this is a comment + if ((P[0] == '/' && P[1] == '/') || P[0] == '#') + readUntilEndOfLine(); + else + ++P; + } +} + + +// places pointer to next begin of a token, and ignores comments +void CXMeshFileLoader::findNextNoneWhiteSpace() +{ + if (BinaryFormat) + return; + + while(true) + { + while((P < End) && core::isspace(P[0])) + { + if (*P=='\n') + ++Line; + ++P; + } + + if (P >= End) + return; + + // check if this is a comment + if ((P[0] == '/' && P[1] == '/') || + P[0] == '#') + readUntilEndOfLine(); + else + break; + } +} + + +//! reads a x file style string +bool CXMeshFileLoader::getNextTokenAsString(core::stringc& out) +{ + if (BinaryFormat) + { + out=getNextToken(); + return true; + } + findNextNoneWhiteSpace(); + + if (P >= End) + return false; + + if (P[0] != '"') + return false; + ++P; + + while(P < End && P[0]!='"') + { + out.append(P[0]); + ++P; + } + + if ( P[1] != ';' || P[0] != '"') + return false; + P+=2; + + return true; +} + + +void CXMeshFileLoader::readUntilEndOfLine() +{ + if (BinaryFormat) + return; + + while(P < End) + { + if (P[0] == '\n' || P[0] == '\r') + { + ++P; + ++Line; + return; + } + + ++P; + } +} + + +u16 CXMeshFileLoader::readBinWord() +{ + if (P>=End) + return 0; +#ifdef __BIG_ENDIAN__ + const u16 tmp = os::Byteswap::byteswap(*(u16 *)P); +#else + const u16 tmp = *(u16 *)P; +#endif + P += 2; + return tmp; +} + + +u32 CXMeshFileLoader::readBinDWord() +{ + if (P>=End) + return 0; +#ifdef __BIG_ENDIAN__ + const u32 tmp = os::Byteswap::byteswap(*(u32 *)P); +#else + const u32 tmp = *(u32 *)P; +#endif + P += 4; + return tmp; +} + + +u32 CXMeshFileLoader::readInt() +{ + if (BinaryFormat) + { + if (!BinaryNumCount) + { + const u16 tmp = readBinWord(); // 0x06 or 0x03 + if (tmp == 0x06) + BinaryNumCount = readBinDWord(); + else + BinaryNumCount = 1; // single int + } + --BinaryNumCount; + return readBinDWord(); + } + else + { + findNextNoneWhiteSpaceNumber(); + return core::strtoul10(P, &P); + } +} + + +f32 CXMeshFileLoader::readFloat() +{ + if (BinaryFormat) + { + if (!BinaryNumCount) + { + const u16 tmp = readBinWord(); // 0x07 or 0x42 + if (tmp == 0x07) + BinaryNumCount = readBinDWord(); + else + BinaryNumCount = 1; // single int + } + --BinaryNumCount; + if (FloatSize == 8) + { +#ifdef __BIG_ENDIAN__ + //TODO: Check if data is properly converted here + f32 ctmp[2]; + ctmp[1] = os::Byteswap::byteswap(*(f32*)P); + ctmp[0] = os::Byteswap::byteswap(*(f32*)P+4); + const f32 tmp = (f32)(*(f64*)(void*)ctmp); +#else + const f32 tmp = (f32)(*(f64 *)P); +#endif + P += 8; + return tmp; + } + else + { +#ifdef __BIG_ENDIAN__ + const f32 tmp = os::Byteswap::byteswap(*(f32 *)P); +#else + const f32 tmp = *(f32 *)P; +#endif + P += 4; + return tmp; + } + } + findNextNoneWhiteSpaceNumber(); + f32 ftmp; + P = core::fast_atof_move(P, ftmp); + return ftmp; +} + + +// read 2-dimensional vector. Stops at semicolon after second value for text file format +bool CXMeshFileLoader::readVector2(core::vector2df& vec) +{ + vec.X = readFloat(); + vec.Y = readFloat(); + return true; +} + + +// read 3-dimensional vector. Stops at semicolon after third value for text file format +bool CXMeshFileLoader::readVector3(core::vector3df& vec) +{ + vec.X = readFloat(); + vec.Y = readFloat(); + vec.Z = readFloat(); + return true; +} + + +// read color without alpha value. Stops after second semicolon after blue value +bool CXMeshFileLoader::readRGB(video::SColor& color) +{ + video::SColorf tmpColor; + tmpColor.r = readFloat(); + tmpColor.g = readFloat(); + tmpColor.b = readFloat(); + color = tmpColor.toSColor(); + return checkForOneFollowingSemicolons(); +} + + +// read color with alpha value. Stops after second semicolon after blue value +bool CXMeshFileLoader::readRGBA(video::SColor& color) +{ + video::SColorf tmpColor; + tmpColor.r = readFloat(); + tmpColor.g = readFloat(); + tmpColor.b = readFloat(); + tmpColor.a = readFloat(); + color = tmpColor.toSColor(); + return checkForOneFollowingSemicolons(); +} + + +// read matrix from list of floats +bool CXMeshFileLoader::readMatrix(core::matrix4& mat) +{ + for (u32 i=0; i<16; ++i) + mat[i] = readFloat(); + return checkForOneFollowingSemicolons(); +} + + +} // end namespace scene +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_X_LOADER_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.h new file mode 100644 index 0000000..67fb041 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CXMeshFileLoader.h @@ -0,0 +1,198 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_X_MESH_FILE_LOADER_H_INCLUDED__ +#define __C_X_MESH_FILE_LOADER_H_INCLUDED__ + +#include "IMeshLoader.h" +#include "irrString.h" +#include "CSkinnedMesh.h" + + +namespace irr +{ +namespace io +{ + class IFileSystem; + class IReadFile; +} // end namespace io +namespace scene +{ +class IMeshManipulator; + +//! Meshloader capable of loading x meshes. +class CXMeshFileLoader : public IMeshLoader +{ +public: + + //! Constructor + CXMeshFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".cob") + virtual bool isALoadableFileExtension(const io::path& filename) const; + + //! creates/loads an animated mesh from the file. + //! \return Pointer to the created mesh. Returns 0 if loading failed. + //! If you no longer need the mesh, you should call IAnimatedMesh::drop(). + //! See IReferenceCounted::drop() for more information. + virtual IAnimatedMesh* createMesh(io::IReadFile* file); + + struct SXTemplateMaterial + { + core::stringc Name; // template name from Xfile + video::SMaterial Material; // material + }; + + struct SXMesh + { + SXMesh() : MaxSkinWeightsPerVertex(0), MaxSkinWeightsPerFace(0), BoneCount(0),AttachedJointID(-1),HasSkinning(false), HasVertexColors(false) {} + // this mesh contains triangulated texture data. + // because in an .x file, faces can be made of more than 3 + // vertices, the indices data structure is triangulated during the + // loading process. The IndexCountPerFace array is filled during + // this triangulation process and stores how much indices belong to + // every face. This data structure can be ignored, because all data + // in this structure is triangulated. + + core::stringc Name; + + u32 MaxSkinWeightsPerVertex; + u32 MaxSkinWeightsPerFace; + u32 BoneCount; + + core::array IndexCountPerFace; // default 3, but could be more + + core::array Buffers; + + core::array Vertices; + core::array TCoords2; + + core::array Indices; + + core::array FaceMaterialIndices; // index of material for each face + + core::array Materials; // material array + + core::array WeightJoint; + core::array WeightNum; + + s32 AttachedJointID; + + bool HasSkinning; + bool HasVertexColors; + }; + +private: + + bool load(io::IReadFile* file); + + bool readFileIntoMemory(io::IReadFile* file); + + bool parseFile(); + + bool parseDataObject(); + + bool parseDataObjectTemplate(); + + bool parseDataObjectFrame(CSkinnedMesh::SJoint *parent); + + bool parseDataObjectTransformationMatrix(core::matrix4 &mat); + + bool parseDataObjectMesh(SXMesh &mesh); + + bool parseDataObjectSkinWeights(SXMesh &mesh); + + bool parseDataObjectSkinMeshHeader(SXMesh &mesh); + + bool parseDataObjectMeshNormals(SXMesh &mesh); + + bool parseDataObjectMeshTextureCoords(SXMesh &mesh); + + bool parseDataObjectMeshVertexColors(SXMesh &mesh); + + bool parseDataObjectMeshMaterialList(SXMesh &mesh); + + bool parseDataObjectMaterial(video::SMaterial& material); + + bool parseDataObjectAnimationSet(); + + bool parseDataObjectAnimation(); + + bool parseDataObjectAnimationKey(ISkinnedMesh::SJoint *joint); + + bool parseDataObjectTextureFilename(core::stringc& texturename); + + bool parseUnknownDataObject(); + + //! places pointer to next begin of a token, and ignores comments + void findNextNoneWhiteSpace(); + + //! places pointer to next begin of a token, which must be a number, + // and ignores comments + void findNextNoneWhiteSpaceNumber(); + + //! returns next parseable token. Returns empty string if no token there + core::stringc getNextToken(); + + //! reads header of dataobject including the opening brace. + //! returns false if error happened, and writes name of object + //! if there is one + bool readHeadOfDataObject(core::stringc* outname=0); + + //! checks for closing curly brace, returns false if not there + bool checkForClosingBrace(); + + //! checks for one following semicolons, returns false if not there + bool checkForOneFollowingSemicolons(); + + //! checks for two following semicolons, returns false if they are not there + bool checkForTwoFollowingSemicolons(); + + //! reads a x file style string + bool getNextTokenAsString(core::stringc& out); + + void readUntilEndOfLine(); + + u16 readBinWord(); + u32 readBinDWord(); + u32 readInt(); + f32 readFloat(); + bool readVector2(core::vector2df& vec); + bool readVector3(core::vector3df& vec); + bool readMatrix(core::matrix4& mat); + bool readRGB(video::SColor& color); + bool readRGBA(video::SColor& color); + + ISceneManager* SceneManager; + io::IFileSystem* FileSystem; + + core::array *AllJoints; + + CSkinnedMesh* AnimatedMesh; + + c8* Buffer; + const c8* P; + c8* End; + // counter for number arrays in binary format + u32 BinaryNumCount; + u32 Line; + io::path FilePath; + + CSkinnedMesh::SJoint *CurFrame; + + core::array Meshes; + + core::array TemplateMaterials; + + u32 MajorVersion; + u32 MinorVersion; + bool BinaryFormat; + c8 FloatSize; +}; + +} // end namespace scene +} // end namespace irr + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.cpp new file mode 100644 index 0000000..23b515b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.cpp @@ -0,0 +1,109 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#include "CZBuffer.h" +#include "irrString.h" + +#ifdef _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + + +//! constructor +CZBuffer::CZBuffer(const core::dimension2d& size) +: Buffer(0), BufferEnd(0), Size(0,0), TotalSize(0) +{ + #ifdef _DEBUG + setDebugName("CZBuffer"); + #endif + + setSize(size); +} + + + +//! destructor +CZBuffer::~CZBuffer() +{ + delete [] Buffer; +} + + + +//! clears the zbuffer +void CZBuffer::clear() +{ + memset(Buffer, 0, (BufferEnd-Buffer)*sizeof(TZBufferType)); +} + + + +//! sets the new size of the zbuffer +void CZBuffer::setSize(const core::dimension2d& size) +{ + if (size == Size) + return; + + Size = size; + + delete [] Buffer; + + TotalSize = size.Width * size.Height; + Buffer = new TZBufferType[TotalSize]; + BufferEnd = Buffer + TotalSize; +} + + + +//! returns the size of the zbuffer +const core::dimension2d& CZBuffer::getSize() const +{ + return Size; +} + + + +//! locks the zbuffer +TZBufferType* CZBuffer::lock() +{ + return Buffer; +} + + + +//! unlocks the zbuffer +void CZBuffer::unlock() +{ +} + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_SOFTWARE_ + +namespace irr +{ +namespace video +{ + +//! creates a ZBuffer +IZBuffer* createZBuffer(const core::dimension2d& size) +{ + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + return new CZBuffer(size); + #else + return 0; + #endif // _IRR_COMPILE_WITH_SOFTWARE_ +} + + +} // end namespace video +} // end namespace irr + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.h new file mode 100644 index 0000000..d923094 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CZBuffer.h @@ -0,0 +1,52 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_Z_BUFFER_H_INCLUDED__ +#define __C_Z_BUFFER_H_INCLUDED__ + +#include "IZBuffer.h" + +namespace irr +{ +namespace video +{ + + class CZBuffer : public IZBuffer + { + public: + + //! constructor + CZBuffer(const core::dimension2d& size); + + //! destructor + virtual ~CZBuffer(); + + //! clears the zbuffer + virtual void clear(); + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size); + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const; + + //! locks the zbuffer + virtual TZBufferType* lock(); + + //! unlocks the zbuffer + virtual void unlock(); + + private: + + TZBufferType* Buffer; + TZBufferType* BufferEnd; + core::dimension2d Size; + s32 TotalSize; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.cpp new file mode 100644 index 0000000..be29f98 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.cpp @@ -0,0 +1,839 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "CZipReader.h" + +#include "os.h" + +// This method is used for error output from bzip2. +extern "C" void bz_internal_error(int errorCode) +{ + irr::os::Printer::log("Error in bzip2 handling", irr::core::stringc(errorCode), irr::ELL_ERROR); +} + +#ifdef __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ + +#include "CFileList.h" +#include "CReadFile.h" +#include "coreutil.h" + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_ZLIB_ + #ifndef _IRR_USE_NON_SYSTEM_ZLIB_ + #include // use system lib + #else + #include "zlib/zlib.h" + #endif + + #ifdef _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ + #include "aesGladman/fileenc.h" + #endif + #ifdef _IRR_COMPILE_WITH_BZIP2_ + #ifndef _IRR_USE_NON_SYSTEM_BZLIB_ + #include + #else + #include "bzip2/bzlib.h" + #endif + #endif + #ifdef _IRR_COMPILE_WITH_LZMA_ + #include "lzma/LzmaDec.h" + #endif +#endif + +namespace irr +{ +namespace io +{ + + +// ----------------------------------------------------------------------------- +// zip loader +// ----------------------------------------------------------------------------- + +//! Constructor +CArchiveLoaderZIP::CArchiveLoaderZIP(io::IFileSystem* fs) +: FileSystem(fs) +{ + #ifdef _DEBUG + setDebugName("CArchiveLoaderZIP"); + #endif +} + +//! returns true if the file maybe is able to be loaded by this class +bool CArchiveLoaderZIP::isALoadableFileFormat(const io::path& filename) const +{ + return core::hasFileExtension(filename, "zip", "pk3") || + core::hasFileExtension(filename, "gz", "tgz"); +} + +//! Check to see if the loader can create archives of this type. +bool CArchiveLoaderZIP::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const +{ + return (fileType == EFAT_ZIP || fileType == EFAT_GZIP); +} + + +//! Creates an archive from the filename +/** \param file File handle to check. +\return Pointer to newly created archive, or 0 upon error. */ +IFileArchive* CArchiveLoaderZIP::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + io::IReadFile* file = FileSystem->createAndOpenFile(filename); + + if (file) + { + archive = createArchive(file, ignoreCase, ignorePaths); + file->drop(); + } + + return archive; +} + +//! creates/loads an archive from the file. +//! \return Pointer to the created archive. Returns 0 if loading failed. +IFileArchive* CArchiveLoaderZIP::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const +{ + IFileArchive *archive = 0; + if (file) + { + file->seek(0); + + u16 sig; + file->read(&sig, 2); + +#ifdef __BIG_ENDIAN__ + sig = os::Byteswap::byteswap(sig); +#endif + + file->seek(0); + + bool isGZip = (sig == 0x8b1f); + + archive = new CZipReader(file, ignoreCase, ignorePaths, isGZip); + } + return archive; +} + +//! Check if the file might be loaded by this class +/** Check might look into the file. +\param file File handle to check. +\return True if file seems to be loadable. */ +bool CArchiveLoaderZIP::isALoadableFileFormat(io::IReadFile* file) const +{ + SZIPFileHeader header; + + file->read( &header.Sig, 4 ); +#ifdef __BIG_ENDIAN__ + header.Sig = os::Byteswap::byteswap(header.Sig); +#endif + + return header.Sig == 0x04034b50 || // ZIP + (header.Sig&0xffff) == 0x8b1f; // gzip +} + +// ----------------------------------------------------------------------------- +// zip archive +// ----------------------------------------------------------------------------- + +CZipReader::CZipReader(IReadFile* file, bool ignoreCase, bool ignorePaths, bool isGZip) + : CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file), IsGZip(isGZip) +{ + #ifdef _DEBUG + setDebugName("CZipReader"); + #endif + + if (File) + { + File->grab(); + + // load file entries + if (IsGZip) + while (scanGZipHeader()) { } + else + while (scanZipHeader()) { } + + sort(); + } +} + +CZipReader::~CZipReader() +{ + if (File) + File->drop(); +} + + +//! get the archive type +E_FILE_ARCHIVE_TYPE CZipReader::getType() const +{ + return IsGZip ? EFAT_GZIP : EFAT_ZIP; +} + +const IFileList* CZipReader::getFileList() const +{ + return this; +} + + +//! scans for a local header, returns false if there is no more local file header. +//! The gzip file format seems to think that there can be multiple files in a gzip file +//! but none +bool CZipReader::scanGZipHeader() +{ + SZipFileEntry entry; + entry.Offset = 0; + memset(&entry.header, 0, sizeof(SZIPFileHeader)); + + // read header + SGZIPMemberHeader header; + if (File->read(&header, sizeof(SGZIPMemberHeader)) == sizeof(SGZIPMemberHeader)) + { + +#ifdef __BIG_ENDIAN__ + header.sig = os::Byteswap::byteswap(header.sig); + header.time = os::Byteswap::byteswap(header.time); +#endif + + // check header value + if (header.sig != 0x8b1f) + return false; + + // now get the file info + if (header.flags & EGZF_EXTRA_FIELDS) + { + // read lenth of extra data + u16 dataLen; + + File->read(&dataLen, 2); + +#ifdef __BIG_ENDIAN__ + dataLen = os::Byteswap::byteswap(dataLen); +#endif + + // skip it + File->seek(dataLen, true); + } + + io::path ZipFileName = ""; + + if (header.flags & EGZF_FILE_NAME) + { + c8 c; + File->read(&c, 1); + while (c) + { + ZipFileName.append(c); + File->read(&c, 1); + } + } + else + { + // no file name? + ZipFileName = Path; + core::deletePathFromFilename(ZipFileName); + + // rename tgz to tar or remove gz extension + if (core::hasFileExtension(ZipFileName, "tgz")) + { + ZipFileName[ ZipFileName.size() - 2] = 'a'; + ZipFileName[ ZipFileName.size() - 1] = 'r'; + } + else if (core::hasFileExtension(ZipFileName, "gz")) + { + ZipFileName[ ZipFileName.size() - 3] = 0; + ZipFileName.validate(); + } + } + + if (header.flags & EGZF_COMMENT) + { + c8 c='a'; + while (c) + File->read(&c, 1); + } + + if (header.flags & EGZF_CRC16) + File->seek(2, true); + + // we are now at the start of the data blocks + entry.Offset = File->getPos(); + + entry.header.FilenameLength = ZipFileName.size(); + + entry.header.CompressionMethod = header.compressionMethod; + entry.header.DataDescriptor.CompressedSize = (File->getSize() - 8) - File->getPos(); + + // seek to file end + File->seek(entry.header.DataDescriptor.CompressedSize, true); + + // read CRC + File->read(&entry.header.DataDescriptor.CRC32, 4); + // read uncompressed size + File->read(&entry.header.DataDescriptor.UncompressedSize, 4); + +#ifdef __BIG_ENDIAN__ + entry.header.DataDescriptor.CRC32 = os::Byteswap::byteswap(entry.header.DataDescriptor.CRC32); + entry.header.DataDescriptor.UncompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.UncompressedSize); +#endif + + // now we've filled all the fields, this is just a standard deflate block + addItem(ZipFileName, entry.Offset, entry.header.DataDescriptor.UncompressedSize, false, 0); + FileInfo.push_back(entry); + } + + // there's only one block of data in a gzip file + return false; +} + +//! scans for a local header, returns false if there is no more local file header. +bool CZipReader::scanZipHeader(bool ignoreGPBits) +{ + io::path ZipFileName = ""; + SZipFileEntry entry; + entry.Offset = 0; + memset(&entry.header, 0, sizeof(SZIPFileHeader)); + + File->read(&entry.header, sizeof(SZIPFileHeader)); + +#ifdef __BIG_ENDIAN__ + entry.header.Sig = os::Byteswap::byteswap(entry.header.Sig); + entry.header.VersionToExtract = os::Byteswap::byteswap(entry.header.VersionToExtract); + entry.header.GeneralBitFlag = os::Byteswap::byteswap(entry.header.GeneralBitFlag); + entry.header.CompressionMethod = os::Byteswap::byteswap(entry.header.CompressionMethod); + entry.header.LastModFileTime = os::Byteswap::byteswap(entry.header.LastModFileTime); + entry.header.LastModFileDate = os::Byteswap::byteswap(entry.header.LastModFileDate); + entry.header.DataDescriptor.CRC32 = os::Byteswap::byteswap(entry.header.DataDescriptor.CRC32); + entry.header.DataDescriptor.CompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.CompressedSize); + entry.header.DataDescriptor.UncompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.UncompressedSize); + entry.header.FilenameLength = os::Byteswap::byteswap(entry.header.FilenameLength); + entry.header.ExtraFieldLength = os::Byteswap::byteswap(entry.header.ExtraFieldLength); +#endif + + if (entry.header.Sig != 0x04034b50) + return false; // local file headers end here. + + // read filename + { + c8 *tmp = new c8 [ entry.header.FilenameLength + 2 ]; + File->read(tmp, entry.header.FilenameLength); + tmp[entry.header.FilenameLength] = 0; + ZipFileName = tmp; + delete [] tmp; + } + +#ifdef _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ + // AES encryption + if ((entry.header.GeneralBitFlag & ZIP_FILE_ENCRYPTED) && (entry.header.CompressionMethod == 99)) + { + s16 restSize = entry.header.ExtraFieldLength; + SZipFileExtraHeader extraHeader; + while (restSize) + { + File->read(&extraHeader, sizeof(extraHeader)); +#ifdef __BIG_ENDIAN__ + extraHeader.ID = os::Byteswap::byteswap(extraHeader.ID); + extraHeader.Size = os::Byteswap::byteswap(extraHeader.Size); +#endif + restSize -= sizeof(extraHeader); + if (extraHeader.ID==(s16)0x9901) + { + SZipFileAESExtraData data; + File->read(&data, sizeof(data)); +#ifdef __BIG_ENDIAN__ + data.Version = os::Byteswap::byteswap(data.Version); + data.CompressionMode = os::Byteswap::byteswap(data.CompressionMode); +#endif + restSize -= sizeof(data); + if (data.Vendor[0]=='A' && data.Vendor[1]=='E') + { + // encode values into Sig + // AE-Version | Strength | ActualMode + entry.header.Sig = + ((data.Version & 0xff) << 24) | + (data.EncryptionStrength << 16) | + (data.CompressionMode); + File->seek(restSize, true); + break; + } + } + } + } + // move forward length of extra field. + else +#endif + if (entry.header.ExtraFieldLength) + File->seek(entry.header.ExtraFieldLength, true); + + // if bit 3 was set, use CentralDirectory for setup + if (!ignoreGPBits && entry.header.GeneralBitFlag & ZIP_INFO_IN_DATA_DESCRIPTOR) + { + SZIPFileCentralDirEnd dirEnd; + FileInfo.clear(); + Files.clear(); + // First place where the end record could be stored + File->seek(File->getSize()-22); + const char endID[] = {0x50, 0x4b, 0x05, 0x06, 0x0}; + char tmp[5]={'\0'}; + bool found=false; + // search for the end record ID + while (!found && File->getPos()>0) + { + int seek=8; + File->read(tmp, 4); + switch (tmp[0]) + { + case 0x50: + if (!strcmp(endID, tmp)) + { + seek=4; + found=true; + } + break; + case 0x4b: + seek=5; + break; + case 0x05: + seek=6; + break; + case 0x06: + seek=7; + break; + } + File->seek(-seek, true); + } + File->read(&dirEnd, sizeof(dirEnd)); +#ifdef __BIG_ENDIAN__ + dirEnd.NumberDisk = os::Byteswap::byteswap(dirEnd.NumberDisk); + dirEnd.NumberStart = os::Byteswap::byteswap(dirEnd.NumberStart); + dirEnd.TotalDisk = os::Byteswap::byteswap(dirEnd.TotalDisk); + dirEnd.TotalEntries = os::Byteswap::byteswap(dirEnd.TotalEntries); + dirEnd.Size = os::Byteswap::byteswap(dirEnd.Size); + dirEnd.Offset = os::Byteswap::byteswap(dirEnd.Offset); + dirEnd.CommentLength = os::Byteswap::byteswap(dirEnd.CommentLength); +#endif + FileInfo.reallocate(dirEnd.TotalEntries); + File->seek(dirEnd.Offset); + while (scanCentralDirectoryHeader()) { } + return false; + } + + // store position in file + entry.Offset = File->getPos(); + // move forward length of data + File->seek(entry.header.DataDescriptor.CompressedSize, true); + + #ifdef _DEBUG + //os::Debuginfo::print("added file from archive", ZipFileName.c_str()); + #endif + + addItem(ZipFileName, entry.Offset, entry.header.DataDescriptor.UncompressedSize, ZipFileName.lastChar()=='/', FileInfo.size()); + FileInfo.push_back(entry); + + return true; +} + + +//! scans for a local header, returns false if there is no more local file header. +bool CZipReader::scanCentralDirectoryHeader() +{ + io::path ZipFileName = ""; + SZIPFileCentralDirFileHeader entry; + File->read(&entry, sizeof(SZIPFileCentralDirFileHeader)); + +#ifdef __BIG_ENDIAN__ + entry.Sig = os::Byteswap::byteswap(entry.Sig); + entry.VersionMadeBy = os::Byteswap::byteswap(entry.VersionMadeBy); + entry.VersionToExtract = os::Byteswap::byteswap(entry.VersionToExtract); + entry.GeneralBitFlag = os::Byteswap::byteswap(entry.GeneralBitFlag); + entry.CompressionMethod = os::Byteswap::byteswap(entry.CompressionMethod); + entry.LastModFileTime = os::Byteswap::byteswap(entry.LastModFileTime); + entry.LastModFileDate = os::Byteswap::byteswap(entry.LastModFileDate); + entry.CRC32 = os::Byteswap::byteswap(entry.CRC32); + entry.CompressedSize = os::Byteswap::byteswap(entry.CompressedSize); + entry.UncompressedSize = os::Byteswap::byteswap(entry.UncompressedSize); + entry.FilenameLength = os::Byteswap::byteswap(entry.FilenameLength); + entry.ExtraFieldLength = os::Byteswap::byteswap(entry.ExtraFieldLength); + entry.FileCommentLength = os::Byteswap::byteswap(entry.FileCommentLength); + entry.DiskNumberStart = os::Byteswap::byteswap(entry.DiskNumberStart); + entry.InternalFileAttributes = os::Byteswap::byteswap(entry.InternalFileAttributes); + entry.ExternalFileAttributes = os::Byteswap::byteswap(entry.ExternalFileAttributes); + entry.RelativeOffsetOfLocalHeader = os::Byteswap::byteswap(entry.RelativeOffsetOfLocalHeader); +#endif + + if (entry.Sig != 0x02014b50) + return false; // central dir headers end here. + + const long pos = File->getPos(); + File->seek(entry.RelativeOffsetOfLocalHeader); + scanZipHeader(true); + File->seek(pos+entry.FilenameLength+entry.ExtraFieldLength+entry.FileCommentLength); + FileInfo.getLast().header.DataDescriptor.CompressedSize=entry.CompressedSize; + FileInfo.getLast().header.DataDescriptor.UncompressedSize=entry.UncompressedSize; + FileInfo.getLast().header.DataDescriptor.CRC32=entry.CRC32; + Files.getLast().Size=entry.UncompressedSize; + return true; +} + + +//! opens a file by file name +IReadFile* CZipReader::createAndOpenFile(const io::path& filename) +{ + s32 index = findFile(filename, false); + + if (index != -1) + return createAndOpenFile(index); + + return 0; +} + +#ifdef _IRR_COMPILE_WITH_LZMA_ +//! Used for LZMA decompression. The lib has no default memory management +namespace +{ + void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } + void SzFree(void *p, void *address) { p = p; free(address); } + ISzAlloc lzmaAlloc = { SzAlloc, SzFree }; +} +#endif + +//! opens a file by index +IReadFile* CZipReader::createAndOpenFile(u32 index) +{ + // Irrlicht supports 0, 8, 12, 14, 99 + //0 - The file is stored (no compression) + //1 - The file is Shrunk + //2 - The file is Reduced with compression factor 1 + //3 - The file is Reduced with compression factor 2 + //4 - The file is Reduced with compression factor 3 + //5 - The file is Reduced with compression factor 4 + //6 - The file is Imploded + //7 - Reserved for Tokenizing compression algorithm + //8 - The file is Deflated + //9 - Reserved for enhanced Deflating + //10 - PKWARE Date Compression Library Imploding + //12 - bzip2 - Compression Method from libbz2, WinZip 10 + //14 - LZMA - Compression Method, WinZip 12 + //96 - Jpeg compression - Compression Method, WinZip 12 + //97 - WavPack - Compression Method, WinZip 11 + //98 - PPMd - Compression Method, WinZip 10 + //99 - AES encryption, WinZip 9 + + const SZipFileEntry &e = FileInfo[Files[index].ID]; + wchar_t buf[64]; + s16 actualCompressionMethod=e.header.CompressionMethod; + IReadFile* decrypted=0; + u8* decryptedBuf=0; + u32 decryptedSize=e.header.DataDescriptor.CompressedSize; +#ifdef _IRR_COMPILE_WITH_ZIP_ENCRYPTION_ + if ((e.header.GeneralBitFlag & ZIP_FILE_ENCRYPTED) && (e.header.CompressionMethod == 99)) + { + os::Printer::log("Reading encrypted file."); + u8 salt[16]={0}; + const u16 saltSize = (((e.header.Sig & 0x00ff0000) >>16)+1)*4; + File->seek(e.Offset); + File->read(salt, saltSize); + char pwVerification[2]; + char pwVerificationFile[2]; + File->read(pwVerification, 2); + fcrypt_ctx zctx; // the encryption context + int rc = fcrypt_init( + (e.header.Sig & 0x00ff0000) >>16, + (const unsigned char*)Password.c_str(), // the password + Password.size(), // number of bytes in password + salt, // the salt + (unsigned char*)pwVerificationFile, // on return contains password verifier + &zctx); // encryption context + if (strncmp(pwVerificationFile, pwVerification, 2)) + { + os::Printer::log("Wrong password"); + return 0; + } + decryptedSize= e.header.DataDescriptor.CompressedSize-saltSize-12; + decryptedBuf= new u8[decryptedSize]; + u32 c = 0; + while ((c+32768)<=decryptedSize) + { + File->read(decryptedBuf+c, 32768); + fcrypt_decrypt( + decryptedBuf+c, // pointer to the data to decrypt + 32768, // how many bytes to decrypt + &zctx); // decryption context + c+=32768; + } + File->read(decryptedBuf+c, decryptedSize-c); + fcrypt_decrypt( + decryptedBuf+c, // pointer to the data to decrypt + decryptedSize-c, // how many bytes to decrypt + &zctx); // decryption context + + char fileMAC[10]; + char resMAC[10]; + rc = fcrypt_end( + (unsigned char*)resMAC, // on return contains the authentication code + &zctx); // encryption context + if (rc != 10) + { + os::Printer::log("Error on encryption closing"); + delete [] decryptedBuf; + return 0; + } + File->read(fileMAC, 10); + if (strncmp(fileMAC, resMAC, 10)) + { + os::Printer::log("Error on encryption check"); + delete [] decryptedBuf; + return 0; + } + decrypted = io::createMemoryReadFile(decryptedBuf, decryptedSize, Files[index].FullName, true); + actualCompressionMethod = (e.header.Sig & 0xffff); +#if 0 + if ((e.header.Sig & 0xff000000)==0x01000000) + { + } + else if ((e.header.Sig & 0xff000000)==0x02000000) + { + } + else + { + os::Printer::log("Unknown encryption method"); + return 0; + } +#endif + } +#endif + switch(actualCompressionMethod) + { + case 0: // no compression + { + if (decrypted) + return decrypted; + else + return createLimitReadFile(Files[index].FullName, File, e.Offset, decryptedSize); + } + case 8: + { + #ifdef _IRR_COMPILE_WITH_ZLIB_ + + const u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize; + c8* pBuf = new c8[ uncompressedSize ]; + if (!pBuf) + { + swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + if (decrypted) + decrypted->drop(); + return 0; + } + + u8 *pcData = decryptedBuf; + if (!pcData) + { + pcData = new u8[decryptedSize]; + if (!pcData) + { + swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + delete [] pBuf; + return 0; + } + + //memset(pcData, 0, decryptedSize); + File->seek(e.Offset); + File->read(pcData, decryptedSize); + } + + // Setup the inflate stream. + z_stream stream; + s32 err; + + stream.next_in = (Bytef*)pcData; + stream.avail_in = (uInt)decryptedSize; + stream.next_out = (Bytef*)pBuf; + stream.avail_out = uncompressedSize; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + // Perform inflation. wbits < 0 indicates no zlib header inside the data. + err = inflateInit2(&stream, -MAX_WBITS); + if (err == Z_OK) + { + err = inflate(&stream, Z_FINISH); + inflateEnd(&stream); + if (err == Z_STREAM_END) + err = Z_OK; + err = Z_OK; + inflateEnd(&stream); + } + + if (decrypted) + decrypted->drop(); + else + delete[] pcData; + + if (err != Z_OK) + { + swprintf ( buf, 64, L"Error decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + delete [] pBuf; + return 0; + } + else + return io::createMemoryReadFile(pBuf, uncompressedSize, Files[index].FullName, true); + + #else + return 0; // zlib not compiled, we cannot decompress the data. + #endif + } + case 12: + { + #ifdef _IRR_COMPILE_WITH_BZIP2_ + + const u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize; + c8* pBuf = new c8[ uncompressedSize ]; + if (!pBuf) + { + swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + if (decrypted) + decrypted->drop(); + return 0; + } + + u8 *pcData = decryptedBuf; + if (!pcData) + { + pcData = new u8[decryptedSize]; + if (!pcData) + { + swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + delete [] pBuf; + return 0; + } + + //memset(pcData, 0, decryptedSize); + File->seek(e.Offset); + File->read(pcData, decryptedSize); + } + + bz_stream bz_ctx={0}; + /* use BZIP2's default memory allocation + bz_ctx->bzalloc = NULL; + bz_ctx->bzfree = NULL; + bz_ctx->opaque = NULL; + */ + int err = BZ2_bzDecompressInit(&bz_ctx, 0, 0); /* decompression */ + if(err != BZ_OK) + { + os::Printer::log("bzip2 decompression failed. File cannot be read.", ELL_ERROR); + return 0; + } + bz_ctx.next_in = (char*)pcData; + bz_ctx.avail_in = decryptedSize; + /* pass all input to decompressor */ + bz_ctx.next_out = pBuf; + bz_ctx.avail_out = uncompressedSize; + err = BZ2_bzDecompress(&bz_ctx); + err = BZ2_bzDecompressEnd(&bz_ctx); + + if (decrypted) + decrypted->drop(); + else + delete[] pcData; + + if (err != BZ_OK) + { + swprintf ( buf, 64, L"Error decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + delete [] pBuf; + return 0; + } + else + return io::createMemoryReadFile(pBuf, uncompressedSize, Files[index].FullName, true); + + #else + os::Printer::log("bzip2 decompression not supported. File cannot be read.", ELL_ERROR); + return 0; + #endif + } + case 14: + { + #ifdef _IRR_COMPILE_WITH_LZMA_ + + u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize; + c8* pBuf = new c8[ uncompressedSize ]; + if (!pBuf) + { + swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + if (decrypted) + decrypted->drop(); + return 0; + } + + u8 *pcData = decryptedBuf; + if (!pcData) + { + pcData = new u8[decryptedSize]; + if (!pcData) + { + swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + delete [] pBuf; + return 0; + } + + //memset(pcData, 0, decryptedSize); + File->seek(e.Offset); + File->read(pcData, decryptedSize); + } + + ELzmaStatus status; + SizeT tmpDstSize = uncompressedSize; + SizeT tmpSrcSize = decryptedSize; + + unsigned int propSize = (pcData[3]<<8)+pcData[2]; + int err = LzmaDecode((Byte*)pBuf, &tmpDstSize, + pcData+4+propSize, &tmpSrcSize, + pcData+4, propSize, + e.header.GeneralBitFlag&0x1?LZMA_FINISH_END:LZMA_FINISH_ANY, &status, + &lzmaAlloc); + uncompressedSize = tmpDstSize; // may be different to expected value + + if (decrypted) + decrypted->drop(); + else + delete[] pcData; + + if (err != SZ_OK) + { + os::Printer::log( "Error decompressing", Files[index].FullName, ELL_ERROR); + delete [] pBuf; + return 0; + } + else + return io::createMemoryReadFile(pBuf, uncompressedSize, Files[index].FullName, true); + + #else + os::Printer::log("lzma decompression not supported. File cannot be read.", ELL_ERROR); + return 0; + #endif + } + case 99: + // If we come here with an encrypted file, decryption support is missing + os::Printer::log("Decryption support not enabled. File cannot be read.", ELL_ERROR); + return 0; + default: + swprintf ( buf, 64, L"file has unsupported compression method. %s", Files[index].FullName.c_str() ); + os::Printer::log( buf, ELL_ERROR); + return 0; + }; + +} + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.h new file mode 100644 index 0000000..14251e8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CZipReader.h @@ -0,0 +1,227 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_ZIP_READER_H_INCLUDED__ +#define __C_ZIP_READER_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ + +#include "IReadFile.h" +#include "irrArray.h" +#include "irrString.h" +#include "IFileSystem.h" +#include "CFileList.h" + +namespace irr +{ +namespace io +{ + // set if the file is encrypted + const s16 ZIP_FILE_ENCRYPTED = 0x0001; + // the fields crc-32, compressed size and uncompressed size are set to + // zero in the local header + const s16 ZIP_INFO_IN_DATA_DESCRIPTOR = 0x0008; + +// byte-align structures +#include "irrpack.h" + + struct SZIPFileDataDescriptor + { + u32 CRC32; + u32 CompressedSize; + u32 UncompressedSize; + } PACK_STRUCT; + + struct SZIPFileHeader + { + u32 Sig; // 'PK0304' little endian (0x04034b50) + s16 VersionToExtract; + s16 GeneralBitFlag; + s16 CompressionMethod; + s16 LastModFileTime; + s16 LastModFileDate; + SZIPFileDataDescriptor DataDescriptor; + s16 FilenameLength; + s16 ExtraFieldLength; + // filename (variable size) + // extra field (variable size ) + } PACK_STRUCT; + + struct SZIPFileCentralDirFileHeader + { + u32 Sig; // 'PK0102' (0x02014b50) + u16 VersionMadeBy; + u16 VersionToExtract; + u16 GeneralBitFlag; + u16 CompressionMethod; + u16 LastModFileTime; + u16 LastModFileDate; + u32 CRC32; + u32 CompressedSize; + u32 UncompressedSize; + u16 FilenameLength; + u16 ExtraFieldLength; + u16 FileCommentLength; + u16 DiskNumberStart; + u16 InternalFileAttributes; + u32 ExternalFileAttributes; + u32 RelativeOffsetOfLocalHeader; + + // filename (variable size) + // extra field (variable size) + // file comment (variable size) + + } PACK_STRUCT; + + struct SZIPFileCentralDirEnd + { + u32 Sig; // 'PK0506' end_of central dir signature // (0x06054b50) + u16 NumberDisk; // number of this disk + u16 NumberStart; // number of the disk with the start of the central directory + u16 TotalDisk; // total number of entries in the central dir on this disk + u16 TotalEntries; // total number of entries in the central dir + u32 Size; // size of the central directory + u32 Offset; // offset of start of centraldirectory with respect to the starting disk number + u16 CommentLength; // zipfile comment length + // zipfile comment (variable size) + } PACK_STRUCT; + + struct SZipFileExtraHeader + { + s16 ID; + s16 Size; + } PACK_STRUCT; + + struct SZipFileAESExtraData + { + s16 Version; + u8 Vendor[2]; + u8 EncryptionStrength; + s16 CompressionMode; + } PACK_STRUCT; + + enum E_GZIP_FLAGS + { + EGZF_TEXT_DAT = 1, + EGZF_CRC16 = 2, + EGZF_EXTRA_FIELDS = 4, + EGZF_FILE_NAME = 8, + EGZF_COMMENT = 16 + }; + + struct SGZIPMemberHeader + { + u16 sig; // 0x8b1f + u8 compressionMethod; // 8 = deflate + u8 flags; + u32 time; + u8 extraFlags; // slow compress = 2, fast compress = 4 + u8 operatingSystem; + } PACK_STRUCT; + +// Default alignment +#include "irrunpack.h" + + //! Contains extended info about zip files in the archive + struct SZipFileEntry + { + //! Position of data in the archive file + s32 Offset; + + //! The header for this file containing compression info etc + SZIPFileHeader header; + }; + + //! Archiveloader capable of loading ZIP Archives + class CArchiveLoaderZIP : public IArchiveLoader + { + public: + + //! Constructor + CArchiveLoaderZIP(io::IFileSystem* fs); + + //! returns true if the file maybe is able to be loaded by this class + //! based on the file extension (e.g. ".zip") + virtual bool isALoadableFileFormat(const io::path& filename) const; + + //! Check if the file might be loaded by this class + /** Check might look into the file. + \param file File handle to check. + \return True if file seems to be loadable. */ + virtual bool isALoadableFileFormat(io::IReadFile* file) const; + + //! Check to see if the loader can create archives of this type. + /** Check based on the archive type. + \param fileType The archive type to check. + \return True if the archile loader supports this type, false if not */ + virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const; + + //! Creates an archive from the filename + /** \param file File handle to check. + \return Pointer to newly created archive, or 0 upon error. */ + virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const; + + //! creates/loads an archive from the file. + //! \return Pointer to the created archive. Returns 0 if loading failed. + virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const; + + private: + io::IFileSystem* FileSystem; + }; + +/*! + Zip file Reader written April 2002 by N.Gebhardt. +*/ + class CZipReader : public virtual IFileArchive, virtual CFileList + { + public: + + //! constructor + CZipReader(IReadFile* file, bool ignoreCase, bool ignorePaths, bool isGZip=false); + + //! destructor + virtual ~CZipReader(); + + //! opens a file by file name + virtual IReadFile* createAndOpenFile(const io::path& filename); + + //! opens a file by index + virtual IReadFile* createAndOpenFile(u32 index); + + //! returns the list of files + virtual const IFileList* getFileList() const; + + //! get the archive type + virtual E_FILE_ARCHIVE_TYPE getType() const; + + protected: + + //! reads the next file header from a ZIP file, returns false if there are no more headers. + /* if ignoreGPBits is set, the item will be read despite missing + file information. This is used when reading items from the central + directory. */ + bool scanZipHeader(bool ignoreGPBits=false); + + //! the same but for gzip files + bool scanGZipHeader(); + + bool scanCentralDirectoryHeader(); + + IReadFile* File; + + // holds extended info about files + core::array FileInfo; + + bool IsGZip; + }; + + +} // end namespace io +} // end namespace irr + +#endif // __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_ +#endif // __C_ZIP_READER_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/IAttribute.h b/src/others/irrlicht-1.8.1/source/Irrlicht/IAttribute.h new file mode 100644 index 0000000..69d499f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/IAttribute.h @@ -0,0 +1,107 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_ATTRIBUTE_H_INCLUDED__ +#define __I_ATTRIBUTE_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "SColor.h" +#include "vector3d.h" +#include "vector2d.h" +#include "line2d.h" +#include "line3d.h" +#include "triangle3d.h" +#include "position2d.h" +#include "rect.h" +#include "dimension2d.h" +#include "matrix4.h" +#include "quaternion.h" +#include "plane3d.h" +#include "triangle3d.h" +#include "line2d.h" +#include "line3d.h" +#include "irrString.h" +#include "irrArray.h" +#include "EAttributes.h" + + +namespace irr +{ +namespace io +{ + +class IAttribute : public virtual IReferenceCounted +{ +public: + + virtual ~IAttribute() {}; + + virtual s32 getInt() { return 0; } + virtual f32 getFloat() { return 0; } + virtual video::SColorf getColorf() { return video::SColorf(1.0f,1.0f,1.0f,1.0f); } + virtual video::SColor getColor() { return video::SColor(255,255,255,255); } + virtual core::stringc getString() { return core::stringc(getStringW().c_str()); } + virtual core::stringw getStringW() { return core::stringw(); } + virtual core::array getArray() { return core::array(); }; + virtual bool getBool() { return false; } + virtual void getBinary(void* outdata, s32 maxLength) {}; + virtual core::vector3df getVector() { return core::vector3df(); } + virtual core::position2di getPosition() { return core::position2di(); } + virtual core::rect getRect() { return core::rect(); } + virtual core::quaternion getQuaternion(){ return core::quaternion(); } + virtual core::matrix4 getMatrix() { return core::matrix4(); } + virtual core::triangle3df getTriangle() { return core::triangle3df(); } + virtual core::vector2df getVector2d() { return core::vector2df(); } + virtual core::vector2di getVector2di() { return core::vector2di(); } + virtual core::line2df getLine2d() { return core::line2df(); } + virtual core::line2di getLine2di() { return core::line2di(); } + virtual core::line3df getLine3d() { return core::line3df(); } + virtual core::line3di getLine3di() { return core::line3di(); } + virtual core::dimension2du getDimension2d() { return core::dimension2du(); } + virtual core::aabbox3d getBBox() { return core::aabbox3d(); } + virtual core::plane3df getPlane() { return core::plane3df(); } + + virtual video::ITexture* getTexture() { return 0; } + virtual const char* getEnum() { return 0; } + virtual void* getUserPointer() { return 0; } + + virtual void setInt(s32 intValue) {}; + virtual void setFloat(f32 floatValue) {}; + virtual void setString(const char* text) {}; + virtual void setString(const wchar_t* text){ setString(core::stringc(text).c_str()); }; + virtual void setArray(const core::array& arr ) {}; + virtual void setColor(video::SColorf color) {}; + virtual void setColor(video::SColor color) {}; + virtual void setBool(bool boolValue) {}; + virtual void setBinary(void* data, s32 maxLenght) {}; + virtual void setVector(core::vector3df v) {}; + virtual void setPosition(core::position2di v) {}; + virtual void setRect(core::rect v) {}; + virtual void setQuaternion(core::quaternion v) {}; + virtual void setMatrix(core::matrix4 v) {}; + virtual void setTriangle(core::triangle3df v) {}; + virtual void setVector2d(core::vector2df v) {}; + virtual void setVector2d(core::vector2di v) {}; + virtual void setLine2d(core::line2df v) {}; + virtual void setLine2d(core::line2di v) {}; + virtual void setLine3d(core::line3df v) {}; + virtual void setLine3d(core::line3di v) {}; + virtual void setDimension2d(core::dimension2du v) {}; + virtual void setBBox(core::aabbox3d v) {}; + virtual void setPlane(core::plane3df v) {}; + virtual void setUserPointer(void* v) {}; + + virtual void setEnum(const char* enumValue, const char* const* enumerationLiterals) {}; + virtual void setTexture(video::ITexture*, const path& filename) {}; + + core::stringc Name; + + virtual E_ATTRIBUTE_TYPE getType() const = 0; + virtual const wchar_t* getTypeString() const = 0; +}; + +} // end namespace io +} // end namespace irr + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.cpp new file mode 100644 index 0000000..b4856b8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" +#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + +#include "SoftwareDriver2_compile_config.h" +#include "IBurningShader.h" +#include "CSoftwareDriver2.h" + +namespace irr +{ +namespace video +{ + + const tFixPointu IBurningShader::dithermask[] = + { + 0x00,0x80,0x20,0xa0, + 0xc0,0x40,0xe0,0x60, + 0x30,0xb0,0x10,0x90, + 0xf0,0x70,0xd0,0x50 + }; + + IBurningShader::IBurningShader(CBurningVideoDriver* driver) + { + #ifdef _DEBUG + setDebugName("IBurningShader"); + #endif + + for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i ) + { + IT[i].Texture = 0; + } + + Driver = driver; + RenderTarget = 0; + ColorMask = COLOR_BRIGHT_WHITE; + DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer (); + if ( DepthBuffer ) + DepthBuffer->grab(); + + Stencil = (CStencilBuffer*) driver->getStencilBuffer (); + if ( Stencil ) + Stencil->grab(); + + } + + + //! destructor + IBurningShader::~IBurningShader() + { + if (RenderTarget) + RenderTarget->drop(); + + if (DepthBuffer) + DepthBuffer->drop(); + + if (Stencil) + Stencil->drop(); + + for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i ) + { + if ( IT[i].Texture ) + IT[i].Texture->drop(); + } + } + + //! sets a render target + void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect& viewPort) + { + if (RenderTarget) + RenderTarget->drop(); + + RenderTarget = (video::CImage* ) surface; + + if (RenderTarget) + { + RenderTarget->grab(); + + //(tVideoSample*)RenderTarget->lock() = (tVideoSample*)RenderTarget->lock(); + //(fp24*) DepthBuffer->lock() = DepthBuffer->lock(); + } + } + + + //! sets the Texture + void IBurningShader::setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel) + { + sInternalTexture *it = &IT[stage]; + + if ( it->Texture) + it->Texture->drop(); + + it->Texture = texture; + + if ( it->Texture) + { + it->Texture->grab(); + + // select mignify and magnify ( lodLevel ) + //SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS + it->lodLevel = lodLevel; + it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, + core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 )); + + // prepare for optimal fixpoint + it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() ); + + const core::dimension2d &dim = it->Texture->getSize(); + it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK; + it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK; + } + } + + +} // end namespace video +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.h b/src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.h new file mode 100644 index 0000000..50f1059 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/IBurningShader.h @@ -0,0 +1,201 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_BURNING_SHADER_H_INCLUDED__ +#define __I_BURNING_SHADER_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "IReferenceCounted.h" +#include "irrMath.h" +#include "IImage.h" +#include "S2DVertex.h" +#include "rect.h" +#include "CDepthBuffer.h" +#include "S4DVertex.h" +#include "irrArray.h" +#include "SLight.h" +#include "SMaterial.h" +#include "os.h" + + +namespace irr +{ + +namespace video +{ + + struct SBurningShaderLight + { + //SLight org; + bool LightIsOn; + + E_LIGHT_TYPE Type; + f32 radius; + f32 linearAttenuation; + f32 constantAttenuation; + f32 quadraticAttenuation; + sVec4 pos; + + sVec3 AmbientColor; + sVec3 DiffuseColor; + sVec3 SpecularColor; + sVec4 pos_objectspace; + }; + + enum eLightFlags + { + ENABLED = 0x01, + POINTLIGHT = 0x02, + SPECULAR = 0x04, + FOG = 0x08, + NORMALIZE = 0x10, + VERTEXTRANSFORM = 0x20, + }; + + struct SBurningShaderLightSpace + { + void reset () + { + Light.set_used ( 0 ); + Global_AmbientLight.set ( 0.f, 0.f, 0.f ); + Flags = 0; + } + core::array Light; + sVec3 Global_AmbientLight; + sVec4 FogColor; + sVec4 campos; + sVec4 vertex; + sVec4 normal; + u32 Flags; + }; + + struct SBurningShaderMaterial + { + SMaterial org; + + sVec3 AmbientColor; + sVec3 DiffuseColor; + sVec3 SpecularColor; + sVec3 EmissiveColor; + + }; + + enum EBurningFFShader + { + ETR_FLAT = 0, + ETR_FLAT_WIRE, + ETR_GOURAUD, + ETR_GOURAUD_WIRE, + ETR_TEXTURE_FLAT, + ETR_TEXTURE_FLAT_WIRE, + ETR_TEXTURE_GOURAUD, + ETR_TEXTURE_GOURAUD_WIRE, + ETR_TEXTURE_GOURAUD_NOZ, + ETR_TEXTURE_GOURAUD_ADD, + ETR_TEXTURE_GOURAUD_ADD_NO_Z, + + ETR_TEXTURE_GOURAUD_VERTEX_ALPHA, + + ETR_TEXTURE_GOURAUD_LIGHTMAP_M1, + ETR_TEXTURE_GOURAUD_LIGHTMAP_M2, + ETR_TEXTURE_GOURAUD_LIGHTMAP_M4, + ETR_TEXTURE_LIGHTMAP_M4, + + ETR_TEXTURE_GOURAUD_DETAIL_MAP, + ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD, + + ETR_GOURAUD_ALPHA, + ETR_GOURAUD_ALPHA_NOZ, + + ETR_TEXTURE_GOURAUD_ALPHA, + ETR_TEXTURE_GOURAUD_ALPHA_NOZ, + + ETR_NORMAL_MAP_SOLID, + ETR_STENCIL_SHADOW, + + ETR_TEXTURE_BLEND, + ETR_REFERENCE, + ETR_INVALID, + + ETR2_COUNT + }; + + + class CBurningVideoDriver; + class IBurningShader : public virtual IReferenceCounted + { + public: + IBurningShader(CBurningVideoDriver* driver); + + //! destructor + virtual ~IBurningShader(); + + //! sets a render target + virtual void setRenderTarget(video::IImage* surface, const core::rect& viewPort); + + //! sets the Texture + virtual void setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel); + virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0; + virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {}; + + virtual void setParam ( u32 index, f32 value) {}; + virtual void setZCompareFunc ( u32 func) {}; + + virtual void setMaterial ( const SBurningShaderMaterial &material ) {}; + + protected: + + CBurningVideoDriver *Driver; + + video::CImage* RenderTarget; + CDepthBuffer* DepthBuffer; + CStencilBuffer * Stencil; + tVideoSample ColorMask; + + sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ]; + + static const tFixPointu dithermask[ 4 * 4]; + }; + + + IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver); + + + IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver); + IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureFlat2(CBurningVideoDriver* driver); + IBurningShader* createTriangleRendererTextureFlatWire2(CBurningVideoDriver* driver); + IBurningShader* createTRFlat2(CBurningVideoDriver* driver); + IBurningShader* createTRFlatWire2(CBurningVideoDriver* driver); + IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver); + IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver); + IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver); + + IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver); + IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver); + IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver); + IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver); + + IBurningShader* createTRNormalMap(CBurningVideoDriver* driver); + IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver); + + IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver); + + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/IDepthBuffer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/IDepthBuffer.h new file mode 100644 index 0000000..719d9f1 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/IDepthBuffer.h @@ -0,0 +1,82 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Z2_BUFFER_H_INCLUDED__ +#define __I_Z2_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" +#include "S4DVertex.h" + +namespace irr +{ +namespace video +{ + class IDepthBuffer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IDepthBuffer() {}; + + //! clears the zbuffer + virtual void clear() = 0; + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size) = 0; + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const = 0; + + //! locks the zbuffer + virtual void* lock() = 0; + + //! unlocks the zbuffer + virtual void unlock() = 0; + + //! returns pitch of depthbuffer (in bytes) + virtual u32 getPitch() const = 0; + + }; + + + //! creates a ZBuffer + IDepthBuffer* createDepthBuffer(const core::dimension2d& size); + + class IStencilBuffer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IStencilBuffer() {}; + + //! clears the zbuffer + virtual void clear() = 0; + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size) = 0; + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const = 0; + + //! locks the zbuffer + virtual void* lock() = 0; + + //! unlocks the zbuffer + virtual void unlock() = 0; + + //! returns pitch of depthbuffer (in bytes) + virtual u32 getPitch() const = 0; + + }; + + + //! creates a Stencil Buffer + IStencilBuffer* createStencilBuffer(const core::dimension2d& size); + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/IImagePresenter.h b/src/others/irrlicht-1.8.1/source/Irrlicht/IImagePresenter.h new file mode 100644 index 0000000..4f083f0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/IImagePresenter.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_IMAGE_PRESENTER_H_INCLUDED__ +#define __I_IMAGE_PRESENTER_H_INCLUDED__ + +#include "IImage.h" + +namespace irr +{ +namespace video +{ + +/*! + Interface for a class which is able to present an IImage + an the Screen. Usually only implemented by an IrrDevice for + presenting Software Device Rendered images. + + This class should be used only internally. +*/ + + class IImagePresenter + { + public: + + virtual ~IImagePresenter() {}; + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0 ) = 0; + }; + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/ISceneNodeAnimatorFinishing.h b/src/others/irrlicht-1.8.1/source/Irrlicht/ISceneNodeAnimatorFinishing.h new file mode 100644 index 0000000..6535a6c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/ISceneNodeAnimatorFinishing.h @@ -0,0 +1,36 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_SCENE_NODE_ANIMATOR_FINISHING_H_INCLUDED__ +#define __I_SCENE_NODE_ANIMATOR_FINISHING_H_INCLUDED__ + +#include "ISceneNode.h" + +namespace irr +{ +namespace scene +{ + //! This is an abstract base class for animators that have a discrete end time. + class ISceneNodeAnimatorFinishing : public ISceneNodeAnimator + { + public: + + //! constructor + ISceneNodeAnimatorFinishing(u32 finishTime) + : FinishTime(finishTime), HasFinished(false) { } + + virtual bool hasFinished(void) const { return HasFinished; } + + protected: + + u32 FinishTime; + bool HasFinished; + }; + + +} // end namespace scene +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/ITriangleRenderer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/ITriangleRenderer.h new file mode 100644 index 0000000..629a736 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/ITriangleRenderer.h @@ -0,0 +1,68 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_TRIANGLE_RENDERER_H_INCLUDED__ +#define __I_TRIANGLE_RENDERER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "S2DVertex.h" +#include "rect.h" +#include "IZBuffer.h" + +namespace irr +{ +namespace video +{ + class IImage; + + enum ETriangleRenderer + { + ETR_FLAT = 0, + ETR_FLAT_WIRE, + ETR_GOURAUD, + ETR_GOURAUD_WIRE, + ETR_TEXTURE_FLAT, + ETR_TEXTURE_FLAT_WIRE, + ETR_TEXTURE_GOURAUD, + ETR_TEXTURE_GOURAUD_WIRE, + ETR_TEXTURE_GOURAUD_NOZ, + ETR_TEXTURE_GOURAUD_ADD, + ETR_COUNT + }; + + class ITriangleRenderer : public virtual IReferenceCounted + { + public: + + //! sets a render target + virtual void setRenderTarget(video::IImage* surface, const core::rect& viewPort) = 0; + + //! en or disables the backface culling + virtual void setBackfaceCulling(bool enabled = true) = 0; + + //! sets the Texture + virtual void setTexture(video::IImage* texture) = 0; + + //! draws an indexed triangle list + virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount) = 0; + }; + + + ITriangleRenderer* createTriangleRendererTextureGouraud(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureGouraudWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererGouraud(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererGouraudWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureFlat(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureFlatWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererFlat(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererFlatWire(IZBuffer* zbuffer); + ITriangleRenderer* createTriangleRendererTextureGouraudNoZ(); + ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer); + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/IZBuffer.h b/src/others/irrlicht-1.8.1/source/Irrlicht/IZBuffer.h new file mode 100644 index 0000000..2c235a8 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/IZBuffer.h @@ -0,0 +1,47 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __I_Z_BUFFER_H_INCLUDED__ +#define __I_Z_BUFFER_H_INCLUDED__ + +#include "IReferenceCounted.h" +#include "dimension2d.h" +#include "S2DVertex.h" + +namespace irr +{ +namespace video +{ + class IZBuffer : public virtual IReferenceCounted + { + public: + + //! destructor + virtual ~IZBuffer() {}; + + //! clears the zbuffer + virtual void clear() = 0; + + //! sets the new size of the zbuffer + virtual void setSize(const core::dimension2d& size) = 0; + + //! returns the size of the zbuffer + virtual const core::dimension2d& getSize() const = 0; + + //! locks the zbuffer + virtual TZBufferType* lock() = 0; + + //! unlocks the zbuffer + virtual void unlock() = 0; + }; + + + //! creates a ZBuffer + IZBuffer* createZBuffer(const core::dimension2d& size); + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht-gcc.cbp b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht-gcc.cbp new file mode 100644 index 0000000..073b409 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht-gcc.cbp @@ -0,0 +1,1323 @@ + + + + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.aps b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.aps new file mode 100644 index 0000000..1c5c2c9 Binary files /dev/null and b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.aps differ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.cpp new file mode 100644 index 0000000..da0043b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.cpp @@ -0,0 +1,154 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "IrrCompileConfig.h" + +static const char* const copyright = "Irrlicht Engine (c) 2002-2012 Nikolaus Gebhardt"; + +#ifdef _IRR_WINDOWS_ + #include + #if defined(_DEBUG) && !defined(__GNUWIN32__) && !defined(_WIN32_WCE) + #include + #endif // _DEBUG +#endif + +#include "irrlicht.h" +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ +#include "CIrrDeviceWin32.h" +#endif + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ +#include "MacOSX/CIrrDeviceMacOSX.h" +#endif + +#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ +#include "CIrrDeviceWinCE.h" +#endif + +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ +#include "CIrrDeviceLinux.h" +#endif + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ +#include "CIrrDeviceSDL.h" +#endif + +#ifdef _IRR_COMPILE_WITH_FB_DEVICE_ +#include "CIrrDeviceFB.h" +#endif + +#ifdef _IRR_COMPILE_WITH_CONSOLE_DEVICE_ +#include "CIrrDeviceConsole.h" +#endif + +namespace irr +{ + //! stub for calling createDeviceEx + IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDevice(video::E_DRIVER_TYPE driverType, + const core::dimension2d& windowSize, + u32 bits, bool fullscreen, + bool stencilbuffer, bool vsync, IEventReceiver* res) + { + SIrrlichtCreationParameters p; + p.DriverType = driverType; + p.WindowSize = windowSize; + p.Bits = (u8)bits; + p.Fullscreen = fullscreen; + p.Stencilbuffer = stencilbuffer; + p.Vsync = vsync; + p.EventReceiver = res; + + return createDeviceEx(p); + } + + extern "C" IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& params) + { + + IrrlichtDevice* dev = 0; + +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + if (params.DeviceType == EIDT_WIN32 || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceWin32(params); +#endif + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + if (params.DeviceType == EIDT_OSX || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceMacOSX(params); +#endif + +#ifdef _IRR_COMPILE_WITH_WINDOWS_CE_DEVICE_ + if (params.DeviceType == EIDT_WINCE || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceWinCE(params); +#endif + +#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ + if (params.DeviceType == EIDT_X11 || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceLinux(params); +#endif + +#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_ + if (params.DeviceType == EIDT_SDL || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceSDL(params); +#endif + +#ifdef _IRR_COMPILE_WITH_FB_DEVICE_ + if (params.DeviceType == EIDT_FRAMEBUFFER || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceFB(params); +#endif + +#ifdef _IRR_COMPILE_WITH_CONSOLE_DEVICE_ + if (params.DeviceType == EIDT_CONSOLE || (!dev && params.DeviceType == EIDT_BEST)) + dev = new CIrrDeviceConsole(params); +#endif + + if (dev && !dev->getVideoDriver() && params.DriverType != video::EDT_NULL) + { + dev->closeDevice(); // destroy window + dev->run(); // consume quit message + dev->drop(); + dev = 0; + } + + return dev; + } + +namespace core +{ + const matrix4 IdentityMatrix(matrix4::EM4CONST_IDENTITY); + irr::core::stringc LOCALE_DECIMAL_POINTS("."); +} + +namespace video +{ + SMaterial IdentityMaterial; +} + +} // end namespace irr + + +#if defined(_IRR_WINDOWS_API_) + +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved ) +{ + // _crtBreakAlloc = 139; + + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + #if defined(_DEBUG) && !defined(__GNUWIN32__) && !defined(__BORLANDC__) && !defined (_WIN32_WCE) && !defined (_IRR_XBOX_PLATFORM_) + _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); + #endif + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +#endif // defined(_IRR_WINDOWS_) + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.dev b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.dev new file mode 100644 index 0000000..704da54 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.dev @@ -0,0 +1,6630 @@ +[Project] +FileName=Irrlicht.dev +Name=Irrlicht +Ver=1 +IsCpp=1 +Type=3 +Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIRRLICHT_EXPORTS_@@_ +CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -D_USRDLL -DIRRLICHT_EXPORTS_@@_ +Includes=..\..\include;zlib +Linker=-lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lwinmm -lopengl32_@@_ +Libs= +UnitCount=658 +Folders=doc,include,include/core,include/gui,include/io,include/scene,include/video,Irrlicht,Irrlicht/extern,Irrlicht/extern/jpeglib,Irrlicht/extern/libpng,Irrlicht/extern/zlib,Irrlicht/extern/aesGladman,Irrlicht/gui,Irrlicht/io,Irrlicht/io/archive,Irrlicht/io/attributes,Irrlicht/io/file,Irrlicht/io/xml,Irrlicht/irr,Irrlicht/irr/IrrlichtDevice,Irrlicht/scene,Irrlicht/scene/animators,Irrlicht/scene/collision,Irrlicht/scene/mesh,Irrlicht/scene/mesh/loaders,Irrlicht/scene/mesh/writers,Irrlicht/scene/nodes,Irrlicht/scene/nodes/particles,Irrlicht/video,"Irrlicht/video/Burning Video",Irrlicht/video/DirectX8,Irrlicht/video/DirectX9,Irrlicht/video/Null,Irrlicht/video/Null/Loader,Irrlicht/video/Null/Writer,Irrlicht/video/OpenGL,Irrlicht/video/Software +ObjFiles= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Icon= +ExeOutput=..\..\bin\Win32-gcc +ObjectOutput=obj +OverrideOutput=1 +OverrideOutputName=Irrlicht.dll +HostApplication= +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000001001000000100 + +[Unit1] +FileName=..\..\include\EDriverTypes.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\include\ITexture.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\include\IVideoDriver.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\include\S3DVertex.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\include\SColor.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\include\SLight.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\include\SMaterial.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\include\aabbox3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\include\dimension2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\include\heapsort.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\include\irrArray.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\include\irrList.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\include\irrMath.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\include\irrString.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\include\line2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\include\line3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\include\matrix4.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\include\plane3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\include\position2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\include\rect.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\include\vector2d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\include\vector3d.h +Folder=include/core +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\include\IFileList.h +Folder=include/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\include\IFileSystem.h +Folder=include/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\include\IReadFile.H +Folder=include/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\include\IAnimatedMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\include\IAnimatedMeshSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\include\IBillboardSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\include\ICameraSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\include\ILightSceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\include\IMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\include\IMeshBuffer.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\include\IQ3LevelMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\include\ISceneManager.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\include\ISceneNode.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\include\ISceneNodeAnimator.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\include\SMesh.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\include\SMeshBuffer.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\include\SMeshBufferLightMap.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\include\ICursorControl.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\include\IGUIButton.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\include\IGUICheckbox.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\include\IGUIElement.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\include\IGUIEnvironment.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit45] +FileName=..\..\include\IGUIFileOpenDialog.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit46] +FileName=..\..\include\IGUIFont.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\include\IGUIImage.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\include\IGUIListBox.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\include\IGUIMeshViewer.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\include\IGUIScrollBar.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\include\IGUISkin.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\include\IGUIWindow.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\include\IEventReceiver.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\include\Irrlicht.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\include\IrrlichtDevice.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\include\irrTypes.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\include\Keycodes.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\include\SIrrCreationParameters.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=BuiltInFont.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=CGUIButton.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=CGUIButton.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=CGUICheckbox.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=CGUICheckbox.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=CGUIComboBox.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=CGUIComboBox.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=CGUIContextMenu.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=CGUIContextMenu.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=CGUIEditBox.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=CGUIEditBox.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=CGUIEnvironment.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=CGUIEnvironment.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=CGUIFileOpenDialog.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=CGUIFileOpenDialog.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=CGUIFont.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit75] +FileName=CGUIFont.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=CGUIImage.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=CGUIImage.H +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=CGUIInOutFader.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=CGUIInOutFader.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=CGUIListBox.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=CGUIListBox.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=CGUIMenu.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=CGUIMenu.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=CGUIMeshViewer.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=CGUIMeshViewer.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=CGUIMessageBox.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=CGUIMessageBox.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=CGUIModalScreen.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=CGUIModalScreen.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=CGUIScrollBar.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=CGUIScrollBar.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit92] +FileName=CGUISkin.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=CGUISkin.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=CGUIStaticText.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=CGUIStaticText.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=CGUITabControl.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=CGUITabControl.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=CGUIToolBar.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit99] +FileName=CGUIToolBar.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=CGUIWindow.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=CGUIWindow.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=CSoftwareDriver.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=CSoftwareDriver.h +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit104] +FileName=CSoftwareTexture.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit105] +FileName=CSoftwareTexture.h +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit106] +FileName=CTRFlat.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=CTRFlatWire.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=CTRGouraud.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=CTRGouraudWire.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=CTRTextureFlat.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=CTRTextureFlatWire.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=CTRTextureGouraud.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit113] +FileName=CTRTextureGouraud.h +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit114] +FileName=CTRTextureGouraudAdd.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=CTRTextureGouraudNoZ.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=CTRTextureGouraudWire.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=CZBuffer.cpp +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=CZBuffer.h +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=IZBuffer.h +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=S2DVertex.h +Folder=Irrlicht/video/Software +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit121] +FileName=COpenGLDriver.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=COpenGLDriver.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit123] +FileName=COpenGLMaterialRenderer.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit124] +FileName=COpenGLNormalMapRenderer.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=COpenGLNormalMapRenderer.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit126] +FileName=COpenGLParallaxMapRenderer.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit127] +FileName=COpenGLParallaxMapRenderer.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit128] +FileName=COpenGLShaderMaterialRenderer.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit129] +FileName=COpenGLShaderMaterialRenderer.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit130] +FileName=COpenGLTexture.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit131] +FileName=COpenGLTexture.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit132] +FileName=glext.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit133] +FileName=CD3D8Driver.cpp +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit134] +FileName=CD3D8Driver.h +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit135] +FileName=CD3D8MaterialRenderer.h +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit136] +FileName=CD3D8NormalMapRenderer.cpp +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit137] +FileName=CD3D8NormalMapRenderer.h +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit138] +FileName=CD3D8ParallaxMapRenderer.cpp +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit139] +FileName=CD3D8ParallaxMapRenderer.h +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit140] +FileName=CD3D8ShaderMaterialRenderer.cpp +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit141] +FileName=CD3D8ShaderMaterialRenderer.h +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit142] +FileName=CD3D8Texture.cpp +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit143] +FileName=CD3D8Texture.h +Folder=Irrlicht/video/DirectX8 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit144] +FileName=CColorConverter.cpp +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit145] +FileName=CColorConverter.h +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit146] +FileName=CFPSCounter.cpp +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit147] +FileName=CFPSCounter.h +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit148] +FileName=CImage.cpp +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit149] +FileName=CImage.h +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit150] +FileName=CImageLoaderBMP.cpp +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit151] +FileName=CImageLoaderBMP.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit152] +FileName=CImageLoaderJPG.cpp +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit153] +FileName=CImageLoaderJPG.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit154] +FileName=CImageLoaderPCX.cpp +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit155] +FileName=CImageLoaderPCX.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit156] +FileName=CImageLoaderPNG.cpp +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit157] +FileName=CImageLoaderPNG.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit158] +FileName=CImageLoaderPSD.cpp +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit159] +FileName=CImageLoaderPSD.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit160] +FileName=CImageLoaderTGA.cpp +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit161] +FileName=CImageLoaderTGA.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit162] +FileName=CNullDriver.cpp +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit163] +FileName=CNullDriver.h +Folder=Irrlicht/video/Null +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit164] +FileName=CD3D9Driver.cpp +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit165] +FileName=CD3D9Driver.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit166] +FileName=CD3D9HLSLMaterialRenderer.cpp +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit167] +FileName=CD3D9HLSLMaterialRenderer.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit168] +FileName=CD3D9MaterialRenderer.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit169] +FileName=CD3D9NormalMapRenderer.cpp +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit170] +FileName=CD3D9NormalMapRenderer.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit171] +FileName=CD3D9ParallaxMapRenderer.cpp +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit172] +FileName=CD3D9ParallaxMapRenderer.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit173] +FileName=CD3D9ShaderMaterialRenderer.cpp +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit174] +FileName=CD3D9ShaderMaterialRenderer.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit175] +FileName=CD3D9Texture.cpp +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit176] +FileName=CD3D9Texture.h +Folder=Irrlicht/video/DirectX9 +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit177] +FileName=CVideoModeList.cpp +Folder=Irrlicht/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit178] +FileName=CVideoModeList.h +Folder=Irrlicht/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit179] +FileName=C3DSMeshFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit180] +FileName=C3DSMeshFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit181] +FileName=CAnimatedMeshMD2.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit182] +FileName=CAnimatedMeshMD2.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit183] +FileName=CAnimatedMeshSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit184] +FileName=CAnimatedMeshSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit185] +FileName=CBillboardSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit186] +FileName=CBillboardSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit187] +FileName=CCameraSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit188] +FileName=CCameraSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit189] +FileName=CColladaFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit190] +FileName=CColladaFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit191] +FileName=CCSMLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit192] +FileName=CCSMLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit193] +FileName=CDMFLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit194] +FileName=CDMFLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit195] +FileName=CDummyTransformationSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit196] +FileName=CDummyTransformationSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit197] +FileName=CEmptySceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit198] +FileName=CEmptySceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit199] +FileName=CGeometryCreator.cpp +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit200] +FileName=CGeometryCreator.h +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit201] +FileName=CLightSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit202] +FileName=CLightSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit203] +FileName=CLMTSMeshFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit204] +FileName=CLMTSMeshFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit205] +FileName=CMeshManipulator.cpp +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit206] +FileName=CMeshManipulator.h +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit207] +FileName=CMeshSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit208] +FileName=CMeshSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit209] +FileName=CMetaTriangleSelector.cpp +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit210] +FileName=CMetaTriangleSelector.h +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit211] +FileName=CMY3DHelper.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit212] +FileName=CMY3DMeshFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit213] +FileName=CMY3DMeshFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit214] +FileName=..\..\include\EGUIAlignment.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit215] +FileName=COCTLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit216] +FileName=COCTLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit217] +FileName=COctreeSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit218] +FileName=COctreeSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit219] +FileName=COctreeTriangleSelector.cpp +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit220] +FileName=COctreeTriangleSelector.h +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit221] +FileName=CParticleBoxEmitter.cpp +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit222] +FileName=CParticleBoxEmitter.h +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit223] +FileName=CParticleFadeOutAffector.cpp +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit224] +FileName=CParticleFadeOutAffector.h +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit225] +FileName=CParticleGravityAffector.cpp +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit226] +FileName=CParticleGravityAffector.h +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit227] +FileName=CParticlePointEmitter.cpp +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit228] +FileName=CParticlePointEmitter.h +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit229] +FileName=CParticleSystemSceneNode.cpp +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit230] +FileName=CParticleSystemSceneNode.h +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit231] +FileName=CQ3LevelMesh.cpp +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit232] +FileName=CQ3LevelMesh.h +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit233] +FileName=CSceneCollisionManager.cpp +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit234] +FileName=CSceneCollisionManager.h +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit235] +FileName=CSceneManager.cpp +Folder=Irrlicht/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit236] +FileName=CSceneManager.h +Folder=Irrlicht/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit237] +FileName=CSceneNodeAnimatorCollisionResponse.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit238] +FileName=CSceneNodeAnimatorCollisionResponse.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit239] +FileName=CSceneNodeAnimatorDelete.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit240] +FileName=CSceneNodeAnimatorDelete.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit241] +FileName=CSceneNodeAnimatorFlyCircle.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit242] +FileName=CSceneNodeAnimatorFlyCircle.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit243] +FileName=CSceneNodeAnimatorFlyStraight.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit244] +FileName=CSceneNodeAnimatorFlyStraight.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit245] +FileName=CSceneNodeAnimatorFollowSpline.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit246] +FileName=CSceneNodeAnimatorFollowSpline.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit247] +FileName=CSceneNodeAnimatorRotation.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit248] +FileName=CSceneNodeAnimatorRotation.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit249] +FileName=CSceneNodeAnimatorTexture.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit250] +FileName=CSceneNodeAnimatorTexture.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit251] +FileName=CShadowVolumeSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit252] +FileName=CShadowVolumeSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit253] +FileName=CSkyBoxSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit254] +FileName=CSkyBoxSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit255] +FileName=COBJMeshFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit256] +FileName=COBJMeshFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit257] +FileName=CTerrainSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit258] +FileName=CTerrainSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit259] +FileName=CTerrainTriangleSelector.cpp +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit260] +FileName=CTerrainTriangleSelector.h +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit261] +FileName=CTextSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit262] +FileName=CTextSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit263] +FileName=CTriangleBBSelector.cpp +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit264] +FileName=CTriangleBBSelector.h +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit265] +FileName=CTriangleSelector.cpp +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit266] +FileName=CTriangleSelector.h +Folder=Irrlicht/scene/collision +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit267] +FileName=CWaterSurfaceSceneNode.cpp +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit268] +FileName=CWaterSurfaceSceneNode.h +Folder=Irrlicht/scene/nodes +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit269] +FileName=..\..\include\SExposedVideoData.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit270] +FileName=..\..\include\SKeyMap.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit271] +FileName=..\..\include\SMeshBufferTangents.h +Folder=include/video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit272] +FileName=..\..\include\SParticle.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit273] +FileName=CXMeshFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit274] +FileName=CXMeshFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit275] +FileName=Octree.h +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit276] +FileName=CFileList.cpp +Folder=Irrlicht/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit277] +FileName=CFileList.h +Folder=Irrlicht/io +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit278] +FileName=CFileSystem.cpp +CompileCpp=1 +Folder=Irrlicht/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit279] +FileName=CFileSystem.h +CompileCpp=1 +Folder=Irrlicht/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit280] +FileName=CLimitReadFile.cpp +CompileCpp=1 +Folder=Irrlicht/io/file +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit281] +FileName=CLimitReadFile.h +CompileCpp=1 +Folder=Irrlicht/io/file +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit282] +FileName=CMemoryFile.cpp +Folder=Irrlicht/io/file +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit283] +FileName=CMemoryFile.h +Folder=Irrlicht/io/file +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit284] +FileName=CReadFile.cpp +Folder=Irrlicht/io/file +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit285] +FileName=CReadFile.h +Folder=Irrlicht/io/file +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit286] +FileName=CWriteFile.cpp +Folder=Irrlicht/io/file +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit287] +FileName=CWriteFile.h +Folder=Irrlicht/io/file +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit288] +FileName=CXMLReader.cpp +Folder=Irrlicht/io/xml +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit289] +FileName=CXMLReader.h +Folder=Irrlicht/io/xml +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit290] +FileName=CXMLWriter.cpp +Folder=Irrlicht/io/xml +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit291] +FileName=CXMLWriter.h +Folder=Irrlicht/io/xml +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit292] +FileName=CZipReader.cpp +Folder=Irrlicht/io/archive +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit293] +FileName=CZipReader.h +Folder=Irrlicht/io/archive +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit294] +FileName=irrXML.cpp +Folder=Irrlicht/io/xml +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit295] +FileName=zlib\adler32.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit296] +FileName=zlib\compress.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit297] +FileName=zlib\crc32.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit298] +FileName=zlib\crc32.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit299] +FileName=zlib\deflate.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit300] +FileName=zlib\deflate.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit301] +FileName=zlib\inffast.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit302] +FileName=zlib\inffast.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit303] +FileName=zlib\inflate.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit304] +FileName=zlib\inftrees.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit305] +FileName=zlib\inftrees.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit306] +FileName=zlib\trees.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit307] +FileName=zlib\trees.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit308] +FileName=zlib\uncompr.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit309] +FileName=zlib\zconf.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit310] +FileName=zlib\zlib.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit311] +FileName=zlib\zutil.c +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit312] +FileName=zlib\zutil.h +Folder=Irrlicht/extern/zlib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit313] +FileName=jpeglib\cderror.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit314] +FileName=CSceneNodeAnimatorCameraFPS.h +CompileCpp=1 +Folder=Irrlicht/scene/animators +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit315] +FileName=CSceneNodeAnimatorCameraMaya.cpp +CompileCpp=1 +Folder=Irrlicht/scene/animators +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit316] +FileName=jpeglib\jcapimin.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit317] +FileName=jpeglib\jcapistd.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit318] +FileName=jpeglib\jccoefct.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit319] +FileName=jpeglib\jccolor.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit320] +FileName=jpeglib\jcdctmgr.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit321] +FileName=jpeglib\jchuff.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit322] +FileName=jpeglib\jchuff.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit323] +FileName=jpeglib\jcinit.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit324] +FileName=jpeglib\jcmainct.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit325] +FileName=jpeglib\jcmarker.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit326] +FileName=jpeglib\jcmaster.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit327] +FileName=jpeglib\jcomapi.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit328] +FileName=jpeglib\jconfig.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit329] +FileName=jpeglib\jcparam.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit330] +FileName=jpeglib\jcarith.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit331] +FileName=jpeglib\jcprepct.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit332] +FileName=jpeglib\jcsample.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit333] +FileName=jpeglib\jctrans.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit334] +FileName=jpeglib\jdapimin.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit335] +FileName=jpeglib\jdapistd.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit336] +FileName=jpeglib\jdatadst.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit337] +FileName=jpeglib\jdatasrc.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit338] +FileName=jpeglib\jdcoefct.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit339] +FileName=jpeglib\jdcolor.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit340] +FileName=jpeglib\jdct.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit341] +FileName=jpeglib\jddctmgr.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit342] +FileName=jpeglib\jdhuff.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit343] +FileName=jpeglib\jdhuff.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit344] +FileName=jpeglib\jdinput.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit345] +FileName=jpeglib\jdmainct.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit346] +FileName=jpeglib\jdmarker.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit347] +FileName=jpeglib\jdmaster.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit348] +FileName=jpeglib\jdmerge.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit349] +FileName=jpeglib\jdarith.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit350] +FileName=jpeglib\jdpostct.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit351] +FileName=jpeglib\jdsample.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit352] +FileName=jpeglib\jdtrans.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit353] +FileName=jpeglib\jerror.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit354] +FileName=jpeglib\jerror.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit355] +FileName=jpeglib\jfdctflt.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit356] +FileName=jpeglib\jfdctfst.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit357] +FileName=jpeglib\jfdctint.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit358] +FileName=jpeglib\jidctflt.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit359] +FileName=jpeglib\jidctfst.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit360] +FileName=jpeglib\jidctint.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit361] +FileName=jpeglib\jaricom.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit362] +FileName=jpeglib\jinclude.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit363] +FileName=jpeglib\jmemmgr.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit364] +FileName=jpeglib\jmemnobs.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit365] +FileName=jpeglib\jmemsys.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit366] +FileName=jpeglib\jmorecfg.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit367] +FileName=jpeglib\jpegint.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit368] +FileName=jpeglib\jpeglib.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit369] +FileName=jpeglib\jquant1.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit370] +FileName=jpeglib\jquant2.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit371] +FileName=jpeglib\jutils.c +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit372] +FileName=jpeglib\jversion.h +Folder=Irrlicht/extern/jpeglib +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit373] +FileName=CMD3MeshFileLoader.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit374] +FileName=CMD3MeshFileLoader.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit375] +FileName=CAnimatedMeshMD3.h +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit376] +FileName=CAnimatedMeshMD3.cpp +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit377] +FileName=CGUISpriteBank.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit378] +FileName=CGUISpriteBank.cpp +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit379] +FileName=..\..\include\IGUIFontBitmap.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit380] +FileName=..\..\include\IGUISpriteBank.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit381] +FileName=COpenGLExtensionHandler.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit382] +FileName=CGUISpinBox.h +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit383] +FileName=CGUISpinBox.cpp +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit384] +FileName=..\..\include\IGUISpinBox.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit385] +FileName=..\..\include\SViewFrustum.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit386] +FileName=..\..\include\triangle3d.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit387] +FileName=libpng\png.c +CompileCpp=0 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit388] +FileName=libpng\png.h +CompileCpp=1 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit389] +FileName=libpng\pngconf.h +CompileCpp=1 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit390] +FileName=libpng\pngerror.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit391] +FileName=libpng\pngget.c +CompileCpp=0 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit392] +FileName=libpng\pngmem.c +CompileCpp=0 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit393] +FileName=libpng\pngpread.c +CompileCpp=0 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit394] +FileName=libpng\pngread.c +CompileCpp=0 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit395] +FileName=libpng\pngrio.c +CompileCpp=0 +Folder=Irrlicht/extern/libpng +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit396] +FileName=libpng\pngrtran.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit397] +FileName=libpng\pngrutil.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit398] +FileName=libpng\pngset.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit399] +FileName=libpng\pngtrans.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit400] +FileName=libpng\pngwio.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit401] +FileName=libpng\pngwrite.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit402] +FileName=libpng\pngwtran.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit403] +FileName=libpng\pngwutil.c +Folder=Irrlicht/extern/libpng +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit404] +FileName=CIrrDeviceLinux.cpp +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit405] +FileName=CIrrDeviceLinux.h +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit406] +FileName=CIrrDeviceStub.cpp +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit407] +FileName=CIrrDeviceStub.h +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit408] +FileName=CIrrDeviceWin32.cpp +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit409] +FileName=CIrrDeviceWin32.h +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit410] +FileName=CLogger.cpp +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit411] +FileName=CLogger.h +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit412] +FileName=COSOperator.cpp +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit413] +FileName=COSOperator.h +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit414] +FileName=CTimer.h +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit415] +FileName=IImagePresenter.h +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit416] +FileName=Irrlicht.cpp +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit417] +FileName=os.cpp +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit418] +FileName=os.h +Folder=Irrlicht/irr +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit419] +FileName=..\..\include\IrrCompileConfig.h +Folder=include +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit420] +FileName=CMeshCache.h +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit421] +FileName=CMeshCache.cpp +Folder=Irrlicht/scene/mesh +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit422] +FileName=COpenGLSLMaterialRenderer.h +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit423] +FileName=COpenGLSLMaterialRenderer.cpp +Folder=Irrlicht/video/OpenGL +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit424] +FileName=CSoftwareTexture2.h +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit425] +FileName=S4DVertex.h +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit426] +FileName=SoftwareDriver2_compile_config.h +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit427] +FileName=CSoftwareDriver2.h +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit428] +FileName=CTRTextureGouraudNoZ2.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit429] +FileName=CTRTextureLightMap2_M2.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit430] +FileName=CTRTextureLightMap2_M4.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit431] +FileName=CTRTextureLightMap2_M1.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit432] +FileName=SoftwareDriver2_helper.h +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit433] +FileName=CSoftwareDriver2.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit434] +FileName=CSoftwareTexture2.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit435] +FileName=CTRTextureGouraud2.cpp +Folder=Irrlicht/video/Burning Video +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion=0.1 +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename=Irrlicht.dll +ProductName=Irrlicht +ProductVersion=0.1 +AutoIncBuildNr=0 + +[Unit436] +FileName=COgreMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit437] +FileName=COgreMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit438] +FileName=CDefaultSceneNodeFactory.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit439] +FileName=CDefaultSceneNodeAnimatorFactory.cpp +CompileCpp=1 +Folder=Irrlicht/scene/animators +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit440] +FileName=CDefaultSceneNodeAnimatorFactory.h +CompileCpp=1 +Folder=Irrlicht/scene/animators +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit441] +FileName=CDefaultSceneNodeFactory.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit442] +FileName=CAttributes.h +CompileCpp=1 +Folder=Irrlicht/io/attributes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit443] +FileName=CAttributeImpl.h +CompileCpp=1 +Folder=Irrlicht/io/attributes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit444] +FileName=CAttributes.cpp +CompileCpp=1 +Folder=Irrlicht/io/attributes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit445] +FileName=CCubeSceneNode.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit446] +FileName=CCubeSceneNode.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit447] +FileName=CTRTextureGouraudAddNoZ2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit448] +FileName=CTRTextureGouraudAdd2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit449] +FileName=CTRGouraud2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit450] +FileName=CTRGouraudAlpha2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit451] +FileName=CTRGouraudAlphaNoZ2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit452] +FileName=CTRTextureDetailMap2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit453] +FileName=CTRTextureLightMap2_Add.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit454] +FileName=CTRTextureWire2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit455] +FileName=CTRTextureGouraudVertexAlpha2.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit456] +FileName=..\..\changes.txt +CompileCpp=1 +Folder=doc +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit457] +FileName=..\..\readme.txt +CompileCpp=1 +Folder=doc +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit458] +FileName=CSphereSceneNode.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit459] +FileName=CSphereSceneNode.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit460] +FileName=CPakReader.h +CompileCpp=1 +Folder=Irrlicht/io/archive +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit461] +FileName=CPakReader.cpp +CompileCpp=1 +Folder=Irrlicht/io/archive +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit462] +FileName=CSkyDomeSceneNode.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit463] +FileName=CSkyDomeSceneNode.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit464] +FileName=CImageWriterTGA.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit465] +FileName=CImageWriterBMP.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit466] +FileName=CImageWriterBMP.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit467] +FileName=CImageWriterJPG.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit468] +FileName=CImageWriterJPG.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit469] +FileName=CImageWriterPCX.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit470] +FileName=CImageWriterPCX.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit471] +FileName=CImageWriterPNG.cpp +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=1 + +[Unit472] +FileName=CImageWriterPNG.h +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= +CompileCpp=1 + +[Unit473] +FileName=CImageWriterPPM.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit474] +FileName=CImageWriterPPM.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit475] +FileName=CImageWriterPSD.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit476] +FileName=CImageWriterPSD.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit477] +FileName=CImageWriterTGA.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Writer +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit478] +FileName=CTRTextureLightMapGouraud2_M4.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit479] +FileName=CGUIColorSelectDialog.cpp +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit480] +FileName=IBurningShader.h +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit481] +FileName=IBurningShader.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit482] +FileName=IDepthBuffer.h +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit483] +FileName=CDepthBuffer.h +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit484] +FileName=CDepthBuffer.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit485] +FileName=CQuake3ShaderSceneNode.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit486] +FileName=CQuake3ShaderSceneNode.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit487] +FileName=..\..\include\fast_atof.h +CompileCpp=1 +Folder=include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit488] +FileName=CTRTextureBlend.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit489] +FileName=CTRTextureGouraudAlpha.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit490] +FileName=CTRTextureGouraudAlphaNoZ.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit491] +FileName=CDefaultGUIElementFactory.cpp +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit492] +FileName=CDefaultGUIElementFactory.h +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit493] +FileName=CGUIColorSelectDialog.h +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit494] +FileName=CSoftware2MaterialRenderer.h +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit495] +FileName=CXMLReaderImpl.h +CompileCpp=1 +Folder=Irrlicht/io/xml +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit496] +FileName=ITriangleRenderer.h +CompileCpp=1 +Folder=Irrlicht/video/Software +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit497] +FileName=..\..\include\EGUIElementTypes.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit498] +FileName=..\..\include\ESceneNodeAnimatorTypes.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit499] +FileName=..\..\include\ESceneNodeTypes.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit500] +FileName=..\..\include\ETerrainElements.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit501] +FileName=..\..\include\IAnimatedMeshMD2.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit502] +FileName=..\..\include\IAttributeExchangingObject.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit503] +FileName=..\..\include\IAttributes.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit504] +FileName=..\..\include\IDummyTransformationSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit505] +FileName=..\..\include\IGPUProgrammingServices.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit506] +FileName=..\..\include\IGUIColorSelectDialog.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit507] +FileName=..\..\include\IGUIComboBox.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit508] +FileName=..\..\include\IGUIContextMenu.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit509] +FileName=..\..\include\IGUIEditBox.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit510] +FileName=..\..\include\IGUIElementFactory.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit511] +FileName=..\..\include\IGUIInOutFader.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit512] +FileName=..\..\include\IGUIStaticText.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit513] +FileName=..\..\include\IGUITabControl.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit514] +FileName=..\..\include\IGUIToolbar.h +CompileCpp=1 +Folder=include/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit515] +FileName=..\..\include\IImage.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit516] +FileName=..\..\include\IImageLoader.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit517] +FileName=..\..\include\IImageWriter.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit518] +FileName=..\..\include\ILogger.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit519] +FileName=..\..\include\IMaterialRenderer.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit520] +FileName=..\..\include\IMaterialRendererServices.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit521] +FileName=..\..\include\IMeshCache.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit522] +FileName=..\..\include\IMeshLoader.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit523] +FileName=..\..\include\IMeshManipulator.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit524] +FileName=..\..\include\IMeshSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit525] +FileName=..\..\include\IMetaTriangleSelector.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit526] +FileName=..\..\include\IOSOperator.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit527] +FileName=..\..\include\IParticleAffector.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit528] +FileName=..\..\include\IParticleEmitter.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit529] +FileName=..\..\include\IParticleSystemSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit530] +FileName=..\..\include\IQ3Shader.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit531] +FileName=..\..\include\irrAllocator.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit532] +FileName=..\..\include\irrMap.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit533] +FileName=..\..\include\irrXML.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit534] +FileName=..\..\include\ISceneCollisionManager.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit535] +FileName=..\..\include\ISceneNodeAnimatorCollisionResponse.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit536] +FileName=..\..\include\ISceneNodeAnimatorFactory.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit537] +FileName=..\..\include\ISceneNodeFactory.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit538] +FileName=..\..\include\ISceneUserDataSerializer.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit539] +FileName=..\..\include\IShaderConstantSetCallBack.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit540] +FileName=..\..\include\IShadowVolumeSceneNode.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit541] +FileName=..\..\include\ITerrainSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit542] +FileName=..\..\include\ITextSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit543] +FileName=..\..\include\ITimer.h +CompileCpp=1 +Folder=include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit544] +FileName=..\..\include\ITriangleSelector.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit545] +FileName=..\..\include\IVideoModeList.h +CompileCpp=1 +Folder=include/video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit546] +FileName=..\..\include\IWriteFile.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit547] +FileName=..\..\include\IXMLReader.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit548] +FileName=..\..\include\IXMLWriter.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit549] +FileName=..\..\include\quaternion.h +CompileCpp=1 +Folder=include/core +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit550] +FileName=..\..\include\SAnimatedMesh.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit551] +FileName=..\..\include\SceneParameters.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit552] +FileName=..\..\include\IReferenceCounted.h +CompileCpp=1 +Folder=include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit553] +FileName=CParticleAnimatedMeshSceneNodeEmitter.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit554] +FileName=CParticleAnimatedMeshSceneNodeEmitter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit555] +FileName=CParticleSphereEmitter.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit556] +FileName=CParticleAttractionAffector.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit557] +FileName=CParticleAttractionAffector.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit558] +FileName=CParticleCylinderEmitter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit559] +FileName=CParticleCylinderEmitter.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit560] +FileName=CParticleMeshEmitter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit561] +FileName=CParticleMeshEmitter.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit562] +FileName=CParticleRingEmitter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit563] +FileName=CParticleRingEmitter.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit564] +FileName=CParticleRotationAffector.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit565] +FileName=CParticleRotationAffector.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit566] +FileName=CParticleSphereEmitter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes/particles +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit567] +FileName=CIrrMeshWriter.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit568] +FileName=CIrrMeshWriter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit569] +FileName=CColladaMeshWriter.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit570] +FileName=CColladaMeshWriter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit571] +FileName=CIrrMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit572] +FileName=CIrrMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit573] +FileName=CBSPMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit574] +FileName=CBSPMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit575] +FileName=CMD2MeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit576] +FileName=CMD2MeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit577] +FileName=CMS3DMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit578] +FileName=CMS3DMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit579] +FileName=CB3DMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit580] +FileName=CB3DMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit581] +FileName=CSkinnedMesh.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit582] +FileName=CSkinnedMesh.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit583] +FileName=CBoneSceneNode.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit584] +FileName=CBoneSceneNode.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit585] +FileName=CSTLMeshWriter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit586] +FileName=CSTLMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit587] +FileName=CImageLoaderPPM.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Loader +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit588] +FileName=CImageLoaderPPM.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Loader +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit589] +FileName=CBurningShader_Raster_Reference.cpp +CompileCpp=1 +Folder=Irrlicht/video/Burning Video +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit590] +FileName=CImageLoaderWAL.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Loader +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit591] +FileName=CImageLoaderWAL.h +Folder=Irrlicht/video/Null/Loader +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit592] +FileName=CGUITable.h +Folder=Irrlicht/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit593] +FileName=CGUITable.cpp +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit594] +FileName=..\..\include\IGUITable.h +Folder=include/gui +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit595] +FileName=CVolumeLightSceneNode.h +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit596] +FileName=CVolumeLightSceneNode.cpp +CompileCpp=1 +Folder=Irrlicht/scene/nodes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit597] +FileName=..\..\include\IVolumeLightSceneNode.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit598] +FileName=CLWOMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit599] +FileName=CLWOMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit600] +FileName=..\..\include\ISceneNodeAnimatorCameraMaya.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit601] +FileName=..\..\include\ISceneNodeAnimatorCameraFPS.h +CompileCpp=1 +Folder=include/scene +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit602] +FileName=CSceneNodeAnimatorCameraMaya.h +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit603] +FileName=CSceneNodeAnimatorCameraFPS.cpp +Folder=Irrlicht/scene/animators +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit604] +FileName=COBJMeshWriter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit605] +FileName=..\..\include\SSkinMeshBuffer.h +Folder=include/scene +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit606] +FileName=CParticleScaleAffector.cpp +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit607] +FileName=CParticleScaleAffector.h +Folder=Irrlicht/scene/nodes/particles +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit608] +FileName=CGUIImageList.cpp +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit609] +FileName=CGUIImageList.h +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit610] +FileName=CGUITreeView.cpp +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit611] +FileName=CGUITreeView.h +CompileCpp=1 +Folder=Irrlicht/gui +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit612] +FileName=CIrrDeviceConsole.cpp +CompileCpp=1 +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit613] +FileName=CIrrDeviceConsole.h +CompileCpp=1 +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit614] +FileName=CPLYMeshWriter.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit615] +FileName=CPLYMeshWriter.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/writers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit616] +FileName=CPLYMeshFileLoader.cpp +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit617] +FileName=CPLYMeshFileLoader.h +CompileCpp=1 +Folder=Irrlicht/scene/mesh/loaders +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit618] +FileName=CIrrDeviceSDL.cpp +CompileCpp=1 +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit619] +FileName=CIrrDeviceSDL.h +CompileCpp=1 +Folder=Irrlicht/irr/IrrlichtDevice +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit620] +FileName=CImageLoaderRGB.cpp +CompileCpp=1 +Folder=Irrlicht/video/Null/Loader +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit621] +FileName=CImageLoaderRGB.h +CompileCpp=1 +Folder=Irrlicht/video/Null/Loader +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit622] +FileName=CTarReader.cpp +Folder=Irrlicht/io/archive +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit623] +FileName=CTarReader.h +Folder=Irrlicht/io/archive +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + + +[Unit624] +FileName=CMountPointReader.cpp +Folder=Irrlicht/io/archive +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit625] +FileName=CMountPointReader.h +Folder=Irrlicht/io/archive +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit626] +FileName=CNPKReader.h +CompileCpp=1 +Folder=Irrlicht/io/archive +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit627] +FileName=CNPKReader.cpp +CompileCpp=1 +Folder=Irrlicht/io/archive +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit628] +FileName=..\..\include\EAttributes.h +CompileCpp=1 +Folder=include/io +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit629] +FileName=IAttribute.h +CompileCpp=1 +Folder=Irrlicht/io/attributes +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit630] +FileName=aesGladman\aes.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit631] +FileName=aesGladman\aescrypt.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit632] +FileName=aesGladman\aeskey.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit633] +FileName=aesGladman\aesopt.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit634] +FileName=aesGladman\aestab.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit635] +FileName=aesGladman\sha2.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit636] +FileName=aesGladman\fileenc.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit637] +FileName=aesGladman\fileenc.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit638] +FileName=aesGladman\hmac.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit639] +FileName=aesGladman\hmac.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit640] +FileName=aesGladman\prng.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit641] +FileName=aesGladman\prng.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit642] +FileName=aesGladman\pwd2key.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit643] +FileName=aesGladman\pwd2key.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit644] +FileName=aesGladman\sha1.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit645] +FileName=aesGladman\sha1.h +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit646] +FileName=aesGladman\sha2.cpp +Folder=Irrlicht/extern/aesGladman +Compile=1 +CompileCpp=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit647] +FileName=bzip2\blocksort.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit648] +FileName=bzip2\bzcompress.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit649] +FileName=bzip2\bzlib.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit650] +FileName=bzip2\bzlib.h +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit651] +FileName=bzip2\bzlib_private.h +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit652] +FileName=bzip2\crctable.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit653] +FileName=bzip2\decompress.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit654] +FileName=bzip2\huffman.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit655] +FileName=bzip2\randtable.c +Folder=Irrlicht/extern/bzip2 +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit656] +FileName=lzma\LzmaDec.c +Folder=Irrlicht/extern +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit657] +FileName=lzma\LzmaDec.h +Folder=Irrlicht/extern +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit658] +FileName=lzma\Types.h +Folder=Irrlicht/extern +Compile=1 +CompileCpp=0 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.rc b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.rc new file mode 100644 index 0000000..57f8f37 Binary files /dev/null and b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht.rc differ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.sln b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.sln new file mode 100644 index 0000000..f3dcbb4 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "Irrlicht10.0.vcxproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release - Fast FPU|Win32 = Release - Fast FPU|Win32 + Release - Fast FPU|x64 = Release - Fast FPU|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Static lib - Debug|Win32 = Static lib - Debug|Win32 + Static lib - Debug|x64 = Static lib - Debug|x64 + Static lib - Release - Fast FPU|Win32 = Static lib - Release - Fast FPU|Win32 + Static lib - Release - Fast FPU|x64 = Static lib - Release - Fast FPU|x64 + Static lib - Release|Win32 = Static lib - Release|Win32 + Static lib - Release|x64 = Static lib - Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.Build.0 = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|x64.ActiveCfg = Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|x64.Build.0 = Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|Win32.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|Win32.Build.0 = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|x64.ActiveCfg = Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|x64.Build.0 = Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.ActiveCfg = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|x64.ActiveCfg = Release|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|x64.Build.0 = Release|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.ActiveCfg = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.Build.0 = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|x64.ActiveCfg = Static lib - Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|x64.Build.0 = Static lib - Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.ActiveCfg = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.Build.0 = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|x64.ActiveCfg = Static lib - Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|x64.Build.0 = Static lib - Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.ActiveCfg = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.Build.0 = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|x64.ActiveCfg = Static lib - Release|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|x64.Build.0 = Static lib - Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj new file mode 100644 index 0000000..4a10236 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj @@ -0,0 +1,1555 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release - Fast FPU + Win32 + + + Release - Fast FPU + x64 + + + Release + Win32 + + + Release + x64 + + + SDL-Debug + Win32 + + + SDL-Debug + x64 + + + Static lib - Debug + Win32 + + + Static lib - Debug + x64 + + + Static lib - Release - Fast FPU + Win32 + + + Static lib - Release - Fast FPU + x64 + + + Static lib - Release + Win32 + + + Static lib - Release + x64 + + + + Irrlicht + {E08E042A-6C45-411B-92BE-3CC31331019F} + Irrlicht + + + + DynamicLibrary + NotSet + + + DynamicLibrary + NotSet + Windows7.1SDK + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + Windows7.1SDK + + + StaticLibrary + MultiByte + true + + + StaticLibrary + MultiByte + true + Windows7.1SDK + + + StaticLibrary + NotSet + + + StaticLibrary + NotSet + Windows7.1SDK + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + true + Windows7.1SDK + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + true + Windows7.1SDK + + + DynamicLibrary + NotSet + + + DynamicLibrary + NotSet + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + false + false + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + false + false + ..\..\lib\Win32-VisualStudio\ + ..\..\lib\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + ..\..\lib\Win32-VisualStudio\ + ..\..\lib\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + ..\..\lib\Win32-VisualStudio\ + ..\..\lib\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + true + true + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + $(DXSDK_DIR)include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + obj\$(Configuration)\ + obj\$(Configuration)64\ + true + true + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Debug/Irrlicht.tlb + + + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + Disabled + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + 1.8 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\..\Debug/Irrlicht.tlb + + + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + Disabled + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + 1.8 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + false + MultiThreaded + Default + false + false + StreamingSIMDExtensions2 + Fast + false + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + true + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + Windows + 1.8 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + false + MultiThreaded + Default + false + false + StreamingSIMDExtensions2 + Fast + false + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + true + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win32-visualstudio\Irrlicht.lib + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win64-visualstudio\Irrlicht.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + false + false + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win32-visualstudio\Irrlicht.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + false + false + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win64-visualstudio\Irrlicht.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Fast + false + Level3 + + + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win32-visualstudio\Irrlicht.lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Fast + false + Level3 + + + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win64-visualstudio\Irrlicht.lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_IRR_USE_SDL_DEVICE_=1;%(PreprocessorDefinitions) + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + 1.8 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_IRR_USE_SDL_DEVICE_=1;%(PreprocessorDefinitions) + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj.filters b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj.filters new file mode 100644 index 0000000..c522cec --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht10.0.vcxproj.filters @@ -0,0 +1,2247 @@ + + + + + {b5bde5d3-f9e4-4036-8c28-2f4e8cd03846} + + + {0b0937fb-2270-4e3e-a94f-f92bc0fa74ae} + + + {67300400-93d5-4a7e-8b59-7c0d7b1f6d75} + + + {feb206b9-81b6-45c0-b4e5-9e637fe060e7} + + + {af459bf5-2849-4a0e-9a21-91acbbf1c6b5} + + + {aa649d49-922d-4118-8574-f05c13d67706} + + + {a72cb2e5-a5c3-41bc-9c86-fdbdae8f7866} + + + {72c30315-bbc0-4109-9ccd-fb7107ba316a} + + + {1fcdc900-911d-4b7a-9328-afce5bbe44fa} + + + {41e16cbf-c3cb-4d74-8aef-c0416b6b9d7f} + + + {b84f01e5-ae3c-457b-8d96-b3e271800162} + + + {eca36d94-d8fb-477d-a0dc-b5498c9686d7} + + + {67826246-df05-4523-9191-5286f9157963} + + + {659a61d5-7ab3-4aa3-95ca-879780810b4e} + + + {f65e8d89-c715-4794-8c2d-22f2b57cffb0} + + + {3cb7865d-a5e9-4b22-8f54-dde759b88c51} + + + {919fcfa4-4277-4c88-8bfc-4bfcfcbb1b65} + + + {834213c7-9515-49de-aa27-8d3ed9c0c87a} + + + {19838bc4-396f-4d23-ad1b-3bb652e33e6d} + + + {a9ca9d4d-7678-4687-b78b-15236c0dcf53} + + + {d694e7b0-0fb0-4685-ace7-56d9ec65a3d0} + + + {e2571a61-945c-4509-b47c-daea464916ab} + + + {1354e9fa-cea6-461e-af7f-9940bb5f0a2f} + + + {ac7af7ba-0e6b-4da4-a695-a0070a4da974} + + + {1173499e-79e8-4c34-8046-abc325e2f2a9} + + + {ca095ff3-25e4-4852-ab55-af28c602cd8a} + + + {1c8bd90a-8361-4478-8942-a062450ef209} + + + {128cac28-b6f8-49e7-87f5-ee15951d0396} + + + {6f10ce97-ed8b-47bc-a189-f2262eb467e4} + + + {5d58bc55-284e-4880-9226-85083e65d660} + + + {064ee182-9f07-4026-ac22-c141ae2c7281} + + + {6e842906-e193-451d-8716-12eaafabd0d8} + + + {799f220e-3a58-4788-876b-88c175b69871} + + + {da421793-4674-481c-be46-f7a44e78aee5} + + + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\video + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr\extern + + + Irrlicht\irr\extern + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + include\scene + + + + Irrlicht\scene\loaders + + + include\scene + + + Irrlicht\scene\loaders + + + include\video + + + include + + + include\video + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\OpenGL + + + Irrlicht\video + + + + + doc + + + doc + + + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\video + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr\extern + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\OpenGL + + + Irrlicht\video + + + + + + \ No newline at end of file diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.sln b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.sln new file mode 100644 index 0000000..3a28918 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "Irrlicht11.0.vcxproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release - Fast FPU|Win32 = Release - Fast FPU|Win32 + Release - Fast FPU|x64 = Release - Fast FPU|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Static lib - Debug|Win32 = Static lib - Debug|Win32 + Static lib - Debug|x64 = Static lib - Debug|x64 + Static lib - Release - Fast FPU|Win32 = Static lib - Release - Fast FPU|Win32 + Static lib - Release - Fast FPU|x64 = Static lib - Release - Fast FPU|x64 + Static lib - Release|Win32 = Static lib - Release|Win32 + Static lib - Release|x64 = Static lib - Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.Build.0 = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|x64.ActiveCfg = Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|x64.Build.0 = Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|Win32.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|Win32.Build.0 = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|x64.ActiveCfg = Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|x64.Build.0 = Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.ActiveCfg = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|x64.ActiveCfg = Release|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|x64.Build.0 = Release|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.ActiveCfg = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.Build.0 = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|x64.ActiveCfg = Static lib - Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|x64.Build.0 = Static lib - Debug|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.ActiveCfg = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.Build.0 = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|x64.ActiveCfg = Static lib - Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|x64.Build.0 = Static lib - Release - Fast FPU|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.ActiveCfg = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.Build.0 = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|x64.ActiveCfg = Static lib - Release|x64 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|x64.Build.0 = Static lib - Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj new file mode 100644 index 0000000..bd821ff --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj @@ -0,0 +1,1563 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release - Fast FPU + Win32 + + + Release - Fast FPU + x64 + + + Release + Win32 + + + Release + x64 + + + SDL-Debug + Win32 + + + SDL-Debug + x64 + + + Static lib - Debug + Win32 + + + Static lib - Debug + x64 + + + Static lib - Release - Fast FPU + Win32 + + + Static lib - Release - Fast FPU + x64 + + + Static lib - Release + Win32 + + + Static lib - Release + x64 + + + + Irrlicht + {E08E042A-6C45-411B-92BE-3CC31331019F} + Irrlicht + + + + DynamicLibrary + NotSet + v110 + + + DynamicLibrary + NotSet + Windows7.1SDK + + + StaticLibrary + MultiByte + true + v110 + + + StaticLibrary + MultiByte + true + Windows7.1SDK + + + StaticLibrary + MultiByte + true + v110 + + + StaticLibrary + MultiByte + true + Windows7.1SDK + + + StaticLibrary + NotSet + v110 + + + StaticLibrary + NotSet + Windows7.1SDK + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + true + Windows7.1SDK + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + true + Windows7.1SDK + + + DynamicLibrary + NotSet + v110 + + + DynamicLibrary + NotSet + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + false + false + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + false + false + ..\..\lib\Win32-VisualStudio\ + ..\..\lib\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + ..\..\lib\Win32-VisualStudio\ + ..\..\lib\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + ..\..\lib\Win32-VisualStudio\ + ..\..\lib\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + obj\$(Configuration)\ + obj\$(Configuration)64\ + true + true + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + $(IncludePath);$(DXSDK_DIR)include;$(CG_INC_PATH) + $(DXSDK_DIR)include;$(IncludePath) + obj\$(Configuration)\ + obj\$(Configuration)64\ + true + true + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(DXSDK_DIR)include;$(IncludePath) + $(LibraryPath);$(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + $(DXSDK_DIR)Lib\x64;$(LibraryPath);$(VSInstallDir);$(VSInstallDir)lib\amd64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Debug/Irrlicht.tlb + + + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + Disabled + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + 1.8 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\..\Debug/Irrlicht.tlb + + + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + Disabled + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + 1.8 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + Default + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + kernel32.lib;user32.lib;gdi32.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + false + MultiThreaded + Default + false + false + StreamingSIMDExtensions2 + Fast + false + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + true + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + Windows + 1.8 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + false + MultiThreaded + Default + false + false + StreamingSIMDExtensions2 + Fast + false + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + libci.lib;%(IgnoreSpecificDefaultLibraries) + false + true + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win32-visualstudio\Irrlicht.lib + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions); _ITERATOR_DEBUG_LEVEL=0 + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win64-visualstudio\Irrlicht.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + false + false + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win32-visualstudio\Irrlicht.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + MaxSpeed + OnlyExplicitInline + false + false + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Level3 + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win64-visualstudio\Irrlicht.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Fast + false + Level3 + + + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win32-visualstudio\Irrlicht.lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\..\Release/Irrlicht.tlb + + + Full + AnySuitable + true + Speed + true + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_WINDOWS;_USRDLL;_IRR_STATIC_LIB_;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + Fast + false + Level3 + + + FastCall + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + winmm.lib;%(AdditionalDependencies) + ..\..\lib\Win64-visualstudio\Irrlicht.lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_IRR_USE_SDL_DEVICE_=1;%(PreprocessorDefinitions) + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + /MACHINE:I386 %(AdditionalOptions) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;%(AdditionalDependencies) + ..\..\bin\Win32-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win32-visualstudio\Irrlicht.lib + 1.8 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\..\Debug/Irrlicht.tlb + + + Disabled + ..\..\include;zlib;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;IRRLICHT_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_IRR_USE_SDL_DEVICE_=1;%(PreprocessorDefinitions) + + + EnableFastChecks + MultiThreadedDebug + false + false + Level3 + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + true + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;opengl32.lib;winmm.lib;%(AdditionalDependencies) + ..\..\bin\Win64-visualstudio\Irrlicht.dll + %(AdditionalLibraryDirectories) + libci.lib;%(IgnoreSpecificDefaultLibraries) + true + + + ..\..\lib\Win64-visualstudio\Irrlicht.lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj.filters b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj.filters new file mode 100644 index 0000000..c522cec --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht11.0.vcxproj.filters @@ -0,0 +1,2247 @@ + + + + + {b5bde5d3-f9e4-4036-8c28-2f4e8cd03846} + + + {0b0937fb-2270-4e3e-a94f-f92bc0fa74ae} + + + {67300400-93d5-4a7e-8b59-7c0d7b1f6d75} + + + {feb206b9-81b6-45c0-b4e5-9e637fe060e7} + + + {af459bf5-2849-4a0e-9a21-91acbbf1c6b5} + + + {aa649d49-922d-4118-8574-f05c13d67706} + + + {a72cb2e5-a5c3-41bc-9c86-fdbdae8f7866} + + + {72c30315-bbc0-4109-9ccd-fb7107ba316a} + + + {1fcdc900-911d-4b7a-9328-afce5bbe44fa} + + + {41e16cbf-c3cb-4d74-8aef-c0416b6b9d7f} + + + {b84f01e5-ae3c-457b-8d96-b3e271800162} + + + {eca36d94-d8fb-477d-a0dc-b5498c9686d7} + + + {67826246-df05-4523-9191-5286f9157963} + + + {659a61d5-7ab3-4aa3-95ca-879780810b4e} + + + {f65e8d89-c715-4794-8c2d-22f2b57cffb0} + + + {3cb7865d-a5e9-4b22-8f54-dde759b88c51} + + + {919fcfa4-4277-4c88-8bfc-4bfcfcbb1b65} + + + {834213c7-9515-49de-aa27-8d3ed9c0c87a} + + + {19838bc4-396f-4d23-ad1b-3bb652e33e6d} + + + {a9ca9d4d-7678-4687-b78b-15236c0dcf53} + + + {d694e7b0-0fb0-4685-ace7-56d9ec65a3d0} + + + {e2571a61-945c-4509-b47c-daea464916ab} + + + {1354e9fa-cea6-461e-af7f-9940bb5f0a2f} + + + {ac7af7ba-0e6b-4da4-a695-a0070a4da974} + + + {1173499e-79e8-4c34-8046-abc325e2f2a9} + + + {ca095ff3-25e4-4852-ab55-af28c602cd8a} + + + {1c8bd90a-8361-4478-8942-a062450ef209} + + + {128cac28-b6f8-49e7-87f5-ee15951d0396} + + + {6f10ce97-ed8b-47bc-a189-f2262eb467e4} + + + {5d58bc55-284e-4880-9226-85083e65d660} + + + {064ee182-9f07-4026-ac22-c141ae2c7281} + + + {6e842906-e193-451d-8716-12eaafabd0d8} + + + {799f220e-3a58-4788-876b-88c175b69871} + + + {da421793-4674-481c-be46-f7a44e78aee5} + + + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\video + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\core + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\io + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\scene + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + include\gui + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\video + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr\extern + + + Irrlicht\irr\extern + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + include\scene + + + + Irrlicht\scene\loaders + + + include\scene + + + Irrlicht\scene\loaders + + + include\video + + + include + + + include\video + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\OpenGL + + + Irrlicht\video + + + + + doc + + + doc + + + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\sceneNodes + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\particleSystem + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\collision + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\animators + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\scene\writers + + + Irrlicht\video + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\Software + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\OpenGL + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Direct3D8 + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Writer + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Null\Loader + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\video\Burning Video + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr + + + Irrlicht\irr\extern + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\zlib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\jpeglib + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\libpng + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\aesGladman + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\extern\bzip2 + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\irr\device + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\io + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\gui + + + Irrlicht\scene\loaders + + + Irrlicht\scene\loaders + + + Irrlicht\video\Direct3D9 + + + Irrlicht\video\OpenGL + + + Irrlicht\video + + + + + + \ No newline at end of file diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.sln b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.sln new file mode 100644 index 0000000..e9759b2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "Irrlicht8.0.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Static lib - Debug|Win32 = Static lib - Debug|Win32 + Static lib - Release - Fast FPU|Win32 = Static lib - Release - Fast FPU|Win32 + Static lib - Release|Win32 = Static lib - Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.Build.0 = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.ActiveCfg = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.ActiveCfg = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.Build.0 = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.ActiveCfg = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.Build.0 = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.ActiveCfg = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.Build.0 = Static lib - Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.vcproj b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.vcproj new file mode 100644 index 0000000..38ce04b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht8.0.vcproj @@ -0,0 +1,3512 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.sln b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.sln new file mode 100644 index 0000000..17f0dab --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.sln @@ -0,0 +1,32 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "Irrlicht9.0.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release - Fast FPU|Win32 = Release - Fast FPU|Win32 + Release|Win32 = Release|Win32 + Static lib - Debug|Win32 = Static lib - Debug|Win32 + Static lib - Release - Fast FPU|Win32 = Static lib - Release - Fast FPU|Win32 + Static lib - Release|Win32 = Static lib - Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Win32.Build.0 = Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|Win32.ActiveCfg = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release - Fast FPU|Win32.Build.0 = Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.ActiveCfg = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Win32.Build.0 = Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.ActiveCfg = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Debug|Win32.Build.0 = Static lib - Debug|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.ActiveCfg = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release - Fast FPU|Win32.Build.0 = Static lib - Release - Fast FPU|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.ActiveCfg = Static lib - Release|Win32 + {E08E042A-6C45-411B-92BE-3CC31331019F}.Static lib - Release|Win32.Build.0 = Static lib - Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.vcproj b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.vcproj new file mode 100644 index 0000000..610fbcf --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht9.0.vcproj @@ -0,0 +1,3656 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.sln b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.sln new file mode 100644 index 0000000..be319a3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "Irrlicht_mobile6.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Windows Mobile 6 Professional SDK (ARMV4I) = Debug|Windows Mobile 6 Professional SDK (ARMV4I) + Release|Windows Mobile 6 Professional SDK (ARMV4I) = Release|Windows Mobile 6 Professional SDK (ARMV4I) + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I) + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Debug|Windows Mobile 6 Professional SDK (ARMV4I) + {E08E042A-6C45-411B-92BE-3CC31331019F}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 6 Professional SDK (ARMV4I) + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I) + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I) + {E08E042A-6C45-411B-92BE-3CC31331019F}.Release|Windows Mobile 6 Professional SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I) + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.vcproj b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.vcproj new file mode 100644 index 0000000..5a400c0 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_mobile6.vcproj @@ -0,0 +1,3085 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.sln b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.sln new file mode 100644 index 0000000..1a35817 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht_xbox", "Irrlicht_xbox.vcproj", "{2440E601-7438-4C6B-B4AF-BBFE9735875E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Profile = Profile + Profile_FastCap = Profile_FastCap + Release = Release + Release_LTCG = Release_LTCG + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Debug.ActiveCfg = Debug|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Debug.Build.0 = Debug|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Profile.ActiveCfg = Profile|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Profile.Build.0 = Profile|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Release.ActiveCfg = Release|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Release.Build.0 = Release|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox + {2440E601-7438-4C6B-B4AF-BBFE9735875E}.Release_LTCG.Build.0 = Release_LTCG|Xbox + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.vcproj b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.vcproj new file mode 100644 index 0000000..d92d0df --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Irrlicht_xbox.vcproj @@ -0,0 +1,1987 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/._MainMenu.nib b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/._MainMenu.nib new file mode 100644 index 0000000..ed1f83f Binary files /dev/null and b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/._MainMenu.nib differ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.h b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.h new file mode 100644 index 0000000..ccb116d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.h @@ -0,0 +1,24 @@ +// Copyright (C) 2005-2006 Etienne Petitjean +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + +#import +#import "CIrrDeviceMacOSX.h" + +@interface AppDelegate : NSObject +{ + BOOL _quit; + irr::CIrrDeviceMacOSX *_device; +} + +- (id)initWithDevice:(irr::CIrrDeviceMacOSX *)device; +- (BOOL)isQuit; + +@end + +#endif // _IRR_COMPILE_WITH_OSX_DEVICE_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.mm b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.mm new file mode 100644 index 0000000..14a7f86 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/AppDelegate.mm @@ -0,0 +1,79 @@ +// Copyright (C) 2005-2006 Etienne Petitjean +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#import "AppDelegate.h" + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + +@implementation AppDelegate + +- (id)initWithDevice:(irr::CIrrDeviceMacOSX *)device +{ + self = [super init]; + if (self) _device = device; + return (self); +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + _quit = FALSE; +} + +- (void)orderFrontStandardAboutPanel:(id)sender +{ + [NSApp orderFrontStandardAboutPanel:sender]; +} + +- (void)unhideAllApplications:(id)sender +{ + [NSApp unhideAllApplications:sender]; +} + +- (void)hide:(id)sender +{ + [NSApp hide:sender]; +} + +- (void)hideOtherApplications:(id)sender +{ + [NSApp hideOtherApplications:sender]; +} + +- (void)terminate:(id)sender +{ + _quit = TRUE; +} + +- (void)windowWillClose:(id)sender +{ + _quit = TRUE; +} + +- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize +{ + if (_device->isResizable()) + return proposedFrameSize; + else + return [window frame].size; +} + +- (void)windowDidResize:(NSNotification *)aNotification +{ + NSWindow *window; + NSRect frame; + + window = [aNotification object]; + frame = [window frame]; + _device->setResize((int)frame.size.width,(int)frame.size.height); +} + +- (BOOL)isQuit +{ + return (_quit); +} + +@end + +#endif // _IRR_COMPILE_WITH_OSX_DEVICE_ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h new file mode 100644 index 0000000..f629588 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h @@ -0,0 +1,251 @@ +// Copyright (C) 2005-2006 Etienne Petitjean +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef __C_IRR_DEVICE_MACOSX_H_INCLUDED__ +#define __C_IRR_DEVICE_MACOSX_H_INCLUDED__ + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + +#import +#import +#import + +#include "CIrrDeviceStub.h" +#include "IrrlichtDevice.h" +#include "IImagePresenter.h" +#include "IGUIEnvironment.h" +#include "ICursorControl.h" + +#include +#include + +namespace irr +{ + class CIrrDeviceMacOSX : public CIrrDeviceStub, video::IImagePresenter + { + public: + + //! constructor + CIrrDeviceMacOSX(const SIrrlichtCreationParameters& params); + + //! destructor + virtual ~CIrrDeviceMacOSX(); + + //! runs the device. Returns false if device wants to be deleted + virtual bool run(); + + //! Cause the device to temporarily pause execution and let other processes to run + // This should bring down processor usage without major performance loss for Irrlicht + virtual void yield(); + + //! Pause execution and let other processes to run for a specified amount of time. + virtual void sleep(u32 timeMs, bool pauseTimer); + + //! sets the caption of the window + virtual void setWindowCaption(const wchar_t* text); + + //! returns if window is active. if not, nothing need to be drawn + virtual bool isWindowActive() const; + + //! Checks if the Irrlicht window has focus + virtual bool isWindowFocused() const; + + //! Checks if the Irrlicht window is minimized + virtual bool isWindowMinimized() const; + + //! presents a surface in the client area + virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0 ); + + //! notifies the device that it should close itself + virtual void closeDevice(); + + //! Sets if the window should be resizable in windowed mode. + virtual void setResizable(bool resize); + + //! Returns true if the window is resizable, false if not + virtual bool isResizable() const; + + //! Minimizes the window if possible + virtual void minimizeWindow(); + + //! Maximizes the window if possible. + virtual void maximizeWindow(); + + //! Restore the window to normal size if possible. + virtual void restoreWindow(); + + //! Activate any joysticks, and generate events for them. + virtual bool activateJoysticks(core::array & joystickInfo); + + //! \return Returns a pointer to a list with all video modes + //! supported by the gfx adapter. + virtual video::IVideoModeList* getVideoModeList(); + + //! Get the device type + virtual E_DEVICE_TYPE getType() const + { + return EIDT_OSX; + } + + void flush(); + void setMouseLocation(int x, int y); + void setResize(int width, int height); + void setCursorVisible(bool visible); + + private: + + //! create the driver + void createDriver(); + + //! Implementation of the macos x cursor control + class CCursorControl : public gui::ICursorControl + { + public: + + CCursorControl(const core::dimension2d& wsize, CIrrDeviceMacOSX *device) + : WindowSize(wsize), IsVisible(true), InvWindowSize(0.0f, 0.0f), Device(device), UseReferenceRect(false) + { + CursorPos.X = CursorPos.Y = 0; + if (WindowSize.Width!=0) + InvWindowSize.Width = 1.0f / WindowSize.Width; + if (WindowSize.Height!=0) + InvWindowSize.Height = 1.0f / WindowSize.Height; + } + + //! Changes the visible state of the mouse cursor. + virtual void setVisible(bool visible) + { + IsVisible = visible; + Device->setCursorVisible(visible); + } + + //! Returns if the cursor is currently visible. + virtual bool isVisible() const + { + return IsVisible; + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(f32 x, f32 y) + { + setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); + } + + //! Sets the new position of the cursor. + virtual void setPosition(const core::position2d &pos) + { + if (CursorPos.X != pos.X || CursorPos.Y != pos.Y) + setPosition(pos.X, pos.Y); + } + + //! Sets the new position of the cursor. + virtual void setPosition(s32 x, s32 y) + { + if (UseReferenceRect) + { + Device->setMouseLocation(ReferenceRect.UpperLeftCorner.X + x, ReferenceRect.UpperLeftCorner.Y + y); + } + else + { + Device->setMouseLocation(x,y); + } + } + + //! Returns the current position of the mouse cursor. + virtual const core::position2d& getPosition() + { + return CursorPos; + } + + //! Returns the current position of the mouse cursor. + virtual core::position2d getRelativePosition() + { + if (!UseReferenceRect) + { + return core::position2d(CursorPos.X * InvWindowSize.Width, + CursorPos.Y * InvWindowSize.Height); + } + + return core::position2d(CursorPos.X / (f32)ReferenceRect.getWidth(), + CursorPos.Y / (f32)ReferenceRect.getHeight()); + } + + //! Sets an absolute reference rect for calculating the cursor position. + virtual void setReferenceRect(core::rect* rect=0) + { + if (rect) + { + ReferenceRect = *rect; + UseReferenceRect = true; + + // prevent division through zero and uneven sizes + + if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2) + ReferenceRect.LowerRightCorner.Y += 1; + + if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2) + ReferenceRect.LowerRightCorner.X += 1; + } + else + UseReferenceRect = false; + } + + //! Updates the internal cursor position + void updateInternalCursorPosition(int x,int y) + { + CursorPos.X = x; + CursorPos.Y = y; + } + + private: + + core::position2d CursorPos; + core::dimension2d WindowSize; + core::dimension2d InvWindowSize; + core::rect ReferenceRect; + CIrrDeviceMacOSX *Device; + bool IsVisible; + bool UseReferenceRect; + }; + + bool createWindow(); + void initKeycodes(); + void storeMouseLocation(); + void postMouseEvent(void *event, irr::SEvent &ievent); + void postKeyEvent(void *event, irr::SEvent &ievent, bool pressed); + void pollJoysticks(); + + NSWindow *Window; + CGLContextObj CGLContext; + NSOpenGLContext *OGLContext; + NSBitmapImageRep *SoftwareDriverTarget; + std::map KeyCodes; + int DeviceWidth; + int DeviceHeight; + int ScreenWidth; + int ScreenHeight; + u32 MouseButtonStates; + u32 SoftwareRendererType; + bool IsFullscreen; + bool IsActive; + bool IsShiftDown; + bool IsControlDown; + bool IsResizable; + }; + + +} // end namespace irr + +#endif // _IRR_COMPILE_WITH_OSX_DEVICE_ +#endif // __C_IRR_DEVICE_MACOSX_H_INCLUDED__ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm new file mode 100644 index 0000000..8b48134 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm @@ -0,0 +1,1889 @@ +// Copyright (C) 2005-2006 Etienne Petitjean +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#include "IrrCompileConfig.h" + +#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_ + +#import +#import +#ifndef __MAC_10_6 +#import +#endif + +#include "CIrrDeviceMacOSX.h" +#include "IEventReceiver.h" +#include "irrList.h" +#include "os.h" +#include "CTimer.h" +#include "irrString.h" +#include "Keycodes.h" +#include +#include +#include "COSOperator.h" +#include "CColorConverter.h" +#include "irrlicht.h" + + +#import +#import +#import "AppDelegate.h" + +#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + +#include +#include +#ifdef MACOS_10_0_4 +#include +#else +/* The header was moved here in Mac OS X 10.1 */ +#include +#endif +#include +#include + +// only OSX 10.5 seems to not need these defines... +#if !defined(__MAC_10_5) || defined(__MAC_10_6) +// Contents from Events.h from Carbon/HIToolbox but we need it with Cocoa too +// and for some reason no Cocoa equivalent of these constants seems provided. +// So I'm doing like everyone else and using copy-and-paste. + +/* + * Summary: + * Virtual keycodes + * + * Discussion: + * These constants are the virtual keycodes defined originally in + * Inside Mac Volume V, pg. V-191. They identify physical keys on a + * keyboard. Those constants with "ANSI" in the name are labeled + * according to the key position on an ANSI-standard US keyboard. + * For example, kVK_ANSI_A indicates the virtual keycode for the key + * with the letter 'A' in the US keyboard layout. Other keyboard + * layouts may have the 'A' key label on a different physical key; + * in this case, pressing 'A' will generate a different virtual + * keycode. + */ +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; +#endif + +struct JoystickComponent +{ + IOHIDElementCookie cookie; // unique value which identifies element, will NOT change + long min; // reported min value possible + long max; // reported max value possible + + long minRead; //min read value + long maxRead; //max read value + + JoystickComponent() : min(0), minRead(0), max(0), maxRead(0) + { + } +}; + +struct JoystickInfo +{ + irr::core::array axisComp; + irr::core::array buttonComp; + irr::core::array hatComp; + + int hats; + int axes; + int buttons; + int numActiveJoysticks; + + irr::SEvent persistentData; + + IOHIDDeviceInterface ** interface; + bool removed; + char joystickName[256]; + long usage; // usage page from IOUSBHID Parser.h which defines general usage + long usagePage; // usage within above page from IOUSBHID Parser.h which defines specific usage + + JoystickInfo() : hats(0), axes(0), buttons(0), interface(0), removed(false), usage(0), usagePage(0), numActiveJoysticks(0) + { + interface = NULL; + memset(joystickName, '\0', 256); + axisComp.clear(); + buttonComp.clear(); + hatComp.clear(); + + persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT; + persistentData.JoystickEvent.POV = 65535; + persistentData.JoystickEvent.ButtonStates = 0; + } +}; +irr::core::array ActiveJoysticks; + +//helper functions for init joystick +static IOReturn closeJoystickDevice (JoystickInfo* joyInfo) +{ + IOReturn result = kIOReturnSuccess; + if (joyInfo && joyInfo->interface) + { + /* close the interface */ + result = (*(joyInfo->interface))->close (joyInfo->interface); + if (kIOReturnNotOpen == result) + { + /* do nothing as device was not opened, thus can't be closed */ + } + else if (kIOReturnSuccess != result) + irr::os::Printer::log("IOHIDDeviceInterface failed to close", irr::ELL_ERROR); + /* release the interface */ + result = (*(joyInfo->interface))->Release (joyInfo->interface); + if (kIOReturnSuccess != result) + irr::os::Printer::log("IOHIDDeviceInterface failed to release", irr::ELL_ERROR); + joyInfo->interface = NULL; + } + return result; +} + +static void addComponentInfo (CFTypeRef refElement, JoystickComponent *pComponent, int numActiveJoysticks) +{ + long number; + CFTypeRef refType; + + refType = CFDictionaryGetValue ((CFDictionaryRef)refElement, CFSTR(kIOHIDElementCookieKey)); + if (refType && CFNumberGetValue ((CFNumberRef)refType, kCFNumberLongType, &number)) + pComponent->cookie = (IOHIDElementCookie) number; + refType = CFDictionaryGetValue ((CFDictionaryRef)refElement, CFSTR(kIOHIDElementMinKey)); + if (refType && CFNumberGetValue ((CFNumberRef)refType, kCFNumberLongType, &number)) + pComponent->minRead = pComponent->min = number; + refType = CFDictionaryGetValue ((CFDictionaryRef)refElement, CFSTR(kIOHIDElementMaxKey)); + if (refType && CFNumberGetValue ((CFNumberRef)refType, kCFNumberLongType, &number)) + pComponent->maxRead = pComponent->max = number; +} + +static void getJoystickComponentArrayHandler (const void * value, void * parameter); + +static void addJoystickComponent (CFTypeRef refElement, JoystickInfo* joyInfo) +{ + long elementType, usagePage, usage; + CFTypeRef refElementType = CFDictionaryGetValue ((CFDictionaryRef)refElement, CFSTR(kIOHIDElementTypeKey)); + CFTypeRef refUsagePage = CFDictionaryGetValue ((CFDictionaryRef)refElement, CFSTR(kIOHIDElementUsagePageKey)); + CFTypeRef refUsage = CFDictionaryGetValue ((CFDictionaryRef)refElement, CFSTR(kIOHIDElementUsageKey)); + + if ((refElementType) && (CFNumberGetValue ((CFNumberRef)refElementType, kCFNumberLongType, &elementType))) + { + /* look at types of interest */ + if ((elementType == kIOHIDElementTypeInput_Misc) || (elementType == kIOHIDElementTypeInput_Button) || + (elementType == kIOHIDElementTypeInput_Axis)) + { + if (refUsagePage && CFNumberGetValue ((CFNumberRef)refUsagePage, kCFNumberLongType, &usagePage) && + refUsage && CFNumberGetValue ((CFNumberRef)refUsage, kCFNumberLongType, &usage)) + { + switch (usagePage) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ + { + case kHIDPage_GenericDesktop: + { + switch (usage) /* look at usage to determine function */ + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + case kHIDUsage_GD_Slider: + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + { + joyInfo->axes++; + JoystickComponent newComponent; + addComponentInfo(refElement, &newComponent, joyInfo->numActiveJoysticks); + joyInfo->axisComp.push_back(newComponent); + } + break; + case kHIDUsage_GD_Hatswitch: + { + joyInfo->hats++; + JoystickComponent newComponent; + addComponentInfo(refElement, &newComponent, joyInfo->numActiveJoysticks); + joyInfo->hatComp.push_back(newComponent); + } + break; + } + } + break; + case kHIDPage_Button: + { + joyInfo->buttons++; + JoystickComponent newComponent; + addComponentInfo(refElement, &newComponent, joyInfo->numActiveJoysticks); + joyInfo->buttonComp.push_back(newComponent); + } + break; + default: + break; + } + } + } + else if (kIOHIDElementTypeCollection == elementType) + { + //get elements + CFTypeRef refElementTop = CFDictionaryGetValue ((CFMutableDictionaryRef) refElement, CFSTR(kIOHIDElementKey)); + if (refElementTop) + { + CFTypeID type = CFGetTypeID (refElementTop); + if (type == CFArrayGetTypeID()) + { + CFRange range = {0, CFArrayGetCount ((CFArrayRef)refElementTop)}; + CFArrayApplyFunction ((CFArrayRef)refElementTop, range, getJoystickComponentArrayHandler, joyInfo); + } + } + } + } +} + +static void getJoystickComponentArrayHandler (const void * value, void * parameter) +{ + if (CFGetTypeID (value) == CFDictionaryGetTypeID ()) + addJoystickComponent ((CFTypeRef) value, (JoystickInfo *) parameter); +} + +static void joystickTopLevelElementHandler (const void * value, void * parameter) +{ + CFTypeRef refCF = 0; + if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) + return; + refCF = CFDictionaryGetValue ((CFDictionaryRef)value, CFSTR(kIOHIDElementUsagePageKey)); + if (!CFNumberGetValue ((CFNumberRef)refCF, kCFNumberLongType, &((JoystickInfo *) parameter)->usagePage)) + irr::os::Printer::log("CFNumberGetValue error retrieving JoystickInfo->usagePage", irr::ELL_ERROR); + refCF = CFDictionaryGetValue ((CFDictionaryRef)value, CFSTR(kIOHIDElementUsageKey)); + if (!CFNumberGetValue ((CFNumberRef)refCF, kCFNumberLongType, &((JoystickInfo *) parameter)->usage)) + irr::os::Printer::log("CFNumberGetValue error retrieving JoystickInfo->usage", irr::ELL_ERROR); +} + +static void getJoystickDeviceInfo (io_object_t hidDevice, CFMutableDictionaryRef hidProperties, JoystickInfo *joyInfo) +{ + CFMutableDictionaryRef usbProperties = 0; + io_registry_entry_t parent1, parent2; + + /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also + * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties + */ + if ((KERN_SUCCESS == IORegistryEntryGetParentEntry (hidDevice, kIOServicePlane, &parent1)) && + (KERN_SUCCESS == IORegistryEntryGetParentEntry (parent1, kIOServicePlane, &parent2)) && + (KERN_SUCCESS == IORegistryEntryCreateCFProperties (parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) + { + if (usbProperties) + { + CFTypeRef refCF = 0; + /* get device info + * try hid dictionary first, if fail then go to usb dictionary + */ + + /* get joystickName name */ + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey)); + if (!refCF) + refCF = CFDictionaryGetValue (usbProperties, CFSTR("USB Product Name")); + if (refCF) + { + if (!CFStringGetCString ((CFStringRef)refCF, joyInfo->joystickName, 256, CFStringGetSystemEncoding ())) + irr::os::Printer::log("CFStringGetCString error getting joyInfo->joystickName", irr::ELL_ERROR); + } + + /* get usage page and usage */ + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); + if (refCF) + { + if (!CFNumberGetValue ((CFNumberRef)refCF, kCFNumberLongType, &joyInfo->usagePage)) + irr::os::Printer::log("CFNumberGetValue error getting joyInfo->usagePage", irr::ELL_ERROR); + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); + if (refCF) + if (!CFNumberGetValue ((CFNumberRef)refCF, kCFNumberLongType, &joyInfo->usage)) + irr::os::Printer::log("CFNumberGetValue error getting joyInfo->usage", irr::ELL_ERROR); + } + + if (NULL == refCF) /* get top level element HID usage page or usage */ + { + /* use top level element instead */ + CFTypeRef refCFTopElement = 0; + refCFTopElement = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); + { + /* refCFTopElement points to an array of element dictionaries */ + CFRange range = {0, CFArrayGetCount ((CFArrayRef)refCFTopElement)}; + CFArrayApplyFunction ((CFArrayRef)refCFTopElement, range, joystickTopLevelElementHandler, joyInfo); + } + } + + CFRelease (usbProperties); + } + else + irr::os::Printer::log("IORegistryEntryCreateCFProperties failed to create usbProperties", irr::ELL_ERROR); + + if (kIOReturnSuccess != IOObjectRelease (parent2)) + irr::os::Printer::log("IOObjectRelease failed to release parent2", irr::ELL_ERROR); + if (kIOReturnSuccess != IOObjectRelease (parent1)) + irr::os::Printer::log("IOObjectRelease failed to release parent1", irr::ELL_ERROR); + } +} + +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + +//------------------------------------------------------------------------------------------ +Boolean GetDictionaryBoolean(CFDictionaryRef theDict, const void* key) +{ + // get a boolean from the dictionary + Boolean value = false; + CFBooleanRef boolRef; + boolRef = (CFBooleanRef)CFDictionaryGetValue(theDict, key); + if (boolRef != NULL) + value = CFBooleanGetValue(boolRef); + return value; +} +//------------------------------------------------------------------------------------------ +long GetDictionaryLong(CFDictionaryRef theDict, const void* key) +{ + // get a long from the dictionary + long value = 0; + CFNumberRef numRef; + numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key); + if (numRef != NULL) + CFNumberGetValue(numRef, kCFNumberLongType, &value); + return value; +} + +namespace irr +{ + namespace video + { + IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& param, io::IFileSystem* io, CIrrDeviceMacOSX *device); + } +} // end namespace irr + +static bool firstLaunch = true; + +namespace irr +{ +//! constructor +CIrrDeviceMacOSX::CIrrDeviceMacOSX(const SIrrlichtCreationParameters& param) + : CIrrDeviceStub(param), Window(NULL), CGLContext(NULL), OGLContext(NULL), + SoftwareDriverTarget(0), DeviceWidth(0), DeviceHeight(0), + ScreenWidth(0), ScreenHeight(0), MouseButtonStates(0), SoftwareRendererType(0), + IsActive(true), IsFullscreen(false), IsShiftDown(false), IsControlDown(false), IsResizable(false) +{ + struct utsname name; + NSString *path; + + #ifdef _DEBUG + setDebugName("CIrrDeviceMacOSX"); + #endif + + if (firstLaunch) + { + firstLaunch = false; + + if(!CreationParams.WindowId) //load menus if standalone application + { + [[NSAutoreleasePool alloc] init]; + [NSApplication sharedApplication]; + [NSApp setDelegate:[[[AppDelegate alloc] initWithDevice:this] autorelease]]; + [NSBundle loadNibNamed:@"MainMenu" owner:[NSApp delegate]]; + [NSApp finishLaunching]; + } + + path = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent]; + chdir([path fileSystemRepresentation]); + [path release]; + } + NSWindow* a; + uname(&name); + Operator = new COSOperator(name.version); + os::Printer::log(name.version,ELL_INFORMATION); + + initKeycodes(); + + VideoModeList->setDesktop(CreationParams.Bits, core::dimension2d([[NSScreen mainScreen] frame].size.width, [[NSScreen mainScreen] frame].size.height)); + + bool success = true; + if (CreationParams.DriverType != video::EDT_NULL) + success = createWindow(); + + // in case of failure, one can check VideoDriver for initialization + if (!success) + return; + + setResizable(false); + CursorControl = new CCursorControl(CreationParams.WindowSize, this); + + createDriver(); + createGUIAndScene(); +} + +CIrrDeviceMacOSX::~CIrrDeviceMacOSX() +{ + [SoftwareDriverTarget release]; +#ifdef __MAC_10_6 + [NSApp setPresentationOptions:(NSApplicationPresentationDefault)]; +#else + SetSystemUIMode(kUIModeNormal, kUIOptionAutoShowMenuBar); +#endif + closeDevice(); +#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + for (u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + if (ActiveJoysticks[joystick].interface) + closeJoystickDevice(&ActiveJoysticks[joystick]); + } +#endif +} + +void CIrrDeviceMacOSX::closeDevice() +{ + if (Window != NULL) + { + [Window setIsVisible:FALSE]; + + if (OGLContext != NULL) + { + [OGLContext clearDrawable]; + [OGLContext release]; + OGLContext = NULL; + } + + [Window setReleasedWhenClosed:TRUE]; + [Window release]; + Window = NULL; + + if (IsFullscreen) + CGReleaseAllDisplays(); + } + else + { + if (CGLContext != NULL) + { + if(CreationParams.WindowId) + { + [(NSOpenGLContext *)OGLContext clearDrawable]; + [(NSOpenGLContext *)OGLContext release]; + OGLContext = NULL; + } + else + { + CGLSetCurrentContext(NULL); + CGLClearDrawable(CGLContext); + CGLDestroyContext(CGLContext); + CGReleaseAllDisplays(); + } + } + } + + IsFullscreen = false; + IsActive = false; + CGLContext = NULL; +} + +bool CIrrDeviceMacOSX::createWindow() +{ + CGDisplayErr error; + bool result=false; + CGDirectDisplayID display=CGMainDisplayID(); + CGLPixelFormatObj pixelFormat; + CGRect displayRect; +#ifdef __MAC_10_6 + CGDisplayModeRef displaymode, olddisplaymode; +#else + CFDictionaryRef displaymode, olddisplaymode; +#endif + GLint numPixelFormats, newSwapInterval; + + int alphaSize = CreationParams.WithAlphaChannel?4:0; + int depthSize = CreationParams.ZBufferBits; + if (CreationParams.WithAlphaChannel && (CreationParams.Bits == 32)) + alphaSize = 8; + + ScreenWidth = (int) CGDisplayPixelsWide(display); + ScreenHeight = (int) CGDisplayPixelsHigh(display); + + // we need to check where the exceptions may happen and work at them + // for now we will just catch them to be able to avoid an app exit + @try + { + if (!CreationParams.Fullscreen) + { + if(!CreationParams.WindowId) //create another window when WindowId is null + { + NSBackingStoreType type = (CreationParams.DriverType == video::EDT_OPENGL) ? NSBackingStoreBuffered : NSBackingStoreNonretained; + + Window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,CreationParams.WindowSize.Width,CreationParams.WindowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:type defer:FALSE]; + } + + if (Window != NULL || CreationParams.WindowId) + { + if (CreationParams.DriverType == video::EDT_OPENGL) + { + NSOpenGLPixelFormatAttribute windowattribs[] = + { + NSOpenGLPFANoRecovery, + NSOpenGLPFAAccelerated, + NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)depthSize, + NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)CreationParams.Bits, + NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)alphaSize, + NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)1, + NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)CreationParams.AntiAlias, + NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)(CreationParams.Stencilbuffer?1:0), + NSOpenGLPFADoubleBuffer, + (NSOpenGLPixelFormatAttribute)nil + }; + + if (CreationParams.AntiAlias<2) + { + windowattribs[ 9] = (NSOpenGLPixelFormatAttribute)0; + windowattribs[11] = (NSOpenGLPixelFormatAttribute)0; + } + + NSOpenGLPixelFormat *format; + for (int i=0; i<3; ++i) + { + if (1==i) + { + // Second try without stencilbuffer + if (CreationParams.Stencilbuffer) + { + windowattribs[13]=(NSOpenGLPixelFormatAttribute)0; + } + else + continue; + } + else if (2==i) + { + // Third try without Doublebuffer + os::Printer::log("No doublebuffering available.", ELL_WARNING); + windowattribs[14]=(NSOpenGLPixelFormatAttribute)nil; + } + + format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs]; + if (format == NULL) + { + if (CreationParams.AntiAlias>1) + { + while (!format && windowattribs[12]>1) + { + windowattribs[12] = (NSOpenGLPixelFormatAttribute)((int)windowattribs[12]-1); + format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs]; + } + + if (!format) + { + windowattribs[9] = (NSOpenGLPixelFormatAttribute)0; + windowattribs[11] = (NSOpenGLPixelFormatAttribute)0; + format = [[NSOpenGLPixelFormat alloc] initWithAttributes:windowattribs]; + if (!format) + { + // reset values for next try + windowattribs[9] = (NSOpenGLPixelFormatAttribute)1; + windowattribs[11] = (NSOpenGLPixelFormatAttribute)CreationParams.AntiAlias; + } + else + { + os::Printer::log("No FSAA available.", ELL_WARNING); + } + } + } + } + else + break; + } + CreationParams.AntiAlias = windowattribs[11]; + CreationParams.Stencilbuffer=(windowattribs[13]==1); + + if (format != NULL) + { + OGLContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:NULL]; + [format release]; + } + } + + if (OGLContext != NULL || CreationParams.DriverType != video::EDT_OPENGL) + { + if (!CreationParams.WindowId) + { + [Window center]; + [Window setDelegate:[NSApp delegate]]; + + if(CreationParams.DriverType == video::EDT_OPENGL) + [OGLContext setView:[Window contentView]]; + + [Window setAcceptsMouseMovedEvents:TRUE]; + [Window setIsVisible:TRUE]; + [Window makeKeyAndOrderFront:nil]; + } + else if(CreationParams.DriverType == video::EDT_OPENGL) //use another window for drawing + [OGLContext setView:(NSView*)CreationParams.WindowId]; + + if (CreationParams.DriverType == video::EDT_OPENGL) + CGLContext = (CGLContextObj) [OGLContext CGLContextObj]; + + DeviceWidth = CreationParams.WindowSize.Width; + DeviceHeight = CreationParams.WindowSize.Height; + result = true; + } + } + } + else + { + IsFullscreen = true; + +#ifdef __MAC_10_6 + displaymode = CGDisplayCopyDisplayMode(display); + + CFArrayRef Modes = CGDisplayCopyAllDisplayModes(display, NULL); + + for(int i = 0; i < CFArrayGetCount(Modes); ++i) + { + CGDisplayModeRef CurrentMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(Modes, i); + + u8 Depth = 0; + + CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(CurrentMode); + + if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + Depth = 32; + else + if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + Depth = 16; + else + if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + Depth = 8; + + if(Depth == CreationParams.Bits) + if((CGDisplayModeGetWidth(CurrentMode) == CreationParams.WindowSize.Width) && (CGDisplayModeGetHeight(CurrentMode) == CreationParams.WindowSize.Height)) + { + displaymode = CurrentMode; + break; + } + } +#else + displaymode = CGDisplayBestModeForParameters(display,CreationParams.Bits,CreationParams.WindowSize.Width,CreationParams.WindowSize.Height,NULL); +#endif + + if (displaymode != NULL) + { +#ifdef __MAC_10_6 + olddisplaymode = CGDisplayCopyDisplayMode(display); +#else + olddisplaymode = CGDisplayCurrentMode(display); +#endif + + error = CGCaptureAllDisplays(); + if (error == CGDisplayNoErr) + { +#ifdef __MAC_10_6 + error = CGDisplaySetDisplayMode(display, displaymode, NULL); +#else + error = CGDisplaySwitchToMode(display, displaymode); +#endif + + if (error == CGDisplayNoErr) + { + if (CreationParams.DriverType == video::EDT_OPENGL) + { + CGLPixelFormatAttribute fullattribs[] = + { + kCGLPFAFullScreen, + kCGLPFADisplayMask, (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display), + kCGLPFADoubleBuffer, + kCGLPFANoRecovery, + kCGLPFAAccelerated, + kCGLPFADepthSize, (CGLPixelFormatAttribute)depthSize, + kCGLPFAColorSize, (CGLPixelFormatAttribute)CreationParams.Bits, + kCGLPFAAlphaSize, (CGLPixelFormatAttribute)alphaSize, + kCGLPFASampleBuffers, (CGLPixelFormatAttribute)(CreationParams.AntiAlias?1:0), + kCGLPFASamples, (CGLPixelFormatAttribute)CreationParams.AntiAlias, + kCGLPFAStencilSize, (CGLPixelFormatAttribute)(CreationParams.Stencilbuffer?1:0), + (CGLPixelFormatAttribute)NULL + }; + + pixelFormat = NULL; + numPixelFormats = 0; + CGLChoosePixelFormat(fullattribs,&pixelFormat,&numPixelFormats); + + if (pixelFormat != NULL) + { + CGLCreateContext(pixelFormat,NULL,&CGLContext); + CGLDestroyPixelFormat(pixelFormat); + } + + if (CGLContext != NULL) + { +#ifdef __MAC_10_6 + CGLSetFullScreenOnDisplay(CGLContext, CGDisplayIDToOpenGLDisplayMask(display)); +#else + CGLSetFullScreen(CGLContext); +#endif + displayRect = CGDisplayBounds(display); + ScreenWidth = DeviceWidth = (int)displayRect.size.width; + ScreenHeight = DeviceHeight = (int)displayRect.size.height; + CreationParams.WindowSize.set(ScreenWidth, ScreenHeight); + result = true; + } + } + else + { + Window = [[NSWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO screen:[NSScreen mainScreen]]; + + [Window setLevel: CGShieldingWindowLevel()]; + [Window setAcceptsMouseMovedEvents:TRUE]; + [Window setIsVisible:TRUE]; + [Window makeKeyAndOrderFront:nil]; + + displayRect = CGDisplayBounds(display); + ScreenWidth = DeviceWidth = (int)displayRect.size.width; + ScreenHeight = DeviceHeight = (int)displayRect.size.height; + CreationParams.WindowSize.set(ScreenWidth, ScreenHeight); + result = true; + } + } + if (!result) + CGReleaseAllDisplays(); + } + } + } + } + @catch (NSException *exception) + { + closeDevice(); + result = false; + } + + if (result) + { + // fullscreen? + if (Window == NULL && !CreationParams.WindowId) //hide menus in fullscreen mode only +#ifdef __MAC_10_6 + [NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)]; +#else + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); +#endif + + if(CreationParams.DriverType == video::EDT_OPENGL) + { + CGLSetCurrentContext(CGLContext); + newSwapInterval = (CreationParams.Vsync) ? 1 : 0; + CGLSetParameter(CGLContext,kCGLCPSwapInterval,&newSwapInterval); + } + } + + return (result); +} + +void CIrrDeviceMacOSX::setResize(int width, int height) +{ + // set new window size + DeviceWidth = width; + DeviceHeight = height; + + // update the size of the opengl rendering context + if(OGLContext); + [OGLContext update]; + + // resize the driver to the inner pane size + if (Window) + { + NSRect driverFrame = [Window contentRectForFrameRect:[Window frame]]; + getVideoDriver()->OnResize(core::dimension2d( (s32)driverFrame.size.width, (s32)driverFrame.size.height)); + } + else + getVideoDriver()->OnResize(core::dimension2d( (s32)width, (s32)height)); + + if (CreationParams.WindowId && OGLContext) + [(NSOpenGLContext *)OGLContext update]; +} + + +void CIrrDeviceMacOSX::createDriver() +{ + switch (CreationParams.DriverType) + { + case video::EDT_SOFTWARE: + #ifdef _IRR_COMPILE_WITH_SOFTWARE_ + VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); + SoftwareRendererType = 2; + #else + os::Printer::log("No Software driver support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_BURNINGSVIDEO: + #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ + VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); + SoftwareRendererType = 1; + #else + os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_OPENGL: + #ifdef _IRR_COMPILE_WITH_OPENGL_ + VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); + #else + os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); + #endif + break; + + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in OSX. Try OpenGL or Software renderer.", ELL_ERROR); + break; + + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + +void CIrrDeviceMacOSX::flush() +{ + if (CGLContext != NULL) + CGLFlushDrawable(CGLContext); +} + +bool CIrrDeviceMacOSX::run() +{ + NSAutoreleasePool* Pool = [[NSAutoreleasePool alloc] init]; + + NSEvent *event; + irr::SEvent ievent; + + os::Timer::tick(); + storeMouseLocation(); + + event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; + if (event != nil) + { + bzero(&ievent,sizeof(ievent)); + + switch([(NSEvent *)event type]) + { + case NSKeyDown: + postKeyEvent(event,ievent,true); + break; + + case NSKeyUp: + postKeyEvent(event,ievent,false); + break; + + case NSFlagsChanged: + ievent.EventType = irr::EET_KEY_INPUT_EVENT; + ievent.KeyInput.Shift = ([(NSEvent *)event modifierFlags] & NSShiftKeyMask) != 0; + ievent.KeyInput.Control = ([(NSEvent *)event modifierFlags] & NSControlKeyMask) != 0; + + if (IsShiftDown != ievent.KeyInput.Shift) + { + ievent.KeyInput.Char = irr::KEY_SHIFT; + ievent.KeyInput.Key = irr::KEY_SHIFT; + ievent.KeyInput.PressedDown = ievent.KeyInput.Shift; + + IsShiftDown = ievent.KeyInput.Shift; + + postEventFromUser(ievent); + } + + if (IsControlDown != ievent.KeyInput.Control) + { + ievent.KeyInput.Char = irr::KEY_CONTROL; + ievent.KeyInput.Key = irr::KEY_CONTROL; + ievent.KeyInput.PressedDown = ievent.KeyInput.Control; + + IsControlDown = ievent.KeyInput.Control; + + postEventFromUser(ievent); + } + + [NSApp sendEvent:event]; + break; + + case NSLeftMouseDown: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; + MouseButtonStates |= irr::EMBSM_LEFT; + ievent.MouseInput.ButtonStates = MouseButtonStates; + postMouseEvent(event,ievent); + break; + + case NSLeftMouseUp: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + MouseButtonStates &= !irr::EMBSM_LEFT; + ievent.MouseInput.ButtonStates = MouseButtonStates; + ievent.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; + postMouseEvent(event,ievent); + break; + + case NSOtherMouseDown: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; + MouseButtonStates |= irr::EMBSM_MIDDLE; + ievent.MouseInput.ButtonStates = MouseButtonStates; + postMouseEvent(event,ievent); + break; + + case NSOtherMouseUp: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + MouseButtonStates &= !irr::EMBSM_MIDDLE; + ievent.MouseInput.ButtonStates = MouseButtonStates; + ievent.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; + postMouseEvent(event,ievent); + break; + + case NSMouseMoved: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + ievent.MouseInput.ButtonStates = MouseButtonStates; + postMouseEvent(event,ievent); + break; + + case NSRightMouseDown: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; + MouseButtonStates |= irr::EMBSM_RIGHT; + ievent.MouseInput.ButtonStates = MouseButtonStates; + postMouseEvent(event,ievent); + break; + + case NSRightMouseUp: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; + MouseButtonStates &= !irr::EMBSM_RIGHT; + ievent.MouseInput.ButtonStates = MouseButtonStates; + postMouseEvent(event,ievent); + break; + + case NSScrollWheel: + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL; + ievent.MouseInput.Wheel = [(NSEvent *)event deltaY]; + if (ievent.MouseInput.Wheel < 1.0f) + ievent.MouseInput.Wheel *= 10.0f; + else + ievent.MouseInput.Wheel *= 5.0f; + postMouseEvent(event,ievent); + break; + + default: + [NSApp sendEvent:event]; + break; + } + } + + pollJoysticks(); + + [Pool release]; + + return (![[NSApp delegate] isQuit] && IsActive); +} + + +//! Pause the current process for the minimum time allowed only to allow other processes to execute +void CIrrDeviceMacOSX::yield() +{ + struct timespec ts = {0,0}; + nanosleep(&ts, NULL); +} + + +//! Pause execution and let other processes to run for a specified amount of time. +void CIrrDeviceMacOSX::sleep(u32 timeMs, bool pauseTimer=false) +{ + bool wasStopped = Timer ? Timer->isStopped() : true; + + struct timespec ts; + ts.tv_sec = (time_t) (timeMs / 1000); + ts.tv_nsec = (long) (timeMs % 1000) * 1000000; + + if (pauseTimer && !wasStopped) + Timer->stop(); + + nanosleep(&ts, NULL); + + if (pauseTimer && !wasStopped) + Timer->start(); +} + + +void CIrrDeviceMacOSX::setWindowCaption(const wchar_t* text) +{ + size_t size; + char title[1024]; + + if (Window != NULL) + { + size = wcstombs(title,text,1024); + title[1023] = 0; +#ifdef __MAC_10_6 + NSString* name = [NSString stringWithCString:title encoding:NSUTF8StringEncoding]; +#else + NSString* name = [NSString stringWithCString:title length:size]; +#endif + [Window setTitle:name]; + [name release]; + } +} + + +bool CIrrDeviceMacOSX::isWindowActive() const +{ + return (IsActive); +} + + +bool CIrrDeviceMacOSX::isWindowFocused() const +{ + if (Window != NULL) + return [Window isKeyWindow]; + return false; +} + + +bool CIrrDeviceMacOSX::isWindowMinimized() const +{ + if (Window != NULL) + return [Window isMiniaturized]; + return false; +} + + +void CIrrDeviceMacOSX::postKeyEvent(void *event,irr::SEvent &ievent,bool pressed) +{ + NSString *str; + std::map::const_iterator iter; + unsigned int result,c,mkey,mchar; + const unsigned char *cStr; + BOOL skipCommand; + + str = [(NSEvent *)event characters]; + if ((str != nil) && ([str length] > 0)) + { + mkey = mchar = 0; + skipCommand = false; + c = [str characterAtIndex:0]; + mchar = c; + + iter = KeyCodes.find([(NSEvent *)event keyCode]); + if (iter != KeyCodes.end()) + mkey = (*iter).second; + else if ((iter = KeyCodes.find(c)) != KeyCodes.end()) + mkey = (*iter).second; + else + { + // workaround for period character + if (c == 0x2E) + { + mkey = irr::KEY_PERIOD; + mchar = '.'; + } + else + { + cStr = (unsigned char *)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding]; + if (cStr != NULL && strlen((char*)cStr) > 0) + { + mchar = cStr[0]; + mkey = toupper(mchar); + if ([(NSEvent *)event modifierFlags] & NSCommandKeyMask) + { + if (mkey == 'C' || mkey == 'V' || mkey == 'X') + { + mchar = 0; + skipCommand = true; + } + } + } + } + } + + ievent.EventType = irr::EET_KEY_INPUT_EVENT; + ievent.KeyInput.Key = (irr::EKEY_CODE)mkey; + ievent.KeyInput.PressedDown = pressed; + ievent.KeyInput.Shift = ([(NSEvent *)event modifierFlags] & NSShiftKeyMask) != 0; + ievent.KeyInput.Control = ([(NSEvent *)event modifierFlags] & NSControlKeyMask) != 0; + ievent.KeyInput.Char = mchar; + + if (skipCommand) + ievent.KeyInput.Control = true; + else if ([(NSEvent *)event modifierFlags] & NSCommandKeyMask) + [NSApp sendEvent:(NSEvent *)event]; + + postEventFromUser(ievent); + } +} + + +void CIrrDeviceMacOSX::postMouseEvent(void *event,irr::SEvent &ievent) +{ + bool post = true; + + if (Window != NULL) + { + ievent.MouseInput.X = (int)[(NSEvent *)event locationInWindow].x; + ievent.MouseInput.Y = DeviceHeight - (int)[(NSEvent *)event locationInWindow].y; + + if (ievent.MouseInput.Y < 0) + post = false; + } + else + { + CGEventRef ourEvent = CGEventCreate(NULL); + CGPoint point = CGEventGetLocation(ourEvent); + CFRelease(ourEvent); + + ievent.MouseInput.X = (int)point.x; + ievent.MouseInput.Y = (int)point.y; + + if (ievent.MouseInput.Y < 0) + post = false; + } + + if (post) + postEventFromUser(ievent); + + [NSApp sendEvent:(NSEvent *)event]; +} + + +void CIrrDeviceMacOSX::storeMouseLocation() +{ + int x,y; + + if (Window != NULL) + { + NSPoint p; + p = [NSEvent mouseLocation]; + p = [Window convertScreenToBase:p]; + x = (int)p.x; + y = DeviceHeight - (int)p.y; + } + else + { + CGEventRef ourEvent = CGEventCreate(NULL); + CGPoint point = CGEventGetLocation(ourEvent); + CFRelease(ourEvent); + + x = (int)point.x; + y = (int)point.y; + + const core::position2di& curr = ((CCursorControl *)CursorControl)->getPosition(); + if (curr.X != x || curr.Y != y) + { + // In fullscreen mode, events are not sent regularly so rely on polling + irr::SEvent ievent; + ievent.EventType = irr::EET_MOUSE_INPUT_EVENT; + ievent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; + ievent.MouseInput.X = x; + ievent.MouseInput.Y = y; + postEventFromUser(ievent); + } + } + + ((CCursorControl *)CursorControl)->updateInternalCursorPosition(x,y); +} + + +void CIrrDeviceMacOSX::setMouseLocation(int x,int y) +{ + NSPoint p; + CGPoint c; + + if (Window != NULL) + { + // Irrlicht window exists + p.x = (float) x; + p.y = (float) (DeviceHeight - y); + p = [Window convertBaseToScreen:p]; + p.y = ScreenHeight - p.y; + } + else + { + p.x = (float) x; + p.y = (float) y + (ScreenHeight - DeviceHeight); + } + + c.x = p.x; + c.y = p.y; + +#ifdef __MAC_10_6 + /*CGEventSourceRef SourceRef = CGEventSourceCreate(0); + CGEventSourceSetLocalEventsSuppressionInterval(SourceRef, 0); + CFRelease(SourceRef);*/ + CGSetLocalEventsSuppressionInterval(0); +#else + CGSetLocalEventsSuppressionInterval(0); +#endif + CGWarpMouseCursorPosition(c); +} + + +void CIrrDeviceMacOSX::setCursorVisible(bool visible) +{ + if (visible) + CGDisplayShowCursor(CGMainDisplayID()); + else + CGDisplayHideCursor(CGMainDisplayID()); +} + + +void CIrrDeviceMacOSX::initKeycodes() +{ + KeyCodes[kVK_UpArrow] = irr::KEY_UP; + KeyCodes[kVK_DownArrow] = irr::KEY_DOWN; + KeyCodes[kVK_LeftArrow] = irr::KEY_LEFT; + KeyCodes[kVK_RightArrow] = irr::KEY_RIGHT; + KeyCodes[kVK_F1] = irr::KEY_F1; + KeyCodes[kVK_F2] = irr::KEY_F2; + KeyCodes[kVK_F3] = irr::KEY_F3; + KeyCodes[kVK_F4] = irr::KEY_F4; + KeyCodes[kVK_F5] = irr::KEY_F5; + KeyCodes[kVK_F6] = irr::KEY_F6; + KeyCodes[kVK_F7] = irr::KEY_F7; + KeyCodes[kVK_F8] = irr::KEY_F8; + KeyCodes[kVK_F9] = irr::KEY_F9; + KeyCodes[kVK_F10] = irr::KEY_F10; + KeyCodes[kVK_F11] = irr::KEY_F11; + KeyCodes[kVK_F12] = irr::KEY_F12; + KeyCodes[kVK_F13] = irr::KEY_F13; + KeyCodes[kVK_F14] = irr::KEY_F14; + KeyCodes[kVK_F15] = irr::KEY_F15; + KeyCodes[kVK_F16] = irr::KEY_F16; + KeyCodes[kVK_F17] = irr::KEY_F17; + KeyCodes[kVK_F18] = irr::KEY_F18; + KeyCodes[kVK_F19] = irr::KEY_F19; + KeyCodes[kVK_F20] = irr::KEY_F20; + KeyCodes[kVK_Home] = irr::KEY_HOME; + KeyCodes[kVK_End] = irr::KEY_END; + KeyCodes[NSInsertFunctionKey] = irr::KEY_INSERT; + KeyCodes[kVK_ForwardDelete] = irr::KEY_DELETE; + KeyCodes[kVK_Help] = irr::KEY_HELP; + KeyCodes[NSSelectFunctionKey] = irr::KEY_SELECT; + KeyCodes[NSPrintFunctionKey] = irr::KEY_PRINT; + KeyCodes[NSExecuteFunctionKey] = irr::KEY_EXECUT; + KeyCodes[NSPrintScreenFunctionKey] = irr::KEY_SNAPSHOT; + KeyCodes[NSPauseFunctionKey] = irr::KEY_PAUSE; + KeyCodes[NSScrollLockFunctionKey] = irr::KEY_SCROLL; + KeyCodes[kVK_Delete] = irr::KEY_BACK; + KeyCodes[kVK_Tab] = irr::KEY_TAB; + KeyCodes[kVK_Return] = irr::KEY_RETURN; + KeyCodes[kVK_Escape] = irr::KEY_ESCAPE; + KeyCodes[kVK_Control] = irr::KEY_CONTROL; + KeyCodes[kVK_RightControl] = irr::KEY_RCONTROL; + KeyCodes[kVK_Command] = irr::KEY_MENU; + KeyCodes[kVK_Shift] = irr::KEY_SHIFT; + KeyCodes[kVK_RightShift] = irr::KEY_RSHIFT; + KeyCodes[kVK_Space] = irr::KEY_SPACE; + + KeyCodes[kVK_ANSI_A] = irr::KEY_KEY_A; + KeyCodes[kVK_ANSI_B] = irr::KEY_KEY_B; + KeyCodes[kVK_ANSI_C] = irr::KEY_KEY_C; + KeyCodes[kVK_ANSI_D] = irr::KEY_KEY_D; + KeyCodes[kVK_ANSI_E] = irr::KEY_KEY_E; + KeyCodes[kVK_ANSI_F] = irr::KEY_KEY_F; + KeyCodes[kVK_ANSI_G] = irr::KEY_KEY_G; + KeyCodes[kVK_ANSI_H] = irr::KEY_KEY_H; + KeyCodes[kVK_ANSI_I] = irr::KEY_KEY_I; + KeyCodes[kVK_ANSI_J] = irr::KEY_KEY_J; + KeyCodes[kVK_ANSI_K] = irr::KEY_KEY_K; + KeyCodes[kVK_ANSI_L] = irr::KEY_KEY_L; + KeyCodes[kVK_ANSI_M] = irr::KEY_KEY_M; + KeyCodes[kVK_ANSI_N] = irr::KEY_KEY_N; + KeyCodes[kVK_ANSI_O] = irr::KEY_KEY_O; + KeyCodes[kVK_ANSI_P] = irr::KEY_KEY_P; + KeyCodes[kVK_ANSI_Q] = irr::KEY_KEY_Q; + KeyCodes[kVK_ANSI_R] = irr::KEY_KEY_R; + KeyCodes[kVK_ANSI_S] = irr::KEY_KEY_S; + KeyCodes[kVK_ANSI_T] = irr::KEY_KEY_T; + KeyCodes[kVK_ANSI_U] = irr::KEY_KEY_U; + KeyCodes[kVK_ANSI_V] = irr::KEY_KEY_V; + KeyCodes[kVK_ANSI_W] = irr::KEY_KEY_W; + KeyCodes[kVK_ANSI_X] = irr::KEY_KEY_X; + KeyCodes[kVK_ANSI_X] = irr::KEY_KEY_X; + KeyCodes[kVK_ANSI_Y] = irr::KEY_KEY_Y; + KeyCodes[kVK_ANSI_Z] = irr::KEY_KEY_Z; + + KeyCodes[kVK_ANSI_0] = irr::KEY_KEY_0; + KeyCodes[kVK_ANSI_1] = irr::KEY_KEY_1; + KeyCodes[kVK_ANSI_2] = irr::KEY_KEY_2; + KeyCodes[kVK_ANSI_3] = irr::KEY_KEY_3; + KeyCodes[kVK_ANSI_4] = irr::KEY_KEY_4; + KeyCodes[kVK_ANSI_5] = irr::KEY_KEY_5; + KeyCodes[kVK_ANSI_6] = irr::KEY_KEY_6; + KeyCodes[kVK_ANSI_7] = irr::KEY_KEY_7; + KeyCodes[kVK_ANSI_8] = irr::KEY_KEY_8; + KeyCodes[kVK_ANSI_9] = irr::KEY_KEY_9; + + KeyCodes[kVK_ANSI_Slash] = irr::KEY_DIVIDE; + KeyCodes[kVK_ANSI_Comma] = irr::KEY_COMMA; + KeyCodes[kVK_ANSI_Period] = irr::KEY_PERIOD; + KeyCodes[kVK_PageUp] = irr::KEY_PRIOR; + KeyCodes[kVK_PageDown] = irr::KEY_NEXT; + + KeyCodes[kVK_ANSI_Keypad0] = irr::KEY_NUMPAD0; + KeyCodes[kVK_ANSI_Keypad1] = irr::KEY_NUMPAD1; + KeyCodes[kVK_ANSI_Keypad2] = irr::KEY_NUMPAD2; + KeyCodes[kVK_ANSI_Keypad3] = irr::KEY_NUMPAD3; + KeyCodes[kVK_ANSI_Keypad4] = irr::KEY_NUMPAD4; + KeyCodes[kVK_ANSI_Keypad5] = irr::KEY_NUMPAD5; + KeyCodes[kVK_ANSI_Keypad6] = irr::KEY_NUMPAD6; + KeyCodes[kVK_ANSI_Keypad7] = irr::KEY_NUMPAD7; + KeyCodes[kVK_ANSI_Keypad8] = irr::KEY_NUMPAD8; + KeyCodes[kVK_ANSI_Keypad9] = irr::KEY_NUMPAD9; + + KeyCodes[kVK_ANSI_KeypadDecimal] = irr::KEY_DECIMAL; + KeyCodes[kVK_ANSI_KeypadMultiply] = irr::KEY_MULTIPLY; + KeyCodes[kVK_ANSI_KeypadPlus] = irr::KEY_PLUS; + KeyCodes[kVK_ANSI_KeypadClear] = irr::KEY_OEM_CLEAR; + KeyCodes[kVK_ANSI_KeypadDivide] = irr::KEY_DIVIDE; + KeyCodes[kVK_ANSI_KeypadEnter] = irr::KEY_RETURN; + KeyCodes[kVK_ANSI_KeypadMinus] = irr::KEY_SUBTRACT; +} + + +//! Sets if the window should be resizable in windowed mode. +void CIrrDeviceMacOSX::setResizable(bool resize) +{ + IsResizable = resize; +#if 0 + if (resize) + [Window setStyleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask]; + else + [Window setStyleMask:NSTitledWindowMask|NSClosableWindowMask]; +#endif +} + + +bool CIrrDeviceMacOSX::isResizable() const +{ + return IsResizable; +} + + +void CIrrDeviceMacOSX::minimizeWindow() +{ + if (Window != NULL) + [Window miniaturize:[NSApp self]]; +} + + +//! Maximizes the window if possible. +void CIrrDeviceMacOSX::maximizeWindow() +{ + // todo: implement +} + + +//! Restore the window to normal size if possible. +void CIrrDeviceMacOSX::restoreWindow() +{ + [Window deminiaturize:[NSApp self]]; +} + + +bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rect* src ) +{ + // todo: implement window ID and src rectangle + + if (!surface) + return false; + + if (SoftwareRendererType > 0) + { + const u32 colorSamples=3; + // do we need to change the size? + const bool updateSize = !SoftwareDriverTarget || + s32([SoftwareDriverTarget size].width) != surface->getDimension().Width || + s32([SoftwareDriverTarget size].height) != surface->getDimension().Height; + + NSRect areaRect = NSMakeRect(0.0, 0.0, surface->getDimension().Width, surface->getDimension().Height); + const u32 destPitch = (colorSamples * areaRect.size.width); + + // create / update the target + if (updateSize) + { + [SoftwareDriverTarget release]; + // allocate target for IImage + SoftwareDriverTarget = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: nil + pixelsWide: areaRect.size.width + pixelsHigh: areaRect.size.height + bitsPerSample: 8 + samplesPerPixel: colorSamples + hasAlpha: NO + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bytesPerRow: destPitch + bitsPerPixel: 8*colorSamples]; + } + + if (SoftwareDriverTarget==nil) + return false; + + // get pointer to image data + unsigned char* imgData = (unsigned char*)surface->lock(); + + u8* srcdata = reinterpret_cast(imgData); + u8* destData = reinterpret_cast([SoftwareDriverTarget bitmapData]); + const u32 srcheight = core::min_(surface->getDimension().Height, (u32)areaRect.size.height); + const u32 srcPitch = surface->getPitch(); + const u32 minWidth = core::min_(surface->getDimension().Width, (u32)areaRect.size.width); + for (u32 y=0; y!=srcheight; ++y) + { + if(SoftwareRendererType == 2) + { + if (surface->getColorFormat() == video::ECF_A8R8G8B8) + video::CColorConverter::convert_A8R8G8B8toB8G8R8(srcdata, minWidth, destData); + else if (surface->getColorFormat() == video::ECF_A1R5G5B5) + video::CColorConverter::convert_A1R5G5B5toB8G8R8(srcdata, minWidth, destData); + else + video::CColorConverter::convert_viaFormat(srcdata, surface->getColorFormat(), minWidth, destData, video::ECF_R8G8B8); + } + else + { + if (surface->getColorFormat() == video::ECF_A8R8G8B8) + video::CColorConverter::convert_A8R8G8B8toR8G8B8(srcdata, minWidth, destData); + else if (surface->getColorFormat() == video::ECF_A1R5G5B5) + video::CColorConverter::convert_A1R5G5B5toR8G8B8(srcdata, minWidth, destData); + else + video::CColorConverter::convert_viaFormat(srcdata, surface->getColorFormat(), minWidth, destData, video::ECF_R8G8B8); + } + + srcdata += srcPitch; + destData += destPitch; + } + + // unlock the data + surface->unlock(); + + // todo: draw properly into a sub-view + [SoftwareDriverTarget draw]; + } + + return false; +} + + +#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) +static void joystickRemovalCallback(void * target, + IOReturn result, void * refcon, void * sender) +{ + JoystickInfo *joy = (JoystickInfo *) refcon; + joy->removed = 1; +} +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + + +bool CIrrDeviceMacOSX::activateJoysticks(core::array & joystickInfo) +{ +#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + ActiveJoysticks.clear(); + joystickInfo.clear(); + + io_object_t hidObject = 0; + io_iterator_t hidIterator = 0; + IOReturn result = kIOReturnSuccess; + mach_port_t masterPort = 0; + CFMutableDictionaryRef hidDictionaryRef = NULL; + + result = IOMasterPort (bootstrap_port, &masterPort); + if (kIOReturnSuccess != result) + { + os::Printer::log("initialiseJoysticks IOMasterPort failed", ELL_ERROR); + return false; + } + + hidDictionaryRef = IOServiceMatching (kIOHIDDeviceKey); + if (!hidDictionaryRef) + { + os::Printer::log("initialiseJoysticks IOServiceMatching failed", ELL_ERROR); + return false; + } + result = IOServiceGetMatchingServices (masterPort, hidDictionaryRef, &hidIterator); + + if (kIOReturnSuccess != result) + { + os::Printer::log("initialiseJoysticks IOServiceGetMatchingServices failed", ELL_ERROR); + return false; + } + + //no joysticks just return + if (!hidIterator) + return false; + + u32 jindex = 0u; + while ((hidObject = IOIteratorNext (hidIterator))) + { + JoystickInfo info; + + // get dictionary for HID properties + CFMutableDictionaryRef hidProperties = 0; + + kern_return_t kern_result = IORegistryEntryCreateCFProperties (hidObject, &hidProperties, kCFAllocatorDefault, kNilOptions); + if ((kern_result == KERN_SUCCESS) && hidProperties) + { + HRESULT plugInResult = S_OK; + SInt32 score = 0; + IOCFPlugInInterface ** ppPlugInInterface = NULL; + result = IOCreatePlugInInterfaceForService (hidObject, kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); + if (kIOReturnSuccess == result) + { + plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, + CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void **) &(info.interface)); + if (plugInResult != S_OK) + os::Printer::log("initialiseJoysticks query HID class device interface failed", ELL_ERROR); + (*ppPlugInInterface)->Release(ppPlugInInterface); + } + else + continue; + + if (info.interface != NULL) + { + result = (*(info.interface))->open (info.interface, 0); + if (result == kIOReturnSuccess) + { + (*(info.interface))->setRemovalCallback (info.interface, joystickRemovalCallback, &info, &info); + getJoystickDeviceInfo(hidObject, hidProperties, &info); + + // get elements + CFTypeRef refElementTop = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); + if (refElementTop) + { + CFTypeID type = CFGetTypeID (refElementTop); + if (type == CFArrayGetTypeID()) + { + CFRange range = {0, CFArrayGetCount ((CFArrayRef)refElementTop)}; + info.numActiveJoysticks = ActiveJoysticks.size(); + CFArrayApplyFunction ((CFArrayRef)refElementTop, range, getJoystickComponentArrayHandler, &info); + } + } + } + else + { + CFRelease (hidProperties); + os::Printer::log("initialiseJoysticks Open interface failed", ELL_ERROR); + continue; + } + + CFRelease (hidProperties); + + result = IOObjectRelease (hidObject); + + if ( (info.usagePage != kHIDPage_GenericDesktop) || + ((info.usage != kHIDUsage_GD_Joystick && + info.usage != kHIDUsage_GD_GamePad && + info.usage != kHIDUsage_GD_MultiAxisController)) ) + { + closeJoystickDevice (&info); + continue; + } + + for (u32 i = 0; i < 6; ++i) + info.persistentData.JoystickEvent.Axis[i] = 0; + + ActiveJoysticks.push_back(info); + + SJoystickInfo returnInfo; + returnInfo.Joystick = jindex; + returnInfo.Axes = info.axes; + //returnInfo.Hats = info.hats; + returnInfo.Buttons = info.buttons; + returnInfo.Name = info.joystickName; + returnInfo.PovHat = SJoystickInfo::POV_HAT_UNKNOWN; + ++ jindex; + + //if (info.hatComp.size()) + // returnInfo.PovHat = SJoystickInfo::POV_HAT_PRESENT; + //else + // returnInfo.PovHat = SJoystickInfo::POV_HAT_ABSENT; + + joystickInfo.push_back(returnInfo); + } + + } + else + { + continue; + } + } + result = IOObjectRelease (hidIterator); + + return true; +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ + + return false; +} + +void CIrrDeviceMacOSX::pollJoysticks() +{ +#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) + if(0 == ActiveJoysticks.size()) + return; + + u32 joystick; + for (joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) + { + if (ActiveJoysticks[joystick].removed) + continue; + + bool found = false; + ActiveJoysticks[joystick].persistentData.JoystickEvent.Joystick = joystick; + + if (ActiveJoysticks[joystick].interface) + { + for (u32 n = 0; n < ActiveJoysticks[joystick].axisComp.size(); n++) + { + IOReturn result = kIOReturnSuccess; + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + result = (*(ActiveJoysticks[joystick].interface))->getElementValue(ActiveJoysticks[joystick].interface, ActiveJoysticks[joystick].axisComp[n].cookie, &hidEvent); + if (kIOReturnSuccess == result) + { + const f32 min = -32768.0f; + const f32 max = 32767.0f; + const f32 deviceScale = max - min; + const f32 readScale = (f32)ActiveJoysticks[joystick].axisComp[n].maxRead - (f32)ActiveJoysticks[joystick].axisComp[n].minRead; + + if (hidEvent.value < ActiveJoysticks[joystick].axisComp[n].minRead) + ActiveJoysticks[joystick].axisComp[n].minRead = hidEvent.value; + if (hidEvent.value > ActiveJoysticks[joystick].axisComp[n].maxRead) + ActiveJoysticks[joystick].axisComp[n].maxRead = hidEvent.value; + + if (readScale != 0.0f) + hidEvent.value = (int)(((f32)((f32)hidEvent.value - (f32)ActiveJoysticks[joystick].axisComp[n].minRead) * deviceScale / readScale) + min); + + if (ActiveJoysticks[joystick].persistentData.JoystickEvent.Axis[n] != (s16)hidEvent.value) + found = true; + ActiveJoysticks[joystick].persistentData.JoystickEvent.Axis[n] = (s16)hidEvent.value; + } + }//axis check + + for (u32 n = 0; n < ActiveJoysticks[joystick].buttonComp.size(); n++) + { + IOReturn result = kIOReturnSuccess; + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + result = (*(ActiveJoysticks[joystick].interface))->getElementValue(ActiveJoysticks[joystick].interface, ActiveJoysticks[joystick].buttonComp[n].cookie, &hidEvent); + if (kIOReturnSuccess == result) + { + u32 ButtonStates = 0; + + if (hidEvent.value && !((ActiveJoysticks[joystick].persistentData.JoystickEvent.ButtonStates & (1 << n)) ? true : false) ) + found = true; + else if (!hidEvent.value && ((ActiveJoysticks[joystick].persistentData.JoystickEvent.ButtonStates & (1 << n)) ? true : false)) + found = true; + + if (hidEvent.value) + ActiveJoysticks[joystick].persistentData.JoystickEvent.ButtonStates |= (1 << n); + else + ActiveJoysticks[joystick].persistentData.JoystickEvent.ButtonStates &= ~(1 << n); + } + }//button check + //still ToDo..will be done soon :) +/* + for (u32 n = 0; n < ActiveJoysticks[joystick].hatComp.size(); n++) + { + IOReturn result = kIOReturnSuccess; + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + result = (*(ActiveJoysticks[joystick].interface))->getElementValue(ActiveJoysticks[joystick].interface, ActiveJoysticks[joystick].hatComp[n].cookie, &hidEvent); + if (kIOReturnSuccess == result) + { + if (ActiveJoysticks[joystick].persistentData.JoystickEvent.POV != hidEvent.value) + found = true; + ActiveJoysticks[joystick].persistentData.JoystickEvent.POV = hidEvent.value; + } + }//hat check +*/ + } + + if (found) + postEventFromUser(ActiveJoysticks[joystick].persistentData); + } +#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ +} + +video::IVideoModeList* CIrrDeviceMacOSX::getVideoModeList() +{ + if (!VideoModeList->getVideoModeCount()) + { + CGDirectDisplayID display; + display = CGMainDisplayID(); + +#ifdef __MAC_10_6 + CFArrayRef Modes = CGDisplayCopyAllDisplayModes(display, NULL); + + for(int i = 0; i < CFArrayGetCount(Modes); ++i) + { + CGDisplayModeRef CurrentMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(Modes, i); + + u8 Depth = 0; + + CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(CurrentMode); + + if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + Depth = 32; + else + if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + Depth = 16; + else + if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + Depth = 8; + + if(Depth) + { + unsigned int Width = CGDisplayModeGetWidth(CurrentMode); + unsigned int Height = CGDisplayModeGetHeight(CurrentMode); + + VideoModeList->addMode(core::dimension2d(Width, Height), Depth); + } + } +#else + CFArrayRef availableModes = CGDisplayAvailableModes(display); + unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes); + for (u32 i= 0; i(width, height), + bitsPerPixel); + } +#endif + } + return VideoModeList; +} + +} // end namespace + +#endif // _IRR_COMPILE_WITH_OSX_DEVICE_ + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/DemoApp-Info.plist b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/DemoApp-Info.plist new file mode 100644 index 0000000..a754c7f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/DemoApp-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.irrlicht.${EXECUTABLE_NAME} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + IRRL + CFBundleVersion + 1.0 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/Irrlicht-Info.plist b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/Irrlicht-Info.plist new file mode 100644 index 0000000..fd4ba51 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/Irrlicht-Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.irrlichtengine.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.6 + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj new file mode 100644 index 0000000..65f4cec --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX.xcodeproj/project.pbxproj @@ -0,0 +1,7232 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + B81CFFC6097FE9980057C06F /* All */ = { + isa = PBXAggregateTarget; + buildConfigurationList = B81CFFE8097FE9C30057C06F /* Build configuration list for PBXAggregateTarget "All" */; + buildPhases = ( + ); + dependencies = ( + 0946CCD90EC99D8C00D945A5 /* PBXTargetDependency */, + 09F649210D2CDFF0001E0599 /* PBXTargetDependency */, + 4CA5CB9A0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB980A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB960A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB940A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB920A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB900A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB8E0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB8C0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB8A0A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB880A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB860A4868B500ADB3D7 /* PBXTargetDependency */, + 4CA5CB840A4868B500ADB3D7 /* PBXTargetDependency */, + 0E2E3D901103EB32002DE8D7 /* PBXTargetDependency */, + 0E2E3D921103EB39002DE8D7 /* PBXTargetDependency */, + 0E2E3D8E1103EB1A002DE8D7 /* PBXTargetDependency */, + 0E2E3D941103EB41002DE8D7 /* PBXTargetDependency */, + 0E2E3D8C1103EB12002DE8D7 /* PBXTargetDependency */, + 4CA5CB820A4868B500ADB3D7 /* PBXTargetDependency */, + ); + name = All; + productName = ALL; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 09022C560EA0E97F00CD54EE /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 09022C5B0EA0E97F00CD54EE /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 09022C5C0EA0E97F00CD54EE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 09022C5D0EA0E97F00CD54EE /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 09022C5E0EA0E97F00CD54EE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 09022C7E0EA0EA9D00CD54EE /* CGUIAttributeEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C690EA0EA9D00CD54EE /* CGUIAttributeEditor.cpp */; }; + 09022C7F0EA0EA9D00CD54EE /* CGUIEditFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C6E0EA0EA9D00CD54EE /* CGUIEditFactory.cpp */; }; + 09022C800EA0EA9D00CD54EE /* CGUIEditWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C700EA0EA9D00CD54EE /* CGUIEditWindow.cpp */; }; + 09022C810EA0EA9D00CD54EE /* CGUIEditWorkspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C720EA0EA9D00CD54EE /* CGUIEditWorkspace.cpp */; }; + 09022C820EA0EA9D00CD54EE /* CGUIPanel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C750EA0EA9D00CD54EE /* CGUIPanel.cpp */; }; + 09022C830EA0EA9D00CD54EE /* CGUITextureCacheBrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C790EA0EA9D00CD54EE /* CGUITextureCacheBrowser.cpp */; }; + 09022C840EA0EA9D00CD54EE /* CMemoryReadWriteFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C7B0EA0EA9D00CD54EE /* CMemoryReadWriteFile.cpp */; }; + 09022C850EA0EA9D00CD54EE /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09022C7D0EA0EA9D00CD54EE /* main.cpp */; }; + 090FBC820D31085E0076D847 /* CVolumeLightSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */; }; + 090FBC830D31085E0076D847 /* CVolumeLightSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 090FBC810D31085E0076D847 /* CVolumeLightSceneNode.h */; }; + 0910B9DE0D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9D90D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp */; }; + 0910B9DF0D1F5D4100D46B04 /* CGUITable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9DA0D1F5D4100D46B04 /* CGUITable.cpp */; }; + 0910B9E00D1F5D4100D46B04 /* CGUITable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9DB0D1F5D4100D46B04 /* CGUITable.h */; }; + 0910B9E10D1F5D4100D46B04 /* CImageLoaderWAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9DC0D1F5D4100D46B04 /* CImageLoaderWAL.cpp */; }; + 0910B9E20D1F5D4100D46B04 /* CImageLoaderWAL.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9DD0D1F5D4100D46B04 /* CImageLoaderWAL.h */; }; + 0910BA240D1F64B300D46B04 /* CMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9FD0D1F64B300D46B04 /* CMeshBuffer.h */; }; + 0910BA250D1F64B300D46B04 /* coreutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9FE0D1F64B300D46B04 /* coreutil.h */; }; + 0910BA260D1F64B300D46B04 /* ECullingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9FF0D1F64B300D46B04 /* ECullingTypes.h */; }; + 0910BA270D1F64B300D46B04 /* EDebugSceneTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA000D1F64B300D46B04 /* EDebugSceneTypes.h */; }; + 0910BA280D1F64B300D46B04 /* EDriverFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA010D1F64B300D46B04 /* EDriverFeatures.h */; }; + 0910BA290D1F64B300D46B04 /* EGUIAlignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA020D1F64B300D46B04 /* EGUIAlignment.h */; }; + 0910BA2A0D1F64B300D46B04 /* EHardwareBufferFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA030D1F64B300D46B04 /* EHardwareBufferFlags.h */; }; + 0910BA2B0D1F64B300D46B04 /* EMaterialFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA040D1F64B300D46B04 /* EMaterialFlags.h */; }; + 0910BA2C0D1F64B300D46B04 /* EMaterialTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA050D1F64B300D46B04 /* EMaterialTypes.h */; }; + 0910BA2D0D1F64B300D46B04 /* EMeshWriterEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA060D1F64B300D46B04 /* EMeshWriterEnums.h */; }; + 0910BA2E0D1F64B300D46B04 /* EMessageBoxFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA070D1F64B300D46B04 /* EMessageBoxFlags.h */; }; + 0910BA2F0D1F64B300D46B04 /* ETerrainElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA080D1F64B300D46B04 /* ETerrainElements.h */; }; + 0910BA300D1F64B300D46B04 /* IAnimatedMeshMD3.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA090D1F64B300D46B04 /* IAnimatedMeshMD3.h */; }; + 0910BA310D1F64B300D46B04 /* IBoneSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0A0D1F64B300D46B04 /* IBoneSceneNode.h */; }; + 0910BA320D1F64B300D46B04 /* IGUIColorSelectDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0B0D1F64B300D46B04 /* IGUIColorSelectDialog.h */; }; + 0910BA330D1F64B300D46B04 /* IGUIElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0C0D1F64B300D46B04 /* IGUIElementFactory.h */; }; + 0910BA340D1F64B300D46B04 /* IGUIFontBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0D0D1F64B300D46B04 /* IGUIFontBitmap.h */; }; + 0910BA350D1F64B300D46B04 /* IGUISpinBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0E0D1F64B300D46B04 /* IGUISpinBox.h */; }; + 0910BA360D1F64B300D46B04 /* IGUISpriteBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0F0D1F64B300D46B04 /* IGUISpriteBank.h */; }; + 0910BA370D1F64B300D46B04 /* IGUITable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA100D1F64B300D46B04 /* IGUITable.h */; }; + 0910BA380D1F64B300D46B04 /* IMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA110D1F64B300D46B04 /* IMeshWriter.h */; }; + 0910BA390D1F64B300D46B04 /* IParticleAnimatedMeshSceneNodeEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA120D1F64B300D46B04 /* IParticleAnimatedMeshSceneNodeEmitter.h */; }; + 0910BA3A0D1F64B300D46B04 /* IParticleAttractionAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA130D1F64B300D46B04 /* IParticleAttractionAffector.h */; }; + 0910BA3B0D1F64B300D46B04 /* IParticleBoxEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA140D1F64B300D46B04 /* IParticleBoxEmitter.h */; }; + 0910BA3C0D1F64B300D46B04 /* IParticleCylinderEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA150D1F64B300D46B04 /* IParticleCylinderEmitter.h */; }; + 0910BA3D0D1F64B300D46B04 /* IParticleFadeOutAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA160D1F64B300D46B04 /* IParticleFadeOutAffector.h */; }; + 0910BA3E0D1F64B300D46B04 /* IParticleGravityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA170D1F64B300D46B04 /* IParticleGravityAffector.h */; }; + 0910BA3F0D1F64B300D46B04 /* IParticleMeshEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA180D1F64B300D46B04 /* IParticleMeshEmitter.h */; }; + 0910BA400D1F64B300D46B04 /* IParticleRingEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA190D1F64B300D46B04 /* IParticleRingEmitter.h */; }; + 0910BA410D1F64B300D46B04 /* IParticleRotationAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1A0D1F64B300D46B04 /* IParticleRotationAffector.h */; }; + 0910BA420D1F64B300D46B04 /* IParticleSphereEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1B0D1F64B300D46B04 /* IParticleSphereEmitter.h */; }; + 0910BA430D1F64B300D46B04 /* IQ3Shader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1C0D1F64B300D46B04 /* IQ3Shader.h */; }; + 0910BA440D1F64B300D46B04 /* IReferenceCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1D0D1F64B300D46B04 /* IReferenceCounted.h */; }; + 0910BA450D1F64B300D46B04 /* irrMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1E0D1F64B300D46B04 /* irrMap.h */; }; + 0910BA460D1F64B300D46B04 /* ISkinnedMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1F0D1F64B300D46B04 /* ISkinnedMesh.h */; }; + 0910BA470D1F64B300D46B04 /* SMaterialLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA200D1F64B300D46B04 /* SMaterialLayer.h */; }; + 0910BA480D1F64B300D46B04 /* SSharedMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA210D1F64B300D46B04 /* SSharedMeshBuffer.h */; }; + 0910BA490D1F64B300D46B04 /* SSkinMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA220D1F64B300D46B04 /* SSkinMeshBuffer.h */; }; + 0910BA4A0D1F64B300D46B04 /* SViewFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA230D1F64B300D46B04 /* SViewFrustum.h */; }; + 0925113E0D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0925113F0D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511400D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511410D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511420D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511430D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511440D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511450D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511460D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511470D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511480D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 092511490D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0925114A0D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0925114B0D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0925114C0D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0925114D0D744ADE006784D9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 09293C3E0ED32029003B8C9C /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C2C0ED32029003B8C9C /* png.c */; }; + 09293C3F0ED32029003B8C9C /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C2D0ED32029003B8C9C /* pngerror.c */; }; + 09293C410ED32029003B8C9C /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C2F0ED32029003B8C9C /* pngget.c */; }; + 09293C420ED32029003B8C9C /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C300ED32029003B8C9C /* pngmem.c */; }; + 09293C430ED32029003B8C9C /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C310ED32029003B8C9C /* pngpread.c */; }; + 09293C440ED32029003B8C9C /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C320ED32029003B8C9C /* pngread.c */; }; + 09293C450ED32029003B8C9C /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C330ED32029003B8C9C /* pngrio.c */; }; + 09293C460ED32029003B8C9C /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C340ED32029003B8C9C /* pngrtran.c */; }; + 09293C470ED32029003B8C9C /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C350ED32029003B8C9C /* pngrutil.c */; }; + 09293C480ED32029003B8C9C /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C360ED32029003B8C9C /* pngset.c */; }; + 09293C4A0ED32029003B8C9C /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C380ED32029003B8C9C /* pngtrans.c */; }; + 09293C4C0ED32029003B8C9C /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3A0ED32029003B8C9C /* pngwio.c */; }; + 09293C4D0ED32029003B8C9C /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3B0ED32029003B8C9C /* pngwrite.c */; }; + 09293C4E0ED32029003B8C9C /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3C0ED32029003B8C9C /* pngwtran.c */; }; + 09293C4F0ED32029003B8C9C /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3D0ED32029003B8C9C /* pngwutil.c */; }; + 0930CE560EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE570EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE580EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE590EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE5A0EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE5B0EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE5C0EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE5D0EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE5E0EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE5F0EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE600EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE610EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE620EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE630EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE640EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE650EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0930CE660EC39F4500D63866 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 093973C00E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 093973BC0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.cpp */; }; + 093973C10E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 093973BD0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.h */; }; + 093973C20E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 093973BE0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.cpp */; }; + 093973C30E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.h in Headers */ = {isa = PBXBuildFile; fileRef = 093973BF0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.h */; }; + 0946CCA70EC99BBE00D945A5 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 0946CCAC0EC99BBE00D945A5 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 0946CCAD0EC99BBE00D945A5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 0946CCAE0EC99BBE00D945A5 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 0946CCAF0EC99BBE00D945A5 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0946CCB00EC99BBE00D945A5 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0946CCCB0EC99C6E00D945A5 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0946CCCA0EC99C6E00D945A5 /* main.cpp */; }; + 096840470D0F1A2300333EFD /* CB3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968401E0D0F1A2300333EFD /* CB3DMeshFileLoader.cpp */; }; + 096840480D0F1A2300333EFD /* CB3DMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0968401F0D0F1A2300333EFD /* CB3DMeshFileLoader.h */; }; + 096840490D0F1A2300333EFD /* CBoneSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840200D0F1A2300333EFD /* CBoneSceneNode.cpp */; }; + 0968404A0D0F1A2300333EFD /* CBoneSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840210D0F1A2300333EFD /* CBoneSceneNode.h */; }; + 0968404B0D0F1A2300333EFD /* CBSPMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840220D0F1A2300333EFD /* CBSPMeshFileLoader.cpp */; }; + 0968404C0D0F1A2300333EFD /* CBSPMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840230D0F1A2300333EFD /* CBSPMeshFileLoader.h */; }; + 0968404E0D0F1A2300333EFD /* CColladaMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840250D0F1A2300333EFD /* CColladaMeshWriter.cpp */; }; + 0968404F0D0F1A2300333EFD /* CColladaMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840260D0F1A2300333EFD /* CColladaMeshWriter.h */; }; + 096840500D0F1A2300333EFD /* CImageLoaderPPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840270D0F1A2300333EFD /* CImageLoaderPPM.cpp */; }; + 096840510D0F1A2300333EFD /* CImageLoaderPPM.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840280D0F1A2300333EFD /* CImageLoaderPPM.h */; }; + 096840540D0F1A2300333EFD /* CIrrMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968402B0D0F1A2300333EFD /* CIrrMeshFileLoader.cpp */; }; + 096840550D0F1A2300333EFD /* CIrrMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0968402C0D0F1A2300333EFD /* CIrrMeshFileLoader.h */; }; + 096840560D0F1A2300333EFD /* CIrrMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968402D0D0F1A2300333EFD /* CIrrMeshWriter.cpp */; }; + 096840570D0F1A2300333EFD /* CIrrMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0968402E0D0F1A2300333EFD /* CIrrMeshWriter.h */; }; + 096840580D0F1A2300333EFD /* CMD2MeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968402F0D0F1A2300333EFD /* CMD2MeshFileLoader.cpp */; }; + 096840590D0F1A2300333EFD /* CMD2MeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840300D0F1A2300333EFD /* CMD2MeshFileLoader.h */; }; + 0968405A0D0F1A2300333EFD /* CMS3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840310D0F1A2300333EFD /* CMS3DMeshFileLoader.cpp */; }; + 0968405B0D0F1A2300333EFD /* CMS3DMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840320D0F1A2300333EFD /* CMS3DMeshFileLoader.h */; }; + 0968405C0D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840330D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.cpp */; }; + 0968405D0D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840340D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.h */; }; + 0968405E0D0F1A2300333EFD /* CParticleAttractionAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840350D0F1A2300333EFD /* CParticleAttractionAffector.cpp */; }; + 0968405F0D0F1A2300333EFD /* CParticleAttractionAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840360D0F1A2300333EFD /* CParticleAttractionAffector.h */; }; + 096840600D0F1A2300333EFD /* CParticleCylinderEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840370D0F1A2300333EFD /* CParticleCylinderEmitter.cpp */; }; + 096840610D0F1A2300333EFD /* CParticleCylinderEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840380D0F1A2300333EFD /* CParticleCylinderEmitter.h */; }; + 096840620D0F1A2300333EFD /* CParticleMeshEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840390D0F1A2300333EFD /* CParticleMeshEmitter.cpp */; }; + 096840630D0F1A2300333EFD /* CParticleMeshEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0968403A0D0F1A2300333EFD /* CParticleMeshEmitter.h */; }; + 096840640D0F1A2300333EFD /* CParticleRingEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968403B0D0F1A2300333EFD /* CParticleRingEmitter.cpp */; }; + 096840650D0F1A2300333EFD /* CParticleRingEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0968403C0D0F1A2300333EFD /* CParticleRingEmitter.h */; }; + 096840660D0F1A2300333EFD /* CParticleRotationAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968403D0D0F1A2300333EFD /* CParticleRotationAffector.cpp */; }; + 096840670D0F1A2300333EFD /* CParticleRotationAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0968403E0D0F1A2300333EFD /* CParticleRotationAffector.h */; }; + 096840680D0F1A2300333EFD /* CParticleSphereEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968403F0D0F1A2300333EFD /* CParticleSphereEmitter.cpp */; }; + 096840690D0F1A2300333EFD /* CParticleSphereEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840400D0F1A2300333EFD /* CParticleSphereEmitter.h */; }; + 0968406A0D0F1A2300333EFD /* CSkinnedMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840410D0F1A2300333EFD /* CSkinnedMesh.cpp */; }; + 0968406B0D0F1A2300333EFD /* CSkinnedMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840420D0F1A2300333EFD /* CSkinnedMesh.h */; }; + 0968406C0D0F1A2300333EFD /* CSTLMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840430D0F1A2300333EFD /* CSTLMeshFileLoader.cpp */; }; + 0968406D0D0F1A2300333EFD /* CSTLMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840440D0F1A2300333EFD /* CSTLMeshFileLoader.h */; }; + 0968406E0D0F1A2300333EFD /* CSTLMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840450D0F1A2300333EFD /* CSTLMeshWriter.cpp */; }; + 0968406F0D0F1A2300333EFD /* CSTLMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 096840460D0F1A2300333EFD /* CSTLMeshWriter.h */; }; + 096CC0E00ECE65B500C81DC7 /* CParticleScaleAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096CC0DE0ECE65B500C81DC7 /* CParticleScaleAffector.cpp */; }; + 096CC0E10ECE65B500C81DC7 /* CParticleScaleAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 096CC0DF0ECE65B500C81DC7 /* CParticleScaleAffector.h */; }; + 096F8E3D0EA2EFBA00907EC5 /* COBJMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096F8E3B0EA2EFBA00907EC5 /* COBJMeshWriter.cpp */; }; + 096F8E3E0EA2EFBA00907EC5 /* COBJMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 096F8E3C0EA2EFBA00907EC5 /* COBJMeshWriter.h */; }; + 09C638720D4F1A69000B6A18 /* CLWOMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09C638700D4F1A69000B6A18 /* CLWOMeshFileLoader.cpp */; }; + 09C638730D4F1A69000B6A18 /* CLWOMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 09C638710D4F1A69000B6A18 /* CLWOMeshFileLoader.h */; }; + 09F460EB0D3223ED00D0A9B0 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09F6492E0D2CE038001E0599 /* main.cpp */; }; + 09F648F80D2CDED9001E0599 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 09F648FD0D2CDED9001E0599 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 09F648FE0D2CDED9001E0599 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 09F648FF0D2CDED9001E0599 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 09F6491A0D2CDF9A001E0599 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054710A48470500C844C2 /* main.cpp */; }; + 09F649330D2CE03E001E0599 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 09F649380D2CE03E001E0599 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 09F649390D2CE03E001E0599 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 09F6493A0D2CE03E001E0599 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 09F6495A0D2CE206001E0599 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 09F6495F0D2CE206001E0599 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 09F649600D2CE206001E0599 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 09F649610D2CE206001E0599 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 09F649740D2CE2D0001E0599 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09F649730D2CE2D0001E0599 /* main.cpp */; }; + 0E2E3C461103B1B5002DE8D7 /* jaricom.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C431103B1B5002DE8D7 /* jaricom.c */; }; + 0E2E3C471103B1B5002DE8D7 /* jcarith.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C441103B1B5002DE8D7 /* jcarith.c */; }; + 0E2E3C481103B1B5002DE8D7 /* jdarith.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C451103B1B5002DE8D7 /* jdarith.c */; }; + 0E2E3C4A1103B224002DE8D7 /* Octree.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E2E3C491103B224002DE8D7 /* Octree.h */; }; + 0E2E3C4D1103B247002DE8D7 /* COctreeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C4B1103B247002DE8D7 /* COctreeSceneNode.cpp */; }; + 0E2E3C4E1103B247002DE8D7 /* COctreeSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E2E3C4C1103B247002DE8D7 /* COctreeSceneNode.h */; }; + 0E2E3C511103B261002DE8D7 /* COctreeTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C4F1103B261002DE8D7 /* COctreeTriangleSelector.cpp */; }; + 0E2E3C521103B261002DE8D7 /* COctreeTriangleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E2E3C501103B261002DE8D7 /* COctreeTriangleSelector.h */; }; + 0E2E3C551103B27D002DE8D7 /* CNPKReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C531103B27D002DE8D7 /* CNPKReader.cpp */; }; + 0E2E3C561103B27D002DE8D7 /* CNPKReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E2E3C541103B27D002DE8D7 /* CNPKReader.h */; }; + 0E2E3C5B1103B2AE002DE8D7 /* CIrrDeviceFB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C571103B2AE002DE8D7 /* CIrrDeviceFB.cpp */; }; + 0E2E3C5C1103B2AE002DE8D7 /* CIrrDeviceFB.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E2E3C581103B2AE002DE8D7 /* CIrrDeviceFB.h */; }; + 0E2E3C5D1103B2AE002DE8D7 /* CIrrDeviceWinCE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C591103B2AE002DE8D7 /* CIrrDeviceWinCE.cpp */; }; + 0E2E3C5E1103B2AE002DE8D7 /* CIrrDeviceWinCE.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E2E3C5A1103B2AE002DE8D7 /* CIrrDeviceWinCE.h */; }; + 0E2E3C641103B384002DE8D7 /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C631103B384002DE8D7 /* LzmaDec.c */; }; + 0E2E3C6F1103B3B9002DE8D7 /* blocksort.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C661103B3B9002DE8D7 /* blocksort.c */; }; + 0E2E3C701103B3B9002DE8D7 /* bzcompress.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C671103B3B9002DE8D7 /* bzcompress.c */; }; + 0E2E3C731103B3B9002DE8D7 /* crctable.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6A1103B3B9002DE8D7 /* crctable.c */; }; + 0E2E3C741103B3B9002DE8D7 /* decompress.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6B1103B3B9002DE8D7 /* decompress.c */; }; + 0E2E3C751103B3B9002DE8D7 /* huffman.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6C1103B3B9002DE8D7 /* huffman.c */; }; + 0E2E3C771103B3B9002DE8D7 /* randtable.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6E1103B3B9002DE8D7 /* randtable.c */; }; + 0E2E3C7C1103B4E1002DE8D7 /* bzlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C7B1103B4E1002DE8D7 /* bzlib.c */; }; + 0E2E3C871103B53C002DE8D7 /* aescrypt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C7E1103B53C002DE8D7 /* aescrypt.cpp */; }; + 0E2E3C881103B53C002DE8D7 /* aeskey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C7F1103B53C002DE8D7 /* aeskey.cpp */; }; + 0E2E3C891103B53C002DE8D7 /* aestab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C801103B53C002DE8D7 /* aestab.cpp */; }; + 0E2E3C8A1103B53C002DE8D7 /* fileenc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C811103B53C002DE8D7 /* fileenc.cpp */; }; + 0E2E3C8B1103B53C002DE8D7 /* hmac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C821103B53C002DE8D7 /* hmac.cpp */; }; + 0E2E3C8C1103B53C002DE8D7 /* prng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C831103B53C002DE8D7 /* prng.cpp */; }; + 0E2E3C8D1103B53C002DE8D7 /* pwd2key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C841103B53C002DE8D7 /* pwd2key.cpp */; }; + 0E2E3C8E1103B53C002DE8D7 /* sha1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C851103B53C002DE8D7 /* sha1.cpp */; }; + 0E2E3C8F1103B53C002DE8D7 /* sha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C861103B53C002DE8D7 /* sha2.cpp */; }; + 0E2E3CEF1103E294002DE8D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 0E2E3CF41103E294002DE8D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 0E2E3CF51103E294002DE8D7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 0E2E3CF61103E294002DE8D7 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 0E2E3CF71103E294002DE8D7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0E2E3CF81103E294002DE8D7 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0E2E3D301103E3F4002DE8D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 0E2E3D341103E3F4002DE8D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 0E2E3D351103E3F4002DE8D7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 0E2E3D361103E3F4002DE8D7 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 0E2E3D371103E3F4002DE8D7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0925113D0D744ADE006784D9 /* Carbon.framework */; }; + 0E2E3D381103E3F4002DE8D7 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0930CE550EC39F4500D63866 /* IOKit.framework */; }; + 0E2E3D701103E6C6002DE8D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3D681103E6C6002DE8D7 /* main.cpp */; }; + 0E2E3D811103E6E4002DE8D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3D791103E6E4002DE8D7 /* main.cpp */; }; + 3430E4D61022C391006271FD /* CTarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3430E4D41022C391006271FD /* CTarReader.h */; }; + 3430E4D71022C391006271FD /* CTarReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3430E4D51022C391006271FD /* CTarReader.cpp */; }; + 344FD4A61039E98C0045FD3F /* CMountPointReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 344FD4A41039E98C0045FD3F /* CMountPointReader.cpp */; }; + 344FD4A71039E98C0045FD3F /* CMountPointReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 344FD4A51039E98C0045FD3F /* CMountPointReader.h */; }; + 3484C4E10F48D1B000C81F60 /* CGUIImageList.h in Headers */ = {isa = PBXBuildFile; fileRef = 3484C4DF0F48D1B000C81F60 /* CGUIImageList.h */; }; + 3484C4E20F48D1B000C81F60 /* CGUIImageList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3484C4E00F48D1B000C81F60 /* CGUIImageList.cpp */; }; + 3484C4EE0F48D3A100C81F60 /* CGUITreeView.h in Headers */ = {isa = PBXBuildFile; fileRef = 3484C4EC0F48D3A100C81F60 /* CGUITreeView.h */; }; + 3484C4EF0F48D3A100C81F60 /* CGUITreeView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3484C4ED0F48D3A100C81F60 /* CGUITreeView.cpp */; }; + 3484C4FD0F48D4CB00C81F60 /* CMemoryFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 3484C4FB0F48D4CB00C81F60 /* CMemoryFile.h */; }; + 3484C4FE0F48D4CB00C81F60 /* CMemoryFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3484C4FC0F48D4CB00C81F60 /* CMemoryFile.cpp */; }; + 34EC243C0F59272E0037BC3A /* CIrrDeviceConsole.h in Headers */ = {isa = PBXBuildFile; fileRef = 34EC243A0F59272E0037BC3A /* CIrrDeviceConsole.h */; }; + 34EC243D0F59272E0037BC3A /* CIrrDeviceConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EC243B0F59272E0037BC3A /* CIrrDeviceConsole.cpp */; }; + 34EF91D20F65FCA6000B5651 /* CImageLoaderRGB.h in Headers */ = {isa = PBXBuildFile; fileRef = 34EF91D00F65FCA6000B5651 /* CImageLoaderRGB.h */; }; + 34EF91D30F65FCA6000B5651 /* CImageLoaderRGB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EF91D10F65FCA6000B5651 /* CImageLoaderRGB.cpp */; }; + 34EF91D70F65FCF6000B5651 /* CPLYMeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 34EF91D50F65FCF6000B5651 /* CPLYMeshFileLoader.h */; }; + 34EF91D80F65FCF6000B5651 /* CPLYMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EF91D60F65FCF6000B5651 /* CPLYMeshFileLoader.cpp */; }; + 34EF91DC0F65FD14000B5651 /* CPLYMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 34EF91DA0F65FD14000B5651 /* CPLYMeshWriter.h */; }; + 34EF91DD0F65FD14000B5651 /* CPLYMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EF91DB0F65FD14000B5651 /* CPLYMeshWriter.cpp */; }; + 4C364EA40A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */; }; + 4C43EEC00A74A5C800F942FC /* CPakReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */; }; + 4C53E2500A48504D0014E966 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054770A48470500C844C2 /* main.cpp */; }; + 4C53E2510A4850550014E966 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4C53E26F0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2700A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2710A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2720A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2730A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2740A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2750A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2760A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2770A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2780A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2790A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E27A0A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E27B0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E27C0A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E27D0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E27E0A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E27F0A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2800A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2810A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2820A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2830A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2840A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2850A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2860A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E2870A4850D60014E966 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26D0A4850D60014E966 /* Cocoa.framework */; }; + 4C53E2880A4850D60014E966 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E26E0A4850D60014E966 /* OpenGL.framework */; }; + 4C53E3890A48559C0014E966 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4C53E3D80A4856B30014E966 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1800A484C2C0014E966 /* inffast.c */; }; + 4C53E3DC0A4856B30014E966 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1850A484C2C0014E966 /* inftrees.c */; }; + 4C53E3E40A4856B30014E966 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E18D0A484C2C0014E966 /* uncompr.c */; }; + 4C53E3F30A4856B30014E966 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1750A484C2C0014E966 /* compress.c */; }; + 4C53E3F60A4856B30014E966 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1770A484C2C0014E966 /* crc32.c */; }; + 4C53E3FE0A4856B30014E966 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1920A484C2C0014E966 /* zutil.c */; }; + 4C53E4010A4856B30014E966 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E18B0A484C2C0014E966 /* trees.c */; }; + 4C53E40A0A4856B30014E966 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1790A484C2C0014E966 /* deflate.c */; }; + 4C53E4150A4856B30014E966 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1720A484C2C0014E966 /* adler32.c */; }; + 4C53E4280A4856B30014E966 /* CImageLoaderPNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */; }; + 4C53E4290A4856B30014E966 /* CColorConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */; }; + 4C53E42A0A4856B30014E966 /* CSceneManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */; }; + 4C53E42B0A4856B30014E966 /* CTRTextureGouraudAdd2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */; }; + 4C53E42C0A4856B30014E966 /* CNullDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF820A484C240014E966 /* CNullDriver.cpp */; }; + 4C53E42D0A4856B30014E966 /* CCSMLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */; }; + 4C53E42E0A4856B30014E966 /* irrXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E00E0A484C250014E966 /* irrXML.cpp */; }; + 4C53E42F0A4856B30014E966 /* CGUIListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF420A484C230014E966 /* CGUIListBox.cpp */; }; + 4C53E4300A4856B30014E966 /* CTRGouraudWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */; }; + 4C53E4310A4856B30014E966 /* CIrrDeviceStub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */; }; + 4C53E4320A4856B30014E966 /* CGUIMessageBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */; }; + 4C53E4330A4856B30014E966 /* CMeshSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */; }; + 4C53E4340A4856B30014E966 /* CGUIStaticText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */; }; + 4C53E4350A4856B30014E966 /* os.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E16A0A484C2C0014E966 /* os.cpp */; }; + 4C53E4360A4856B30014E966 /* COCTLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF840A484C240014E966 /* COCTLoader.cpp */; }; + 4C53E4370A4856B30014E966 /* CGUIContextMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */; }; + 4C53E4390A4856B30014E966 /* CSceneNodeAnimatorFlyCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */; }; + 4C53E43A0A4856B30014E966 /* CDefaultSceneNodeFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */; }; + 4C53E43B0A4856B30014E966 /* CD3D9Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */; }; + 4C53E43C0A4856B30014E966 /* CTRGouraud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */; }; + 4C53E43D0A4856B30014E966 /* C3DSMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */; }; + 4C53E43E0A4856B30014E966 /* COgreMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */; }; + 4C53E43F0A4856B30014E966 /* CMY3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */; }; + 4C53E4400A4856B30014E966 /* CLMTSMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */; }; + 4C53E4410A4856B30014E966 /* CGUIFileOpenDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */; }; + 4C53E4420A4856B30014E966 /* CSceneNodeAnimatorDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */; }; + 4C53E4430A4856B30014E966 /* CTRGouraudAlphaNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */; }; + 4C53E4440A4856B30014E966 /* CGeometryCreator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */; }; + 4C53E4450A4856B30014E966 /* CD3D8Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */; }; + 4C53E4460A4856B30014E966 /* CSkyBoxSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */; }; + 4C53E4470A4856B30014E966 /* CMeshManipulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */; }; + 4C53E4480A4856B30014E966 /* CTextSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */; }; + 4C53E4490A4856B30014E966 /* CTRTextureDetailMap2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */; }; + 4C53E44A0A4856B30014E966 /* CTRTextureGouraudAddNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */; }; + 4C53E44C0A4856B30014E966 /* CTRTextureGouraudNoZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */; }; + 4C53E44E0A4856B30014E966 /* CGUIScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */; }; + 4C53E44F0A4856B30014E966 /* CSceneCollisionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */; }; + 4C53E4500A4856B30014E966 /* CGUICheckBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */; }; + 4C53E4510A4856B30014E966 /* CQ3LevelMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */; }; + 4C53E4520A4856B30014E966 /* CParticleGravityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */; }; + 4C53E4530A4856B30014E966 /* CSoftwareDriver2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */; }; + 4C53E4540A4856B30014E966 /* CD3D9ParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */; }; + 4C53E4550A4856B30014E966 /* CD3D8ParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */; }; + 4C53E4560A4856B30014E966 /* CAnimatedMeshMD2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */; }; + 4C53E4570A4856B30014E966 /* CSceneNodeAnimatorFlyStraight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */; }; + 4C53E4580A4856B30014E966 /* CImageLoaderPCX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */; }; + 4C53E4590A4856B30014E966 /* CAnimatedMeshSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */; }; + 4C53E45A0A4856B30014E966 /* CTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */; }; + 4C53E45B0A4856B30014E966 /* CTRTextureGouraudVertexAlpha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */; }; + 4C53E45C0A4856B30014E966 /* CTRTextureWire2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */; }; + 4C53E45D0A4856B30014E966 /* CTRTextureFlatWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */; }; + 4C53E45E0A4856B30014E966 /* CTRGouraud2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */; }; + 4C53E45F0A4856B30014E966 /* CEmptySceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */; }; + 4C53E4600A4856B30014E966 /* CTRTextureLightMap2_Add.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */; }; + 4C53E4610A4856B30014E966 /* CReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA70A484C240014E966 /* CReadFile.cpp */; }; + 4C53E4620A4856B30014E966 /* COpenGLTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */; }; + 4C53E4640A4856B30014E966 /* COSOperator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF990A484C240014E966 /* COSOperator.cpp */; }; + 4C53E4660A4856B30014E966 /* CColladaFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */; }; + 4C53E4670A4856B30014E966 /* CCameraSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */; }; + 4C53E4680A4856B30014E966 /* CMetaTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */; }; + 4C53E4690A4856B30014E966 /* CTRTextureFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */; }; + 4C53E46A0A4856B30014E966 /* CVideoModeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */; }; + 4C53E46B0A4856B30014E966 /* CXMLReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */; }; + 4C53E46C0A4856B30014E966 /* COpenGLParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */; }; + 4C53E46E0A4856B30014E966 /* CTRTextureGouraudNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */; }; + 4C53E46F0A4856B30014E966 /* CTRTextureGouraudWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */; }; + 4C53E4700A4856B30014E966 /* CParticlePointEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */; }; + 4C53E4710A4856B30014E966 /* CGUIWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF560A484C230014E966 /* CGUIWindow.cpp */; }; + 4C53E4720A4856B30014E966 /* CGUIModalScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */; }; + 4C53E4730A4856B30014E966 /* CImageLoaderPSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */; }; + 4C53E4740A4856B30014E966 /* CWaterSurfaceSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */; }; + 4C53E4750A4856B30014E966 /* CXMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */; }; + 4C53E4760A4856B30014E966 /* CIrrDeviceLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */; }; + 4C53E4770A4856B30014E966 /* CLightSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */; }; + 4C53E4780A4856B30014E966 /* CTRTextureGouraudAdd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */; }; + 4C53E4790A4856B30014E966 /* CTRTextureGouraud2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */; }; + 4C53E47A0A4856B30014E966 /* CSoftwareDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */; }; + 4C53E47B0A4856B30014E966 /* CTRFlatWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */; }; + 4C53E47C0A4856B30014E966 /* CTRGouraudAlpha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */; }; + 4C53E47D0A4856B30014E966 /* CSoftwareTexture2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */; }; + 4C53E47E0A4856B30014E966 /* CZipReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E0030A484C250014E966 /* CZipReader.cpp */; }; + 4C53E47F0A4856B30014E966 /* COpenGLNormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */; }; + 4C53E4800A4856B30014E966 /* CTRTextureLightMap2_M1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */; }; + 4C53E4810A4856B30014E966 /* CTRTextureLightMap2_M4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */; }; + 4C53E4820A4856B30014E966 /* CGUISkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */; }; + 4C53E4830A4856B30014E966 /* CD3D8Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */; }; + 4C53E4840A4856B30014E966 /* CIrrDeviceWin32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */; }; + 4C53E4850A4856B30014E966 /* CFileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF280A484C230014E966 /* CFileSystem.cpp */; }; + 4C53E4860A4856B30014E966 /* CGUIMeshViewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */; }; + 4C53E4870A4856B30014E966 /* CGUIComboBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */; }; + 4C53E4880A4856B30014E966 /* CSceneNodeAnimatorRotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */; }; + 4C53E4890A4856B30014E966 /* CSceneNodeAnimatorTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */; }; + 4C53E48B0A4856B30014E966 /* CParticleSystemSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */; }; + 4C53E48C0A4856B30014E966 /* CTerrainSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */; }; + 4C53E48E0A4856B30014E966 /* CGUIFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */; }; + 4C53E48F0A4856B30014E966 /* CParticleFadeOutAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */; }; + 4C53E4910A4856B30014E966 /* CDummyTransformationSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */; }; + 4C53E4920A4856B30014E966 /* CFileList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF260A484C230014E966 /* CFileList.cpp */; }; + 4C53E4930A4856B30014E966 /* CImageLoaderTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */; }; + 4C53E4940A4856B30014E966 /* CXMLWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */; }; + 4C53E4950A4856B30014E966 /* CSceneNodeAnimatorFollowSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */; }; + 4C53E4960A4856B30014E966 /* CZBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */; }; + 4C53E4970A4856B30014E966 /* CDMFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF200A484C230014E966 /* CDMFLoader.cpp */; }; + 4C53E4980A4856B30014E966 /* CD3D9Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */; }; + 4C53E4990A4856B30014E966 /* COpenGLShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */; }; + 4C53E49A0A4856B30014E966 /* Irrlicht.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E00A0A484C250014E966 /* Irrlicht.cpp */; }; + 4C53E49B0A4856B30014E966 /* CGUIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */; }; + 4C53E49C0A4856B30014E966 /* COpenGLSLMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */; }; + 4C53E49D0A4856B30014E966 /* CD3D9HLSLMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */; }; + 4C53E49E0A4856B30014E966 /* CSoftwareTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */; }; + 4C53E49F0A4856B30014E966 /* CCubeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */; }; + 4C53E4A00A4856B30014E966 /* CTriangleBBSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */; }; + 4C53E4A10A4856B30014E966 /* CD3D9ShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */; }; + 4C53E4A20A4856B30014E966 /* CD3D8ShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */; }; + 4C53E4A30A4856B30014E966 /* CGUIButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */; }; + 4C53E4A40A4856B30014E966 /* CGUIToolBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */; }; + 4C53E4A50A4856B30014E966 /* CDefaultSceneNodeAnimatorFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */; }; + 4C53E4A60A4856B30014E966 /* CBillboardSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */; }; + 4C53E4A70A4856B30014E966 /* CSceneNodeAnimatorCollisionResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */; }; + 4C53E4A80A4856B30014E966 /* CLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF720A484C230014E966 /* CLogger.cpp */; }; + 4C53E4A90A4856B30014E966 /* CGUIInOutFader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */; }; + 4C53E4AA0A4856B30014E966 /* CWriteFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF20A484C250014E966 /* CWriteFile.cpp */; }; + 4C53E4AD0A4856B30014E966 /* CTRTextureGouraud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */; }; + 4C53E4AE0A4856B30014E966 /* CTRFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD10A484C240014E966 /* CTRFlat.cpp */; }; + 4C53E4AF0A4856B30014E966 /* CTerrainTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */; }; + 4C53E4B10A4856B30014E966 /* CGUITabControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF520A484C230014E966 /* CGUITabControl.cpp */; }; + 4C53E4B20A4856B30014E966 /* CParticleBoxEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */; }; + 4C53E4B30A4856B30014E966 /* CGUIMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF440A484C230014E966 /* CGUIMenu.cpp */; }; + 4C53E4B40A4856B30014E966 /* CImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF580A484C230014E966 /* CImage.cpp */; }; + 4C53E4B50A4856B30014E966 /* CShadowVolumeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */; }; + 4C53E4B70A4856B30014E966 /* CGUIEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */; }; + 4C53E4B80A4856B30014E966 /* CLimitReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */; }; + 4C53E4B90A4856B30014E966 /* CAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF00A484C220014E966 /* CAttributes.cpp */; }; + 4C53E4BA0A4856B30014E966 /* COpenGLDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */; }; + 4C53E4BB0A4856B30014E966 /* CTRTextureLightMap2_M2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */; }; + 4C53E4BC0A4856B30014E966 /* CGUIImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */; }; + 4C53E4BD0A4856B30014E966 /* CD3D9NormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */; }; + 4C53E4BE0A4856B30014E966 /* CD3D8NormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */; }; + 4C53E4BF0A4856B30014E966 /* CMeshCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF760A484C230014E966 /* CMeshCache.cpp */; }; + 4C53E4C00A4856B30014E966 /* CImageLoaderJPG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */; }; + 4C53E4C10A4856B30014E966 /* CFPSCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */; }; + 4C53E57E0A4856B30014E966 /* OSXClipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */; }; + 4C53E57F0A4856B30014E966 /* CIrrDeviceMacOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */; }; + 4C53E5800A4856B30014E966 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */; }; + 4C6DC9B70A48715A0017A6E5 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6DC9B60A48715A0017A6E5 /* inflate.c */; }; + 4CA25BCE0A485EAD00B4E469 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F10A485CD80014E966 /* jcapimin.c */; }; + 4CA25BCF0A485EAD00B4E469 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F20A485CD80014E966 /* jcapistd.c */; }; + 4CA25BD00A485EAD00B4E469 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F30A485CD80014E966 /* jccoefct.c */; }; + 4CA25BD10A485EAD00B4E469 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F40A485CD80014E966 /* jccolor.c */; }; + 4CA25BD20A485EAD00B4E469 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F50A485CD80014E966 /* jcdctmgr.c */; }; + 4CA25BD30A485EAD00B4E469 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F60A485CD80014E966 /* jchuff.c */; }; + 4CA25BD50A485EAD00B4E469 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F80A485CD80014E966 /* jcinit.c */; }; + 4CA25BD60A485EAD00B4E469 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F90A485CD80014E966 /* jcmainct.c */; }; + 4CA25BD70A485EAD00B4E469 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FA0A485CD80014E966 /* jcmarker.c */; }; + 4CA25BD80A485EAD00B4E469 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FB0A485CD80014E966 /* jcmaster.c */; }; + 4CA25BD90A485EAD00B4E469 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FC0A485CD80014E966 /* jcomapi.c */; }; + 4CA25BDB0A485EAD00B4E469 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70A0A485CD80014E966 /* jcparam.c */; }; + 4CA25BDD0A485EAD00B4E469 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70C0A485CD80014E966 /* jcprepct.c */; }; + 4CA25BDE0A485EAD00B4E469 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70D0A485CD80014E966 /* jcsample.c */; }; + 4CA25BDF0A485EAD00B4E469 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70E0A485CD80014E966 /* jctrans.c */; }; + 4CA25BE00A485EAD00B4E469 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70F0A485CD80014E966 /* jdapimin.c */; }; + 4CA25BE10A485EAD00B4E469 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7100A485CD80014E966 /* jdapistd.c */; }; + 4CA25BE20A485EAD00B4E469 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7110A485CD80014E966 /* jdatadst.c */; }; + 4CA25BE30A485EAD00B4E469 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7120A485CD80014E966 /* jdatasrc.c */; }; + 4CA25BE40A485EAD00B4E469 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7130A485CD80014E966 /* jdcoefct.c */; }; + 4CA25BE50A485EAD00B4E469 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7140A485CD80014E966 /* jdcolor.c */; }; + 4CA25BE70A485EAD00B4E469 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7160A485CD80014E966 /* jddctmgr.c */; }; + 4CA25BE80A485EAD00B4E469 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7170A485CD80014E966 /* jdhuff.c */; }; + 4CA25BEA0A485EAD00B4E469 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7190A485CD80014E966 /* jdinput.c */; }; + 4CA25BEB0A485EAD00B4E469 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71A0A485CD80014E966 /* jdmainct.c */; }; + 4CA25BEC0A485EAD00B4E469 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71B0A485CD80014E966 /* jdmarker.c */; }; + 4CA25BED0A485EAD00B4E469 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71C0A485CD80014E966 /* jdmaster.c */; }; + 4CA25BEE0A485EAD00B4E469 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71D0A485CD80014E966 /* jdmerge.c */; }; + 4CA25BF00A485EAD00B4E469 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71F0A485CD80014E966 /* jdpostct.c */; }; + 4CA25BF10A485EAD00B4E469 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7200A485CD80014E966 /* jdsample.c */; }; + 4CA25BF20A485EAD00B4E469 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7210A485CD80014E966 /* jdtrans.c */; }; + 4CA25BF30A485EAD00B4E469 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7220A485CD80014E966 /* jerror.c */; }; + 4CA25BF50A485EAD00B4E469 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7240A485CD80014E966 /* jfdctflt.c */; }; + 4CA25BF60A485EAD00B4E469 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7250A485CD80014E966 /* jfdctfst.c */; }; + 4CA25BF70A485EAD00B4E469 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7260A485CD80014E966 /* jfdctint.c */; }; + 4CA25BF80A485EAD00B4E469 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7270A485CD80014E966 /* jidctflt.c */; }; + 4CA25BF90A485EAD00B4E469 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7280A485CD80014E966 /* jidctfst.c */; }; + 4CA25BFA0A485EAD00B4E469 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7290A485CD80014E966 /* jidctint.c */; }; + 4CA25C000A485EAD00B4E469 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7300A485CD80014E966 /* jmemmgr.c */; }; + 4CA25C020A485EAD00B4E469 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7320A485CD80014E966 /* jmemnobs.c */; }; + 4CA25C080A485EAD00B4E469 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7390A485CD80014E966 /* jquant1.c */; }; + 4CA25C090A485EAD00B4E469 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E73A0A485CD80014E966 /* jquant2.c */; }; + 4CA25C0A0A485EAD00B4E469 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E73B0A485CD80014E966 /* jutils.c */; }; + 4CA25C350A4860EE00B4E469 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00547D0A48470500C844C2 /* main.cpp */; }; + 4CA25C360A48610400B4E469 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA25C520A48618800B4E469 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA25C560A4861AE00B4E469 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA25C690A4861D100B4E469 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054830A48470500C844C2 /* main.cpp */; }; + 4CA25C6A0A4861D800B4E469 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA25C8B0A48626600B4E469 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA25C8C0A48627600B4E469 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054890A48470500C844C2 /* main.cpp */; }; + 4CA25C8D0A48628200B4E469 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBA70A4869C600ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBA90A4869DD00ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBAE0A4869E600ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054A30A48470500C844C2 /* main.cpp */; }; + 4CA5CBAF0A4869F300ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB00A4869FD00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054AA0A48470500C844C2 /* main.cpp */; }; + 4CA5CBB10A486A0200ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB20A486A0D00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054B00A48470500C844C2 /* main.cpp */; }; + 4CA5CBB30A486A1300ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBB40A486A1600ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB50A486A1F00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054B60A48470500C844C2 /* main.cpp */; }; + 4CA5CBB60A486A2200ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBB70A486A2500ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBB80A486A2E00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054BC0A48470500C844C2 /* main.cpp */; }; + 4CA5CBB90A486A3100ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBBA0A486A3A00ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CA5CBBB0A486A4C00ADB3D7 /* CMainMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054C70A48470500C844C2 /* CMainMenu.cpp */; }; + 4CA5CBBC0A486A4C00ADB3D7 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054CA0A48470500C844C2 /* main.cpp */; }; + 4CA5CBBD0A486A4C00ADB3D7 /* CDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054C50A48470500C844C2 /* CDemo.cpp */; }; + 4CA5CBBE0A486A4F00ADB3D7 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CA5CBBF0A486A5700ADB3D7 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CC36B0F0A6B61DB0076C4B2 /* CSphereSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */; }; + 4CF146F50A486648006EBA03 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CF146F60A486651006EBA03 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CF146F70A486668006EBA03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00548F0A48470500C844C2 /* main.cpp */; }; + 4CF1470A0A4866FA006EBA03 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CF1470B0A486704006EBA03 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CF147100A486709006EBA03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0054950A48470500C844C2 /* main.cpp */; }; + 4CF147180A48676A006EBA03 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 4C53E1650A484C2C0014E966 /* MainMenu.nib */; }; + 4CF147190A48676E006EBA03 /* libIrrlicht.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; }; + 4CF1471A0A486774006EBA03 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00549B0A48470500C844C2 /* main.cpp */; }; + 4CFA7BEE0A88735A00B03626 /* CImageLoaderBMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */; }; + 4CFA7BF00A88735A00B03626 /* CImageWriterBMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */; }; + 4CFA7BF20A88735A00B03626 /* CImageWriterJPG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */; }; + 4CFA7BF40A88735A00B03626 /* CImageWriterPCX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */; }; + 4CFA7BF60A88735A00B03626 /* CImageWriterPNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */; }; + 4CFA7BF80A88735A00B03626 /* CImageWriterPPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */; }; + 4CFA7BFA0A88735A00B03626 /* CImageWriterPSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */; }; + 4CFA7BFC0A88735A00B03626 /* CImageWriterTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */; }; + 4CFA7BFE0A88735A00B03626 /* CSkyDomeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */; }; + 5DD4804E0C7D91DF00728AA9 /* CDepthBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */; }; + 5DD4804F0C7D91DF00728AA9 /* CDepthBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD4804D0C7D91DF00728AA9 /* CDepthBuffer.h */; }; + 5DD480520C7D936700728AA9 /* IBurningShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480500C7D936700728AA9 /* IBurningShader.cpp */; }; + 5DD480530C7D936700728AA9 /* IBurningShader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480510C7D936700728AA9 /* IBurningShader.h */; }; + 5DD480550C7D93AB00728AA9 /* IDepthBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480540C7D93AB00728AA9 /* IDepthBuffer.h */; }; + 5DD4805A0C7D945800728AA9 /* CAnimatedMeshMD3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */; }; + 5DD4805B0C7D945800728AA9 /* CAnimatedMeshMD3.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480570C7D945800728AA9 /* CAnimatedMeshMD3.h */; }; + 5DD4805C0C7D945800728AA9 /* CDefaultGUIElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */; }; + 5DD4805D0C7D945800728AA9 /* CDefaultGUIElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480590C7D945800728AA9 /* CDefaultGUIElementFactory.h */; }; + 5DD480640C7D947B00728AA9 /* CGUIColorSelectDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */; }; + 5DD480650C7D947B00728AA9 /* CGUIColorSelectDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD4805F0C7D947B00728AA9 /* CGUIColorSelectDialog.h */; }; + 5DD480660C7D947B00728AA9 /* CGUISpinBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */; }; + 5DD480670C7D947B00728AA9 /* CGUISpinBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480610C7D947B00728AA9 /* CGUISpinBox.h */; }; + 5DD480680C7D947B00728AA9 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */; }; + 5DD480690C7D947B00728AA9 /* CGUISpriteBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480630C7D947B00728AA9 /* CGUISpriteBank.h */; }; + 5DD480710C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */; }; + 5DD480720C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD4806B0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h */; }; + 5DD480730C7D94AC00728AA9 /* CTRTextureBlend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */; }; + 5DD480740C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */; }; + 5DD480750C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */; }; + 5DD480760C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */; }; + 5DD480770C7D94AC00728AA9 /* glxext.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480700C7D94AC00728AA9 /* glxext.h */; }; + 5DD480C70C7DA66800728AA9 /* COpenGLExtensionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480C10C7DA66800728AA9 /* COpenGLExtensionHandler.h */; }; + 5DD480C80C7DA66800728AA9 /* CMD3MeshFileLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480C20C7DA66800728AA9 /* CMD3MeshFileLoader.h */; }; + 5DD480C90C7DA66800728AA9 /* CIrrDeviceSDL.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DD480C30C7DA66800728AA9 /* CIrrDeviceSDL.h */; }; + 5DD480CA0C7DA66800728AA9 /* CIrrDeviceSDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */; }; + 5DD480CB0C7DA66800728AA9 /* COpenGLExtensionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */; }; + 5DD480CC0C7DA66800728AA9 /* CMD3MeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */; }; + 95154774133CD9DA008D792F /* aabbox3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C0A0A88742800B03626 /* aabbox3d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154775133CD9DA008D792F /* CMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9FD0D1F64B300D46B04 /* CMeshBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154776133CD9DA008D792F /* coreutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9FE0D1F64B300D46B04 /* coreutil.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154777133CD9DA008D792F /* dimension2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C0B0A88742800B03626 /* dimension2d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154778133CD9DA008D792F /* ECullingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910B9FF0D1F64B300D46B04 /* ECullingTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154779133CD9DA008D792F /* EDebugSceneTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA000D1F64B300D46B04 /* EDebugSceneTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515477A133CD9DA008D792F /* EDriverFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA010D1F64B300D46B04 /* EDriverFeatures.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515477B133CD9DA008D792F /* EDriverTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C0C0A88742800B03626 /* EDriverTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515477C133CD9DA008D792F /* EGUIAlignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA020D1F64B300D46B04 /* EGUIAlignment.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515477D133CD9DA008D792F /* EGUIElementTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C0D0A88742800B03626 /* EGUIElementTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515477E133CD9DA008D792F /* EHardwareBufferFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA030D1F64B300D46B04 /* EHardwareBufferFlags.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515477F133CD9DA008D792F /* EMaterialFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA040D1F64B300D46B04 /* EMaterialFlags.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154780133CD9DA008D792F /* EMaterialTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA050D1F64B300D46B04 /* EMaterialTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154781133CD9DA008D792F /* EMeshWriterEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA060D1F64B300D46B04 /* EMeshWriterEnums.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154782133CD9DA008D792F /* EMessageBoxFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA070D1F64B300D46B04 /* EMessageBoxFlags.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154783133CD9DA008D792F /* ESceneNodeAnimatorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C0E0A88742800B03626 /* ESceneNodeAnimatorTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154784133CD9DA008D792F /* ESceneNodeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C0F0A88742800B03626 /* ESceneNodeTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154785133CD9DA008D792F /* ETerrainElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA080D1F64B300D46B04 /* ETerrainElements.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154786133CD9DA008D792F /* heapsort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C100A88742800B03626 /* heapsort.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154787133CD9DA008D792F /* IAnimatedMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C110A88742900B03626 /* IAnimatedMesh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154788133CD9DA008D792F /* IAnimatedMeshMD2.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C130A88742900B03626 /* IAnimatedMeshMD2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154789133CD9DA008D792F /* IAnimatedMeshMD3.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA090D1F64B300D46B04 /* IAnimatedMeshMD3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515478A133CD9DA008D792F /* IAnimatedMeshSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C150A88742900B03626 /* IAnimatedMeshSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515478B133CD9DA008D792F /* IAttributeExchangingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C170A88742900B03626 /* IAttributeExchangingObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515478C133CD9DA008D792F /* IAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C180A88742900B03626 /* IAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515478D133CD9DA008D792F /* IBillboardSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C190A88742900B03626 /* IBillboardSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515478E133CD9DA008D792F /* IBoneSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0A0D1F64B300D46B04 /* IBoneSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515478F133CD9DA008D792F /* ICameraSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C1A0A88742900B03626 /* ICameraSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154790133CD9DA008D792F /* ICursorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C1B0A88742900B03626 /* ICursorControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154791133CD9DA008D792F /* IDummyTransformationSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C1C0A88742900B03626 /* IDummyTransformationSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154792133CD9DA008D792F /* IEventReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C1D0A88742900B03626 /* IEventReceiver.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154793133CD9DA008D792F /* IFileList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C1E0A88742900B03626 /* IFileList.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154794133CD9DA008D792F /* IFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C1F0A88742900B03626 /* IFileSystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154795133CD9DA008D792F /* IGPUProgrammingServices.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C200A88742900B03626 /* IGPUProgrammingServices.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154796133CD9DA008D792F /* IGUIButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C210A88742900B03626 /* IGUIButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154797133CD9DA008D792F /* IGUICheckBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C220A88742900B03626 /* IGUICheckBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154798133CD9DA008D792F /* IGUIColorSelectDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0B0D1F64B300D46B04 /* IGUIColorSelectDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154799133CD9DA008D792F /* IGUIComboBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C230A88742900B03626 /* IGUIComboBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515479A133CD9DA008D792F /* IGUIContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C240A88742900B03626 /* IGUIContextMenu.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515479B133CD9DA008D792F /* IGUIEditBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C250A88742900B03626 /* IGUIEditBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515479C133CD9DA008D792F /* IGUIElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C260A88742900B03626 /* IGUIElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515479D133CD9DA008D792F /* IGUIElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0C0D1F64B300D46B04 /* IGUIElementFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515479E133CD9DA008D792F /* IGUIEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C270A88742900B03626 /* IGUIEnvironment.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515479F133CD9DA008D792F /* IGUIFileOpenDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C280A88742900B03626 /* IGUIFileOpenDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A0133CD9DA008D792F /* IGUIFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C290A88742900B03626 /* IGUIFont.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A1133CD9DA008D792F /* IGUIFontBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0D0D1F64B300D46B04 /* IGUIFontBitmap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A2133CD9DA008D792F /* IGUIImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C2A0A88742900B03626 /* IGUIImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A3133CD9DA008D792F /* IGUIInOutFader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C2B0A88742900B03626 /* IGUIInOutFader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A4133CD9DA008D792F /* IGUIListBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C2C0A88742900B03626 /* IGUIListBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A5133CD9DA008D792F /* IGUIMeshViewer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C2D0A88742900B03626 /* IGUIMeshViewer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A6133CD9DA008D792F /* IGUIScrollBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C2E0A88742900B03626 /* IGUIScrollBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A7133CD9DA008D792F /* IGUISkin.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C2F0A88742900B03626 /* IGUISkin.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A8133CD9DA008D792F /* IGUISpinBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0E0D1F64B300D46B04 /* IGUISpinBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547A9133CD9DA008D792F /* IGUISpriteBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA0F0D1F64B300D46B04 /* IGUISpriteBank.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547AA133CD9DA008D792F /* IGUIStaticText.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C300A88742900B03626 /* IGUIStaticText.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547AB133CD9DA008D792F /* IGUITabControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C310A88742900B03626 /* IGUITabControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547AC133CD9DA008D792F /* IGUITable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA100D1F64B300D46B04 /* IGUITable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547AD133CD9DA008D792F /* IGUIToolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C320A88742900B03626 /* IGUIToolbar.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547AE133CD9DA008D792F /* IGUIWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C330A88742900B03626 /* IGUIWindow.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547AF133CD9DA008D792F /* IImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C340A88742900B03626 /* IImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B0133CD9DA008D792F /* IImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C350A88742900B03626 /* IImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B1133CD9DA008D792F /* IImageWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C360A88742900B03626 /* IImageWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B2133CD9DA008D792F /* ILightSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C370A88742900B03626 /* ILightSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B3133CD9DA008D792F /* ILogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C380A88742900B03626 /* ILogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B4133CD9DA008D792F /* IMaterialRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C390A88742900B03626 /* IMaterialRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B5133CD9DA008D792F /* IMaterialRendererServices.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C3A0A88742900B03626 /* IMaterialRendererServices.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B6133CD9DA008D792F /* IMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C3B0A88742900B03626 /* IMesh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B7133CD9DA008D792F /* IMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C3C0A88742900B03626 /* IMeshBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B8133CD9DA008D792F /* IMeshCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C3D0A88742900B03626 /* IMeshCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547B9133CD9DA008D792F /* IMeshLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C3E0A88742900B03626 /* IMeshLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547BA133CD9DA008D792F /* IMeshManipulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C3F0A88742900B03626 /* IMeshManipulator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547BB133CD9DA008D792F /* IMeshSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C400A88742900B03626 /* IMeshSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547BC133CD9DA008D792F /* IMeshWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA110D1F64B300D46B04 /* IMeshWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547BD133CD9DA008D792F /* IMetaTriangleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C410A88742900B03626 /* IMetaTriangleSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547BE133CD9DA008D792F /* IOSOperator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C420A88742900B03626 /* IOSOperator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547BF133CD9DA008D792F /* IParticleAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C430A88742900B03626 /* IParticleAffector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C0133CD9DA008D792F /* IParticleAnimatedMeshSceneNodeEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA120D1F64B300D46B04 /* IParticleAnimatedMeshSceneNodeEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C1133CD9DA008D792F /* IParticleAttractionAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA130D1F64B300D46B04 /* IParticleAttractionAffector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C2133CD9DA008D792F /* IParticleBoxEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA140D1F64B300D46B04 /* IParticleBoxEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C3133CD9DA008D792F /* IParticleCylinderEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA150D1F64B300D46B04 /* IParticleCylinderEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C4133CD9DA008D792F /* IParticleEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C440A88742900B03626 /* IParticleEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C5133CD9DA008D792F /* IParticleFadeOutAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA160D1F64B300D46B04 /* IParticleFadeOutAffector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C6133CD9DA008D792F /* IParticleGravityAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA170D1F64B300D46B04 /* IParticleGravityAffector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C7133CD9DA008D792F /* IParticleMeshEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA180D1F64B300D46B04 /* IParticleMeshEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C8133CD9DA008D792F /* IParticleRingEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA190D1F64B300D46B04 /* IParticleRingEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547C9133CD9DA008D792F /* IParticleRotationAffector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1A0D1F64B300D46B04 /* IParticleRotationAffector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547CA133CD9DA008D792F /* IParticleSphereEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1B0D1F64B300D46B04 /* IParticleSphereEmitter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547CB133CD9DA008D792F /* IParticleSystemSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C450A88742900B03626 /* IParticleSystemSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547CC133CD9DA008D792F /* IQ3LevelMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C460A88742900B03626 /* IQ3LevelMesh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547CD133CD9DA008D792F /* IQ3Shader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1C0D1F64B300D46B04 /* IQ3Shader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547CE133CD9DA008D792F /* IReadFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C470A88742900B03626 /* IReadFile.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547CF133CD9DA008D792F /* IReferenceCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1D0D1F64B300D46B04 /* IReferenceCounted.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D0133CD9DA008D792F /* irrAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C480A88742900B03626 /* irrAllocator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D1133CD9DA008D792F /* irrArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C490A88742900B03626 /* irrArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D2133CD9DA008D792F /* IrrCompileConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C4A0A88742900B03626 /* IrrCompileConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D3133CD9DA008D792F /* irrlicht.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C4B0A88742900B03626 /* irrlicht.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D4133CD9DA008D792F /* IrrlichtDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C4C0A88742900B03626 /* IrrlichtDevice.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D5133CD9DA008D792F /* irrList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C4D0A88742900B03626 /* irrList.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D6133CD9DA008D792F /* irrMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1E0D1F64B300D46B04 /* irrMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D7133CD9DA008D792F /* irrMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C4E0A88742900B03626 /* irrMath.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D8133CD9DA008D792F /* irrString.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C4F0A88742900B03626 /* irrString.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547D9133CD9DA008D792F /* irrTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C500A88742900B03626 /* irrTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547DA133CD9DA008D792F /* irrXML.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C510A88742900B03626 /* irrXML.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547DB133CD9DA008D792F /* ISceneCollisionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C520A88742900B03626 /* ISceneCollisionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547DC133CD9DA008D792F /* ISceneManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C530A88742900B03626 /* ISceneManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547DD133CD9DA008D792F /* ISceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C540A88742900B03626 /* ISceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547DE133CD9DA008D792F /* ISceneNodeAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C550A88742900B03626 /* ISceneNodeAnimator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547DF133CD9DA008D792F /* ISceneNodeAnimatorCollisionResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C560A88742900B03626 /* ISceneNodeAnimatorCollisionResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E0133CD9DA008D792F /* ISceneNodeAnimatorFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C570A88742900B03626 /* ISceneNodeAnimatorFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E1133CD9DA008D792F /* ISceneNodeFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C580A88742900B03626 /* ISceneNodeFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E2133CD9DA008D792F /* ISceneUserDataSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C590A88742900B03626 /* ISceneUserDataSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E3133CD9DA008D792F /* IShaderConstantSetCallBack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C5A0A88742900B03626 /* IShaderConstantSetCallBack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E4133CD9DA008D792F /* IShadowVolumeSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C5B0A88742900B03626 /* IShadowVolumeSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E5133CD9DA008D792F /* ISkinnedMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA1F0D1F64B300D46B04 /* ISkinnedMesh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E6133CD9DA008D792F /* ITerrainSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C5C0A88742900B03626 /* ITerrainSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E7133CD9DA008D792F /* ITextSceneNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C5D0A88742900B03626 /* ITextSceneNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E8133CD9DA008D792F /* ITexture.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C5E0A88742900B03626 /* ITexture.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547E9133CD9DA008D792F /* ITimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C5F0A88742900B03626 /* ITimer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547EA133CD9DA008D792F /* ITriangleSelector.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C600A88742900B03626 /* ITriangleSelector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547EB133CD9DA008D792F /* IVideoDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C620A88742900B03626 /* IVideoDriver.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547EC133CD9DA008D792F /* IVideoModeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C630A88742900B03626 /* IVideoModeList.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547ED133CD9DA008D792F /* IWriteFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C640A88742900B03626 /* IWriteFile.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547EE133CD9DA008D792F /* IXMLReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C650A88742900B03626 /* IXMLReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547EF133CD9DA008D792F /* IXMLWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C660A88742900B03626 /* IXMLWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F0133CD9DA008D792F /* Keycodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C670A88742900B03626 /* Keycodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F1133CD9DA008D792F /* line2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C680A88742900B03626 /* line2d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F2133CD9DA008D792F /* line3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C690A88742900B03626 /* line3d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F3133CD9DA008D792F /* matrix4.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C6A0A88742900B03626 /* matrix4.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F4133CD9DA008D792F /* plane3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C6B0A88742900B03626 /* plane3d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F5133CD9DA008D792F /* position2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C6C0A88742900B03626 /* position2d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F6133CD9DA008D792F /* quaternion.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C6D0A88742900B03626 /* quaternion.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F7133CD9DA008D792F /* rect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C6E0A88742900B03626 /* rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F8133CD9DA008D792F /* S3DVertex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C6F0A88742900B03626 /* S3DVertex.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547F9133CD9DA008D792F /* SAnimatedMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C700A88742900B03626 /* SAnimatedMesh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547FA133CD9DA008D792F /* SceneParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C710A88742900B03626 /* SceneParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547FB133CD9DA008D792F /* SColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C720A88742900B03626 /* SColor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547FC133CD9DA008D792F /* SExposedVideoData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C730A88742900B03626 /* SExposedVideoData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547FD133CD9DA008D792F /* SIrrCreationParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C740A88742900B03626 /* SIrrCreationParameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547FE133CD9DA008D792F /* SKeyMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C750A88742900B03626 /* SKeyMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 951547FF133CD9DA008D792F /* SLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C760A88742900B03626 /* SLight.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154800133CD9DA008D792F /* SMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C770A88742900B03626 /* SMaterial.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154801133CD9DA008D792F /* SMaterialLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA200D1F64B300D46B04 /* SMaterialLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154802133CD9DA008D792F /* SMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C780A88742900B03626 /* SMesh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154803133CD9DA008D792F /* SMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C790A88742900B03626 /* SMeshBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154804133CD9DA008D792F /* SMeshBufferLightMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C7A0A88742900B03626 /* SMeshBufferLightMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154805133CD9DA008D792F /* SMeshBufferTangents.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C7B0A88742900B03626 /* SMeshBufferTangents.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154806133CD9DA008D792F /* SParticle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C7C0A88742900B03626 /* SParticle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154807133CD9DA008D792F /* SSharedMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA210D1F64B300D46B04 /* SSharedMeshBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154808133CD9DA008D792F /* SSkinMeshBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA220D1F64B300D46B04 /* SSkinMeshBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95154809133CD9DA008D792F /* SViewFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0910BA230D1F64B300D46B04 /* SViewFrustum.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515480A133CD9DA008D792F /* triangle3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C7E0A88742900B03626 /* triangle3d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515480B133CD9DA008D792F /* vector2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C7F0A88742900B03626 /* vector2d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9515480C133CD9DA008D792F /* vector3d.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFA7C800A88742900B03626 /* vector3d.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 959729E912C192DA00BF73D3 /* jcapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F10A485CD80014E966 /* jcapimin.c */; }; + 959729EA12C192DA00BF73D3 /* jcapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F20A485CD80014E966 /* jcapistd.c */; }; + 959729EB12C192DA00BF73D3 /* jccoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F30A485CD80014E966 /* jccoefct.c */; }; + 959729EC12C192DA00BF73D3 /* jccolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F40A485CD80014E966 /* jccolor.c */; }; + 959729ED12C192DA00BF73D3 /* jcdctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F50A485CD80014E966 /* jcdctmgr.c */; }; + 959729EE12C192DA00BF73D3 /* jchuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F60A485CD80014E966 /* jchuff.c */; }; + 959729EF12C192DA00BF73D3 /* jcinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F80A485CD80014E966 /* jcinit.c */; }; + 959729F012C192DA00BF73D3 /* jcmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6F90A485CD80014E966 /* jcmainct.c */; }; + 959729F112C192DA00BF73D3 /* jcmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FA0A485CD80014E966 /* jcmarker.c */; }; + 959729F212C192DA00BF73D3 /* jcmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FB0A485CD80014E966 /* jcmaster.c */; }; + 959729F312C192DA00BF73D3 /* jcomapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E6FC0A485CD80014E966 /* jcomapi.c */; }; + 959729F412C192DA00BF73D3 /* jcparam.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70A0A485CD80014E966 /* jcparam.c */; }; + 959729F512C192DA00BF73D3 /* jcprepct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70C0A485CD80014E966 /* jcprepct.c */; }; + 959729F612C192DA00BF73D3 /* jcsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70D0A485CD80014E966 /* jcsample.c */; }; + 959729F712C192DA00BF73D3 /* jctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70E0A485CD80014E966 /* jctrans.c */; }; + 959729F812C192DA00BF73D3 /* jdapimin.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E70F0A485CD80014E966 /* jdapimin.c */; }; + 959729F912C192DA00BF73D3 /* jdapistd.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7100A485CD80014E966 /* jdapistd.c */; }; + 959729FA12C192DA00BF73D3 /* jdatadst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7110A485CD80014E966 /* jdatadst.c */; }; + 959729FB12C192DA00BF73D3 /* jdatasrc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7120A485CD80014E966 /* jdatasrc.c */; }; + 959729FC12C192DA00BF73D3 /* jdcoefct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7130A485CD80014E966 /* jdcoefct.c */; }; + 959729FD12C192DA00BF73D3 /* jdcolor.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7140A485CD80014E966 /* jdcolor.c */; }; + 959729FE12C192DA00BF73D3 /* jddctmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7160A485CD80014E966 /* jddctmgr.c */; }; + 959729FF12C192DA00BF73D3 /* jdhuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7170A485CD80014E966 /* jdhuff.c */; }; + 95972A0012C192DA00BF73D3 /* jdinput.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7190A485CD80014E966 /* jdinput.c */; }; + 95972A0112C192DA00BF73D3 /* jdmainct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71A0A485CD80014E966 /* jdmainct.c */; }; + 95972A0212C192DA00BF73D3 /* jdmarker.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71B0A485CD80014E966 /* jdmarker.c */; }; + 95972A0312C192DA00BF73D3 /* jdmaster.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71C0A485CD80014E966 /* jdmaster.c */; }; + 95972A0412C192DA00BF73D3 /* jdmerge.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71D0A485CD80014E966 /* jdmerge.c */; }; + 95972A0512C192DA00BF73D3 /* jdpostct.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E71F0A485CD80014E966 /* jdpostct.c */; }; + 95972A0612C192DA00BF73D3 /* jdsample.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7200A485CD80014E966 /* jdsample.c */; }; + 95972A0712C192DA00BF73D3 /* jdtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7210A485CD80014E966 /* jdtrans.c */; }; + 95972A0812C192DA00BF73D3 /* jerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7220A485CD80014E966 /* jerror.c */; }; + 95972A0912C192DA00BF73D3 /* jfdctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7240A485CD80014E966 /* jfdctflt.c */; }; + 95972A0A12C192DA00BF73D3 /* jfdctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7250A485CD80014E966 /* jfdctfst.c */; }; + 95972A0B12C192DA00BF73D3 /* jfdctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7260A485CD80014E966 /* jfdctint.c */; }; + 95972A0C12C192DA00BF73D3 /* jidctflt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7270A485CD80014E966 /* jidctflt.c */; }; + 95972A0D12C192DA00BF73D3 /* jidctfst.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7280A485CD80014E966 /* jidctfst.c */; }; + 95972A0E12C192DA00BF73D3 /* jidctint.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7290A485CD80014E966 /* jidctint.c */; }; + 95972A0F12C192DA00BF73D3 /* jmemmgr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7300A485CD80014E966 /* jmemmgr.c */; }; + 95972A1012C192DA00BF73D3 /* jmemnobs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7320A485CD80014E966 /* jmemnobs.c */; }; + 95972A1112C192DA00BF73D3 /* jquant1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E7390A485CD80014E966 /* jquant1.c */; }; + 95972A1212C192DA00BF73D3 /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E73A0A485CD80014E966 /* jquant2.c */; }; + 95972A1312C192DA00BF73D3 /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E73B0A485CD80014E966 /* jutils.c */; }; + 95972A2212C192DA00BF73D3 /* inffast.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1800A484C2C0014E966 /* inffast.c */; }; + 95972A2312C192DA00BF73D3 /* inftrees.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1850A484C2C0014E966 /* inftrees.c */; }; + 95972A2412C192DA00BF73D3 /* uncompr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E18D0A484C2C0014E966 /* uncompr.c */; }; + 95972A2512C192DA00BF73D3 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1750A484C2C0014E966 /* compress.c */; }; + 95972A2612C192DA00BF73D3 /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1770A484C2C0014E966 /* crc32.c */; }; + 95972A2712C192DA00BF73D3 /* zutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1920A484C2C0014E966 /* zutil.c */; }; + 95972A2812C192DA00BF73D3 /* trees.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E18B0A484C2C0014E966 /* trees.c */; }; + 95972A2912C192DA00BF73D3 /* deflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1790A484C2C0014E966 /* deflate.c */; }; + 95972A2A12C192DA00BF73D3 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1720A484C2C0014E966 /* adler32.c */; }; + 95972A2B12C192DA00BF73D3 /* CImageLoaderPNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */; }; + 95972A2C12C192DA00BF73D3 /* CColorConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */; }; + 95972A2D12C192DA00BF73D3 /* CSceneManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */; }; + 95972A2E12C192DA00BF73D3 /* CTRTextureGouraudAdd2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */; }; + 95972A2F12C192DA00BF73D3 /* CNullDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF820A484C240014E966 /* CNullDriver.cpp */; }; + 95972A3012C192DA00BF73D3 /* CCSMLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */; }; + 95972A3112C192DA00BF73D3 /* irrXML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E00E0A484C250014E966 /* irrXML.cpp */; }; + 95972A3212C192DA00BF73D3 /* CGUIListBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF420A484C230014E966 /* CGUIListBox.cpp */; }; + 95972A3312C192DA00BF73D3 /* CTRGouraudWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */; }; + 95972A3412C192DA00BF73D3 /* CIrrDeviceStub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */; }; + 95972A3512C192DA00BF73D3 /* CGUIMessageBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */; }; + 95972A3612C192DA00BF73D3 /* CMeshSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */; }; + 95972A3712C192DA00BF73D3 /* CGUIStaticText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */; }; + 95972A3812C192DA00BF73D3 /* os.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E16A0A484C2C0014E966 /* os.cpp */; }; + 95972A3912C192DA00BF73D3 /* COCTLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF840A484C240014E966 /* COCTLoader.cpp */; }; + 95972A3A12C192DA00BF73D3 /* CGUIContextMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */; }; + 95972A3B12C192DA00BF73D3 /* CSceneNodeAnimatorFlyCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */; }; + 95972A3C12C192DA00BF73D3 /* CDefaultSceneNodeFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */; }; + 95972A3D12C192DA00BF73D3 /* CD3D9Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */; }; + 95972A3E12C192DA00BF73D3 /* CTRGouraud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */; }; + 95972A3F12C192DA00BF73D3 /* C3DSMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */; }; + 95972A4012C192DA00BF73D3 /* COgreMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */; }; + 95972A4112C192DA00BF73D3 /* CMY3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */; }; + 95972A4212C192DA00BF73D3 /* CLMTSMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */; }; + 95972A4312C192DA00BF73D3 /* CGUIFileOpenDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */; }; + 95972A4412C192DA00BF73D3 /* CSceneNodeAnimatorDelete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */; }; + 95972A4512C192DA00BF73D3 /* CTRGouraudAlphaNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */; }; + 95972A4612C192DA00BF73D3 /* CGeometryCreator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */; }; + 95972A4712C192DA00BF73D3 /* CD3D8Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */; }; + 95972A4812C192DA00BF73D3 /* CSkyBoxSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */; }; + 95972A4912C192DA00BF73D3 /* CMeshManipulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */; }; + 95972A4A12C192DA00BF73D3 /* CTextSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */; }; + 95972A4B12C192DA00BF73D3 /* CTRTextureDetailMap2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */; }; + 95972A4C12C192DA00BF73D3 /* CTRTextureGouraudAddNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */; }; + 95972A4D12C192DA00BF73D3 /* CTRTextureGouraudNoZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */; }; + 95972A4E12C192DA00BF73D3 /* CGUIScrollBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */; }; + 95972A4F12C192DA00BF73D3 /* CSceneCollisionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */; }; + 95972A5012C192DA00BF73D3 /* CGUICheckBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */; }; + 95972A5112C192DA00BF73D3 /* CQ3LevelMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */; }; + 95972A5212C192DA00BF73D3 /* CParticleGravityAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */; }; + 95972A5312C192DA00BF73D3 /* CSoftwareDriver2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */; }; + 95972A5412C192DA00BF73D3 /* CD3D9ParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */; }; + 95972A5512C192DA00BF73D3 /* CD3D8ParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */; }; + 95972A5612C192DA00BF73D3 /* CAnimatedMeshMD2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */; }; + 95972A5712C192DA00BF73D3 /* CSceneNodeAnimatorFlyStraight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */; }; + 95972A5812C192DA00BF73D3 /* CImageLoaderPCX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */; }; + 95972A5912C192DA00BF73D3 /* CAnimatedMeshSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */; }; + 95972A5A12C192DA00BF73D3 /* CTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */; }; + 95972A5B12C192DA00BF73D3 /* CTRTextureGouraudVertexAlpha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */; }; + 95972A5C12C192DA00BF73D3 /* CTRTextureWire2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */; }; + 95972A5D12C192DA00BF73D3 /* CTRTextureFlatWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */; }; + 95972A5E12C192DA00BF73D3 /* CTRGouraud2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */; }; + 95972A5F12C192DA00BF73D3 /* CEmptySceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */; }; + 95972A6012C192DA00BF73D3 /* CTRTextureLightMap2_Add.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */; }; + 95972A6112C192DA00BF73D3 /* CReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA70A484C240014E966 /* CReadFile.cpp */; }; + 95972A6212C192DA00BF73D3 /* COpenGLTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */; }; + 95972A6312C192DA00BF73D3 /* COSOperator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF990A484C240014E966 /* COSOperator.cpp */; }; + 95972A6412C192DA00BF73D3 /* CColladaFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */; }; + 95972A6512C192DA00BF73D3 /* CCameraSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */; }; + 95972A6612C192DA00BF73D3 /* CMetaTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */; }; + 95972A6712C192DA00BF73D3 /* CTRTextureFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */; }; + 95972A6812C192DA00BF73D3 /* CVideoModeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */; }; + 95972A6912C192DA00BF73D3 /* CXMLReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */; }; + 95972A6A12C192DA00BF73D3 /* COpenGLParallaxMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */; }; + 95972A6B12C192DA00BF73D3 /* CTRTextureGouraudNoZ2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */; }; + 95972A6C12C192DA00BF73D3 /* CTRTextureGouraudWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */; }; + 95972A6D12C192DA00BF73D3 /* CParticlePointEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */; }; + 95972A6E12C192DA00BF73D3 /* CGUIWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF560A484C230014E966 /* CGUIWindow.cpp */; }; + 95972A6F12C192DA00BF73D3 /* CGUIModalScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */; }; + 95972A7012C192DA00BF73D3 /* CImageLoaderPSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */; }; + 95972A7112C192DA00BF73D3 /* CWaterSurfaceSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */; }; + 95972A7212C192DA00BF73D3 /* CXMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */; }; + 95972A7312C192DA00BF73D3 /* CIrrDeviceLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */; }; + 95972A7412C192DA00BF73D3 /* CLightSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */; }; + 95972A7512C192DA00BF73D3 /* CTRTextureGouraudAdd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */; }; + 95972A7612C192DA00BF73D3 /* CTRTextureGouraud2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */; }; + 95972A7712C192DA00BF73D3 /* CSoftwareDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */; }; + 95972A7812C192DA00BF73D3 /* CTRFlatWire.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */; }; + 95972A7912C192DA00BF73D3 /* CTRGouraudAlpha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */; }; + 95972A7A12C192DA00BF73D3 /* CSoftwareTexture2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */; }; + 95972A7B12C192DA00BF73D3 /* CZipReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E0030A484C250014E966 /* CZipReader.cpp */; }; + 95972A7C12C192DA00BF73D3 /* COpenGLNormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */; }; + 95972A7D12C192DA00BF73D3 /* CTRTextureLightMap2_M1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */; }; + 95972A7E12C192DA00BF73D3 /* CTRTextureLightMap2_M4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */; }; + 95972A7F12C192DA00BF73D3 /* CGUISkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */; }; + 95972A8012C192DA00BF73D3 /* CD3D8Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */; }; + 95972A8112C192DA00BF73D3 /* CIrrDeviceWin32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */; }; + 95972A8212C192DA00BF73D3 /* CFileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF280A484C230014E966 /* CFileSystem.cpp */; }; + 95972A8312C192DA00BF73D3 /* CGUIMeshViewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */; }; + 95972A8412C192DA00BF73D3 /* CGUIComboBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */; }; + 95972A8512C192DA00BF73D3 /* CSceneNodeAnimatorRotation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */; }; + 95972A8612C192DA00BF73D3 /* CSceneNodeAnimatorTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */; }; + 95972A8712C192DA00BF73D3 /* CParticleSystemSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */; }; + 95972A8812C192DA00BF73D3 /* CTerrainSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */; }; + 95972A8912C192DA00BF73D3 /* CGUIFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */; }; + 95972A8A12C192DA00BF73D3 /* CParticleFadeOutAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */; }; + 95972A8B12C192DA00BF73D3 /* CDummyTransformationSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */; }; + 95972A8C12C192DA00BF73D3 /* CFileList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF260A484C230014E966 /* CFileList.cpp */; }; + 95972A8D12C192DA00BF73D3 /* CImageLoaderTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */; }; + 95972A8E12C192DA00BF73D3 /* CXMLWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */; }; + 95972A8F12C192DA00BF73D3 /* CSceneNodeAnimatorFollowSpline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */; }; + 95972A9012C192DA00BF73D3 /* CZBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */; }; + 95972A9112C192DA00BF73D3 /* CDMFLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF200A484C230014E966 /* CDMFLoader.cpp */; }; + 95972A9212C192DA00BF73D3 /* CD3D9Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */; }; + 95972A9312C192DA00BF73D3 /* COpenGLShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */; }; + 95972A9412C192DA00BF73D3 /* Irrlicht.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E00A0A484C250014E966 /* Irrlicht.cpp */; }; + 95972A9512C192DA00BF73D3 /* CGUIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */; }; + 95972A9612C192DA00BF73D3 /* COpenGLSLMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */; }; + 95972A9712C192DA00BF73D3 /* CD3D9HLSLMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */; }; + 95972A9812C192DA00BF73D3 /* CSoftwareTexture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */; }; + 95972A9912C192DA00BF73D3 /* CCubeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */; }; + 95972A9A12C192DA00BF73D3 /* CTriangleBBSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */; }; + 95972A9B12C192DA00BF73D3 /* CD3D9ShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */; }; + 95972A9C12C192DA00BF73D3 /* CD3D8ShaderMaterialRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */; }; + 95972A9D12C192DA00BF73D3 /* CGUIButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */; }; + 95972A9E12C192DA00BF73D3 /* CGUIToolBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */; }; + 95972A9F12C192DA00BF73D3 /* CDefaultSceneNodeAnimatorFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */; }; + 95972AA012C192DA00BF73D3 /* CBillboardSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */; }; + 95972AA112C192DA00BF73D3 /* CSceneNodeAnimatorCollisionResponse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */; }; + 95972AA212C192DA00BF73D3 /* CLogger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF720A484C230014E966 /* CLogger.cpp */; }; + 95972AA312C192DA00BF73D3 /* CGUIInOutFader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */; }; + 95972AA412C192DA00BF73D3 /* CWriteFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFF20A484C250014E966 /* CWriteFile.cpp */; }; + 95972AA512C192DA00BF73D3 /* CTRTextureGouraud.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */; }; + 95972AA612C192DA00BF73D3 /* CTRFlat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFD10A484C240014E966 /* CTRFlat.cpp */; }; + 95972AA712C192DA00BF73D3 /* CTerrainTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */; }; + 95972AA812C192DA00BF73D3 /* CGUITabControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF520A484C230014E966 /* CGUITabControl.cpp */; }; + 95972AA912C192DA00BF73D3 /* CParticleBoxEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */; }; + 95972AAA12C192DA00BF73D3 /* CGUIMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF440A484C230014E966 /* CGUIMenu.cpp */; }; + 95972AAB12C192DA00BF73D3 /* CImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF580A484C230014E966 /* CImage.cpp */; }; + 95972AAC12C192DA00BF73D3 /* CShadowVolumeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */; }; + 95972AAD12C192DA00BF73D3 /* CGUIEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */; }; + 95972AAE12C192DA00BF73D3 /* CLimitReadFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */; }; + 95972AAF12C192DA00BF73D3 /* CAttributes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DEF00A484C220014E966 /* CAttributes.cpp */; }; + 95972AB012C192DA00BF73D3 /* COpenGLDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */; }; + 95972AB112C192DA00BF73D3 /* CTRTextureLightMap2_M2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */; }; + 95972AB212C192DA00BF73D3 /* CGUIImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */; }; + 95972AB312C192DA00BF73D3 /* CD3D9NormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */; }; + 95972AB412C192DA00BF73D3 /* CD3D8NormalMapRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */; }; + 95972AB512C192DA00BF73D3 /* CMeshCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF760A484C230014E966 /* CMeshCache.cpp */; }; + 95972AB612C192DA00BF73D3 /* CImageLoaderJPG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */; }; + 95972AB712C192DA00BF73D3 /* CFPSCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */; }; + 95972AB812C192DA00BF73D3 /* OSXClipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */; }; + 95972AB912C192DA00BF73D3 /* CIrrDeviceMacOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */; }; + 95972ABA12C192DA00BF73D3 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */; }; + 95972ABB12C192DA00BF73D3 /* inflate.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6DC9B60A48715A0017A6E5 /* inflate.c */; }; + 95972ABC12C192DA00BF73D3 /* CSphereSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */; }; + 95972ABD12C192DA00BF73D3 /* COBJMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */; }; + 95972ABE12C192DA00BF73D3 /* CPakReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */; }; + 95972ABF12C192DA00BF73D3 /* CImageLoaderBMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */; }; + 95972AC012C192DA00BF73D3 /* CImageWriterBMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */; }; + 95972AC112C192DA00BF73D3 /* CImageWriterJPG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */; }; + 95972AC212C192DA00BF73D3 /* CImageWriterPCX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */; }; + 95972AC312C192DA00BF73D3 /* CImageWriterPNG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */; }; + 95972AC412C192DA00BF73D3 /* CImageWriterPPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */; }; + 95972AC512C192DA00BF73D3 /* CImageWriterPSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */; }; + 95972AC612C192DA00BF73D3 /* CImageWriterTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */; }; + 95972AC712C192DA00BF73D3 /* CSkyDomeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */; }; + 95972AC812C192DA00BF73D3 /* CDepthBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */; }; + 95972AC912C192DA00BF73D3 /* IBurningShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480500C7D936700728AA9 /* IBurningShader.cpp */; }; + 95972ACA12C192DA00BF73D3 /* CAnimatedMeshMD3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */; }; + 95972ACB12C192DA00BF73D3 /* CDefaultGUIElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */; }; + 95972ACC12C192DA00BF73D3 /* CGUIColorSelectDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */; }; + 95972ACD12C192DA00BF73D3 /* CGUISpinBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */; }; + 95972ACE12C192DA00BF73D3 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */; }; + 95972ACF12C192DA00BF73D3 /* CQuake3ShaderSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */; }; + 95972AD012C192DA00BF73D3 /* CTRTextureBlend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */; }; + 95972AD112C192DA00BF73D3 /* CTRTextureGouraudAlpha.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */; }; + 95972AD212C192DA00BF73D3 /* CTRTextureGouraudAlphaNoZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */; }; + 95972AD312C192DA00BF73D3 /* CTRTextureLightMapGouraud2_M4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */; }; + 95972AD412C192DA00BF73D3 /* CIrrDeviceSDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */; }; + 95972AD512C192DA00BF73D3 /* COpenGLExtensionHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */; }; + 95972AD612C192DA00BF73D3 /* CMD3MeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */; }; + 95972AD712C192DA00BF73D3 /* CB3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968401E0D0F1A2300333EFD /* CB3DMeshFileLoader.cpp */; }; + 95972AD812C192DA00BF73D3 /* CBoneSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840200D0F1A2300333EFD /* CBoneSceneNode.cpp */; }; + 95972AD912C192DA00BF73D3 /* CBSPMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840220D0F1A2300333EFD /* CBSPMeshFileLoader.cpp */; }; + 95972ADA12C192DA00BF73D3 /* CColladaMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840250D0F1A2300333EFD /* CColladaMeshWriter.cpp */; }; + 95972ADB12C192DA00BF73D3 /* CImageLoaderPPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840270D0F1A2300333EFD /* CImageLoaderPPM.cpp */; }; + 95972ADC12C192DA00BF73D3 /* CIrrMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968402B0D0F1A2300333EFD /* CIrrMeshFileLoader.cpp */; }; + 95972ADD12C192DA00BF73D3 /* CIrrMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968402D0D0F1A2300333EFD /* CIrrMeshWriter.cpp */; }; + 95972ADE12C192DA00BF73D3 /* CMD2MeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968402F0D0F1A2300333EFD /* CMD2MeshFileLoader.cpp */; }; + 95972ADF12C192DA00BF73D3 /* CMS3DMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840310D0F1A2300333EFD /* CMS3DMeshFileLoader.cpp */; }; + 95972AE012C192DA00BF73D3 /* CParticleAnimatedMeshSceneNodeEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840330D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.cpp */; }; + 95972AE112C192DA00BF73D3 /* CParticleAttractionAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840350D0F1A2300333EFD /* CParticleAttractionAffector.cpp */; }; + 95972AE212C192DA00BF73D3 /* CParticleCylinderEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840370D0F1A2300333EFD /* CParticleCylinderEmitter.cpp */; }; + 95972AE312C192DA00BF73D3 /* CParticleMeshEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840390D0F1A2300333EFD /* CParticleMeshEmitter.cpp */; }; + 95972AE412C192DA00BF73D3 /* CParticleRingEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968403B0D0F1A2300333EFD /* CParticleRingEmitter.cpp */; }; + 95972AE512C192DA00BF73D3 /* CParticleRotationAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968403D0D0F1A2300333EFD /* CParticleRotationAffector.cpp */; }; + 95972AE612C192DA00BF73D3 /* CParticleSphereEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0968403F0D0F1A2300333EFD /* CParticleSphereEmitter.cpp */; }; + 95972AE712C192DA00BF73D3 /* CSkinnedMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840410D0F1A2300333EFD /* CSkinnedMesh.cpp */; }; + 95972AE812C192DA00BF73D3 /* CSTLMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840430D0F1A2300333EFD /* CSTLMeshFileLoader.cpp */; }; + 95972AE912C192DA00BF73D3 /* CSTLMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096840450D0F1A2300333EFD /* CSTLMeshWriter.cpp */; }; + 95972AEA12C192DA00BF73D3 /* CBurningShader_Raster_Reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9D90D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp */; }; + 95972AEB12C192DA00BF73D3 /* CGUITable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9DA0D1F5D4100D46B04 /* CGUITable.cpp */; }; + 95972AEC12C192DA00BF73D3 /* CImageLoaderWAL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0910B9DC0D1F5D4100D46B04 /* CImageLoaderWAL.cpp */; }; + 95972AED12C192DA00BF73D3 /* CVolumeLightSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */; }; + 95972AEE12C192DA00BF73D3 /* CLWOMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 09C638700D4F1A69000B6A18 /* CLWOMeshFileLoader.cpp */; }; + 95972AEF12C192DA00BF73D3 /* CSceneNodeAnimatorCameraFPS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 093973BC0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.cpp */; }; + 95972AF012C192DA00BF73D3 /* CSceneNodeAnimatorCameraMaya.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 093973BE0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.cpp */; }; + 95972AF112C192DA00BF73D3 /* COBJMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096F8E3B0EA2EFBA00907EC5 /* COBJMeshWriter.cpp */; }; + 95972AF212C192DA00BF73D3 /* CParticleScaleAffector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 096CC0DE0ECE65B500C81DC7 /* CParticleScaleAffector.cpp */; }; + 95972AF312C192DA00BF73D3 /* png.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C2C0ED32029003B8C9C /* png.c */; }; + 95972AF412C192DA00BF73D3 /* pngerror.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C2D0ED32029003B8C9C /* pngerror.c */; }; + 95972AF612C192DA00BF73D3 /* pngget.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C2F0ED32029003B8C9C /* pngget.c */; }; + 95972AF712C192DA00BF73D3 /* pngmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C300ED32029003B8C9C /* pngmem.c */; }; + 95972AF812C192DA00BF73D3 /* pngpread.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C310ED32029003B8C9C /* pngpread.c */; }; + 95972AF912C192DA00BF73D3 /* pngread.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C320ED32029003B8C9C /* pngread.c */; }; + 95972AFA12C192DA00BF73D3 /* pngrio.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C330ED32029003B8C9C /* pngrio.c */; }; + 95972AFB12C192DA00BF73D3 /* pngrtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C340ED32029003B8C9C /* pngrtran.c */; }; + 95972AFC12C192DA00BF73D3 /* pngrutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C350ED32029003B8C9C /* pngrutil.c */; }; + 95972AFD12C192DA00BF73D3 /* pngset.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C360ED32029003B8C9C /* pngset.c */; }; + 95972AFE12C192DA00BF73D3 /* pngtrans.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C380ED32029003B8C9C /* pngtrans.c */; }; + 95972AFF12C192DA00BF73D3 /* pngwio.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3A0ED32029003B8C9C /* pngwio.c */; }; + 95972B0012C192DA00BF73D3 /* pngwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3B0ED32029003B8C9C /* pngwrite.c */; }; + 95972B0112C192DA00BF73D3 /* pngwtran.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3C0ED32029003B8C9C /* pngwtran.c */; }; + 95972B0212C192DA00BF73D3 /* pngwutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 09293C3D0ED32029003B8C9C /* pngwutil.c */; }; + 95972B0312C192DA00BF73D3 /* CGUIImageList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3484C4E00F48D1B000C81F60 /* CGUIImageList.cpp */; }; + 95972B0412C192DA00BF73D3 /* CGUITreeView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3484C4ED0F48D3A100C81F60 /* CGUITreeView.cpp */; }; + 95972B0512C192DA00BF73D3 /* CMemoryFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3484C4FC0F48D4CB00C81F60 /* CMemoryFile.cpp */; }; + 95972B0612C192DA00BF73D3 /* CIrrDeviceConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EC243B0F59272E0037BC3A /* CIrrDeviceConsole.cpp */; }; + 95972B0712C192DA00BF73D3 /* CImageLoaderRGB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EF91D10F65FCA6000B5651 /* CImageLoaderRGB.cpp */; }; + 95972B0812C192DA00BF73D3 /* CPLYMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EF91D60F65FCF6000B5651 /* CPLYMeshFileLoader.cpp */; }; + 95972B0912C192DA00BF73D3 /* CPLYMeshWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34EF91DB0F65FD14000B5651 /* CPLYMeshWriter.cpp */; }; + 95972B0A12C192DA00BF73D3 /* CTarReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3430E4D51022C391006271FD /* CTarReader.cpp */; }; + 95972B0B12C192DA00BF73D3 /* CMountPointReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 344FD4A41039E98C0045FD3F /* CMountPointReader.cpp */; }; + 95972B0C12C192DA00BF73D3 /* jaricom.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C431103B1B5002DE8D7 /* jaricom.c */; }; + 95972B0D12C192DA00BF73D3 /* jcarith.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C441103B1B5002DE8D7 /* jcarith.c */; }; + 95972B0E12C192DA00BF73D3 /* jdarith.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C451103B1B5002DE8D7 /* jdarith.c */; }; + 95972B0F12C192DA00BF73D3 /* COctreeSceneNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C4B1103B247002DE8D7 /* COctreeSceneNode.cpp */; }; + 95972B1012C192DA00BF73D3 /* COctreeTriangleSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C4F1103B261002DE8D7 /* COctreeTriangleSelector.cpp */; }; + 95972B1112C192DA00BF73D3 /* CNPKReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C531103B27D002DE8D7 /* CNPKReader.cpp */; }; + 95972B1212C192DA00BF73D3 /* CIrrDeviceFB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C571103B2AE002DE8D7 /* CIrrDeviceFB.cpp */; }; + 95972B1312C192DA00BF73D3 /* CIrrDeviceWinCE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C591103B2AE002DE8D7 /* CIrrDeviceWinCE.cpp */; }; + 95972B1412C192DA00BF73D3 /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C631103B384002DE8D7 /* LzmaDec.c */; }; + 95972B1512C192DA00BF73D3 /* blocksort.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C661103B3B9002DE8D7 /* blocksort.c */; }; + 95972B1612C192DA00BF73D3 /* bzcompress.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C671103B3B9002DE8D7 /* bzcompress.c */; }; + 95972B1712C192DA00BF73D3 /* crctable.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6A1103B3B9002DE8D7 /* crctable.c */; }; + 95972B1812C192DA00BF73D3 /* decompress.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6B1103B3B9002DE8D7 /* decompress.c */; }; + 95972B1912C192DA00BF73D3 /* huffman.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6C1103B3B9002DE8D7 /* huffman.c */; }; + 95972B1A12C192DA00BF73D3 /* randtable.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C6E1103B3B9002DE8D7 /* randtable.c */; }; + 95972B1B12C192DA00BF73D3 /* bzlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C7B1103B4E1002DE8D7 /* bzlib.c */; }; + 95972B1C12C192DA00BF73D3 /* aescrypt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C7E1103B53C002DE8D7 /* aescrypt.cpp */; }; + 95972B1D12C192DA00BF73D3 /* aeskey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C7F1103B53C002DE8D7 /* aeskey.cpp */; }; + 95972B1E12C192DA00BF73D3 /* aestab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C801103B53C002DE8D7 /* aestab.cpp */; }; + 95972B1F12C192DA00BF73D3 /* fileenc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C811103B53C002DE8D7 /* fileenc.cpp */; }; + 95972B2012C192DA00BF73D3 /* hmac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C821103B53C002DE8D7 /* hmac.cpp */; }; + 95972B2112C192DA00BF73D3 /* prng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C831103B53C002DE8D7 /* prng.cpp */; }; + 95972B2212C192DA00BF73D3 /* pwd2key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C841103B53C002DE8D7 /* pwd2key.cpp */; }; + 95972B2312C192DA00BF73D3 /* sha1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C851103B53C002DE8D7 /* sha1.cpp */; }; + 95972B2412C192DA00BF73D3 /* sha2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E2E3C861103B53C002DE8D7 /* sha2.cpp */; }; + 95972B8412C19A5C00BF73D3 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95972B8312C19A5C00BF73D3 /* OpenGL.framework */; }; + 95972B8A12C19A7600BF73D3 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95972B8912C19A7600BF73D3 /* IOKit.framework */; }; + 95972B8E12C19A7F00BF73D3 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95972B8D12C19A7F00BF73D3 /* Carbon.framework */; }; + 95E5857112FCE277004946C6 /* CWADReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5857012FCE277004946C6 /* CWADReader.cpp */; }; + 95E5857212FCE277004946C6 /* CWADReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5857012FCE277004946C6 /* CWADReader.cpp */; }; + 95E5857712FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5857512FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp */; }; + 95E5857812FCE2CB004946C6 /* CAnimatedMeshHalfLife.h in Headers */ = {isa = PBXBuildFile; fileRef = 95E5857612FCE2CB004946C6 /* CAnimatedMeshHalfLife.h */; }; + 95E5857912FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5857512FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp */; }; + 95E5857C12FCE2DE004946C6 /* CSceneLoaderIrr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5857B12FCE2DE004946C6 /* CSceneLoaderIrr.cpp */; }; + 95E5857D12FCE2DE004946C6 /* CSceneLoaderIrr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5857B12FCE2DE004946C6 /* CSceneLoaderIrr.cpp */; }; + 95E5858D12FCE388004946C6 /* CTRNormalMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5858C12FCE388004946C6 /* CTRNormalMap.cpp */; }; + 95E5858E12FCE388004946C6 /* CTRNormalMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5858C12FCE388004946C6 /* CTRNormalMap.cpp */; }; + 95E5859212FCE3A1004946C6 /* CTRStencilShadow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5859112FCE3A1004946C6 /* CTRStencilShadow.cpp */; }; + 95E5859312FCE3A1004946C6 /* CTRStencilShadow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5859112FCE3A1004946C6 /* CTRStencilShadow.cpp */; }; + 95E5859512FCE3F5004946C6 /* CSMFMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5859412FCE3F5004946C6 /* CSMFMeshFileLoader.cpp */; }; + 95E5859612FCE3F5004946C6 /* CSMFMeshFileLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95E5859412FCE3F5004946C6 /* CSMFMeshFileLoader.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 09022C540EA0E97F00CD54EE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 0946CCA50EC99BBE00D945A5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 0946CCD80EC99D8C00D945A5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09022C520EA0E97F00CD54EE; + remoteInfo = GUIEditor; + }; + 09F648F60D2CDED9001E0599 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 09F649200D2CDFF0001E0599 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09F648F40D2CDED9001E0599; + remoteInfo = HelloWorld; + }; + 09F649310D2CE03E001E0599 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 09F649580D2CE206001E0599 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 0E2E3CED1103E294002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 0E2E3D2E1103E3F4002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + 0E2E3D8B1103EB12002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0E2E3D2C1103E3F4002DE8D7; + remoteInfo = 20.ManagedLights; + }; + 0E2E3D8D1103EB1A002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0E2E3CEB1103E294002DE8D7; + remoteInfo = 18.SplitScreen; + }; + 0E2E3D8F1103EB32002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09F6492F0D2CE03E001E0599; + remoteInfo = 15.LoadIrrFile; + }; + 0E2E3D911103EB39002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 09F649560D2CE206001E0599; + remoteInfo = 16.Quake3Shader; + }; + 0E2E3D931103EB41002DE8D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0946CCA30EC99BBE00D945A5; + remoteInfo = 19.MouseAndJoystick; + }; + 4CA5CB810A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B8DEF35C0950229200FDEA7E; + remoteInfo = Demo; + }; + 4CA5CB830A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFFAF097FE5F80057C06F; + remoteInfo = RenderToTexture; + }; + 4CA5CB850A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFEC2097FDF020057C06F; + remoteInfo = TerrainRendering; + }; + 4CA5CB870A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFEA4097FDE900057C06F; + remoteInfo = PerPixelLightning; + }; + 4CA5CB890A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF4A097FE3050057C06F; + remoteInfo = Shaders; + }; + 4CA5CB8B0A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF91097FE45E0057C06F; + remoteInfo = MeshViewer; + }; + 4CA5CB8D0A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFEE8097FE05F0057C06F; + remoteInfo = SpecialFx; + }; + 4CA5CB8F0A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFE82097FDDE20057C06F; + remoteInfo = Collision; + }; + 4CA5CB910A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFDFE097FD9F50057C06F; + remoteInfo = 2DGraphics; + }; + 4CA5CB930A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF07097FE13E0057C06F; + remoteInfo = UserInterface; + }; + 4CA5CB950A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF78097FE3DC0057C06F; + remoteInfo = Movement; + }; + 4CA5CB970A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF1E097FE1E00057C06F; + remoteInfo = CustomSceneNode; + }; + 4CA5CB990A4868B500ADB3D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B81CFF33097FE25F0057C06F; + remoteInfo = Quake3Map; + }; + B81CFE00097FD9F50057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFE84097FDDE20057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFEA6097FDE900057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFEC4097FDF020057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFEEA097FE05F0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF09097FE13E0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF20097FE1E00057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF35097FE25F0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF4C097FE3050057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF7A097FE3DC0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFF93097FE45E0057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B81CFFB1097FE5F80057C06F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; + B8DEF374095024F600FDEA7E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = MacOSX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 09022C620EA0E97F00CD54EE /* GUIEditor_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GUIEditor_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 09022C680EA0EA9D00CD54EE /* CGUIAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIAttribute.h; path = ../../../tools/GUIEditor/CGUIAttribute.h; sourceTree = SOURCE_ROOT; }; + 09022C690EA0EA9D00CD54EE /* CGUIAttributeEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGUIAttributeEditor.cpp; path = ../../../tools/GUIEditor/CGUIAttributeEditor.cpp; sourceTree = SOURCE_ROOT; }; + 09022C6A0EA0EA9D00CD54EE /* CGUIAttributeEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIAttributeEditor.h; path = ../../../tools/GUIEditor/CGUIAttributeEditor.h; sourceTree = SOURCE_ROOT; }; + 09022C6B0EA0EA9D00CD54EE /* CGUIBoolAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIBoolAttribute.h; path = ../../../tools/GUIEditor/CGUIBoolAttribute.h; sourceTree = SOURCE_ROOT; }; + 09022C6C0EA0EA9D00CD54EE /* CGUIColorAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIColorAttribute.h; path = ../../../tools/GUIEditor/CGUIColorAttribute.h; sourceTree = SOURCE_ROOT; }; + 09022C6D0EA0EA9D00CD54EE /* CGUIDummyEditorStub.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIDummyEditorStub.h; path = ../../../tools/GUIEditor/CGUIDummyEditorStub.h; sourceTree = SOURCE_ROOT; }; + 09022C6E0EA0EA9D00CD54EE /* CGUIEditFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGUIEditFactory.cpp; path = ../../../tools/GUIEditor/CGUIEditFactory.cpp; sourceTree = SOURCE_ROOT; }; + 09022C6F0EA0EA9D00CD54EE /* CGUIEditFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIEditFactory.h; path = ../../../tools/GUIEditor/CGUIEditFactory.h; sourceTree = SOURCE_ROOT; }; + 09022C700EA0EA9D00CD54EE /* CGUIEditWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGUIEditWindow.cpp; path = ../../../tools/GUIEditor/CGUIEditWindow.cpp; sourceTree = SOURCE_ROOT; }; + 09022C710EA0EA9D00CD54EE /* CGUIEditWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIEditWindow.h; path = ../../../tools/GUIEditor/CGUIEditWindow.h; sourceTree = SOURCE_ROOT; }; + 09022C720EA0EA9D00CD54EE /* CGUIEditWorkspace.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGUIEditWorkspace.cpp; path = ../../../tools/GUIEditor/CGUIEditWorkspace.cpp; sourceTree = SOURCE_ROOT; }; + 09022C730EA0EA9D00CD54EE /* CGUIEditWorkspace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIEditWorkspace.h; path = ../../../tools/GUIEditor/CGUIEditWorkspace.h; sourceTree = SOURCE_ROOT; }; + 09022C740EA0EA9D00CD54EE /* CGUIEnumAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIEnumAttribute.h; path = ../../../tools/GUIEditor/CGUIEnumAttribute.h; sourceTree = SOURCE_ROOT; }; + 09022C750EA0EA9D00CD54EE /* CGUIPanel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGUIPanel.cpp; path = ../../../tools/GUIEditor/CGUIPanel.cpp; sourceTree = SOURCE_ROOT; }; + 09022C760EA0EA9D00CD54EE /* CGUIPanel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIPanel.h; path = ../../../tools/GUIEditor/CGUIPanel.h; sourceTree = SOURCE_ROOT; }; + 09022C770EA0EA9D00CD54EE /* CGUIStringAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUIStringAttribute.h; path = ../../../tools/GUIEditor/CGUIStringAttribute.h; sourceTree = SOURCE_ROOT; }; + 09022C780EA0EA9D00CD54EE /* CGUITextureAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUITextureAttribute.h; path = ../../../tools/GUIEditor/CGUITextureAttribute.h; sourceTree = SOURCE_ROOT; }; + 09022C790EA0EA9D00CD54EE /* CGUITextureCacheBrowser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGUITextureCacheBrowser.cpp; path = ../../../tools/GUIEditor/CGUITextureCacheBrowser.cpp; sourceTree = SOURCE_ROOT; }; + 09022C7A0EA0EA9D00CD54EE /* CGUITextureCacheBrowser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGUITextureCacheBrowser.h; path = ../../../tools/GUIEditor/CGUITextureCacheBrowser.h; sourceTree = SOURCE_ROOT; }; + 09022C7B0EA0EA9D00CD54EE /* CMemoryReadWriteFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CMemoryReadWriteFile.cpp; path = ../../../tools/GUIEditor/CMemoryReadWriteFile.cpp; sourceTree = SOURCE_ROOT; }; + 09022C7C0EA0EA9D00CD54EE /* CMemoryReadWriteFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMemoryReadWriteFile.h; path = ../../../tools/GUIEditor/CMemoryReadWriteFile.h; sourceTree = SOURCE_ROOT; }; + 09022C7D0EA0EA9D00CD54EE /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../../../tools/GUIEditor/main.cpp; sourceTree = SOURCE_ROOT; }; + 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CVolumeLightSceneNode.cpp; sourceTree = ""; }; + 090FBC810D31085E0076D847 /* CVolumeLightSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CVolumeLightSceneNode.h; sourceTree = ""; }; + 0910B9D90D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CBurningShader_Raster_Reference.cpp; sourceTree = ""; }; + 0910B9DA0D1F5D4100D46B04 /* CGUITable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUITable.cpp; sourceTree = ""; }; + 0910B9DB0D1F5D4100D46B04 /* CGUITable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUITable.h; sourceTree = ""; }; + 0910B9DC0D1F5D4100D46B04 /* CImageLoaderWAL.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderWAL.cpp; sourceTree = ""; }; + 0910B9DD0D1F5D4100D46B04 /* CImageLoaderWAL.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderWAL.h; sourceTree = ""; }; + 0910B9FD0D1F64B300D46B04 /* CMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshBuffer.h; sourceTree = ""; }; + 0910B9FE0D1F64B300D46B04 /* coreutil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = coreutil.h; sourceTree = ""; }; + 0910B9FF0D1F64B300D46B04 /* ECullingTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ECullingTypes.h; sourceTree = ""; }; + 0910BA000D1F64B300D46B04 /* EDebugSceneTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EDebugSceneTypes.h; sourceTree = ""; }; + 0910BA010D1F64B300D46B04 /* EDriverFeatures.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EDriverFeatures.h; sourceTree = ""; }; + 0910BA020D1F64B300D46B04 /* EGUIAlignment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EGUIAlignment.h; sourceTree = ""; }; + 0910BA030D1F64B300D46B04 /* EHardwareBufferFlags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EHardwareBufferFlags.h; sourceTree = ""; }; + 0910BA040D1F64B300D46B04 /* EMaterialFlags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EMaterialFlags.h; sourceTree = ""; }; + 0910BA050D1F64B300D46B04 /* EMaterialTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EMaterialTypes.h; sourceTree = ""; }; + 0910BA060D1F64B300D46B04 /* EMeshWriterEnums.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EMeshWriterEnums.h; sourceTree = ""; }; + 0910BA070D1F64B300D46B04 /* EMessageBoxFlags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EMessageBoxFlags.h; sourceTree = ""; }; + 0910BA080D1F64B300D46B04 /* ETerrainElements.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ETerrainElements.h; sourceTree = ""; }; + 0910BA090D1F64B300D46B04 /* IAnimatedMeshMD3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshMD3.h; sourceTree = ""; }; + 0910BA0A0D1F64B300D46B04 /* IBoneSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IBoneSceneNode.h; sourceTree = ""; }; + 0910BA0B0D1F64B300D46B04 /* IGUIColorSelectDialog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIColorSelectDialog.h; sourceTree = ""; }; + 0910BA0C0D1F64B300D46B04 /* IGUIElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIElementFactory.h; sourceTree = ""; }; + 0910BA0D0D1F64B300D46B04 /* IGUIFontBitmap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIFontBitmap.h; sourceTree = ""; }; + 0910BA0E0D1F64B300D46B04 /* IGUISpinBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUISpinBox.h; sourceTree = ""; }; + 0910BA0F0D1F64B300D46B04 /* IGUISpriteBank.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUISpriteBank.h; sourceTree = ""; }; + 0910BA100D1F64B300D46B04 /* IGUITable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUITable.h; sourceTree = ""; }; + 0910BA110D1F64B300D46B04 /* IMeshWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshWriter.h; sourceTree = ""; }; + 0910BA120D1F64B300D46B04 /* IParticleAnimatedMeshSceneNodeEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleAnimatedMeshSceneNodeEmitter.h; sourceTree = ""; }; + 0910BA130D1F64B300D46B04 /* IParticleAttractionAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleAttractionAffector.h; sourceTree = ""; }; + 0910BA140D1F64B300D46B04 /* IParticleBoxEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleBoxEmitter.h; sourceTree = ""; }; + 0910BA150D1F64B300D46B04 /* IParticleCylinderEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleCylinderEmitter.h; sourceTree = ""; }; + 0910BA160D1F64B300D46B04 /* IParticleFadeOutAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleFadeOutAffector.h; sourceTree = ""; }; + 0910BA170D1F64B300D46B04 /* IParticleGravityAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleGravityAffector.h; sourceTree = ""; }; + 0910BA180D1F64B300D46B04 /* IParticleMeshEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleMeshEmitter.h; sourceTree = ""; }; + 0910BA190D1F64B300D46B04 /* IParticleRingEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleRingEmitter.h; sourceTree = ""; }; + 0910BA1A0D1F64B300D46B04 /* IParticleRotationAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleRotationAffector.h; sourceTree = ""; }; + 0910BA1B0D1F64B300D46B04 /* IParticleSphereEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleSphereEmitter.h; sourceTree = ""; }; + 0910BA1C0D1F64B300D46B04 /* IQ3Shader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IQ3Shader.h; sourceTree = ""; }; + 0910BA1D0D1F64B300D46B04 /* IReferenceCounted.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IReferenceCounted.h; sourceTree = ""; }; + 0910BA1E0D1F64B300D46B04 /* irrMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrMap.h; sourceTree = ""; }; + 0910BA1F0D1F64B300D46B04 /* ISkinnedMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISkinnedMesh.h; sourceTree = ""; }; + 0910BA200D1F64B300D46B04 /* SMaterialLayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMaterialLayer.h; sourceTree = ""; }; + 0910BA210D1F64B300D46B04 /* SSharedMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SSharedMeshBuffer.h; sourceTree = ""; }; + 0910BA220D1F64B300D46B04 /* SSkinMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SSkinMeshBuffer.h; sourceTree = ""; }; + 0910BA230D1F64B300D46B04 /* SViewFrustum.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SViewFrustum.h; sourceTree = ""; }; + 0925113D0D744ADE006784D9 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 09293C2C0ED32029003B8C9C /* png.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = png.c; path = libpng/png.c; sourceTree = ""; }; + 09293C2D0ED32029003B8C9C /* pngerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngerror.c; path = libpng/pngerror.c; sourceTree = ""; }; + 09293C2F0ED32029003B8C9C /* pngget.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngget.c; path = libpng/pngget.c; sourceTree = ""; }; + 09293C300ED32029003B8C9C /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngmem.c; path = libpng/pngmem.c; sourceTree = ""; }; + 09293C310ED32029003B8C9C /* pngpread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngpread.c; path = libpng/pngpread.c; sourceTree = ""; }; + 09293C320ED32029003B8C9C /* pngread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngread.c; path = libpng/pngread.c; sourceTree = ""; }; + 09293C330ED32029003B8C9C /* pngrio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrio.c; path = libpng/pngrio.c; sourceTree = ""; }; + 09293C340ED32029003B8C9C /* pngrtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrtran.c; path = libpng/pngrtran.c; sourceTree = ""; }; + 09293C350ED32029003B8C9C /* pngrutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngrutil.c; path = libpng/pngrutil.c; sourceTree = ""; }; + 09293C360ED32029003B8C9C /* pngset.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngset.c; path = libpng/pngset.c; sourceTree = ""; }; + 09293C380ED32029003B8C9C /* pngtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngtrans.c; path = libpng/pngtrans.c; sourceTree = ""; }; + 09293C3A0ED32029003B8C9C /* pngwio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwio.c; path = libpng/pngwio.c; sourceTree = ""; }; + 09293C3B0ED32029003B8C9C /* pngwrite.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwrite.c; path = libpng/pngwrite.c; sourceTree = ""; }; + 09293C3C0ED32029003B8C9C /* pngwtran.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwtran.c; path = libpng/pngwtran.c; sourceTree = ""; }; + 09293C3D0ED32029003B8C9C /* pngwutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pngwutil.c; path = libpng/pngwutil.c; sourceTree = ""; }; + 0930CE550EC39F4500D63866 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + 093973BC0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorCameraFPS.cpp; sourceTree = ""; }; + 093973BD0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorCameraFPS.h; sourceTree = ""; }; + 093973BE0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorCameraMaya.cpp; sourceTree = ""; }; + 093973BF0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorCameraMaya.h; sourceTree = ""; }; + 0946CCB40EC99BBE00D945A5 /* MouseAndJoystick_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MouseAndJoystick_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0946CCCA0EC99C6E00D945A5 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = 19.MouseAndJoystick/main.cpp; sourceTree = ""; }; + 0968401E0D0F1A2300333EFD /* CB3DMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CB3DMeshFileLoader.cpp; sourceTree = ""; }; + 0968401F0D0F1A2300333EFD /* CB3DMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CB3DMeshFileLoader.h; sourceTree = ""; }; + 096840200D0F1A2300333EFD /* CBoneSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CBoneSceneNode.cpp; sourceTree = ""; }; + 096840210D0F1A2300333EFD /* CBoneSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CBoneSceneNode.h; sourceTree = ""; }; + 096840220D0F1A2300333EFD /* CBSPMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CBSPMeshFileLoader.cpp; sourceTree = ""; }; + 096840230D0F1A2300333EFD /* CBSPMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CBSPMeshFileLoader.h; sourceTree = ""; }; + 096840250D0F1A2300333EFD /* CColladaMeshWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CColladaMeshWriter.cpp; sourceTree = ""; }; + 096840260D0F1A2300333EFD /* CColladaMeshWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CColladaMeshWriter.h; sourceTree = ""; }; + 096840270D0F1A2300333EFD /* CImageLoaderPPM.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderPPM.cpp; sourceTree = ""; }; + 096840280D0F1A2300333EFD /* CImageLoaderPPM.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPPM.h; sourceTree = ""; }; + 0968402B0D0F1A2300333EFD /* CIrrMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrMeshFileLoader.cpp; sourceTree = ""; }; + 0968402C0D0F1A2300333EFD /* CIrrMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrMeshFileLoader.h; sourceTree = ""; }; + 0968402D0D0F1A2300333EFD /* CIrrMeshWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrMeshWriter.cpp; sourceTree = ""; }; + 0968402E0D0F1A2300333EFD /* CIrrMeshWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrMeshWriter.h; sourceTree = ""; }; + 0968402F0D0F1A2300333EFD /* CMD2MeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMD2MeshFileLoader.cpp; sourceTree = ""; }; + 096840300D0F1A2300333EFD /* CMD2MeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMD2MeshFileLoader.h; sourceTree = ""; }; + 096840310D0F1A2300333EFD /* CMS3DMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMS3DMeshFileLoader.cpp; sourceTree = ""; }; + 096840320D0F1A2300333EFD /* CMS3DMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMS3DMeshFileLoader.h; sourceTree = ""; }; + 096840330D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleAnimatedMeshSceneNodeEmitter.cpp; sourceTree = ""; }; + 096840340D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleAnimatedMeshSceneNodeEmitter.h; sourceTree = ""; }; + 096840350D0F1A2300333EFD /* CParticleAttractionAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleAttractionAffector.cpp; sourceTree = ""; }; + 096840360D0F1A2300333EFD /* CParticleAttractionAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleAttractionAffector.h; sourceTree = ""; }; + 096840370D0F1A2300333EFD /* CParticleCylinderEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleCylinderEmitter.cpp; sourceTree = ""; }; + 096840380D0F1A2300333EFD /* CParticleCylinderEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleCylinderEmitter.h; sourceTree = ""; }; + 096840390D0F1A2300333EFD /* CParticleMeshEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleMeshEmitter.cpp; sourceTree = ""; }; + 0968403A0D0F1A2300333EFD /* CParticleMeshEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleMeshEmitter.h; sourceTree = ""; }; + 0968403B0D0F1A2300333EFD /* CParticleRingEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleRingEmitter.cpp; sourceTree = ""; }; + 0968403C0D0F1A2300333EFD /* CParticleRingEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleRingEmitter.h; sourceTree = ""; }; + 0968403D0D0F1A2300333EFD /* CParticleRotationAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleRotationAffector.cpp; sourceTree = ""; }; + 0968403E0D0F1A2300333EFD /* CParticleRotationAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleRotationAffector.h; sourceTree = ""; }; + 0968403F0D0F1A2300333EFD /* CParticleSphereEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleSphereEmitter.cpp; sourceTree = ""; }; + 096840400D0F1A2300333EFD /* CParticleSphereEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleSphereEmitter.h; sourceTree = ""; }; + 096840410D0F1A2300333EFD /* CSkinnedMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSkinnedMesh.cpp; sourceTree = ""; }; + 096840420D0F1A2300333EFD /* CSkinnedMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSkinnedMesh.h; sourceTree = ""; }; + 096840430D0F1A2300333EFD /* CSTLMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSTLMeshFileLoader.cpp; sourceTree = ""; }; + 096840440D0F1A2300333EFD /* CSTLMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSTLMeshFileLoader.h; sourceTree = ""; }; + 096840450D0F1A2300333EFD /* CSTLMeshWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSTLMeshWriter.cpp; sourceTree = ""; }; + 096840460D0F1A2300333EFD /* CSTLMeshWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSTLMeshWriter.h; sourceTree = ""; }; + 096CC0DE0ECE65B500C81DC7 /* CParticleScaleAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleScaleAffector.cpp; sourceTree = ""; }; + 096CC0DF0ECE65B500C81DC7 /* CParticleScaleAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleScaleAffector.h; sourceTree = ""; }; + 096F8E3B0EA2EFBA00907EC5 /* COBJMeshWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COBJMeshWriter.cpp; sourceTree = ""; }; + 096F8E3C0EA2EFBA00907EC5 /* COBJMeshWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COBJMeshWriter.h; sourceTree = ""; }; + 09C638700D4F1A69000B6A18 /* CLWOMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLWOMeshFileLoader.cpp; sourceTree = ""; }; + 09C638710D4F1A69000B6A18 /* CLWOMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLWOMeshFileLoader.h; sourceTree = ""; }; + 09F649030D2CDED9001E0599 /* HelloWorld_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 09F6492E0D2CE038001E0599 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = 15.LoadIrrFile/main.cpp; sourceTree = ""; }; + 09F6493E0D2CE03E001E0599 /* LoadIrrFile_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LoadIrrFile_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 09F649650D2CE206001E0599 /* Quake3Shader_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Quake3Shader_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 09F649730D2CE2D0001E0599 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = 16.Quake3MapShader/main.cpp; sourceTree = ""; }; + 0E2E3C431103B1B5002DE8D7 /* jaricom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jaricom.c; sourceTree = ""; }; + 0E2E3C441103B1B5002DE8D7 /* jcarith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jcarith.c; sourceTree = ""; }; + 0E2E3C451103B1B5002DE8D7 /* jdarith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jdarith.c; sourceTree = ""; }; + 0E2E3C491103B224002DE8D7 /* Octree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Octree.h; sourceTree = ""; }; + 0E2E3C4B1103B247002DE8D7 /* COctreeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = COctreeSceneNode.cpp; sourceTree = ""; }; + 0E2E3C4C1103B247002DE8D7 /* COctreeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = COctreeSceneNode.h; sourceTree = ""; }; + 0E2E3C4F1103B261002DE8D7 /* COctreeTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = COctreeTriangleSelector.cpp; sourceTree = ""; }; + 0E2E3C501103B261002DE8D7 /* COctreeTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = COctreeTriangleSelector.h; sourceTree = ""; }; + 0E2E3C531103B27D002DE8D7 /* CNPKReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CNPKReader.cpp; sourceTree = ""; }; + 0E2E3C541103B27D002DE8D7 /* CNPKReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNPKReader.h; sourceTree = ""; }; + 0E2E3C571103B2AE002DE8D7 /* CIrrDeviceFB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceFB.cpp; sourceTree = ""; }; + 0E2E3C581103B2AE002DE8D7 /* CIrrDeviceFB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceFB.h; sourceTree = ""; }; + 0E2E3C591103B2AE002DE8D7 /* CIrrDeviceWinCE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceWinCE.cpp; sourceTree = ""; }; + 0E2E3C5A1103B2AE002DE8D7 /* CIrrDeviceWinCE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceWinCE.h; sourceTree = ""; }; + 0E2E3C631103B384002DE8D7 /* LzmaDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaDec.c; path = lzma/LzmaDec.c; sourceTree = ""; }; + 0E2E3C661103B3B9002DE8D7 /* blocksort.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blocksort.c; path = bzip2/blocksort.c; sourceTree = ""; }; + 0E2E3C671103B3B9002DE8D7 /* bzcompress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bzcompress.c; path = bzip2/bzcompress.c; sourceTree = ""; }; + 0E2E3C6A1103B3B9002DE8D7 /* crctable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crctable.c; path = bzip2/crctable.c; sourceTree = ""; }; + 0E2E3C6B1103B3B9002DE8D7 /* decompress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = decompress.c; path = bzip2/decompress.c; sourceTree = ""; }; + 0E2E3C6C1103B3B9002DE8D7 /* huffman.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = huffman.c; path = bzip2/huffman.c; sourceTree = ""; }; + 0E2E3C6E1103B3B9002DE8D7 /* randtable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = randtable.c; path = bzip2/randtable.c; sourceTree = ""; }; + 0E2E3C7B1103B4E1002DE8D7 /* bzlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bzlib.c; path = bzip2/bzlib.c; sourceTree = ""; }; + 0E2E3C7E1103B53C002DE8D7 /* aescrypt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = aescrypt.cpp; path = aesGladman/aescrypt.cpp; sourceTree = ""; }; + 0E2E3C7F1103B53C002DE8D7 /* aeskey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = aeskey.cpp; path = aesGladman/aeskey.cpp; sourceTree = ""; }; + 0E2E3C801103B53C002DE8D7 /* aestab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = aestab.cpp; path = aesGladman/aestab.cpp; sourceTree = ""; }; + 0E2E3C811103B53C002DE8D7 /* fileenc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fileenc.cpp; path = aesGladman/fileenc.cpp; sourceTree = ""; }; + 0E2E3C821103B53C002DE8D7 /* hmac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = hmac.cpp; path = aesGladman/hmac.cpp; sourceTree = ""; }; + 0E2E3C831103B53C002DE8D7 /* prng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = prng.cpp; path = aesGladman/prng.cpp; sourceTree = ""; }; + 0E2E3C841103B53C002DE8D7 /* pwd2key.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pwd2key.cpp; path = aesGladman/pwd2key.cpp; sourceTree = ""; }; + 0E2E3C851103B53C002DE8D7 /* sha1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sha1.cpp; path = aesGladman/sha1.cpp; sourceTree = ""; }; + 0E2E3C861103B53C002DE8D7 /* sha2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sha2.cpp; path = aesGladman/sha2.cpp; sourceTree = ""; }; + 0E2E3CFC1103E294002DE8D7 /* SplitScreen_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SplitScreen_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0E2E3D3C1103E3F4002DE8D7 /* ManagedLights_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ManagedLights_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0E2E3D681103E6C6002DE8D7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 0E2E3D791103E6E4002DE8D7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 0E2E3E1B1103F773002DE8D7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 0E2E3E1D1103F773002DE8D7 /* q3factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = q3factory.cpp; sourceTree = ""; }; + 0E2E3E1E1103F773002DE8D7 /* q3factory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = q3factory.h; sourceTree = ""; }; + 0E2E3E261103F773002DE8D7 /* sound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sound.cpp; sourceTree = ""; }; + 0E2E3E271103F773002DE8D7 /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = ""; }; + 0E2E3E291103F773002DE8D7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 0E2E3E321103F773002DE8D7 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 3430E4D41022C391006271FD /* CTarReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CTarReader.h; sourceTree = ""; }; + 3430E4D51022C391006271FD /* CTarReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTarReader.cpp; sourceTree = ""; }; + 344FD4A41039E98C0045FD3F /* CMountPointReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CMountPointReader.cpp; sourceTree = ""; }; + 344FD4A51039E98C0045FD3F /* CMountPointReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMountPointReader.h; sourceTree = ""; }; + 3484C4DF0F48D1B000C81F60 /* CGUIImageList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUIImageList.h; sourceTree = ""; }; + 3484C4E00F48D1B000C81F60 /* CGUIImageList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIImageList.cpp; sourceTree = ""; }; + 3484C4EC0F48D3A100C81F60 /* CGUITreeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUITreeView.h; sourceTree = ""; }; + 3484C4ED0F48D3A100C81F60 /* CGUITreeView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUITreeView.cpp; sourceTree = ""; }; + 3484C4FB0F48D4CB00C81F60 /* CMemoryFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMemoryFile.h; sourceTree = ""; }; + 3484C4FC0F48D4CB00C81F60 /* CMemoryFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CMemoryFile.cpp; sourceTree = ""; }; + 34EC243A0F59272E0037BC3A /* CIrrDeviceConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceConsole.h; sourceTree = ""; }; + 34EC243B0F59272E0037BC3A /* CIrrDeviceConsole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceConsole.cpp; sourceTree = ""; }; + 34EF91D00F65FCA6000B5651 /* CImageLoaderRGB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CImageLoaderRGB.h; sourceTree = ""; }; + 34EF91D10F65FCA6000B5651 /* CImageLoaderRGB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderRGB.cpp; sourceTree = ""; }; + 34EF91D50F65FCF6000B5651 /* CPLYMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPLYMeshFileLoader.h; sourceTree = ""; }; + 34EF91D60F65FCF6000B5651 /* CPLYMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CPLYMeshFileLoader.cpp; sourceTree = ""; }; + 34EF91DA0F65FD14000B5651 /* CPLYMeshWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPLYMeshWriter.h; sourceTree = ""; }; + 34EF91DB0F65FD14000B5651 /* CPLYMeshWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CPLYMeshWriter.cpp; sourceTree = ""; }; + 4C0054710A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054770A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C00547D0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054830A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = main.cpp; sourceTree = ""; }; + 4C0054890A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C00548F0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054950A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C00549B0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054A30A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054AA0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054B00A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054B60A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054BC0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C0054C50A48470500C844C2 /* CDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDemo.cpp; sourceTree = ""; }; + 4C0054C60A48470500C844C2 /* CDemo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDemo.h; sourceTree = ""; }; + 4C0054C70A48470500C844C2 /* CMainMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMainMenu.cpp; sourceTree = ""; }; + 4C0054C80A48470500C844C2 /* CMainMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMainMenu.h; sourceTree = ""; }; + 4C0054CA0A48470500C844C2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; + 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COBJMeshFileLoader.cpp; sourceTree = ""; }; + 4C364EA30A6C6DC2004CFBB4 /* COBJMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COBJMeshFileLoader.h; sourceTree = ""; }; + 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CPakReader.cpp; sourceTree = ""; }; + 4C43EEBF0A74A5C800F942FC /* CPakReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CPakReader.h; sourceTree = ""; }; + 4C53DEE60A484C220014E966 /* BuiltInFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = BuiltInFont.h; sourceTree = ""; }; + 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = C3DSMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DEE80A484C220014E966 /* C3DSMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = C3DSMeshFileLoader.h; sourceTree = ""; }; + 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CAnimatedMeshMD2.cpp; sourceTree = ""; }; + 4C53DEEA0A484C220014E966 /* CAnimatedMeshMD2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshMD2.h; sourceTree = ""; }; + 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAnimatedMeshSceneNode.cpp; sourceTree = ""; }; + 4C53DEEE0A484C220014E966 /* CAnimatedMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshSceneNode.h; sourceTree = ""; }; + 4C53DEEF0A484C220014E966 /* CAttributeImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAttributeImpl.h; sourceTree = ""; }; + 4C53DEF00A484C220014E966 /* CAttributes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAttributes.cpp; sourceTree = ""; }; + 4C53DEF10A484C220014E966 /* CAttributes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAttributes.h; sourceTree = ""; }; + 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CBillboardSceneNode.cpp; sourceTree = ""; }; + 4C53DEF30A484C220014E966 /* CBillboardSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CBillboardSceneNode.h; sourceTree = ""; }; + 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCameraSceneNode.cpp; sourceTree = ""; }; + 4C53DEF90A484C220014E966 /* CCameraSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCameraSceneNode.h; sourceTree = ""; }; + 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CColladaFileLoader.cpp; sourceTree = ""; }; + 4C53DEFB0A484C220014E966 /* CColladaFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CColladaFileLoader.h; sourceTree = ""; }; + 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CColorConverter.cpp; sourceTree = ""; }; + 4C53DEFD0A484C220014E966 /* CColorConverter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CColorConverter.h; sourceTree = ""; }; + 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCSMLoader.cpp; sourceTree = ""; }; + 4C53DEFF0A484C220014E966 /* CCSMLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCSMLoader.h; sourceTree = ""; }; + 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CCubeSceneNode.cpp; sourceTree = ""; }; + 4C53DF010A484C220014E966 /* CCubeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CCubeSceneNode.h; sourceTree = ""; }; + 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8Driver.cpp; sourceTree = ""; }; + 4C53DF030A484C220014E966 /* CD3D8Driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8Driver.h; sourceTree = ""; }; + 4C53DF040A484C220014E966 /* CD3D8MaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8MaterialRenderer.h; sourceTree = ""; }; + 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8NormalMapRenderer.cpp; sourceTree = ""; }; + 4C53DF060A484C220014E966 /* CD3D8NormalMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8NormalMapRenderer.h; sourceTree = ""; }; + 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8ParallaxMapRenderer.cpp; sourceTree = ""; }; + 4C53DF080A484C230014E966 /* CD3D8ParallaxMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8ParallaxMapRenderer.h; sourceTree = ""; }; + 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8ShaderMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF0A0A484C230014E966 /* CD3D8ShaderMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8ShaderMaterialRenderer.h; sourceTree = ""; }; + 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D8Texture.cpp; sourceTree = ""; }; + 4C53DF0C0A484C230014E966 /* CD3D8Texture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D8Texture.h; sourceTree = ""; }; + 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9Driver.cpp; sourceTree = ""; }; + 4C53DF0E0A484C230014E966 /* CD3D9Driver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9Driver.h; sourceTree = ""; }; + 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9HLSLMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF100A484C230014E966 /* CD3D9HLSLMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9HLSLMaterialRenderer.h; sourceTree = ""; }; + 4C53DF110A484C230014E966 /* CD3D9MaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9MaterialRenderer.h; sourceTree = ""; }; + 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9NormalMapRenderer.cpp; sourceTree = ""; }; + 4C53DF130A484C230014E966 /* CD3D9NormalMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9NormalMapRenderer.h; sourceTree = ""; }; + 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9ParallaxMapRenderer.cpp; sourceTree = ""; }; + 4C53DF150A484C230014E966 /* CD3D9ParallaxMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9ParallaxMapRenderer.h; sourceTree = ""; }; + 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9ShaderMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF170A484C230014E966 /* CD3D9ShaderMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9ShaderMaterialRenderer.h; sourceTree = ""; }; + 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CD3D9Texture.cpp; sourceTree = ""; }; + 4C53DF190A484C230014E966 /* CD3D9Texture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CD3D9Texture.h; sourceTree = ""; }; + 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultSceneNodeAnimatorFactory.cpp; sourceTree = ""; }; + 4C53DF1D0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDefaultSceneNodeAnimatorFactory.h; sourceTree = ""; }; + 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultSceneNodeFactory.cpp; sourceTree = ""; }; + 4C53DF1F0A484C230014E966 /* CDefaultSceneNodeFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDefaultSceneNodeFactory.h; sourceTree = ""; }; + 4C53DF200A484C230014E966 /* CDMFLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDMFLoader.cpp; sourceTree = ""; }; + 4C53DF210A484C230014E966 /* CDMFLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDMFLoader.h; sourceTree = ""; }; + 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CDummyTransformationSceneNode.cpp; sourceTree = ""; }; + 4C53DF230A484C230014E966 /* CDummyTransformationSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CDummyTransformationSceneNode.h; sourceTree = ""; }; + 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CEmptySceneNode.cpp; sourceTree = ""; }; + 4C53DF250A484C230014E966 /* CEmptySceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CEmptySceneNode.h; sourceTree = ""; }; + 4C53DF260A484C230014E966 /* CFileList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFileList.cpp; sourceTree = ""; }; + 4C53DF270A484C230014E966 /* CFileList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFileList.h; sourceTree = ""; }; + 4C53DF280A484C230014E966 /* CFileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFileSystem.cpp; sourceTree = ""; }; + 4C53DF290A484C230014E966 /* CFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFileSystem.h; sourceTree = ""; }; + 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CFPSCounter.cpp; sourceTree = ""; }; + 4C53DF2B0A484C230014E966 /* CFPSCounter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CFPSCounter.h; sourceTree = ""; }; + 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGeometryCreator.cpp; sourceTree = ""; }; + 4C53DF2D0A484C230014E966 /* CGeometryCreator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGeometryCreator.h; sourceTree = ""; }; + 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIButton.cpp; sourceTree = ""; }; + 4C53DF2F0A484C230014E966 /* CGUIButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIButton.h; sourceTree = ""; }; + 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUICheckBox.cpp; sourceTree = ""; }; + 4C53DF310A484C230014E966 /* CGUICheckBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUICheckBox.h; sourceTree = ""; }; + 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIComboBox.cpp; sourceTree = ""; }; + 4C53DF330A484C230014E966 /* CGUIComboBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIComboBox.h; sourceTree = ""; }; + 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIContextMenu.cpp; sourceTree = ""; }; + 4C53DF350A484C230014E966 /* CGUIContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIContextMenu.h; sourceTree = ""; }; + 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIEditBox.cpp; sourceTree = ""; }; + 4C53DF370A484C230014E966 /* CGUIEditBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIEditBox.h; sourceTree = ""; }; + 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CGUIEnvironment.cpp; sourceTree = ""; }; + 4C53DF390A484C230014E966 /* CGUIEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIEnvironment.h; sourceTree = ""; }; + 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIFileOpenDialog.cpp; sourceTree = ""; }; + 4C53DF3B0A484C230014E966 /* CGUIFileOpenDialog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIFileOpenDialog.h; sourceTree = ""; }; + 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CGUIFont.cpp; sourceTree = ""; }; + 4C53DF3D0A484C230014E966 /* CGUIFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIFont.h; sourceTree = ""; }; + 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIImage.cpp; sourceTree = ""; }; + 4C53DF3F0A484C230014E966 /* CGUIImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIImage.h; sourceTree = ""; }; + 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIInOutFader.cpp; sourceTree = ""; }; + 4C53DF410A484C230014E966 /* CGUIInOutFader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIInOutFader.h; sourceTree = ""; }; + 4C53DF420A484C230014E966 /* CGUIListBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIListBox.cpp; sourceTree = ""; }; + 4C53DF430A484C230014E966 /* CGUIListBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIListBox.h; sourceTree = ""; }; + 4C53DF440A484C230014E966 /* CGUIMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIMenu.cpp; sourceTree = ""; }; + 4C53DF450A484C230014E966 /* CGUIMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIMenu.h; sourceTree = ""; }; + 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIMeshViewer.cpp; sourceTree = ""; }; + 4C53DF470A484C230014E966 /* CGUIMeshViewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIMeshViewer.h; sourceTree = ""; }; + 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIMessageBox.cpp; sourceTree = ""; }; + 4C53DF490A484C230014E966 /* CGUIMessageBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIMessageBox.h; sourceTree = ""; }; + 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIModalScreen.cpp; sourceTree = ""; }; + 4C53DF4B0A484C230014E966 /* CGUIModalScreen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIModalScreen.h; sourceTree = ""; }; + 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIScrollBar.cpp; sourceTree = ""; }; + 4C53DF4D0A484C230014E966 /* CGUIScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIScrollBar.h; sourceTree = ""; }; + 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUISkin.cpp; sourceTree = ""; }; + 4C53DF4F0A484C230014E966 /* CGUISkin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUISkin.h; sourceTree = ""; }; + 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIStaticText.cpp; sourceTree = ""; }; + 4C53DF510A484C230014E966 /* CGUIStaticText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIStaticText.h; sourceTree = ""; }; + 4C53DF520A484C230014E966 /* CGUITabControl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUITabControl.cpp; sourceTree = ""; }; + 4C53DF530A484C230014E966 /* CGUITabControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUITabControl.h; sourceTree = ""; }; + 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIToolBar.cpp; sourceTree = ""; }; + 4C53DF550A484C230014E966 /* CGUIToolBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIToolBar.h; sourceTree = ""; }; + 4C53DF560A484C230014E966 /* CGUIWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIWindow.cpp; sourceTree = ""; }; + 4C53DF570A484C230014E966 /* CGUIWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CGUIWindow.h; sourceTree = ""; }; + 4C53DF580A484C230014E966 /* CImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImage.cpp; sourceTree = ""; }; + 4C53DF590A484C230014E966 /* CImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImage.h; sourceTree = ""; }; + 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderJPG.cpp; sourceTree = ""; }; + 4C53DF5D0A484C230014E966 /* CImageLoaderJPG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderJPG.h; sourceTree = ""; }; + 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderPCX.cpp; sourceTree = ""; }; + 4C53DF5F0A484C230014E966 /* CImageLoaderPCX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPCX.h; sourceTree = ""; }; + 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageLoaderPNG.cpp; sourceTree = ""; }; + 4C53DF610A484C230014E966 /* CImageLoaderPNG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPNG.h; sourceTree = ""; }; + 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderPSD.cpp; sourceTree = ""; }; + 4C53DF630A484C230014E966 /* CImageLoaderPSD.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderPSD.h; sourceTree = ""; }; + 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderTGA.cpp; sourceTree = ""; }; + 4C53DF650A484C230014E966 /* CImageLoaderTGA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderTGA.h; sourceTree = ""; }; + 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceLinux.cpp; sourceTree = ""; }; + 4C53DF670A484C230014E966 /* CIrrDeviceLinux.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceLinux.h; sourceTree = ""; }; + 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceStub.cpp; sourceTree = ""; }; + 4C53DF690A484C230014E966 /* CIrrDeviceStub.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceStub.h; sourceTree = ""; }; + 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceWin32.cpp; sourceTree = ""; }; + 4C53DF6B0A484C230014E966 /* CIrrDeviceWin32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceWin32.h; sourceTree = ""; }; + 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLightSceneNode.cpp; sourceTree = ""; }; + 4C53DF6D0A484C230014E966 /* CLightSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLightSceneNode.h; sourceTree = ""; }; + 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CLimitReadFile.cpp; sourceTree = ""; }; + 4C53DF6F0A484C230014E966 /* CLimitReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = CLimitReadFile.h; sourceTree = ""; }; + 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLMTSMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DF710A484C230014E966 /* CLMTSMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLMTSMeshFileLoader.h; sourceTree = ""; }; + 4C53DF720A484C230014E966 /* CLogger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CLogger.cpp; sourceTree = ""; }; + 4C53DF730A484C230014E966 /* CLogger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CLogger.h; sourceTree = ""; }; + 4C53DF760A484C230014E966 /* CMeshCache.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMeshCache.cpp; sourceTree = ""; }; + 4C53DF770A484C230014E966 /* CMeshCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshCache.h; sourceTree = ""; }; + 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMeshManipulator.cpp; sourceTree = ""; }; + 4C53DF790A484C230014E966 /* CMeshManipulator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshManipulator.h; sourceTree = ""; }; + 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMeshSceneNode.cpp; sourceTree = ""; }; + 4C53DF7B0A484C230014E966 /* CMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMeshSceneNode.h; sourceTree = ""; }; + 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMetaTriangleSelector.cpp; sourceTree = ""; }; + 4C53DF7D0A484C230014E966 /* CMetaTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMetaTriangleSelector.h; sourceTree = ""; }; + 4C53DF7E0A484C230014E966 /* CMY3DHelper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMY3DHelper.h; sourceTree = ""; }; + 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMY3DMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DF800A484C230014E966 /* CMY3DMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMY3DMeshFileLoader.h; sourceTree = ""; }; + 4C53DF820A484C240014E966 /* CNullDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CNullDriver.cpp; sourceTree = ""; }; + 4C53DF830A484C240014E966 /* CNullDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CNullDriver.h; sourceTree = ""; }; + 4C53DF840A484C240014E966 /* COCTLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COCTLoader.cpp; sourceTree = ""; }; + 4C53DF850A484C240014E966 /* COCTLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COCTLoader.h; sourceTree = ""; }; + 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = COgreMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DF8B0A484C240014E966 /* COgreMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = COgreMeshFileLoader.h; sourceTree = ""; }; + 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; lineEnding = 2; path = COpenGLDriver.cpp; sourceTree = ""; }; + 4C53DF8D0A484C240014E966 /* COpenGLDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = COpenGLDriver.h; sourceTree = ""; }; + 4C53DF8E0A484C240014E966 /* COpenGLMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLMaterialRenderer.h; sourceTree = ""; }; + 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLNormalMapRenderer.cpp; sourceTree = ""; }; + 4C53DF900A484C240014E966 /* COpenGLNormalMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLNormalMapRenderer.h; sourceTree = ""; }; + 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLParallaxMapRenderer.cpp; sourceTree = ""; }; + 4C53DF920A484C240014E966 /* COpenGLParallaxMapRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLParallaxMapRenderer.h; sourceTree = ""; }; + 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLShaderMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF940A484C240014E966 /* COpenGLShaderMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLShaderMaterialRenderer.h; sourceTree = ""; }; + 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = COpenGLSLMaterialRenderer.cpp; sourceTree = ""; }; + 4C53DF960A484C240014E966 /* COpenGLSLMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLSLMaterialRenderer.h; sourceTree = ""; }; + 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLTexture.cpp; sourceTree = ""; }; + 4C53DF980A484C240014E966 /* COpenGLTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COpenGLTexture.h; sourceTree = ""; }; + 4C53DF990A484C240014E966 /* COSOperator.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = COSOperator.cpp; sourceTree = ""; }; + 4C53DF9A0A484C240014E966 /* COSOperator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = COSOperator.h; sourceTree = ""; }; + 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleBoxEmitter.cpp; sourceTree = ""; }; + 4C53DF9C0A484C240014E966 /* CParticleBoxEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleBoxEmitter.h; sourceTree = ""; }; + 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleFadeOutAffector.cpp; sourceTree = ""; }; + 4C53DF9E0A484C240014E966 /* CParticleFadeOutAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleFadeOutAffector.h; sourceTree = ""; }; + 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleGravityAffector.cpp; sourceTree = ""; }; + 4C53DFA00A484C240014E966 /* CParticleGravityAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleGravityAffector.h; sourceTree = ""; }; + 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticlePointEmitter.cpp; sourceTree = ""; }; + 4C53DFA20A484C240014E966 /* CParticlePointEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticlePointEmitter.h; sourceTree = ""; }; + 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CParticleSystemSceneNode.cpp; sourceTree = ""; }; + 4C53DFA40A484C240014E966 /* CParticleSystemSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CParticleSystemSceneNode.h; sourceTree = ""; }; + 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CQ3LevelMesh.cpp; sourceTree = ""; }; + 4C53DFA60A484C240014E966 /* CQ3LevelMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CQ3LevelMesh.h; sourceTree = ""; }; + 4C53DFA70A484C240014E966 /* CReadFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CReadFile.cpp; sourceTree = ""; }; + 4C53DFA80A484C240014E966 /* CReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = CReadFile.h; sourceTree = ""; }; + 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneCollisionManager.cpp; sourceTree = ""; }; + 4C53DFAA0A484C240014E966 /* CSceneCollisionManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneCollisionManager.h; sourceTree = ""; }; + 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneManager.cpp; sourceTree = ""; }; + 4C53DFAC0A484C240014E966 /* CSceneManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneManager.h; sourceTree = ""; }; + 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorCollisionResponse.cpp; sourceTree = ""; }; + 4C53DFAE0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorCollisionResponse.h; sourceTree = ""; }; + 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorDelete.cpp; sourceTree = ""; }; + 4C53DFB00A484C240014E966 /* CSceneNodeAnimatorDelete.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorDelete.h; sourceTree = ""; }; + 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorFlyCircle.cpp; sourceTree = ""; }; + 4C53DFB20A484C240014E966 /* CSceneNodeAnimatorFlyCircle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorFlyCircle.h; sourceTree = ""; }; + 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorFlyStraight.cpp; sourceTree = ""; }; + 4C53DFB40A484C240014E966 /* CSceneNodeAnimatorFlyStraight.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorFlyStraight.h; sourceTree = ""; }; + 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorFollowSpline.cpp; sourceTree = ""; }; + 4C53DFB60A484C240014E966 /* CSceneNodeAnimatorFollowSpline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorFollowSpline.h; sourceTree = ""; }; + 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorRotation.cpp; sourceTree = ""; }; + 4C53DFB80A484C240014E966 /* CSceneNodeAnimatorRotation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorRotation.h; sourceTree = ""; }; + 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSceneNodeAnimatorTexture.cpp; sourceTree = ""; }; + 4C53DFBA0A484C240014E966 /* CSceneNodeAnimatorTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSceneNodeAnimatorTexture.h; sourceTree = ""; }; + 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CShadowVolumeSceneNode.cpp; sourceTree = ""; }; + 4C53DFBC0A484C240014E966 /* CShadowVolumeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CShadowVolumeSceneNode.h; sourceTree = ""; }; + 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSkyBoxSceneNode.cpp; sourceTree = ""; }; + 4C53DFBE0A484C240014E966 /* CSkyBoxSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSkyBoxSceneNode.h; sourceTree = ""; }; + 4C53DFBF0A484C240014E966 /* CSoftware2MaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftware2MaterialRenderer.h; sourceTree = ""; }; + 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareDriver.cpp; sourceTree = ""; }; + 4C53DFC10A484C240014E966 /* CSoftwareDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareDriver.h; sourceTree = ""; }; + 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareDriver2.cpp; sourceTree = ""; }; + 4C53DFC30A484C240014E966 /* CSoftwareDriver2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareDriver2.h; sourceTree = ""; }; + 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareTexture.cpp; sourceTree = ""; }; + 4C53DFC50A484C240014E966 /* CSoftwareTexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareTexture.h; sourceTree = ""; }; + 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSoftwareTexture2.cpp; sourceTree = ""; }; + 4C53DFC70A484C240014E966 /* CSoftwareTexture2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSoftwareTexture2.h; sourceTree = ""; }; + 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTerrainSceneNode.cpp; sourceTree = ""; }; + 4C53DFCB0A484C240014E966 /* CTerrainSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTerrainSceneNode.h; sourceTree = ""; }; + 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTerrainTriangleSelector.cpp; sourceTree = ""; }; + 4C53DFCD0A484C240014E966 /* CTerrainTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTerrainTriangleSelector.h; sourceTree = ""; }; + 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTextSceneNode.cpp; sourceTree = ""; }; + 4C53DFCF0A484C240014E966 /* CTextSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTextSceneNode.h; sourceTree = ""; }; + 4C53DFD00A484C240014E966 /* CTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTimer.h; sourceTree = ""; }; + 4C53DFD10A484C240014E966 /* CTRFlat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRFlat.cpp; sourceTree = ""; }; + 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRFlatWire.cpp; sourceTree = ""; }; + 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraud.cpp; sourceTree = ""; }; + 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraud2.cpp; sourceTree = ""; }; + 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraudAlpha2.cpp; sourceTree = ""; }; + 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraudAlphaNoZ2.cpp; sourceTree = ""; }; + 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRGouraudWire.cpp; sourceTree = ""; }; + 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTriangleBBSelector.cpp; sourceTree = ""; }; + 4C53DFD90A484C250014E966 /* CTriangleBBSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTriangleBBSelector.h; sourceTree = ""; }; + 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTriangleSelector.cpp; sourceTree = ""; }; + 4C53DFDB0A484C250014E966 /* CTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTriangleSelector.h; sourceTree = ""; }; + 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureDetailMap2.cpp; sourceTree = ""; }; + 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureFlat.cpp; sourceTree = ""; }; + 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureFlatWire.cpp; sourceTree = ""; }; + 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraud.cpp; sourceTree = ""; }; + 4C53DFE00A484C250014E966 /* CTRTextureGouraud.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTRTextureGouraud.h; sourceTree = ""; }; + 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraud2.cpp; sourceTree = ""; }; + 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAdd.cpp; sourceTree = ""; }; + 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAdd2.cpp; sourceTree = ""; }; + 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAddNoZ2.cpp; sourceTree = ""; }; + 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudNoZ.cpp; sourceTree = ""; }; + 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudNoZ2.cpp; sourceTree = ""; }; + 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudVertexAlpha2.cpp; sourceTree = ""; }; + 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudWire.cpp; sourceTree = ""; }; + 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_Add.cpp; sourceTree = ""; }; + 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_M1.cpp; sourceTree = ""; }; + 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_M2.cpp; sourceTree = ""; }; + 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMap2_M4.cpp; sourceTree = ""; }; + 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureWire2.cpp; sourceTree = ""; }; + 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CVideoModeList.cpp; sourceTree = ""; }; + 4C53DFEF0A484C250014E966 /* CVideoModeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CVideoModeList.h; sourceTree = ""; }; + 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CWaterSurfaceSceneNode.cpp; sourceTree = ""; }; + 4C53DFF10A484C250014E966 /* CWaterSurfaceSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CWaterSurfaceSceneNode.h; sourceTree = ""; }; + 4C53DFF20A484C250014E966 /* CWriteFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CWriteFile.cpp; sourceTree = ""; }; + 4C53DFF30A484C250014E966 /* CWriteFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CWriteFile.h; sourceTree = ""; }; + 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXMeshFileLoader.cpp; sourceTree = ""; }; + 4C53DFF90A484C250014E966 /* CXMeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMeshFileLoader.h; sourceTree = ""; }; + 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXMLReader.cpp; sourceTree = ""; }; + 4C53DFFB0A484C250014E966 /* CXMLReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMLReader.h; sourceTree = ""; }; + 4C53DFFC0A484C250014E966 /* CXMLReaderImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMLReaderImpl.h; sourceTree = ""; }; + 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CXMLWriter.cpp; sourceTree = ""; }; + 4C53DFFE0A484C250014E966 /* CXMLWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CXMLWriter.h; sourceTree = ""; }; + 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CZBuffer.cpp; sourceTree = ""; }; + 4C53E0000A484C250014E966 /* CZBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CZBuffer.h; sourceTree = ""; }; + 4C53E0030A484C250014E966 /* CZipReader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CZipReader.cpp; sourceTree = ""; }; + 4C53E0040A484C250014E966 /* CZipReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CZipReader.h; sourceTree = ""; }; + 4C53E0050A484C250014E966 /* dmfsupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dmfsupport.h; sourceTree = ""; }; + 4C53E0070A484C250014E966 /* glext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = glext.h; sourceTree = ""; }; + 4C53E0090A484C250014E966 /* IImagePresenter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImagePresenter.h; sourceTree = ""; }; + 4C53E00A0A484C250014E966 /* Irrlicht.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 30; path = Irrlicht.cpp; sourceTree = ""; }; + 4C53E00E0A484C250014E966 /* irrXML.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = irrXML.cpp; sourceTree = ""; }; + 4C53E00F0A484C250014E966 /* ITriangleRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITriangleRenderer.h; sourceTree = ""; }; + 4C53E0110A484C250014E966 /* IZBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IZBuffer.h; sourceTree = ""; }; + 4C53E14C0A484C2C0014E966 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = ""; }; + 4C53E15E0A484C2C0014E966 /* CIrrDeviceMacOSX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceMacOSX.h; sourceTree = ""; }; + 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = CIrrDeviceMacOSX.mm; sourceTree = ""; }; + 4C53E1640A484C2C0014E966 /* MacOSX_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MacOSX_Prefix.pch; sourceTree = ""; }; + 4C53E1650A484C2C0014E966 /* MainMenu.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = MainMenu.nib; sourceTree = ""; }; + 4C53E1660A484C2C0014E966 /* OSXClipboard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OSXClipboard.h; sourceTree = ""; }; + 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = OSXClipboard.mm; sourceTree = ""; }; + 4C53E16A0A484C2C0014E966 /* os.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = os.cpp; sourceTree = ""; }; + 4C53E16B0A484C2C0014E966 /* os.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = os.h; sourceTree = ""; }; + 4C53E16C0A484C2C0014E966 /* S2DVertex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = S2DVertex.h; sourceTree = ""; }; + 4C53E16D0A484C2C0014E966 /* S4DVertex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = S4DVertex.h; sourceTree = ""; }; + 4C53E16E0A484C2C0014E966 /* SoftwareDriver2_compile_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoftwareDriver2_compile_config.h; sourceTree = ""; }; + 4C53E16F0A484C2C0014E966 /* SoftwareDriver2_helper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SoftwareDriver2_helper.h; sourceTree = ""; }; + 4C53E1720A484C2C0014E966 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = adler32.c; sourceTree = ""; }; + 4C53E1750A484C2C0014E966 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = ""; }; + 4C53E1770A484C2C0014E966 /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = crc32.c; sourceTree = ""; }; + 4C53E1790A484C2C0014E966 /* deflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = deflate.c; sourceTree = ""; }; + 4C53E1800A484C2C0014E966 /* inffast.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inffast.c; sourceTree = ""; }; + 4C53E1850A484C2C0014E966 /* inftrees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inftrees.c; sourceTree = ""; }; + 4C53E18B0A484C2C0014E966 /* trees.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = trees.c; sourceTree = ""; }; + 4C53E18D0A484C2C0014E966 /* uncompr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = uncompr.c; sourceTree = ""; }; + 4C53E1920A484C2C0014E966 /* zutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = zutil.c; sourceTree = ""; }; + 4C53E24D0A4850120014E966 /* libIrrlicht.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIrrlicht.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Quake3Map_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C53E26D0A4850D60014E966 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 4C53E26E0A4850D60014E966 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 4C53E6F10A485CD80014E966 /* jcapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcapimin.c; sourceTree = ""; }; + 4C53E6F20A485CD80014E966 /* jcapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcapistd.c; sourceTree = ""; }; + 4C53E6F30A485CD80014E966 /* jccoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jccoefct.c; sourceTree = ""; }; + 4C53E6F40A485CD80014E966 /* jccolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jccolor.c; sourceTree = ""; }; + 4C53E6F50A485CD80014E966 /* jcdctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcdctmgr.c; sourceTree = ""; }; + 4C53E6F60A485CD80014E966 /* jchuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jchuff.c; sourceTree = ""; }; + 4C53E6F80A485CD80014E966 /* jcinit.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcinit.c; sourceTree = ""; }; + 4C53E6F90A485CD80014E966 /* jcmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmainct.c; sourceTree = ""; }; + 4C53E6FA0A485CD80014E966 /* jcmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmarker.c; sourceTree = ""; }; + 4C53E6FB0A485CD80014E966 /* jcmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcmaster.c; sourceTree = ""; }; + 4C53E6FC0A485CD80014E966 /* jcomapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcomapi.c; sourceTree = ""; }; + 4C53E70A0A485CD80014E966 /* jcparam.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcparam.c; sourceTree = ""; }; + 4C53E70C0A485CD80014E966 /* jcprepct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcprepct.c; sourceTree = ""; }; + 4C53E70D0A485CD80014E966 /* jcsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jcsample.c; sourceTree = ""; }; + 4C53E70E0A485CD80014E966 /* jctrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jctrans.c; sourceTree = ""; }; + 4C53E70F0A485CD80014E966 /* jdapimin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdapimin.c; sourceTree = ""; }; + 4C53E7100A485CD80014E966 /* jdapistd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdapistd.c; sourceTree = ""; }; + 4C53E7110A485CD80014E966 /* jdatadst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdatadst.c; sourceTree = ""; }; + 4C53E7120A485CD80014E966 /* jdatasrc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdatasrc.c; sourceTree = ""; }; + 4C53E7130A485CD80014E966 /* jdcoefct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdcoefct.c; sourceTree = ""; }; + 4C53E7140A485CD80014E966 /* jdcolor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdcolor.c; sourceTree = ""; }; + 4C53E7160A485CD80014E966 /* jddctmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jddctmgr.c; sourceTree = ""; }; + 4C53E7170A485CD80014E966 /* jdhuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdhuff.c; sourceTree = ""; }; + 4C53E7190A485CD80014E966 /* jdinput.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdinput.c; sourceTree = ""; }; + 4C53E71A0A485CD80014E966 /* jdmainct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmainct.c; sourceTree = ""; }; + 4C53E71B0A485CD80014E966 /* jdmarker.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmarker.c; sourceTree = ""; }; + 4C53E71C0A485CD80014E966 /* jdmaster.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmaster.c; sourceTree = ""; }; + 4C53E71D0A485CD80014E966 /* jdmerge.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdmerge.c; sourceTree = ""; }; + 4C53E71F0A485CD80014E966 /* jdpostct.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdpostct.c; sourceTree = ""; }; + 4C53E7200A485CD80014E966 /* jdsample.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdsample.c; sourceTree = ""; }; + 4C53E7210A485CD80014E966 /* jdtrans.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jdtrans.c; sourceTree = ""; }; + 4C53E7220A485CD80014E966 /* jerror.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jerror.c; sourceTree = ""; }; + 4C53E7240A485CD80014E966 /* jfdctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctflt.c; sourceTree = ""; }; + 4C53E7250A485CD80014E966 /* jfdctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctfst.c; sourceTree = ""; }; + 4C53E7260A485CD80014E966 /* jfdctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jfdctint.c; sourceTree = ""; }; + 4C53E7270A485CD80014E966 /* jidctflt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctflt.c; sourceTree = ""; }; + 4C53E7280A485CD80014E966 /* jidctfst.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctfst.c; sourceTree = ""; }; + 4C53E7290A485CD80014E966 /* jidctint.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jidctint.c; sourceTree = ""; }; + 4C53E7300A485CD80014E966 /* jmemmgr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemmgr.c; sourceTree = ""; }; + 4C53E7320A485CD80014E966 /* jmemnobs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jmemnobs.c; sourceTree = ""; }; + 4C53E7390A485CD80014E966 /* jquant1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jquant1.c; sourceTree = ""; }; + 4C53E73A0A485CD80014E966 /* jquant2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jquant2.c; sourceTree = ""; }; + 4C53E73B0A485CD80014E966 /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = jutils.c; sourceTree = ""; }; + 4C6DC9B60A48715A0017A6E5 /* inflate.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = inflate.c; sourceTree = ""; }; + 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomSceneNode_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshViewer_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RenderToTexture_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UserInterface_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerPixelLighting_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movement_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Shaders_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecialFx_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainRendering_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2DGraphics_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Collision_dbg.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSphereSceneNode.cpp; sourceTree = ""; }; + 4CC36B0E0A6B61DB0076C4B2 /* CSphereSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSphereSceneNode.h; sourceTree = ""; }; + 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 2; path = CImageLoaderBMP.cpp; sourceTree = ""; }; + 4CFA7BDD0A88735900B03626 /* CImageLoaderBMP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageLoaderBMP.h; sourceTree = ""; }; + 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterBMP.cpp; sourceTree = ""; }; + 4CFA7BDF0A88735900B03626 /* CImageWriterBMP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterBMP.h; sourceTree = ""; }; + 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterJPG.cpp; sourceTree = ""; }; + 4CFA7BE10A88735900B03626 /* CImageWriterJPG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterJPG.h; sourceTree = ""; }; + 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPCX.cpp; sourceTree = ""; }; + 4CFA7BE30A88735900B03626 /* CImageWriterPCX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPCX.h; sourceTree = ""; }; + 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPNG.cpp; sourceTree = ""; }; + 4CFA7BE50A88735900B03626 /* CImageWriterPNG.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPNG.h; sourceTree = ""; }; + 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPPM.cpp; sourceTree = ""; }; + 4CFA7BE70A88735900B03626 /* CImageWriterPPM.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPPM.h; sourceTree = ""; }; + 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterPSD.cpp; sourceTree = ""; }; + 4CFA7BE90A88735900B03626 /* CImageWriterPSD.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterPSD.h; sourceTree = ""; }; + 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CImageWriterTGA.cpp; sourceTree = ""; }; + 4CFA7BEB0A88735900B03626 /* CImageWriterTGA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CImageWriterTGA.h; sourceTree = ""; }; + 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CSkyDomeSceneNode.cpp; sourceTree = ""; }; + 4CFA7BED0A88735A00B03626 /* CSkyDomeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSkyDomeSceneNode.h; sourceTree = ""; }; + 4CFA7C0A0A88742800B03626 /* aabbox3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = aabbox3d.h; sourceTree = ""; }; + 4CFA7C0B0A88742800B03626 /* dimension2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dimension2d.h; sourceTree = ""; }; + 4CFA7C0C0A88742800B03626 /* EDriverTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EDriverTypes.h; sourceTree = ""; }; + 4CFA7C0D0A88742800B03626 /* EGUIElementTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EGUIElementTypes.h; sourceTree = ""; }; + 4CFA7C0E0A88742800B03626 /* ESceneNodeAnimatorTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ESceneNodeAnimatorTypes.h; sourceTree = ""; }; + 4CFA7C0F0A88742800B03626 /* ESceneNodeTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ESceneNodeTypes.h; sourceTree = ""; }; + 4CFA7C100A88742800B03626 /* heapsort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = heapsort.h; sourceTree = ""; }; + 4CFA7C110A88742900B03626 /* IAnimatedMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMesh.h; sourceTree = ""; }; + 4CFA7C130A88742900B03626 /* IAnimatedMeshMD2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshMD2.h; sourceTree = ""; }; + 4CFA7C150A88742900B03626 /* IAnimatedMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAnimatedMeshSceneNode.h; sourceTree = ""; }; + 4CFA7C170A88742900B03626 /* IAttributeExchangingObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAttributeExchangingObject.h; sourceTree = ""; }; + 4CFA7C180A88742900B03626 /* IAttributes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IAttributes.h; sourceTree = ""; }; + 4CFA7C190A88742900B03626 /* IBillboardSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IBillboardSceneNode.h; sourceTree = ""; }; + 4CFA7C1A0A88742900B03626 /* ICameraSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ICameraSceneNode.h; sourceTree = ""; }; + 4CFA7C1B0A88742900B03626 /* ICursorControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ICursorControl.h; sourceTree = ""; }; + 4CFA7C1C0A88742900B03626 /* IDummyTransformationSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IDummyTransformationSceneNode.h; sourceTree = ""; }; + 4CFA7C1D0A88742900B03626 /* IEventReceiver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IEventReceiver.h; sourceTree = ""; }; + 4CFA7C1E0A88742900B03626 /* IFileList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IFileList.h; sourceTree = ""; }; + 4CFA7C1F0A88742900B03626 /* IFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IFileSystem.h; sourceTree = ""; }; + 4CFA7C200A88742900B03626 /* IGPUProgrammingServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGPUProgrammingServices.h; sourceTree = ""; }; + 4CFA7C210A88742900B03626 /* IGUIButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIButton.h; sourceTree = ""; }; + 4CFA7C220A88742900B03626 /* IGUICheckBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUICheckBox.h; sourceTree = ""; }; + 4CFA7C230A88742900B03626 /* IGUIComboBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIComboBox.h; sourceTree = ""; }; + 4CFA7C240A88742900B03626 /* IGUIContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIContextMenu.h; sourceTree = ""; }; + 4CFA7C250A88742900B03626 /* IGUIEditBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIEditBox.h; sourceTree = ""; }; + 4CFA7C260A88742900B03626 /* IGUIElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIElement.h; sourceTree = ""; }; + 4CFA7C270A88742900B03626 /* IGUIEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIEnvironment.h; sourceTree = ""; }; + 4CFA7C280A88742900B03626 /* IGUIFileOpenDialog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIFileOpenDialog.h; sourceTree = ""; }; + 4CFA7C290A88742900B03626 /* IGUIFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIFont.h; sourceTree = ""; }; + 4CFA7C2A0A88742900B03626 /* IGUIImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIImage.h; sourceTree = ""; }; + 4CFA7C2B0A88742900B03626 /* IGUIInOutFader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIInOutFader.h; sourceTree = ""; }; + 4CFA7C2C0A88742900B03626 /* IGUIListBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIListBox.h; sourceTree = ""; }; + 4CFA7C2D0A88742900B03626 /* IGUIMeshViewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIMeshViewer.h; sourceTree = ""; }; + 4CFA7C2E0A88742900B03626 /* IGUIScrollBar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIScrollBar.h; sourceTree = ""; }; + 4CFA7C2F0A88742900B03626 /* IGUISkin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUISkin.h; sourceTree = ""; }; + 4CFA7C300A88742900B03626 /* IGUIStaticText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIStaticText.h; sourceTree = ""; }; + 4CFA7C310A88742900B03626 /* IGUITabControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUITabControl.h; sourceTree = ""; }; + 4CFA7C320A88742900B03626 /* IGUIToolbar.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIToolbar.h; sourceTree = ""; }; + 4CFA7C330A88742900B03626 /* IGUIWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IGUIWindow.h; sourceTree = ""; }; + 4CFA7C340A88742900B03626 /* IImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImage.h; sourceTree = ""; }; + 4CFA7C350A88742900B03626 /* IImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImageLoader.h; sourceTree = ""; }; + 4CFA7C360A88742900B03626 /* IImageWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IImageWriter.h; sourceTree = ""; }; + 4CFA7C370A88742900B03626 /* ILightSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ILightSceneNode.h; sourceTree = ""; }; + 4CFA7C380A88742900B03626 /* ILogger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ILogger.h; sourceTree = ""; }; + 4CFA7C390A88742900B03626 /* IMaterialRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMaterialRenderer.h; sourceTree = ""; }; + 4CFA7C3A0A88742900B03626 /* IMaterialRendererServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMaterialRendererServices.h; sourceTree = ""; }; + 4CFA7C3B0A88742900B03626 /* IMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMesh.h; sourceTree = ""; }; + 4CFA7C3C0A88742900B03626 /* IMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshBuffer.h; sourceTree = ""; }; + 4CFA7C3D0A88742900B03626 /* IMeshCache.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshCache.h; sourceTree = ""; }; + 4CFA7C3E0A88742900B03626 /* IMeshLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshLoader.h; sourceTree = ""; }; + 4CFA7C3F0A88742900B03626 /* IMeshManipulator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshManipulator.h; sourceTree = ""; }; + 4CFA7C400A88742900B03626 /* IMeshSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMeshSceneNode.h; sourceTree = ""; }; + 4CFA7C410A88742900B03626 /* IMetaTriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IMetaTriangleSelector.h; sourceTree = ""; }; + 4CFA7C420A88742900B03626 /* IOSOperator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IOSOperator.h; sourceTree = ""; }; + 4CFA7C430A88742900B03626 /* IParticleAffector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleAffector.h; sourceTree = ""; }; + 4CFA7C440A88742900B03626 /* IParticleEmitter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleEmitter.h; sourceTree = ""; }; + 4CFA7C450A88742900B03626 /* IParticleSystemSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IParticleSystemSceneNode.h; sourceTree = ""; }; + 4CFA7C460A88742900B03626 /* IQ3LevelMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IQ3LevelMesh.h; sourceTree = ""; }; + 4CFA7C470A88742900B03626 /* IReadFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = IReadFile.h; sourceTree = ""; }; + 4CFA7C480A88742900B03626 /* irrAllocator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrAllocator.h; sourceTree = ""; }; + 4CFA7C490A88742900B03626 /* irrArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrArray.h; sourceTree = ""; }; + 4CFA7C4A0A88742900B03626 /* IrrCompileConfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IrrCompileConfig.h; sourceTree = ""; }; + 4CFA7C4B0A88742900B03626 /* irrlicht.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrlicht.h; sourceTree = ""; }; + 4CFA7C4C0A88742900B03626 /* IrrlichtDevice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IrrlichtDevice.h; sourceTree = ""; }; + 4CFA7C4D0A88742900B03626 /* irrList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrList.h; sourceTree = ""; }; + 4CFA7C4E0A88742900B03626 /* irrMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrMath.h; sourceTree = ""; }; + 4CFA7C4F0A88742900B03626 /* irrString.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrString.h; sourceTree = ""; }; + 4CFA7C500A88742900B03626 /* irrTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; path = irrTypes.h; sourceTree = ""; }; + 4CFA7C510A88742900B03626 /* irrXML.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = irrXML.h; sourceTree = ""; }; + 4CFA7C520A88742900B03626 /* ISceneCollisionManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneCollisionManager.h; sourceTree = ""; }; + 4CFA7C530A88742900B03626 /* ISceneManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneManager.h; sourceTree = ""; }; + 4CFA7C540A88742900B03626 /* ISceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNode.h; sourceTree = ""; }; + 4CFA7C550A88742900B03626 /* ISceneNodeAnimator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeAnimator.h; sourceTree = ""; }; + 4CFA7C560A88742900B03626 /* ISceneNodeAnimatorCollisionResponse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeAnimatorCollisionResponse.h; sourceTree = ""; }; + 4CFA7C570A88742900B03626 /* ISceneNodeAnimatorFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeAnimatorFactory.h; sourceTree = ""; }; + 4CFA7C580A88742900B03626 /* ISceneNodeFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneNodeFactory.h; sourceTree = ""; }; + 4CFA7C590A88742900B03626 /* ISceneUserDataSerializer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ISceneUserDataSerializer.h; sourceTree = ""; }; + 4CFA7C5A0A88742900B03626 /* IShaderConstantSetCallBack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IShaderConstantSetCallBack.h; sourceTree = ""; }; + 4CFA7C5B0A88742900B03626 /* IShadowVolumeSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IShadowVolumeSceneNode.h; sourceTree = ""; }; + 4CFA7C5C0A88742900B03626 /* ITerrainSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITerrainSceneNode.h; sourceTree = ""; }; + 4CFA7C5D0A88742900B03626 /* ITextSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITextSceneNode.h; sourceTree = ""; }; + 4CFA7C5E0A88742900B03626 /* ITexture.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITexture.h; sourceTree = ""; }; + 4CFA7C5F0A88742900B03626 /* ITimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITimer.h; sourceTree = ""; }; + 4CFA7C600A88742900B03626 /* ITriangleSelector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ITriangleSelector.h; sourceTree = ""; }; + 4CFA7C620A88742900B03626 /* IVideoDriver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IVideoDriver.h; sourceTree = ""; }; + 4CFA7C630A88742900B03626 /* IVideoModeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IVideoModeList.h; sourceTree = ""; }; + 4CFA7C640A88742900B03626 /* IWriteFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IWriteFile.h; sourceTree = ""; }; + 4CFA7C650A88742900B03626 /* IXMLReader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IXMLReader.h; sourceTree = ""; }; + 4CFA7C660A88742900B03626 /* IXMLWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IXMLWriter.h; sourceTree = ""; }; + 4CFA7C670A88742900B03626 /* Keycodes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Keycodes.h; sourceTree = ""; }; + 4CFA7C680A88742900B03626 /* line2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = line2d.h; sourceTree = ""; }; + 4CFA7C690A88742900B03626 /* line3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = line3d.h; sourceTree = ""; }; + 4CFA7C6A0A88742900B03626 /* matrix4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = matrix4.h; sourceTree = ""; }; + 4CFA7C6B0A88742900B03626 /* plane3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plane3d.h; sourceTree = ""; }; + 4CFA7C6C0A88742900B03626 /* position2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = position2d.h; sourceTree = ""; }; + 4CFA7C6D0A88742900B03626 /* quaternion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = quaternion.h; sourceTree = ""; }; + 4CFA7C6E0A88742900B03626 /* rect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = rect.h; sourceTree = ""; }; + 4CFA7C6F0A88742900B03626 /* S3DVertex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = S3DVertex.h; sourceTree = ""; }; + 4CFA7C700A88742900B03626 /* SAnimatedMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SAnimatedMesh.h; sourceTree = ""; }; + 4CFA7C710A88742900B03626 /* SceneParameters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SceneParameters.h; sourceTree = ""; }; + 4CFA7C720A88742900B03626 /* SColor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SColor.h; sourceTree = ""; }; + 4CFA7C730A88742900B03626 /* SExposedVideoData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SExposedVideoData.h; sourceTree = ""; }; + 4CFA7C740A88742900B03626 /* SIrrCreationParameters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SIrrCreationParameters.h; sourceTree = ""; }; + 4CFA7C750A88742900B03626 /* SKeyMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SKeyMap.h; sourceTree = ""; }; + 4CFA7C760A88742900B03626 /* SLight.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SLight.h; sourceTree = ""; }; + 4CFA7C770A88742900B03626 /* SMaterial.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMaterial.h; sourceTree = ""; }; + 4CFA7C780A88742900B03626 /* SMesh.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMesh.h; sourceTree = ""; }; + 4CFA7C790A88742900B03626 /* SMeshBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMeshBuffer.h; sourceTree = ""; }; + 4CFA7C7A0A88742900B03626 /* SMeshBufferLightMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMeshBufferLightMap.h; sourceTree = ""; }; + 4CFA7C7B0A88742900B03626 /* SMeshBufferTangents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SMeshBufferTangents.h; sourceTree = ""; }; + 4CFA7C7C0A88742900B03626 /* SParticle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SParticle.h; sourceTree = ""; }; + 4CFA7C7E0A88742900B03626 /* triangle3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = triangle3d.h; sourceTree = ""; }; + 4CFA7C7F0A88742900B03626 /* vector2d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vector2d.h; sourceTree = ""; }; + 4CFA7C800A88742900B03626 /* vector3d.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = vector3d.h; sourceTree = ""; }; + 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDepthBuffer.cpp; sourceTree = ""; }; + 5DD4804D0C7D91DF00728AA9 /* CDepthBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDepthBuffer.h; sourceTree = ""; }; + 5DD480500C7D936700728AA9 /* IBurningShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IBurningShader.cpp; sourceTree = ""; }; + 5DD480510C7D936700728AA9 /* IBurningShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IBurningShader.h; sourceTree = ""; }; + 5DD480540C7D93AB00728AA9 /* IDepthBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDepthBuffer.h; sourceTree = ""; }; + 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAnimatedMeshMD3.cpp; sourceTree = ""; }; + 5DD480570C7D945800728AA9 /* CAnimatedMeshMD3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAnimatedMeshMD3.h; sourceTree = ""; }; + 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDefaultGUIElementFactory.cpp; sourceTree = ""; }; + 5DD480590C7D945800728AA9 /* CDefaultGUIElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDefaultGUIElementFactory.h; sourceTree = ""; }; + 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUIColorSelectDialog.cpp; sourceTree = ""; }; + 5DD4805F0C7D947B00728AA9 /* CGUIColorSelectDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUIColorSelectDialog.h; sourceTree = ""; }; + 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUISpinBox.cpp; sourceTree = ""; }; + 5DD480610C7D947B00728AA9 /* CGUISpinBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUISpinBox.h; sourceTree = ""; }; + 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CGUISpriteBank.cpp; sourceTree = ""; }; + 5DD480630C7D947B00728AA9 /* CGUISpriteBank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGUISpriteBank.h; sourceTree = ""; }; + 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CQuake3ShaderSceneNode.cpp; sourceTree = ""; }; + 5DD4806B0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CQuake3ShaderSceneNode.h; sourceTree = ""; }; + 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureBlend.cpp; sourceTree = ""; }; + 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAlpha.cpp; sourceTree = ""; }; + 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureGouraudAlphaNoZ.cpp; sourceTree = ""; }; + 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CTRTextureLightMapGouraud2_M4.cpp; sourceTree = ""; }; + 5DD480700C7D94AC00728AA9 /* glxext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glxext.h; sourceTree = ""; }; + 5DD480C10C7DA66800728AA9 /* COpenGLExtensionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = COpenGLExtensionHandler.h; sourceTree = ""; }; + 5DD480C20C7DA66800728AA9 /* CMD3MeshFileLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMD3MeshFileLoader.h; sourceTree = ""; }; + 5DD480C30C7DA66800728AA9 /* CIrrDeviceSDL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CIrrDeviceSDL.h; sourceTree = ""; }; + 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CIrrDeviceSDL.cpp; sourceTree = ""; }; + 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = COpenGLExtensionHandler.cpp; sourceTree = ""; }; + 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CMD3MeshFileLoader.cpp; sourceTree = ""; }; + 959726FD12C18FFC00BF73D3 /* IrrFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IrrFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 959726FE12C18FFC00BF73D3 /* irrFramework-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "irrFramework-Info.plist"; sourceTree = ""; }; + 95972B8312C19A5C00BF73D3 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 95972B8912C19A7600BF73D3 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + 95972B8D12C19A7F00BF73D3 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; + 95E5857012FCE277004946C6 /* CWADReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CWADReader.cpp; path = ../CWADReader.cpp; sourceTree = SOURCE_ROOT; }; + 95E5857512FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAnimatedMeshHalfLife.cpp; path = ../CAnimatedMeshHalfLife.cpp; sourceTree = SOURCE_ROOT; }; + 95E5857612FCE2CB004946C6 /* CAnimatedMeshHalfLife.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAnimatedMeshHalfLife.h; path = ../CAnimatedMeshHalfLife.h; sourceTree = SOURCE_ROOT; }; + 95E5857B12FCE2DE004946C6 /* CSceneLoaderIrr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSceneLoaderIrr.cpp; path = ../CSceneLoaderIrr.cpp; sourceTree = SOURCE_ROOT; }; + 95E5858C12FCE388004946C6 /* CTRNormalMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CTRNormalMap.cpp; path = ../CTRNormalMap.cpp; sourceTree = SOURCE_ROOT; }; + 95E5859112FCE3A1004946C6 /* CTRStencilShadow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CTRStencilShadow.cpp; path = ../CTRStencilShadow.cpp; sourceTree = SOURCE_ROOT; }; + 95E5859412FCE3F5004946C6 /* CSMFMeshFileLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSMFMeshFileLoader.cpp; path = ../CSMFMeshFileLoader.cpp; sourceTree = SOURCE_ROOT; }; + 95E9D50210F42F9A008546FE /* jcarith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jcarith.c; path = ../jpeglib/jcarith.c; sourceTree = SOURCE_ROOT; }; + 95E9D50610F42FDF008546FE /* jdarith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jdarith.c; path = ../jpeglib/jdarith.c; sourceTree = SOURCE_ROOT; }; + 95E9D50A10F43011008546FE /* jaricom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jaricom.c; path = ../jpeglib/jaricom.c; sourceTree = SOURCE_ROOT; }; + 95E9D50E10F43194008546FE /* CNPKReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CNPKReader.cpp; path = ../CNPKReader.cpp; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 09022C5A0EA0E97F00CD54EE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09022C5B0EA0E97F00CD54EE /* libIrrlicht.a in Frameworks */, + 09022C5C0EA0E97F00CD54EE /* Cocoa.framework in Frameworks */, + 09022C5D0EA0E97F00CD54EE /* OpenGL.framework in Frameworks */, + 09022C5E0EA0E97F00CD54EE /* Carbon.framework in Frameworks */, + 0930CE590EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0946CCAB0EC99BBE00D945A5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0946CCAC0EC99BBE00D945A5 /* libIrrlicht.a in Frameworks */, + 0946CCAD0EC99BBE00D945A5 /* Cocoa.framework in Frameworks */, + 0946CCAE0EC99BBE00D945A5 /* OpenGL.framework in Frameworks */, + 0946CCAF0EC99BBE00D945A5 /* Carbon.framework in Frameworks */, + 0946CCB00EC99BBE00D945A5 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F648FC0D2CDED9001E0599 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F648FD0D2CDED9001E0599 /* libIrrlicht.a in Frameworks */, + 09F648FE0D2CDED9001E0599 /* Cocoa.framework in Frameworks */, + 09F648FF0D2CDED9001E0599 /* OpenGL.framework in Frameworks */, + 092511400D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE5C0EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F649370D2CE03E001E0599 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F649380D2CE03E001E0599 /* libIrrlicht.a in Frameworks */, + 09F649390D2CE03E001E0599 /* Cocoa.framework in Frameworks */, + 09F6493A0D2CE03E001E0599 /* OpenGL.framework in Frameworks */, + 0925113F0D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE5B0EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F6495E0D2CE206001E0599 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F6495F0D2CE206001E0599 /* libIrrlicht.a in Frameworks */, + 09F649600D2CE206001E0599 /* Cocoa.framework in Frameworks */, + 09F649610D2CE206001E0599 /* OpenGL.framework in Frameworks */, + 0925113E0D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE5A0EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0E2E3CF31103E294002DE8D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2E3CF41103E294002DE8D7 /* libIrrlicht.a in Frameworks */, + 0E2E3CF51103E294002DE8D7 /* Cocoa.framework in Frameworks */, + 0E2E3CF61103E294002DE8D7 /* OpenGL.framework in Frameworks */, + 0E2E3CF71103E294002DE8D7 /* Carbon.framework in Frameworks */, + 0E2E3CF81103E294002DE8D7 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0E2E3D331103E3F4002DE8D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2E3D341103E3F4002DE8D7 /* libIrrlicht.a in Frameworks */, + 0E2E3D351103E3F4002DE8D7 /* Cocoa.framework in Frameworks */, + 0E2E3D361103E3F4002DE8D7 /* OpenGL.framework in Frameworks */, + 0E2E3D371103E3F4002DE8D7 /* Carbon.framework in Frameworks */, + 0E2E3D381103E3F4002DE8D7 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 959726FB12C18FFB00BF73D3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 95972B8412C19A5C00BF73D3 /* OpenGL.framework in Frameworks */, + 95972B8A12C19A7600BF73D3 /* IOKit.framework in Frameworks */, + 95972B8E12C19A7F00BF73D3 /* Carbon.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE08097FD9F50057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF146F50A486648006EBA03 /* libIrrlicht.a in Frameworks */, + 4C53E2750A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2760A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511490D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE650EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE89097FDDE20057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF1470A0A4866FA006EBA03 /* libIrrlicht.a in Frameworks */, + 4C53E2770A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2780A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511480D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE640EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEAB097FDE900057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB40A486A1600ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E27F0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2800A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511440D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE600EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEC9097FDF020057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB70A486A2500ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E2810A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2820A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511430D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE5F0EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEEF097FE05F0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF147190A48676E006EBA03 /* libIrrlicht.a in Frameworks */, + 4C53E2790A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E27A0A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511470D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE630EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF0E097FE13E0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C8D0A48628200B4E469 /* libIrrlicht.a in Frameworks */, + 4C53E2730A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2740A4850D60014E966 /* OpenGL.framework in Frameworks */, + 0925114A0D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE660EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF25097FE1E00057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C520A48618800B4E469 /* libIrrlicht.a in Frameworks */, + 4C53E26F0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2700A4850D60014E966 /* OpenGL.framework in Frameworks */, + 0925114C0D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE580EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF3A097FE25F0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C53E2510A4850550014E966 /* libIrrlicht.a in Frameworks */, + 4C53E2870A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2880A4850D60014E966 /* OpenGL.framework in Frameworks */, + 0925114D0D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE570EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF51097FE3050057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB10A486A0200ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E27D0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E27E0A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511450D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE610EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF7F097FE3DC0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C560A4861AE00B4E469 /* libIrrlicht.a in Frameworks */, + 4C53E2710A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2720A4850D60014E966 /* OpenGL.framework in Frameworks */, + 0925114B0D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE560EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF98097FE45E0057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBAF0A4869F300ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E27B0A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E27C0A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511460D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE620EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFFB6097FE5F80057C06F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBA0A486A3A00ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E2830A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2840A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511420D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE5E0EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8DEF35B0950229200FDEA7E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBF0A486A5700ADB3D7 /* libIrrlicht.a in Frameworks */, + 4C53E2850A4850D60014E966 /* Cocoa.framework in Frameworks */, + 4C53E2860A4850D60014E966 /* OpenGL.framework in Frameworks */, + 092511410D744ADE006784D9 /* Carbon.framework in Frameworks */, + 0930CE5D0EC39F4500D63866 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC07C0554694100DB518D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0867D691FE84028FC02AAC07 /* MacOSX */ = { + isa = PBXGroup; + children = ( + 09022C660EA0EA6500CD54EE /* Tools */, + 4CFA7C090A88742800B03626 /* include */, + 4C53DEE50A484C220014E966 /* Irrlicht */, + 4C00546D0A48470500C844C2 /* examples */, + 4C53E2540A48505D0014E966 /* Libraries */, + 4C53E24C0A484FED0014E966 /* Products */, + 959726FD12C18FFC00BF73D3 /* IrrFramework.framework */, + 959726FE12C18FFC00BF73D3 /* irrFramework-Info.plist */, + 95972B8312C19A5C00BF73D3 /* OpenGL.framework */, + 95972B8912C19A7600BF73D3 /* IOKit.framework */, + 95972B8D12C19A7F00BF73D3 /* Carbon.framework */, + ); + name = MacOSX; + sourceTree = ""; + }; + 09022C660EA0EA6500CD54EE /* Tools */ = { + isa = PBXGroup; + children = ( + 09022C670EA0EA7100CD54EE /* GUIEditor */, + ); + name = Tools; + sourceTree = ""; + }; + 09022C670EA0EA7100CD54EE /* GUIEditor */ = { + isa = PBXGroup; + children = ( + 09022CA40EA0EC1900CD54EE /* source */, + 09022CA30EA0EC0E00CD54EE /* include */, + ); + name = GUIEditor; + sourceTree = ""; + }; + 09022CA30EA0EC0E00CD54EE /* include */ = { + isa = PBXGroup; + children = ( + 09022C680EA0EA9D00CD54EE /* CGUIAttribute.h */, + 09022C6A0EA0EA9D00CD54EE /* CGUIAttributeEditor.h */, + 09022C6B0EA0EA9D00CD54EE /* CGUIBoolAttribute.h */, + 09022C6C0EA0EA9D00CD54EE /* CGUIColorAttribute.h */, + 09022C6D0EA0EA9D00CD54EE /* CGUIDummyEditorStub.h */, + 09022C6F0EA0EA9D00CD54EE /* CGUIEditFactory.h */, + 09022C710EA0EA9D00CD54EE /* CGUIEditWindow.h */, + 09022C730EA0EA9D00CD54EE /* CGUIEditWorkspace.h */, + 09022C740EA0EA9D00CD54EE /* CGUIEnumAttribute.h */, + 09022C760EA0EA9D00CD54EE /* CGUIPanel.h */, + 09022C770EA0EA9D00CD54EE /* CGUIStringAttribute.h */, + 09022C780EA0EA9D00CD54EE /* CGUITextureAttribute.h */, + 09022C7A0EA0EA9D00CD54EE /* CGUITextureCacheBrowser.h */, + 09022C7C0EA0EA9D00CD54EE /* CMemoryReadWriteFile.h */, + ); + name = include; + sourceTree = ""; + }; + 09022CA40EA0EC1900CD54EE /* source */ = { + isa = PBXGroup; + children = ( + 09022C690EA0EA9D00CD54EE /* CGUIAttributeEditor.cpp */, + 09022C6E0EA0EA9D00CD54EE /* CGUIEditFactory.cpp */, + 09022C700EA0EA9D00CD54EE /* CGUIEditWindow.cpp */, + 09022C720EA0EA9D00CD54EE /* CGUIEditWorkspace.cpp */, + 09022C750EA0EA9D00CD54EE /* CGUIPanel.cpp */, + 09022C790EA0EA9D00CD54EE /* CGUITextureCacheBrowser.cpp */, + 09022C7B0EA0EA9D00CD54EE /* CMemoryReadWriteFile.cpp */, + 09022C7D0EA0EA9D00CD54EE /* main.cpp */, + ); + name = source; + sourceTree = ""; + }; + 0910BA4D0D1F64D000D46B04 /* gui */ = { + isa = PBXGroup; + children = ( + 0910BA070D1F64B300D46B04 /* EMessageBoxFlags.h */, + 4CFA7C0D0A88742800B03626 /* EGUIElementTypes.h */, + 0910BA020D1F64B300D46B04 /* EGUIAlignment.h */, + 4CFA7C1B0A88742900B03626 /* ICursorControl.h */, + 4CFA7C210A88742900B03626 /* IGUIButton.h */, + 4CFA7C220A88742900B03626 /* IGUICheckBox.h */, + 0910BA0B0D1F64B300D46B04 /* IGUIColorSelectDialog.h */, + 4CFA7C230A88742900B03626 /* IGUIComboBox.h */, + 4CFA7C240A88742900B03626 /* IGUIContextMenu.h */, + 4CFA7C250A88742900B03626 /* IGUIEditBox.h */, + 4CFA7C260A88742900B03626 /* IGUIElement.h */, + 0910BA0C0D1F64B300D46B04 /* IGUIElementFactory.h */, + 4CFA7C270A88742900B03626 /* IGUIEnvironment.h */, + 4CFA7C280A88742900B03626 /* IGUIFileOpenDialog.h */, + 4CFA7C290A88742900B03626 /* IGUIFont.h */, + 0910BA0D0D1F64B300D46B04 /* IGUIFontBitmap.h */, + 4CFA7C2A0A88742900B03626 /* IGUIImage.h */, + 4CFA7C2B0A88742900B03626 /* IGUIInOutFader.h */, + 4CFA7C2C0A88742900B03626 /* IGUIListBox.h */, + 4CFA7C2D0A88742900B03626 /* IGUIMeshViewer.h */, + 4CFA7C2E0A88742900B03626 /* IGUIScrollBar.h */, + 4CFA7C2F0A88742900B03626 /* IGUISkin.h */, + 0910BA0E0D1F64B300D46B04 /* IGUISpinBox.h */, + 0910BA0F0D1F64B300D46B04 /* IGUISpriteBank.h */, + 4CFA7C300A88742900B03626 /* IGUIStaticText.h */, + 4CFA7C310A88742900B03626 /* IGUITabControl.h */, + 0910BA100D1F64B300D46B04 /* IGUITable.h */, + 4CFA7C320A88742900B03626 /* IGUIToolbar.h */, + 4CFA7C330A88742900B03626 /* IGUIWindow.h */, + ); + name = gui; + sourceTree = ""; + }; + 0910BA4E0D1F652100D46B04 /* core */ = { + isa = PBXGroup; + children = ( + 4CFA7C500A88742900B03626 /* irrTypes.h */, + 0910B9FE0D1F64B300D46B04 /* coreutil.h */, + 4CFA7C5F0A88742900B03626 /* ITimer.h */, + 4CFA7C670A88742900B03626 /* Keycodes.h */, + 4CFA7C750A88742900B03626 /* SKeyMap.h */, + 4CFA7C0A0A88742800B03626 /* aabbox3d.h */, + 4CFA7C0B0A88742800B03626 /* dimension2d.h */, + 4CFA7C100A88742800B03626 /* heapsort.h */, + 4CFA7C480A88742900B03626 /* irrAllocator.h */, + 4CFA7C490A88742900B03626 /* irrArray.h */, + 4CFA7C4D0A88742900B03626 /* irrList.h */, + 0910BA1E0D1F64B300D46B04 /* irrMap.h */, + 4CFA7C4E0A88742900B03626 /* irrMath.h */, + 4CFA7C4F0A88742900B03626 /* irrString.h */, + 4CFA7C680A88742900B03626 /* line2d.h */, + 4CFA7C690A88742900B03626 /* line3d.h */, + 4CFA7C6A0A88742900B03626 /* matrix4.h */, + 4CFA7C6B0A88742900B03626 /* plane3d.h */, + 4CFA7C6C0A88742900B03626 /* position2d.h */, + 4CFA7C6D0A88742900B03626 /* quaternion.h */, + 4CFA7C6E0A88742900B03626 /* rect.h */, + 4CFA7C7E0A88742900B03626 /* triangle3d.h */, + 4CFA7C7F0A88742900B03626 /* vector2d.h */, + 4CFA7C800A88742900B03626 /* vector3d.h */, + ); + name = core; + sourceTree = ""; + }; + 0910BA4F0D1F65A300D46B04 /* io */ = { + isa = PBXGroup; + children = ( + 4CFA7C360A88742900B03626 /* IImageWriter.h */, + 0910BA110D1F64B300D46B04 /* IMeshWriter.h */, + 4CFA7C170A88742900B03626 /* IAttributeExchangingObject.h */, + 4CFA7C180A88742900B03626 /* IAttributes.h */, + 4CFA7C1E0A88742900B03626 /* IFileList.h */, + 4CFA7C1F0A88742900B03626 /* IFileSystem.h */, + 4CFA7C470A88742900B03626 /* IReadFile.h */, + 4CFA7C510A88742900B03626 /* irrXML.h */, + 4CFA7C640A88742900B03626 /* IWriteFile.h */, + 4CFA7C650A88742900B03626 /* IXMLReader.h */, + 4CFA7C660A88742900B03626 /* IXMLWriter.h */, + ); + name = io; + sourceTree = ""; + }; + 0910BA500D1F660300D46B04 /* scene */ = { + isa = PBXGroup; + children = ( + 0910BA220D1F64B300D46B04 /* SSkinMeshBuffer.h */, + 0910BA210D1F64B300D46B04 /* SSharedMeshBuffer.h */, + 0910BA0A0D1F64B300D46B04 /* IBoneSceneNode.h */, + 0910BA080D1F64B300D46B04 /* ETerrainElements.h */, + 0910BA030D1F64B300D46B04 /* EHardwareBufferFlags.h */, + 4CFA7C590A88742900B03626 /* ISceneUserDataSerializer.h */, + 0910B9FF0D1F64B300D46B04 /* ECullingTypes.h */, + 0910BA000D1F64B300D46B04 /* EDebugSceneTypes.h */, + 0910BA060D1F64B300D46B04 /* EMeshWriterEnums.h */, + 4CFA7C0E0A88742800B03626 /* ESceneNodeAnimatorTypes.h */, + 4CFA7C0F0A88742800B03626 /* ESceneNodeTypes.h */, + 4CFA7C110A88742900B03626 /* IAnimatedMesh.h */, + 4CFA7C130A88742900B03626 /* IAnimatedMeshMD2.h */, + 0910BA090D1F64B300D46B04 /* IAnimatedMeshMD3.h */, + 4CFA7C150A88742900B03626 /* IAnimatedMeshSceneNode.h */, + 4CFA7C190A88742900B03626 /* IBillboardSceneNode.h */, + 4CFA7C1A0A88742900B03626 /* ICameraSceneNode.h */, + 4CFA7C1C0A88742900B03626 /* IDummyTransformationSceneNode.h */, + 4CFA7C370A88742900B03626 /* ILightSceneNode.h */, + 4CFA7C3B0A88742900B03626 /* IMesh.h */, + 4CFA7C3C0A88742900B03626 /* IMeshBuffer.h */, + 4CFA7C3D0A88742900B03626 /* IMeshCache.h */, + 4CFA7C3E0A88742900B03626 /* IMeshLoader.h */, + 4CFA7C3F0A88742900B03626 /* IMeshManipulator.h */, + 4CFA7C400A88742900B03626 /* IMeshSceneNode.h */, + 4CFA7C410A88742900B03626 /* IMetaTriangleSelector.h */, + 4CFA7C430A88742900B03626 /* IParticleAffector.h */, + 0910BA120D1F64B300D46B04 /* IParticleAnimatedMeshSceneNodeEmitter.h */, + 0910BA130D1F64B300D46B04 /* IParticleAttractionAffector.h */, + 0910BA140D1F64B300D46B04 /* IParticleBoxEmitter.h */, + 0910BA150D1F64B300D46B04 /* IParticleCylinderEmitter.h */, + 4CFA7C440A88742900B03626 /* IParticleEmitter.h */, + 0910BA160D1F64B300D46B04 /* IParticleFadeOutAffector.h */, + 0910BA170D1F64B300D46B04 /* IParticleGravityAffector.h */, + 0910BA180D1F64B300D46B04 /* IParticleMeshEmitter.h */, + 0910BA190D1F64B300D46B04 /* IParticleRingEmitter.h */, + 0910BA1A0D1F64B300D46B04 /* IParticleRotationAffector.h */, + 0910BA1B0D1F64B300D46B04 /* IParticleSphereEmitter.h */, + 4CFA7C450A88742900B03626 /* IParticleSystemSceneNode.h */, + 4CFA7C460A88742900B03626 /* IQ3LevelMesh.h */, + 0910BA1C0D1F64B300D46B04 /* IQ3Shader.h */, + 4CFA7C520A88742900B03626 /* ISceneCollisionManager.h */, + 4CFA7C530A88742900B03626 /* ISceneManager.h */, + 4CFA7C540A88742900B03626 /* ISceneNode.h */, + 4CFA7C550A88742900B03626 /* ISceneNodeAnimator.h */, + 4CFA7C560A88742900B03626 /* ISceneNodeAnimatorCollisionResponse.h */, + 4CFA7C570A88742900B03626 /* ISceneNodeAnimatorFactory.h */, + 4CFA7C580A88742900B03626 /* ISceneNodeFactory.h */, + 4CFA7C5B0A88742900B03626 /* IShadowVolumeSceneNode.h */, + 0910BA1F0D1F64B300D46B04 /* ISkinnedMesh.h */, + 4CFA7C5C0A88742900B03626 /* ITerrainSceneNode.h */, + 4CFA7C5D0A88742900B03626 /* ITextSceneNode.h */, + 4CFA7C600A88742900B03626 /* ITriangleSelector.h */, + 4CFA7C700A88742900B03626 /* SAnimatedMesh.h */, + 4CFA7C710A88742900B03626 /* SceneParameters.h */, + 4CFA7C780A88742900B03626 /* SMesh.h */, + 4CFA7C790A88742900B03626 /* SMeshBuffer.h */, + 4CFA7C7A0A88742900B03626 /* SMeshBufferLightMap.h */, + 4CFA7C7B0A88742900B03626 /* SMeshBufferTangents.h */, + 4CFA7C7C0A88742900B03626 /* SParticle.h */, + 0910B9FD0D1F64B300D46B04 /* CMeshBuffer.h */, + 0910BA230D1F64B300D46B04 /* SViewFrustum.h */, + ); + name = scene; + sourceTree = ""; + }; + 0910BA800D1F6ADA00D46B04 /* video */ = { + isa = PBXGroup; + children = ( + 0910BA200D1F64B300D46B04 /* SMaterialLayer.h */, + 0910BA050D1F64B300D46B04 /* EMaterialTypes.h */, + 0910BA040D1F64B300D46B04 /* EMaterialFlags.h */, + 0910BA010D1F64B300D46B04 /* EDriverFeatures.h */, + 4CFA7C200A88742900B03626 /* IGPUProgrammingServices.h */, + 4CFA7C340A88742900B03626 /* IImage.h */, + 4CFA7C350A88742900B03626 /* IImageLoader.h */, + 4CFA7C390A88742900B03626 /* IMaterialRenderer.h */, + 4CFA7C3A0A88742900B03626 /* IMaterialRendererServices.h */, + 4CFA7C5A0A88742900B03626 /* IShaderConstantSetCallBack.h */, + 4CFA7C5E0A88742900B03626 /* ITexture.h */, + 4CFA7C620A88742900B03626 /* IVideoDriver.h */, + 4CFA7C630A88742900B03626 /* IVideoModeList.h */, + 4CFA7C6F0A88742900B03626 /* S3DVertex.h */, + 4CFA7C720A88742900B03626 /* SColor.h */, + 4CFA7C730A88742900B03626 /* SExposedVideoData.h */, + 4CFA7C760A88742900B03626 /* SLight.h */, + 4CFA7C770A88742900B03626 /* SMaterial.h */, + ); + name = video; + sourceTree = ""; + }; + 0910BA810D1F6BB800D46B04 /* gui */ = { + isa = PBXGroup; + children = ( + 34FFD9CB0F6601AC00420884 /* element */, + 4C53DEE60A484C220014E966 /* BuiltInFont.h */, + 5DD480580C7D945800728AA9 /* CDefaultGUIElementFactory.cpp */, + 5DD480590C7D945800728AA9 /* CDefaultGUIElementFactory.h */, + 4C53DF3C0A484C230014E966 /* CGUIFont.cpp */, + 4C53DF3D0A484C230014E966 /* CGUIFont.h */, + 4C53DF4E0A484C230014E966 /* CGUISkin.cpp */, + 4C53DF4F0A484C230014E966 /* CGUISkin.h */, + 5DD480620C7D947B00728AA9 /* CGUISpriteBank.cpp */, + 5DD480630C7D947B00728AA9 /* CGUISpriteBank.h */, + ); + name = gui; + sourceTree = ""; + }; + 0910BA820D1F6C3900D46B04 /* io */ = { + isa = PBXGroup; + children = ( + 34FFD9CA0F66018500420884 /* xml */, + 34FFD9C90F66014200420884 /* file */, + 34FFD9C80F66012D00420884 /* attributes */, + 34FFD9C70F66011C00420884 /* archive */, + 4C53DF260A484C230014E966 /* CFileList.cpp */, + 4C53DF270A484C230014E966 /* CFileList.h */, + 4C53DF280A484C230014E966 /* CFileSystem.cpp */, + 4C53DF290A484C230014E966 /* CFileSystem.h */, + ); + name = io; + sourceTree = ""; + }; + 0910BA830D1F6CA600D46B04 /* irr */ = { + isa = PBXGroup; + children = ( + 34FFD9C60F6600DA00420884 /* device */, + 4C53DF720A484C230014E966 /* CLogger.cpp */, + 4C53DF730A484C230014E966 /* CLogger.h */, + 4C53DF990A484C240014E966 /* COSOperator.cpp */, + 4C53DF9A0A484C240014E966 /* COSOperator.h */, + 4C53DFD00A484C240014E966 /* CTimer.h */, + 4C53E00A0A484C250014E966 /* Irrlicht.cpp */, + 4C53E16A0A484C2C0014E966 /* os.cpp */, + 4C53E16B0A484C2C0014E966 /* os.h */, + ); + name = irr; + sourceTree = ""; + }; + 0910BA840D1F6D0200D46B04 /* scene */ = { + isa = PBXGroup; + children = ( + 0E2E3C491103B224002DE8D7 /* Octree.h */, + 0910BA850D1F6D0A00D46B04 /* animators */, + 0910BA860D1F6D2600D46B04 /* collision */, + 0910BA870D1F6D7500D46B04 /* loaders */, + 0910BA880D1F6F1600D46B04 /* particleSystem */, + 0910BA890D1F6F6600D46B04 /* sceneNodes */, + 0910BA8A0D1F70B800D46B04 /* writers */, + 4C53DF1D0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.h */, + 4C53DF1C0A484C230014E966 /* CDefaultSceneNodeAnimatorFactory.cpp */, + 4C53DF1E0A484C230014E966 /* CDefaultSceneNodeFactory.cpp */, + 4C53DF1F0A484C230014E966 /* CDefaultSceneNodeFactory.h */, + 4C53DF2C0A484C230014E966 /* CGeometryCreator.cpp */, + 4C53DF2D0A484C230014E966 /* CGeometryCreator.h */, + 4C53DF760A484C230014E966 /* CMeshCache.cpp */, + 4C53DF770A484C230014E966 /* CMeshCache.h */, + 4C53DF780A484C230014E966 /* CMeshManipulator.cpp */, + 4C53DF790A484C230014E966 /* CMeshManipulator.h */, + 95E9D50E10F43194008546FE /* CNPKReader.cpp */, + 4C53DFAB0A484C240014E966 /* CSceneManager.cpp */, + 4C53DFAC0A484C240014E966 /* CSceneManager.h */, + ); + name = scene; + sourceTree = ""; + }; + 0910BA850D1F6D0A00D46B04 /* animators */ = { + isa = PBXGroup; + children = ( + 4C53DFAD0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.cpp */, + 4C53DFAE0A484C240014E966 /* CSceneNodeAnimatorCollisionResponse.h */, + 4C53DFAF0A484C240014E966 /* CSceneNodeAnimatorDelete.cpp */, + 4C53DFB00A484C240014E966 /* CSceneNodeAnimatorDelete.h */, + 4C53DFB10A484C240014E966 /* CSceneNodeAnimatorFlyCircle.cpp */, + 4C53DFB20A484C240014E966 /* CSceneNodeAnimatorFlyCircle.h */, + 4C53DFB30A484C240014E966 /* CSceneNodeAnimatorFlyStraight.cpp */, + 4C53DFB40A484C240014E966 /* CSceneNodeAnimatorFlyStraight.h */, + 4C53DFB50A484C240014E966 /* CSceneNodeAnimatorFollowSpline.cpp */, + 4C53DFB60A484C240014E966 /* CSceneNodeAnimatorFollowSpline.h */, + 4C53DFB70A484C240014E966 /* CSceneNodeAnimatorRotation.cpp */, + 4C53DFB80A484C240014E966 /* CSceneNodeAnimatorRotation.h */, + 4C53DFB90A484C240014E966 /* CSceneNodeAnimatorTexture.cpp */, + 4C53DFBA0A484C240014E966 /* CSceneNodeAnimatorTexture.h */, + ); + name = animators; + sourceTree = ""; + }; + 0910BA860D1F6D2600D46B04 /* collision */ = { + isa = PBXGroup; + children = ( + 0E2E3C4F1103B261002DE8D7 /* COctreeTriangleSelector.cpp */, + 0E2E3C501103B261002DE8D7 /* COctreeTriangleSelector.h */, + 4C53DF7C0A484C230014E966 /* CMetaTriangleSelector.cpp */, + 4C53DF7D0A484C230014E966 /* CMetaTriangleSelector.h */, + 4C53DFA90A484C240014E966 /* CSceneCollisionManager.cpp */, + 4C53DFAA0A484C240014E966 /* CSceneCollisionManager.h */, + 4C53DFCC0A484C240014E966 /* CTerrainTriangleSelector.cpp */, + 4C53DFCD0A484C240014E966 /* CTerrainTriangleSelector.h */, + 4C53DFD80A484C240014E966 /* CTriangleBBSelector.cpp */, + 4C53DFD90A484C250014E966 /* CTriangleBBSelector.h */, + 4C53DFDA0A484C250014E966 /* CTriangleSelector.cpp */, + 4C53DFDB0A484C250014E966 /* CTriangleSelector.h */, + ); + name = collision; + sourceTree = ""; + }; + 0910BA870D1F6D7500D46B04 /* loaders */ = { + isa = PBXGroup; + children = ( + 096840220D0F1A2300333EFD /* CBSPMeshFileLoader.cpp */, + 096840230D0F1A2300333EFD /* CBSPMeshFileLoader.h */, + 09C638700D4F1A69000B6A18 /* CLWOMeshFileLoader.cpp */, + 09C638710D4F1A69000B6A18 /* CLWOMeshFileLoader.h */, + 4C53DEE70A484C220014E966 /* C3DSMeshFileLoader.cpp */, + 4C53DEE80A484C220014E966 /* C3DSMeshFileLoader.h */, + 4C53DEE90A484C220014E966 /* CAnimatedMeshMD2.cpp */, + 4C53DEEA0A484C220014E966 /* CAnimatedMeshMD2.h */, + 5DD480560C7D945800728AA9 /* CAnimatedMeshMD3.cpp */, + 5DD480570C7D945800728AA9 /* CAnimatedMeshMD3.h */, + 0968401E0D0F1A2300333EFD /* CB3DMeshFileLoader.cpp */, + 0968401F0D0F1A2300333EFD /* CB3DMeshFileLoader.h */, + 4C53DEFA0A484C220014E966 /* CColladaFileLoader.cpp */, + 4C53DEFB0A484C220014E966 /* CColladaFileLoader.h */, + 4C53DEFE0A484C220014E966 /* CCSMLoader.cpp */, + 4C53DEFF0A484C220014E966 /* CCSMLoader.h */, + 4C53DF200A484C230014E966 /* CDMFLoader.cpp */, + 4C53DF210A484C230014E966 /* CDMFLoader.h */, + 0968402B0D0F1A2300333EFD /* CIrrMeshFileLoader.cpp */, + 0968402C0D0F1A2300333EFD /* CIrrMeshFileLoader.h */, + 4C53DF700A484C230014E966 /* CLMTSMeshFileLoader.cpp */, + 4C53DF710A484C230014E966 /* CLMTSMeshFileLoader.h */, + 0968402F0D0F1A2300333EFD /* CMD2MeshFileLoader.cpp */, + 096840300D0F1A2300333EFD /* CMD2MeshFileLoader.h */, + 5DD480C60C7DA66800728AA9 /* CMD3MeshFileLoader.cpp */, + 5DD480C20C7DA66800728AA9 /* CMD3MeshFileLoader.h */, + 096840310D0F1A2300333EFD /* CMS3DMeshFileLoader.cpp */, + 096840320D0F1A2300333EFD /* CMS3DMeshFileLoader.h */, + 4C53DF7E0A484C230014E966 /* CMY3DHelper.h */, + 4C53DF7F0A484C230014E966 /* CMY3DMeshFileLoader.cpp */, + 4C53DF800A484C230014E966 /* CMY3DMeshFileLoader.h */, + 4C364EA20A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp */, + 4C364EA30A6C6DC2004CFBB4 /* COBJMeshFileLoader.h */, + 4C53DF840A484C240014E966 /* COCTLoader.cpp */, + 4C53DF850A484C240014E966 /* COCTLoader.h */, + 4C53DF8A0A484C240014E966 /* COgreMeshFileLoader.cpp */, + 4C53DF8B0A484C240014E966 /* COgreMeshFileLoader.h */, + 34EF91D50F65FCF6000B5651 /* CPLYMeshFileLoader.h */, + 34EF91D60F65FCF6000B5651 /* CPLYMeshFileLoader.cpp */, + 4C53DFA50A484C240014E966 /* CQ3LevelMesh.cpp */, + 4C53DFA60A484C240014E966 /* CQ3LevelMesh.h */, + 096840410D0F1A2300333EFD /* CSkinnedMesh.cpp */, + 096840420D0F1A2300333EFD /* CSkinnedMesh.h */, + 096840430D0F1A2300333EFD /* CSTLMeshFileLoader.cpp */, + 096840440D0F1A2300333EFD /* CSTLMeshFileLoader.h */, + 4C53DFF80A484C250014E966 /* CXMeshFileLoader.cpp */, + 4C53DFF90A484C250014E966 /* CXMeshFileLoader.h */, + 4C53E0050A484C250014E966 /* dmfsupport.h */, + ); + name = loaders; + sourceTree = ""; + }; + 0910BA880D1F6F1600D46B04 /* particleSystem */ = { + isa = PBXGroup; + children = ( + 096CC0DE0ECE65B500C81DC7 /* CParticleScaleAffector.cpp */, + 096CC0DF0ECE65B500C81DC7 /* CParticleScaleAffector.h */, + 096840330D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.cpp */, + 096840340D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.h */, + 096840350D0F1A2300333EFD /* CParticleAttractionAffector.cpp */, + 096840360D0F1A2300333EFD /* CParticleAttractionAffector.h */, + 4C53DF9B0A484C240014E966 /* CParticleBoxEmitter.cpp */, + 4C53DF9C0A484C240014E966 /* CParticleBoxEmitter.h */, + 096840370D0F1A2300333EFD /* CParticleCylinderEmitter.cpp */, + 096840380D0F1A2300333EFD /* CParticleCylinderEmitter.h */, + 4C53DF9D0A484C240014E966 /* CParticleFadeOutAffector.cpp */, + 4C53DF9E0A484C240014E966 /* CParticleFadeOutAffector.h */, + 4C53DF9F0A484C240014E966 /* CParticleGravityAffector.cpp */, + 4C53DFA00A484C240014E966 /* CParticleGravityAffector.h */, + 096840390D0F1A2300333EFD /* CParticleMeshEmitter.cpp */, + 0968403A0D0F1A2300333EFD /* CParticleMeshEmitter.h */, + 4C53DFA10A484C240014E966 /* CParticlePointEmitter.cpp */, + 4C53DFA20A484C240014E966 /* CParticlePointEmitter.h */, + 0968403B0D0F1A2300333EFD /* CParticleRingEmitter.cpp */, + 0968403C0D0F1A2300333EFD /* CParticleRingEmitter.h */, + 0968403D0D0F1A2300333EFD /* CParticleRotationAffector.cpp */, + 0968403E0D0F1A2300333EFD /* CParticleRotationAffector.h */, + 0968403F0D0F1A2300333EFD /* CParticleSphereEmitter.cpp */, + 096840400D0F1A2300333EFD /* CParticleSphereEmitter.h */, + 4C53DFA30A484C240014E966 /* CParticleSystemSceneNode.cpp */, + 4C53DFA40A484C240014E966 /* CParticleSystemSceneNode.h */, + ); + name = particleSystem; + sourceTree = ""; + }; + 0910BA890D1F6F6600D46B04 /* sceneNodes */ = { + isa = PBXGroup; + children = ( + 0E2E3C4B1103B247002DE8D7 /* COctreeSceneNode.cpp */, + 0E2E3C4C1103B247002DE8D7 /* COctreeSceneNode.h */, + 093973BC0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.cpp */, + 093973BD0E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.h */, + 093973BE0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.cpp */, + 093973BF0E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.h */, + 4C53DEED0A484C220014E966 /* CAnimatedMeshSceneNode.cpp */, + 4C53DEEE0A484C220014E966 /* CAnimatedMeshSceneNode.h */, + 4C53DEF20A484C220014E966 /* CBillboardSceneNode.cpp */, + 4C53DEF30A484C220014E966 /* CBillboardSceneNode.h */, + 096840200D0F1A2300333EFD /* CBoneSceneNode.cpp */, + 096840210D0F1A2300333EFD /* CBoneSceneNode.h */, + 4C53DEF80A484C220014E966 /* CCameraSceneNode.cpp */, + 4C53DEF90A484C220014E966 /* CCameraSceneNode.h */, + 4C53DF000A484C220014E966 /* CCubeSceneNode.cpp */, + 4C53DF010A484C220014E966 /* CCubeSceneNode.h */, + 4C53DF220A484C230014E966 /* CDummyTransformationSceneNode.cpp */, + 4C53DF230A484C230014E966 /* CDummyTransformationSceneNode.h */, + 4C53DF240A484C230014E966 /* CEmptySceneNode.cpp */, + 4C53DF250A484C230014E966 /* CEmptySceneNode.h */, + 4C53DF6C0A484C230014E966 /* CLightSceneNode.cpp */, + 4C53DF6D0A484C230014E966 /* CLightSceneNode.h */, + 4C53DF7A0A484C230014E966 /* CMeshSceneNode.cpp */, + 4C53DF7B0A484C230014E966 /* CMeshSceneNode.h */, + 5DD4806A0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp */, + 5DD4806B0C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h */, + 4C53DFBB0A484C240014E966 /* CShadowVolumeSceneNode.cpp */, + 4C53DFBC0A484C240014E966 /* CShadowVolumeSceneNode.h */, + 4C53DFBD0A484C240014E966 /* CSkyBoxSceneNode.cpp */, + 4C53DFBE0A484C240014E966 /* CSkyBoxSceneNode.h */, + 4CFA7BEC0A88735A00B03626 /* CSkyDomeSceneNode.cpp */, + 4CFA7BED0A88735A00B03626 /* CSkyDomeSceneNode.h */, + 4CC36B0D0A6B61DB0076C4B2 /* CSphereSceneNode.cpp */, + 4CC36B0E0A6B61DB0076C4B2 /* CSphereSceneNode.h */, + 4C53DFCA0A484C240014E966 /* CTerrainSceneNode.cpp */, + 4C53DFCB0A484C240014E966 /* CTerrainSceneNode.h */, + 4C53DFCE0A484C240014E966 /* CTextSceneNode.cpp */, + 4C53DFCF0A484C240014E966 /* CTextSceneNode.h */, + 090FBC800D31085E0076D847 /* CVolumeLightSceneNode.cpp */, + 090FBC810D31085E0076D847 /* CVolumeLightSceneNode.h */, + 4C53DFF00A484C250014E966 /* CWaterSurfaceSceneNode.cpp */, + 4C53DFF10A484C250014E966 /* CWaterSurfaceSceneNode.h */, + ); + name = sceneNodes; + sourceTree = ""; + }; + 0910BA8A0D1F70B800D46B04 /* writers */ = { + isa = PBXGroup; + children = ( + 096840250D0F1A2300333EFD /* CColladaMeshWriter.cpp */, + 096840260D0F1A2300333EFD /* CColladaMeshWriter.h */, + 0968402D0D0F1A2300333EFD /* CIrrMeshWriter.cpp */, + 0968402E0D0F1A2300333EFD /* CIrrMeshWriter.h */, + 096F8E3B0EA2EFBA00907EC5 /* COBJMeshWriter.cpp */, + 096F8E3C0EA2EFBA00907EC5 /* COBJMeshWriter.h */, + 34EF91DA0F65FD14000B5651 /* CPLYMeshWriter.h */, + 34EF91DB0F65FD14000B5651 /* CPLYMeshWriter.cpp */, + 096840450D0F1A2300333EFD /* CSTLMeshWriter.cpp */, + 096840460D0F1A2300333EFD /* CSTLMeshWriter.h */, + ); + name = writers; + sourceTree = ""; + }; + 0910BA8B0D1F71D600D46B04 /* video */ = { + isa = PBXGroup; + children = ( + 0910BA8C0D1F729400D46B04 /* Burning Video */, + 0910BA8D0D1F72DB00D46B04 /* Direct3D8 */, + 0910BA8E0D1F72FB00D46B04 /* Direct3D9 */, + 0910BA8F0D1F731900D46B04 /* Null */, + 0910BA910D1F738100D46B04 /* OpenGL */, + 0910BA920D1F73CC00D46B04 /* Software */, + 4C53DFEE0A484C250014E966 /* CVideoModeList.cpp */, + 4C53DFEF0A484C250014E966 /* CVideoModeList.h */, + ); + name = video; + sourceTree = ""; + }; + 0910BA8C0D1F729400D46B04 /* Burning Video */ = { + isa = PBXGroup; + children = ( + 4C53E16D0A484C2C0014E966 /* S4DVertex.h */, + 4C53E16E0A484C2C0014E966 /* SoftwareDriver2_compile_config.h */, + 4C53E16F0A484C2C0014E966 /* SoftwareDriver2_helper.h */, + 5DD4804C0C7D91DF00728AA9 /* CDepthBuffer.cpp */, + 0910B9D90D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp */, + 5DD480500C7D936700728AA9 /* IBurningShader.cpp */, + 5DD480510C7D936700728AA9 /* IBurningShader.h */, + 5DD4804D0C7D91DF00728AA9 /* CDepthBuffer.h */, + 4C53DFC20A484C240014E966 /* CSoftwareDriver2.cpp */, + 4C53DFC30A484C240014E966 /* CSoftwareDriver2.h */, + 4C53DFC60A484C240014E966 /* CSoftwareTexture2.cpp */, + 4C53DFC70A484C240014E966 /* CSoftwareTexture2.h */, + ); + name = "Burning Video"; + sourceTree = ""; + }; + 0910BA8D0D1F72DB00D46B04 /* Direct3D8 */ = { + isa = PBXGroup; + children = ( + 4C53DF020A484C220014E966 /* CD3D8Driver.cpp */, + 4C53DF030A484C220014E966 /* CD3D8Driver.h */, + 4C53DF040A484C220014E966 /* CD3D8MaterialRenderer.h */, + 4C53DF050A484C220014E966 /* CD3D8NormalMapRenderer.cpp */, + 4C53DF060A484C220014E966 /* CD3D8NormalMapRenderer.h */, + 4C53DF070A484C230014E966 /* CD3D8ParallaxMapRenderer.cpp */, + 4C53DF080A484C230014E966 /* CD3D8ParallaxMapRenderer.h */, + 4C53DF090A484C230014E966 /* CD3D8ShaderMaterialRenderer.cpp */, + 4C53DF0A0A484C230014E966 /* CD3D8ShaderMaterialRenderer.h */, + 4C53DF0B0A484C230014E966 /* CD3D8Texture.cpp */, + 4C53DF0C0A484C230014E966 /* CD3D8Texture.h */, + ); + name = Direct3D8; + sourceTree = ""; + }; + 0910BA8E0D1F72FB00D46B04 /* Direct3D9 */ = { + isa = PBXGroup; + children = ( + 4C53DF0D0A484C230014E966 /* CD3D9Driver.cpp */, + 4C53DF0E0A484C230014E966 /* CD3D9Driver.h */, + 4C53DF0F0A484C230014E966 /* CD3D9HLSLMaterialRenderer.cpp */, + 4C53DF100A484C230014E966 /* CD3D9HLSLMaterialRenderer.h */, + 4C53DF110A484C230014E966 /* CD3D9MaterialRenderer.h */, + 4C53DF120A484C230014E966 /* CD3D9NormalMapRenderer.cpp */, + 4C53DF130A484C230014E966 /* CD3D9NormalMapRenderer.h */, + 4C53DF140A484C230014E966 /* CD3D9ParallaxMapRenderer.cpp */, + 4C53DF150A484C230014E966 /* CD3D9ParallaxMapRenderer.h */, + 4C53DF160A484C230014E966 /* CD3D9ShaderMaterialRenderer.cpp */, + 4C53DF170A484C230014E966 /* CD3D9ShaderMaterialRenderer.h */, + 4C53DF180A484C230014E966 /* CD3D9Texture.cpp */, + 4C53DF190A484C230014E966 /* CD3D9Texture.h */, + ); + name = Direct3D9; + sourceTree = ""; + }; + 0910BA8F0D1F731900D46B04 /* Null */ = { + isa = PBXGroup; + children = ( + 34EF91900F65F9AD000B5651 /* loader */, + 0910BA900D1F733100D46B04 /* writer */, + 4C53DEFC0A484C220014E966 /* CColorConverter.cpp */, + 4C53DEFD0A484C220014E966 /* CColorConverter.h */, + 4C53DF2A0A484C230014E966 /* CFPSCounter.cpp */, + 4C53DF2B0A484C230014E966 /* CFPSCounter.h */, + 4C53DF580A484C230014E966 /* CImage.cpp */, + 4C53DF590A484C230014E966 /* CImage.h */, + 4C53DF820A484C240014E966 /* CNullDriver.cpp */, + 4C53DF830A484C240014E966 /* CNullDriver.h */, + 4C53E0090A484C250014E966 /* IImagePresenter.h */, + ); + name = Null; + sourceTree = ""; + }; + 0910BA900D1F733100D46B04 /* writer */ = { + isa = PBXGroup; + children = ( + 4CFA7BDE0A88735900B03626 /* CImageWriterBMP.cpp */, + 4CFA7BDF0A88735900B03626 /* CImageWriterBMP.h */, + 4CFA7BE00A88735900B03626 /* CImageWriterJPG.cpp */, + 4CFA7BE10A88735900B03626 /* CImageWriterJPG.h */, + 4CFA7BE20A88735900B03626 /* CImageWriterPCX.cpp */, + 4CFA7BE30A88735900B03626 /* CImageWriterPCX.h */, + 4CFA7BE40A88735900B03626 /* CImageWriterPNG.cpp */, + 4CFA7BE50A88735900B03626 /* CImageWriterPNG.h */, + 4CFA7BE60A88735900B03626 /* CImageWriterPPM.cpp */, + 4CFA7BE70A88735900B03626 /* CImageWriterPPM.h */, + 4CFA7BE80A88735900B03626 /* CImageWriterPSD.cpp */, + 4CFA7BE90A88735900B03626 /* CImageWriterPSD.h */, + 4CFA7BEA0A88735900B03626 /* CImageWriterTGA.cpp */, + 4CFA7BEB0A88735900B03626 /* CImageWriterTGA.h */, + ); + name = writer; + sourceTree = ""; + }; + 0910BA910D1F738100D46B04 /* OpenGL */ = { + isa = PBXGroup; + children = ( + 5DD480700C7D94AC00728AA9 /* glxext.h */, + 4C53E0070A484C250014E966 /* glext.h */, + 5DD480C10C7DA66800728AA9 /* COpenGLExtensionHandler.h */, + 5DD480C50C7DA66800728AA9 /* COpenGLExtensionHandler.cpp */, + 4C53DF8C0A484C240014E966 /* COpenGLDriver.cpp */, + 4C53DF8D0A484C240014E966 /* COpenGLDriver.h */, + 4C53DF8E0A484C240014E966 /* COpenGLMaterialRenderer.h */, + 4C53DF8F0A484C240014E966 /* COpenGLNormalMapRenderer.cpp */, + 4C53DF900A484C240014E966 /* COpenGLNormalMapRenderer.h */, + 4C53DF910A484C240014E966 /* COpenGLParallaxMapRenderer.cpp */, + 4C53DF920A484C240014E966 /* COpenGLParallaxMapRenderer.h */, + 4C53DF930A484C240014E966 /* COpenGLShaderMaterialRenderer.cpp */, + 4C53DF940A484C240014E966 /* COpenGLShaderMaterialRenderer.h */, + 4C53DF950A484C240014E966 /* COpenGLSLMaterialRenderer.cpp */, + 4C53DF960A484C240014E966 /* COpenGLSLMaterialRenderer.h */, + 4C53DF970A484C240014E966 /* COpenGLTexture.cpp */, + 4C53DF980A484C240014E966 /* COpenGLTexture.h */, + ); + name = OpenGL; + sourceTree = ""; + }; + 0910BA920D1F73CC00D46B04 /* Software */ = { + isa = PBXGroup; + children = ( + 4C53DFBF0A484C240014E966 /* CSoftware2MaterialRenderer.h */, + 4C53DFC00A484C240014E966 /* CSoftwareDriver.cpp */, + 4C53DFC10A484C240014E966 /* CSoftwareDriver.h */, + 4C53DFC40A484C240014E966 /* CSoftwareTexture.cpp */, + 4C53DFC50A484C240014E966 /* CSoftwareTexture.h */, + 4C53DFFF0A484C250014E966 /* CZBuffer.cpp */, + 4C53E0000A484C250014E966 /* CZBuffer.h */, + 5DD480540C7D93AB00728AA9 /* IDepthBuffer.h */, + 4C53E00F0A484C250014E966 /* ITriangleRenderer.h */, + 5DD4806C0C7D94AC00728AA9 /* CTRTextureBlend.cpp */, + 5DD4806D0C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp */, + 5DD4806E0C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp */, + 5DD4806F0C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp */, + 4C53E0110A484C250014E966 /* IZBuffer.h */, + 4C53E16C0A484C2C0014E966 /* S2DVertex.h */, + 4C53DFD10A484C240014E966 /* CTRFlat.cpp */, + 4C53DFD20A484C240014E966 /* CTRFlatWire.cpp */, + 4C53DFD30A484C240014E966 /* CTRGouraud.cpp */, + 4C53DFD40A484C240014E966 /* CTRGouraud2.cpp */, + 4C53DFD50A484C240014E966 /* CTRGouraudAlpha2.cpp */, + 4C53DFD60A484C240014E966 /* CTRGouraudAlphaNoZ2.cpp */, + 4C53DFD70A484C240014E966 /* CTRGouraudWire.cpp */, + 4C53DFDC0A484C250014E966 /* CTRTextureDetailMap2.cpp */, + 4C53DFDD0A484C250014E966 /* CTRTextureFlat.cpp */, + 4C53DFDE0A484C250014E966 /* CTRTextureFlatWire.cpp */, + 4C53DFDF0A484C250014E966 /* CTRTextureGouraud.cpp */, + 4C53DFE00A484C250014E966 /* CTRTextureGouraud.h */, + 4C53DFE10A484C250014E966 /* CTRTextureGouraud2.cpp */, + 4C53DFE20A484C250014E966 /* CTRTextureGouraudAdd.cpp */, + 4C53DFE30A484C250014E966 /* CTRTextureGouraudAdd2.cpp */, + 4C53DFE40A484C250014E966 /* CTRTextureGouraudAddNoZ2.cpp */, + 4C53DFE50A484C250014E966 /* CTRTextureGouraudNoZ.cpp */, + 4C53DFE60A484C250014E966 /* CTRTextureGouraudNoZ2.cpp */, + 4C53DFE70A484C250014E966 /* CTRTextureGouraudVertexAlpha2.cpp */, + 4C53DFE80A484C250014E966 /* CTRTextureGouraudWire.cpp */, + 4C53DFE90A484C250014E966 /* CTRTextureLightMap2_Add.cpp */, + 4C53DFEA0A484C250014E966 /* CTRTextureLightMap2_M1.cpp */, + 4C53DFEB0A484C250014E966 /* CTRTextureLightMap2_M2.cpp */, + 4C53DFEC0A484C250014E966 /* CTRTextureLightMap2_M4.cpp */, + 4C53DFED0A484C250014E966 /* CTRTextureWire2.cpp */, + ); + name = Software; + sourceTree = ""; + }; + 09293C2B0ED31FF8003B8C9C /* libpng */ = { + isa = PBXGroup; + children = ( + 09293C2C0ED32029003B8C9C /* png.c */, + 09293C2D0ED32029003B8C9C /* pngerror.c */, + 09293C2F0ED32029003B8C9C /* pngget.c */, + 09293C300ED32029003B8C9C /* pngmem.c */, + 09293C310ED32029003B8C9C /* pngpread.c */, + 09293C320ED32029003B8C9C /* pngread.c */, + 09293C330ED32029003B8C9C /* pngrio.c */, + 09293C340ED32029003B8C9C /* pngrtran.c */, + 09293C350ED32029003B8C9C /* pngrutil.c */, + 09293C360ED32029003B8C9C /* pngset.c */, + 09293C380ED32029003B8C9C /* pngtrans.c */, + 09293C3A0ED32029003B8C9C /* pngwio.c */, + 09293C3B0ED32029003B8C9C /* pngwrite.c */, + 09293C3C0ED32029003B8C9C /* pngwtran.c */, + 09293C3D0ED32029003B8C9C /* pngwutil.c */, + ); + name = libpng; + sourceTree = ""; + }; + 0946CC980EC99B8B00D945A5 /* 19.MouseAndJoystick */ = { + isa = PBXGroup; + children = ( + 0946CCCA0EC99C6E00D945A5 /* main.cpp */, + ); + name = 19.MouseAndJoystick; + sourceTree = ""; + }; + 09F6492D0D2CE017001E0599 /* 15.LoadIrrFile */ = { + isa = PBXGroup; + children = ( + 09F6492E0D2CE038001E0599 /* main.cpp */, + ); + name = 15.LoadIrrFile; + sourceTree = ""; + }; + 09F649530D2CE1EB001E0599 /* 16.Quake3Shader */ = { + isa = PBXGroup; + children = ( + 09F649730D2CE2D0001E0599 /* main.cpp */, + ); + name = 16.Quake3Shader; + sourceTree = ""; + }; + 0E2E3C621103B350002DE8D7 /* lzma */ = { + isa = PBXGroup; + children = ( + 0E2E3C631103B384002DE8D7 /* LzmaDec.c */, + ); + name = lzma; + sourceTree = ""; + }; + 0E2E3C651103B388002DE8D7 /* bzip2 */ = { + isa = PBXGroup; + children = ( + 0E2E3C7B1103B4E1002DE8D7 /* bzlib.c */, + 0E2E3C661103B3B9002DE8D7 /* blocksort.c */, + 0E2E3C671103B3B9002DE8D7 /* bzcompress.c */, + 0E2E3C6A1103B3B9002DE8D7 /* crctable.c */, + 0E2E3C6B1103B3B9002DE8D7 /* decompress.c */, + 0E2E3C6C1103B3B9002DE8D7 /* huffman.c */, + 0E2E3C6E1103B3B9002DE8D7 /* randtable.c */, + ); + name = bzip2; + sourceTree = ""; + }; + 0E2E3C7D1103B4E6002DE8D7 /* aesGladman */ = { + isa = PBXGroup; + children = ( + 0E2E3C7E1103B53C002DE8D7 /* aescrypt.cpp */, + 0E2E3C7F1103B53C002DE8D7 /* aeskey.cpp */, + 0E2E3C801103B53C002DE8D7 /* aestab.cpp */, + 0E2E3C811103B53C002DE8D7 /* fileenc.cpp */, + 0E2E3C821103B53C002DE8D7 /* hmac.cpp */, + 0E2E3C831103B53C002DE8D7 /* prng.cpp */, + 0E2E3C841103B53C002DE8D7 /* pwd2key.cpp */, + 0E2E3C851103B53C002DE8D7 /* sha1.cpp */, + 0E2E3C861103B53C002DE8D7 /* sha2.cpp */, + ); + name = aesGladman; + sourceTree = ""; + }; + 0E2E3D671103E6C6002DE8D7 /* 18.SplitScreen */ = { + isa = PBXGroup; + children = ( + 0E2E3D681103E6C6002DE8D7 /* main.cpp */, + ); + path = 18.SplitScreen; + sourceTree = ""; + }; + 0E2E3D781103E6E4002DE8D7 /* 20.ManagedLights */ = { + isa = PBXGroup; + children = ( + 0E2E3D791103E6E4002DE8D7 /* main.cpp */, + ); + path = 20.ManagedLights; + sourceTree = ""; + }; + 0E2E3E1A1103F773002DE8D7 /* 21.Quake3Explorer */ = { + isa = PBXGroup; + children = ( + 0E2E3E1B1103F773002DE8D7 /* main.cpp */, + 0E2E3E1D1103F773002DE8D7 /* q3factory.cpp */, + 0E2E3E1E1103F773002DE8D7 /* q3factory.h */, + 0E2E3E261103F773002DE8D7 /* sound.cpp */, + 0E2E3E271103F773002DE8D7 /* sound.h */, + ); + path = 21.Quake3Explorer; + sourceTree = ""; + }; + 0E2E3E281103F773002DE8D7 /* 22.MaterialViewer */ = { + isa = PBXGroup; + children = ( + 0E2E3E291103F773002DE8D7 /* main.cpp */, + ); + path = 22.MaterialViewer; + sourceTree = ""; + }; + 0E2E3E311103F773002DE8D7 /* 23.SMeshHandling */ = { + isa = PBXGroup; + children = ( + 0E2E3E321103F773002DE8D7 /* main.cpp */, + ); + path = 23.SMeshHandling; + sourceTree = ""; + }; + 34EF91900F65F9AD000B5651 /* loader */ = { + isa = PBXGroup; + children = ( + 4CFA7BDC0A88735900B03626 /* CImageLoaderBMP.cpp */, + 4CFA7BDD0A88735900B03626 /* CImageLoaderBMP.h */, + 4C53DF5C0A484C230014E966 /* CImageLoaderJPG.cpp */, + 4C53DF5D0A484C230014E966 /* CImageLoaderJPG.h */, + 4C53DF5E0A484C230014E966 /* CImageLoaderPCX.cpp */, + 4C53DF5F0A484C230014E966 /* CImageLoaderPCX.h */, + 4C53DF600A484C230014E966 /* CImageLoaderPNG.cpp */, + 4C53DF610A484C230014E966 /* CImageLoaderPNG.h */, + 096840270D0F1A2300333EFD /* CImageLoaderPPM.cpp */, + 096840280D0F1A2300333EFD /* CImageLoaderPPM.h */, + 4C53DF620A484C230014E966 /* CImageLoaderPSD.cpp */, + 4C53DF630A484C230014E966 /* CImageLoaderPSD.h */, + 34EF91D00F65FCA6000B5651 /* CImageLoaderRGB.h */, + 34EF91D10F65FCA6000B5651 /* CImageLoaderRGB.cpp */, + 4C53DF640A484C230014E966 /* CImageLoaderTGA.cpp */, + 4C53DF650A484C230014E966 /* CImageLoaderTGA.h */, + 0910B9DC0D1F5D4100D46B04 /* CImageLoaderWAL.cpp */, + 0910B9DD0D1F5D4100D46B04 /* CImageLoaderWAL.h */, + ); + name = loader; + sourceTree = ""; + }; + 34FFD9C50F6600A900420884 /* libraries */ = { + isa = PBXGroup; + children = ( + 0E2E3C7D1103B4E6002DE8D7 /* aesGladman */, + 0E2E3C651103B388002DE8D7 /* bzip2 */, + 0E2E3C621103B350002DE8D7 /* lzma */, + 4C53E1710A484C2C0014E966 /* zlib */, + 4C53E0130A484C250014E966 /* jpeglib */, + 09293C2B0ED31FF8003B8C9C /* libpng */, + ); + name = libraries; + sourceTree = ""; + }; + 34FFD9C60F6600DA00420884 /* device */ = { + isa = PBXGroup; + children = ( + 4C53E14A0A484C2C0014E966 /* MacOSX */, + 0E2E3C571103B2AE002DE8D7 /* CIrrDeviceFB.cpp */, + 0E2E3C581103B2AE002DE8D7 /* CIrrDeviceFB.h */, + 0E2E3C591103B2AE002DE8D7 /* CIrrDeviceWinCE.cpp */, + 0E2E3C5A1103B2AE002DE8D7 /* CIrrDeviceWinCE.h */, + 34EC243A0F59272E0037BC3A /* CIrrDeviceConsole.h */, + 34EC243B0F59272E0037BC3A /* CIrrDeviceConsole.cpp */, + 4C53DF660A484C230014E966 /* CIrrDeviceLinux.cpp */, + 4C53DF670A484C230014E966 /* CIrrDeviceLinux.h */, + 5DD480C40C7DA66800728AA9 /* CIrrDeviceSDL.cpp */, + 5DD480C30C7DA66800728AA9 /* CIrrDeviceSDL.h */, + 4C53DF680A484C230014E966 /* CIrrDeviceStub.cpp */, + 4C53DF690A484C230014E966 /* CIrrDeviceStub.h */, + 4C53DF6A0A484C230014E966 /* CIrrDeviceWin32.cpp */, + 4C53DF6B0A484C230014E966 /* CIrrDeviceWin32.h */, + ); + name = device; + sourceTree = ""; + }; + 34FFD9C70F66011C00420884 /* archive */ = { + isa = PBXGroup; + children = ( + 0E2E3C531103B27D002DE8D7 /* CNPKReader.cpp */, + 0E2E3C541103B27D002DE8D7 /* CNPKReader.h */, + 344FD4A41039E98C0045FD3F /* CMountPointReader.cpp */, + 344FD4A51039E98C0045FD3F /* CMountPointReader.h */, + 3430E4D41022C391006271FD /* CTarReader.h */, + 3430E4D51022C391006271FD /* CTarReader.cpp */, + 4C53E0030A484C250014E966 /* CZipReader.cpp */, + 4C53E0040A484C250014E966 /* CZipReader.h */, + 4C43EEBE0A74A5C800F942FC /* CPakReader.cpp */, + 4C43EEBF0A74A5C800F942FC /* CPakReader.h */, + ); + name = archive; + sourceTree = ""; + }; + 34FFD9C80F66012D00420884 /* attributes */ = { + isa = PBXGroup; + children = ( + 4C53DEEF0A484C220014E966 /* CAttributeImpl.h */, + 4C53DEF00A484C220014E966 /* CAttributes.cpp */, + 4C53DEF10A484C220014E966 /* CAttributes.h */, + ); + name = attributes; + sourceTree = ""; + }; + 34FFD9C90F66014200420884 /* file */ = { + isa = PBXGroup; + children = ( + 4C53DFA70A484C240014E966 /* CReadFile.cpp */, + 4C53DFA80A484C240014E966 /* CReadFile.h */, + 4C53DFF20A484C250014E966 /* CWriteFile.cpp */, + 4C53DFF30A484C250014E966 /* CWriteFile.h */, + 4C53DF6E0A484C230014E966 /* CLimitReadFile.cpp */, + 4C53DF6F0A484C230014E966 /* CLimitReadFile.h */, + 3484C4FB0F48D4CB00C81F60 /* CMemoryFile.h */, + 3484C4FC0F48D4CB00C81F60 /* CMemoryFile.cpp */, + ); + name = file; + sourceTree = ""; + }; + 34FFD9CA0F66018500420884 /* xml */ = { + isa = PBXGroup; + children = ( + 4C53DFFA0A484C250014E966 /* CXMLReader.cpp */, + 4C53DFFB0A484C250014E966 /* CXMLReader.h */, + 4C53DFFC0A484C250014E966 /* CXMLReaderImpl.h */, + 4C53DFFD0A484C250014E966 /* CXMLWriter.cpp */, + 4C53DFFE0A484C250014E966 /* CXMLWriter.h */, + 4C53E00E0A484C250014E966 /* irrXML.cpp */, + ); + name = xml; + sourceTree = ""; + }; + 34FFD9CB0F6601AC00420884 /* element */ = { + isa = PBXGroup; + children = ( + 4C53DF2E0A484C230014E966 /* CGUIButton.cpp */, + 4C53DF2F0A484C230014E966 /* CGUIButton.h */, + 4C53DF300A484C230014E966 /* CGUICheckBox.cpp */, + 4C53DF310A484C230014E966 /* CGUICheckBox.h */, + 5DD4805E0C7D947B00728AA9 /* CGUIColorSelectDialog.cpp */, + 5DD4805F0C7D947B00728AA9 /* CGUIColorSelectDialog.h */, + 4C53DF320A484C230014E966 /* CGUIComboBox.cpp */, + 4C53DF330A484C230014E966 /* CGUIComboBox.h */, + 4C53DF340A484C230014E966 /* CGUIContextMenu.cpp */, + 4C53DF350A484C230014E966 /* CGUIContextMenu.h */, + 4C53DF360A484C230014E966 /* CGUIEditBox.cpp */, + 4C53DF370A484C230014E966 /* CGUIEditBox.h */, + 4C53DF380A484C230014E966 /* CGUIEnvironment.cpp */, + 4C53DF390A484C230014E966 /* CGUIEnvironment.h */, + 4C53DF3A0A484C230014E966 /* CGUIFileOpenDialog.cpp */, + 4C53DF3B0A484C230014E966 /* CGUIFileOpenDialog.h */, + 4C53DF3E0A484C230014E966 /* CGUIImage.cpp */, + 4C53DF3F0A484C230014E966 /* CGUIImage.h */, + 3484C4DF0F48D1B000C81F60 /* CGUIImageList.h */, + 3484C4E00F48D1B000C81F60 /* CGUIImageList.cpp */, + 4C53DF400A484C230014E966 /* CGUIInOutFader.cpp */, + 4C53DF410A484C230014E966 /* CGUIInOutFader.h */, + 4C53DF420A484C230014E966 /* CGUIListBox.cpp */, + 4C53DF430A484C230014E966 /* CGUIListBox.h */, + 4C53DF440A484C230014E966 /* CGUIMenu.cpp */, + 4C53DF450A484C230014E966 /* CGUIMenu.h */, + 4C53DF460A484C230014E966 /* CGUIMeshViewer.cpp */, + 4C53DF470A484C230014E966 /* CGUIMeshViewer.h */, + 4C53DF480A484C230014E966 /* CGUIMessageBox.cpp */, + 4C53DF490A484C230014E966 /* CGUIMessageBox.h */, + 4C53DF4A0A484C230014E966 /* CGUIModalScreen.cpp */, + 4C53DF4B0A484C230014E966 /* CGUIModalScreen.h */, + 4C53DF4C0A484C230014E966 /* CGUIScrollBar.cpp */, + 4C53DF4D0A484C230014E966 /* CGUIScrollBar.h */, + 5DD480600C7D947B00728AA9 /* CGUISpinBox.cpp */, + 5DD480610C7D947B00728AA9 /* CGUISpinBox.h */, + 4C53DF500A484C230014E966 /* CGUIStaticText.cpp */, + 4C53DF510A484C230014E966 /* CGUIStaticText.h */, + 4C53DF520A484C230014E966 /* CGUITabControl.cpp */, + 4C53DF530A484C230014E966 /* CGUITabControl.h */, + 0910B9DA0D1F5D4100D46B04 /* CGUITable.cpp */, + 0910B9DB0D1F5D4100D46B04 /* CGUITable.h */, + 4C53DF540A484C230014E966 /* CGUIToolBar.cpp */, + 4C53DF550A484C230014E966 /* CGUIToolBar.h */, + 3484C4EC0F48D3A100C81F60 /* CGUITreeView.h */, + 3484C4ED0F48D3A100C81F60 /* CGUITreeView.cpp */, + 4C53DF560A484C230014E966 /* CGUIWindow.cpp */, + 4C53DF570A484C230014E966 /* CGUIWindow.h */, + ); + name = element; + sourceTree = ""; + }; + 4C00546D0A48470500C844C2 /* examples */ = { + isa = PBXGroup; + children = ( + 4C00546E0A48470500C844C2 /* 01.HelloWorld */, + 4C0054740A48470500C844C2 /* 02.Quake3Map */, + 4C00547A0A48470500C844C2 /* 03.CustomSceneNode */, + 4C0054800A48470500C844C2 /* 04.Movement */, + 4C0054860A48470500C844C2 /* 05.UserInterface */, + 4C00548C0A48470500C844C2 /* 06.2DGraphics */, + 4C0054920A48470500C844C2 /* 07.Collision */, + 4C0054980A48470500C844C2 /* 08.SpecialFX */, + 4C00549E0A48470500C844C2 /* 09.Meshviewer */, + 4C0054A70A48470500C844C2 /* 10.Shaders */, + 4C0054AD0A48470500C844C2 /* 11.PerPixelLighting */, + 4C0054B30A48470500C844C2 /* 12.TerrainRendering */, + 4C0054B90A48470500C844C2 /* 13.RenderToTexture */, + 09F6492D0D2CE017001E0599 /* 15.LoadIrrFile */, + 09F649530D2CE1EB001E0599 /* 16.Quake3Shader */, + 0E2E3D671103E6C6002DE8D7 /* 18.SplitScreen */, + 0946CC980EC99B8B00D945A5 /* 19.MouseAndJoystick */, + 0E2E3D781103E6E4002DE8D7 /* 20.ManagedLights */, + 0E2E3E1A1103F773002DE8D7 /* 21.Quake3Explorer */, + 0E2E3E281103F773002DE8D7 /* 22.MaterialViewer */, + 0E2E3E311103F773002DE8D7 /* 23.SMeshHandling */, + 4C0054C40A48470500C844C2 /* Demo */, + ); + name = examples; + path = ../../../examples; + sourceTree = SOURCE_ROOT; + }; + 4C00546E0A48470500C844C2 /* 01.HelloWorld */ = { + isa = PBXGroup; + children = ( + 4C0054710A48470500C844C2 /* main.cpp */, + ); + path = 01.HelloWorld; + sourceTree = ""; + }; + 4C0054740A48470500C844C2 /* 02.Quake3Map */ = { + isa = PBXGroup; + children = ( + 4C0054770A48470500C844C2 /* main.cpp */, + ); + path = 02.Quake3Map; + sourceTree = ""; + }; + 4C00547A0A48470500C844C2 /* 03.CustomSceneNode */ = { + isa = PBXGroup; + children = ( + 4C00547D0A48470500C844C2 /* main.cpp */, + ); + path = 03.CustomSceneNode; + sourceTree = ""; + }; + 4C0054800A48470500C844C2 /* 04.Movement */ = { + isa = PBXGroup; + children = ( + 4C0054830A48470500C844C2 /* main.cpp */, + ); + path = 04.Movement; + sourceTree = ""; + }; + 4C0054860A48470500C844C2 /* 05.UserInterface */ = { + isa = PBXGroup; + children = ( + 4C0054890A48470500C844C2 /* main.cpp */, + ); + path = 05.UserInterface; + sourceTree = ""; + }; + 4C00548C0A48470500C844C2 /* 06.2DGraphics */ = { + isa = PBXGroup; + children = ( + 4C00548F0A48470500C844C2 /* main.cpp */, + ); + path = 06.2DGraphics; + sourceTree = ""; + }; + 4C0054920A48470500C844C2 /* 07.Collision */ = { + isa = PBXGroup; + children = ( + 4C0054950A48470500C844C2 /* main.cpp */, + ); + path = 07.Collision; + sourceTree = ""; + }; + 4C0054980A48470500C844C2 /* 08.SpecialFX */ = { + isa = PBXGroup; + children = ( + 4C00549B0A48470500C844C2 /* main.cpp */, + ); + path = 08.SpecialFX; + sourceTree = ""; + }; + 4C00549E0A48470500C844C2 /* 09.Meshviewer */ = { + isa = PBXGroup; + children = ( + 4C0054A30A48470500C844C2 /* main.cpp */, + ); + path = 09.Meshviewer; + sourceTree = ""; + }; + 4C0054A70A48470500C844C2 /* 10.Shaders */ = { + isa = PBXGroup; + children = ( + 4C0054AA0A48470500C844C2 /* main.cpp */, + ); + path = 10.Shaders; + sourceTree = ""; + }; + 4C0054AD0A48470500C844C2 /* 11.PerPixelLighting */ = { + isa = PBXGroup; + children = ( + 4C0054B00A48470500C844C2 /* main.cpp */, + ); + path = 11.PerPixelLighting; + sourceTree = ""; + }; + 4C0054B30A48470500C844C2 /* 12.TerrainRendering */ = { + isa = PBXGroup; + children = ( + 4C0054B60A48470500C844C2 /* main.cpp */, + ); + path = 12.TerrainRendering; + sourceTree = ""; + }; + 4C0054B90A48470500C844C2 /* 13.RenderToTexture */ = { + isa = PBXGroup; + children = ( + 4C0054BC0A48470500C844C2 /* main.cpp */, + ); + path = 13.RenderToTexture; + sourceTree = ""; + }; + 4C0054C40A48470500C844C2 /* Demo */ = { + isa = PBXGroup; + children = ( + 4C0054C50A48470500C844C2 /* CDemo.cpp */, + 4C0054C60A48470500C844C2 /* CDemo.h */, + 4C0054C70A48470500C844C2 /* CMainMenu.cpp */, + 4C0054C80A48470500C844C2 /* CMainMenu.h */, + 4C0054CA0A48470500C844C2 /* main.cpp */, + ); + path = Demo; + sourceTree = ""; + }; + 4C53DEE50A484C220014E966 /* Irrlicht */ = { + isa = PBXGroup; + children = ( + 34FFD9C50F6600A900420884 /* libraries */, + 4C6DC9960A486B110017A6E5 /* Engine */, + ); + name = Irrlicht; + path = ..; + sourceTree = SOURCE_ROOT; + }; + 4C53E0130A484C250014E966 /* jpeglib */ = { + isa = PBXGroup; + children = ( + 0E2E3C431103B1B5002DE8D7 /* jaricom.c */, + 0E2E3C441103B1B5002DE8D7 /* jcarith.c */, + 0E2E3C451103B1B5002DE8D7 /* jdarith.c */, + 4C53E6F10A485CD80014E966 /* jcapimin.c */, + 4C53E6F20A485CD80014E966 /* jcapistd.c */, + 95E9D50210F42F9A008546FE /* jcarith.c */, + 4C53E6F30A485CD80014E966 /* jccoefct.c */, + 4C53E6F40A485CD80014E966 /* jccolor.c */, + 4C53E6F50A485CD80014E966 /* jcdctmgr.c */, + 4C53E6F60A485CD80014E966 /* jchuff.c */, + 4C53E6F80A485CD80014E966 /* jcinit.c */, + 4C53E6F90A485CD80014E966 /* jcmainct.c */, + 4C53E6FA0A485CD80014E966 /* jcmarker.c */, + 4C53E6FB0A485CD80014E966 /* jcmaster.c */, + 4C53E6FC0A485CD80014E966 /* jcomapi.c */, + 4C53E70A0A485CD80014E966 /* jcparam.c */, + 4C53E70C0A485CD80014E966 /* jcprepct.c */, + 4C53E70D0A485CD80014E966 /* jcsample.c */, + 4C53E70E0A485CD80014E966 /* jctrans.c */, + 4C53E70F0A485CD80014E966 /* jdapimin.c */, + 95E9D50A10F43011008546FE /* jaricom.c */, + 4C53E7100A485CD80014E966 /* jdapistd.c */, + 95E9D50610F42FDF008546FE /* jdarith.c */, + 4C53E7110A485CD80014E966 /* jdatadst.c */, + 4C53E7120A485CD80014E966 /* jdatasrc.c */, + 4C53E7130A485CD80014E966 /* jdcoefct.c */, + 4C53E7140A485CD80014E966 /* jdcolor.c */, + 4C53E7160A485CD80014E966 /* jddctmgr.c */, + 4C53E7170A485CD80014E966 /* jdhuff.c */, + 4C53E7190A485CD80014E966 /* jdinput.c */, + 4C53E71A0A485CD80014E966 /* jdmainct.c */, + 4C53E71B0A485CD80014E966 /* jdmarker.c */, + 4C53E71C0A485CD80014E966 /* jdmaster.c */, + 4C53E71D0A485CD80014E966 /* jdmerge.c */, + 4C53E71F0A485CD80014E966 /* jdpostct.c */, + 4C53E7200A485CD80014E966 /* jdsample.c */, + 4C53E7210A485CD80014E966 /* jdtrans.c */, + 4C53E7220A485CD80014E966 /* jerror.c */, + 4C53E7240A485CD80014E966 /* jfdctflt.c */, + 4C53E7250A485CD80014E966 /* jfdctfst.c */, + 4C53E7260A485CD80014E966 /* jfdctint.c */, + 4C53E7270A485CD80014E966 /* jidctflt.c */, + 4C53E7280A485CD80014E966 /* jidctfst.c */, + 4C53E7290A485CD80014E966 /* jidctint.c */, + 4C53E7300A485CD80014E966 /* jmemmgr.c */, + 4C53E7320A485CD80014E966 /* jmemnobs.c */, + 4C53E7390A485CD80014E966 /* jquant1.c */, + 4C53E73A0A485CD80014E966 /* jquant2.c */, + 4C53E73B0A485CD80014E966 /* jutils.c */, + ); + path = jpeglib; + sourceTree = ""; + }; + 4C53E14A0A484C2C0014E966 /* MacOSX */ = { + isa = PBXGroup; + children = ( + 4C53E14C0A484C2C0014E966 /* AppDelegate.h */, + 4C53E14D0A484C2C0014E966 /* AppDelegate.mm */, + 4C53E14E0A484C2C0014E966 /* build */, + 4C53E15E0A484C2C0014E966 /* CIrrDeviceMacOSX.h */, + 4C53E15F0A484C2C0014E966 /* CIrrDeviceMacOSX.mm */, + 4C53E1640A484C2C0014E966 /* MacOSX_Prefix.pch */, + 4C53E1650A484C2C0014E966 /* MainMenu.nib */, + 4C53E1660A484C2C0014E966 /* OSXClipboard.h */, + 4C53E1670A484C2C0014E966 /* OSXClipboard.mm */, + ); + path = MacOSX; + sourceTree = ""; + }; + 4C53E14E0A484C2C0014E966 /* build */ = { + isa = PBXGroup; + children = ( + 4C53E14F0A484C2C0014E966 /* MacOSX.build */, + ); + path = build; + sourceTree = ""; + }; + 4C53E14F0A484C2C0014E966 /* MacOSX.build */ = { + isa = PBXGroup; + children = ( + 4C53E1500A484C2C0014E966 /* MacOSX.pbxindex */, + ); + path = MacOSX.build; + sourceTree = ""; + }; + 4C53E1500A484C2C0014E966 /* MacOSX.pbxindex */ = { + isa = PBXGroup; + children = ( + 4C53E1590A484C2C0014E966 /* strings.pbxstrings */, + ); + path = MacOSX.pbxindex; + sourceTree = ""; + }; + 4C53E1590A484C2C0014E966 /* strings.pbxstrings */ = { + isa = PBXGroup; + children = ( + ); + path = strings.pbxstrings; + sourceTree = ""; + }; + 4C53E1710A484C2C0014E966 /* zlib */ = { + isa = PBXGroup; + children = ( + 4C6DC9B60A48715A0017A6E5 /* inflate.c */, + 4C53E1720A484C2C0014E966 /* adler32.c */, + 4C53E1750A484C2C0014E966 /* compress.c */, + 4C53E1770A484C2C0014E966 /* crc32.c */, + 4C53E1790A484C2C0014E966 /* deflate.c */, + 4C53E1800A484C2C0014E966 /* inffast.c */, + 4C53E1850A484C2C0014E966 /* inftrees.c */, + 4C53E18B0A484C2C0014E966 /* trees.c */, + 4C53E18D0A484C2C0014E966 /* uncompr.c */, + 4C53E1920A484C2C0014E966 /* zutil.c */, + ); + path = zlib; + sourceTree = ""; + }; + 4C53E24C0A484FED0014E966 /* Products */ = { + isa = PBXGroup; + children = ( + 4C53E24D0A4850120014E966 /* libIrrlicht.a */, + 0946CCB40EC99BBE00D945A5 /* MouseAndJoystick_dbg.app */, + 09022C620EA0E97F00CD54EE /* GUIEditor_dbg.app */, + 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */, + 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */, + 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */, + 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */, + 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */, + 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */, + 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */, + 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */, + 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */, + 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */, + 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */, + 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */, + 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */, + 09F6493E0D2CE03E001E0599 /* LoadIrrFile_dbg.app */, + 09F649650D2CE206001E0599 /* Quake3Shader_dbg.app */, + 09F649030D2CDED9001E0599 /* HelloWorld_dbg.app */, + 0E2E3CFC1103E294002DE8D7 /* SplitScreen_dbg.app */, + 0E2E3D3C1103E3F4002DE8D7 /* ManagedLights_dbg.app */, + ); + name = Products; + sourceTree = ""; + }; + 4C53E2540A48505D0014E966 /* Libraries */ = { + isa = PBXGroup; + children = ( + 0930CE550EC39F4500D63866 /* IOKit.framework */, + 0925113D0D744ADE006784D9 /* Carbon.framework */, + 4C53E26D0A4850D60014E966 /* Cocoa.framework */, + 4C53E26E0A4850D60014E966 /* OpenGL.framework */, + ); + name = Libraries; + sourceTree = ""; + }; + 4C6DC9960A486B110017A6E5 /* Engine */ = { + isa = PBXGroup; + children = ( + 95E5858C12FCE388004946C6 /* CTRNormalMap.cpp */, + 95E5857512FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp */, + 95E5859112FCE3A1004946C6 /* CTRStencilShadow.cpp */, + 95E5857612FCE2CB004946C6 /* CAnimatedMeshHalfLife.h */, + 95E5857B12FCE2DE004946C6 /* CSceneLoaderIrr.cpp */, + 95E5859412FCE3F5004946C6 /* CSMFMeshFileLoader.cpp */, + 95E5857012FCE277004946C6 /* CWADReader.cpp */, + 0910BA810D1F6BB800D46B04 /* gui */, + 0910BA820D1F6C3900D46B04 /* io */, + 0910BA830D1F6CA600D46B04 /* irr */, + 0910BA840D1F6D0200D46B04 /* scene */, + 0910BA8B0D1F71D600D46B04 /* video */, + ); + name = Engine; + sourceTree = ""; + }; + 4CFA7C090A88742800B03626 /* include */ = { + isa = PBXGroup; + children = ( + 0910BA4E0D1F652100D46B04 /* core */, + 0910BA4D0D1F64D000D46B04 /* gui */, + 0910BA4F0D1F65A300D46B04 /* io */, + 0910BA500D1F660300D46B04 /* scene */, + 0910BA800D1F6ADA00D46B04 /* video */, + 0910BA1D0D1F64B300D46B04 /* IReferenceCounted.h */, + 4CFA7C0C0A88742800B03626 /* EDriverTypes.h */, + 4CFA7C1D0A88742900B03626 /* IEventReceiver.h */, + 4CFA7C420A88742900B03626 /* IOSOperator.h */, + 4CFA7C380A88742900B03626 /* ILogger.h */, + 4CFA7C4A0A88742900B03626 /* IrrCompileConfig.h */, + 4CFA7C4B0A88742900B03626 /* irrlicht.h */, + 4CFA7C4C0A88742900B03626 /* IrrlichtDevice.h */, + 4CFA7C740A88742900B03626 /* SIrrCreationParameters.h */, + ); + name = include; + path = ../../../include; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 959726F812C18FFB00BF73D3 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 95154774133CD9DA008D792F /* aabbox3d.h in Headers */, + 95154775133CD9DA008D792F /* CMeshBuffer.h in Headers */, + 95154776133CD9DA008D792F /* coreutil.h in Headers */, + 95154777133CD9DA008D792F /* dimension2d.h in Headers */, + 95154778133CD9DA008D792F /* ECullingTypes.h in Headers */, + 95154779133CD9DA008D792F /* EDebugSceneTypes.h in Headers */, + 9515477A133CD9DA008D792F /* EDriverFeatures.h in Headers */, + 9515477B133CD9DA008D792F /* EDriverTypes.h in Headers */, + 9515477C133CD9DA008D792F /* EGUIAlignment.h in Headers */, + 9515477D133CD9DA008D792F /* EGUIElementTypes.h in Headers */, + 9515477E133CD9DA008D792F /* EHardwareBufferFlags.h in Headers */, + 9515477F133CD9DA008D792F /* EMaterialFlags.h in Headers */, + 95154780133CD9DA008D792F /* EMaterialTypes.h in Headers */, + 95154781133CD9DA008D792F /* EMeshWriterEnums.h in Headers */, + 95154782133CD9DA008D792F /* EMessageBoxFlags.h in Headers */, + 95154783133CD9DA008D792F /* ESceneNodeAnimatorTypes.h in Headers */, + 95154784133CD9DA008D792F /* ESceneNodeTypes.h in Headers */, + 95154785133CD9DA008D792F /* ETerrainElements.h in Headers */, + 95154786133CD9DA008D792F /* heapsort.h in Headers */, + 95154787133CD9DA008D792F /* IAnimatedMesh.h in Headers */, + 95154788133CD9DA008D792F /* IAnimatedMeshMD2.h in Headers */, + 95154789133CD9DA008D792F /* IAnimatedMeshMD3.h in Headers */, + 9515478A133CD9DA008D792F /* IAnimatedMeshSceneNode.h in Headers */, + 9515478B133CD9DA008D792F /* IAttributeExchangingObject.h in Headers */, + 9515478C133CD9DA008D792F /* IAttributes.h in Headers */, + 9515478D133CD9DA008D792F /* IBillboardSceneNode.h in Headers */, + 9515478E133CD9DA008D792F /* IBoneSceneNode.h in Headers */, + 9515478F133CD9DA008D792F /* ICameraSceneNode.h in Headers */, + 95154790133CD9DA008D792F /* ICursorControl.h in Headers */, + 95154791133CD9DA008D792F /* IDummyTransformationSceneNode.h in Headers */, + 95154792133CD9DA008D792F /* IEventReceiver.h in Headers */, + 95154793133CD9DA008D792F /* IFileList.h in Headers */, + 95154794133CD9DA008D792F /* IFileSystem.h in Headers */, + 95154795133CD9DA008D792F /* IGPUProgrammingServices.h in Headers */, + 95154796133CD9DA008D792F /* IGUIButton.h in Headers */, + 95154797133CD9DA008D792F /* IGUICheckBox.h in Headers */, + 95154798133CD9DA008D792F /* IGUIColorSelectDialog.h in Headers */, + 95154799133CD9DA008D792F /* IGUIComboBox.h in Headers */, + 9515479A133CD9DA008D792F /* IGUIContextMenu.h in Headers */, + 9515479B133CD9DA008D792F /* IGUIEditBox.h in Headers */, + 9515479C133CD9DA008D792F /* IGUIElement.h in Headers */, + 9515479D133CD9DA008D792F /* IGUIElementFactory.h in Headers */, + 9515479E133CD9DA008D792F /* IGUIEnvironment.h in Headers */, + 9515479F133CD9DA008D792F /* IGUIFileOpenDialog.h in Headers */, + 951547A0133CD9DA008D792F /* IGUIFont.h in Headers */, + 951547A1133CD9DA008D792F /* IGUIFontBitmap.h in Headers */, + 951547A2133CD9DA008D792F /* IGUIImage.h in Headers */, + 951547A3133CD9DA008D792F /* IGUIInOutFader.h in Headers */, + 951547A4133CD9DA008D792F /* IGUIListBox.h in Headers */, + 951547A5133CD9DA008D792F /* IGUIMeshViewer.h in Headers */, + 951547A6133CD9DA008D792F /* IGUIScrollBar.h in Headers */, + 951547A7133CD9DA008D792F /* IGUISkin.h in Headers */, + 951547A8133CD9DA008D792F /* IGUISpinBox.h in Headers */, + 951547A9133CD9DA008D792F /* IGUISpriteBank.h in Headers */, + 951547AA133CD9DA008D792F /* IGUIStaticText.h in Headers */, + 951547AB133CD9DA008D792F /* IGUITabControl.h in Headers */, + 951547AC133CD9DA008D792F /* IGUITable.h in Headers */, + 951547AD133CD9DA008D792F /* IGUIToolbar.h in Headers */, + 951547AE133CD9DA008D792F /* IGUIWindow.h in Headers */, + 951547AF133CD9DA008D792F /* IImage.h in Headers */, + 951547B0133CD9DA008D792F /* IImageLoader.h in Headers */, + 951547B1133CD9DA008D792F /* IImageWriter.h in Headers */, + 951547B2133CD9DA008D792F /* ILightSceneNode.h in Headers */, + 951547B3133CD9DA008D792F /* ILogger.h in Headers */, + 951547B4133CD9DA008D792F /* IMaterialRenderer.h in Headers */, + 951547B5133CD9DA008D792F /* IMaterialRendererServices.h in Headers */, + 951547B6133CD9DA008D792F /* IMesh.h in Headers */, + 951547B7133CD9DA008D792F /* IMeshBuffer.h in Headers */, + 951547B8133CD9DA008D792F /* IMeshCache.h in Headers */, + 951547B9133CD9DA008D792F /* IMeshLoader.h in Headers */, + 951547BA133CD9DA008D792F /* IMeshManipulator.h in Headers */, + 951547BB133CD9DA008D792F /* IMeshSceneNode.h in Headers */, + 951547BC133CD9DA008D792F /* IMeshWriter.h in Headers */, + 951547BD133CD9DA008D792F /* IMetaTriangleSelector.h in Headers */, + 951547BE133CD9DA008D792F /* IOSOperator.h in Headers */, + 951547BF133CD9DA008D792F /* IParticleAffector.h in Headers */, + 951547C0133CD9DA008D792F /* IParticleAnimatedMeshSceneNodeEmitter.h in Headers */, + 951547C1133CD9DA008D792F /* IParticleAttractionAffector.h in Headers */, + 951547C2133CD9DA008D792F /* IParticleBoxEmitter.h in Headers */, + 951547C3133CD9DA008D792F /* IParticleCylinderEmitter.h in Headers */, + 951547C4133CD9DA008D792F /* IParticleEmitter.h in Headers */, + 951547C5133CD9DA008D792F /* IParticleFadeOutAffector.h in Headers */, + 951547C6133CD9DA008D792F /* IParticleGravityAffector.h in Headers */, + 951547C7133CD9DA008D792F /* IParticleMeshEmitter.h in Headers */, + 951547C8133CD9DA008D792F /* IParticleRingEmitter.h in Headers */, + 951547C9133CD9DA008D792F /* IParticleRotationAffector.h in Headers */, + 951547CA133CD9DA008D792F /* IParticleSphereEmitter.h in Headers */, + 951547CB133CD9DA008D792F /* IParticleSystemSceneNode.h in Headers */, + 951547CC133CD9DA008D792F /* IQ3LevelMesh.h in Headers */, + 951547CD133CD9DA008D792F /* IQ3Shader.h in Headers */, + 951547CE133CD9DA008D792F /* IReadFile.h in Headers */, + 951547CF133CD9DA008D792F /* IReferenceCounted.h in Headers */, + 951547D0133CD9DA008D792F /* irrAllocator.h in Headers */, + 951547D1133CD9DA008D792F /* irrArray.h in Headers */, + 951547D2133CD9DA008D792F /* IrrCompileConfig.h in Headers */, + 951547D3133CD9DA008D792F /* irrlicht.h in Headers */, + 951547D4133CD9DA008D792F /* IrrlichtDevice.h in Headers */, + 951547D5133CD9DA008D792F /* irrList.h in Headers */, + 951547D6133CD9DA008D792F /* irrMap.h in Headers */, + 951547D7133CD9DA008D792F /* irrMath.h in Headers */, + 951547D8133CD9DA008D792F /* irrString.h in Headers */, + 951547D9133CD9DA008D792F /* irrTypes.h in Headers */, + 951547DA133CD9DA008D792F /* irrXML.h in Headers */, + 951547DB133CD9DA008D792F /* ISceneCollisionManager.h in Headers */, + 951547DC133CD9DA008D792F /* ISceneManager.h in Headers */, + 951547DD133CD9DA008D792F /* ISceneNode.h in Headers */, + 951547DE133CD9DA008D792F /* ISceneNodeAnimator.h in Headers */, + 951547DF133CD9DA008D792F /* ISceneNodeAnimatorCollisionResponse.h in Headers */, + 951547E0133CD9DA008D792F /* ISceneNodeAnimatorFactory.h in Headers */, + 951547E1133CD9DA008D792F /* ISceneNodeFactory.h in Headers */, + 951547E2133CD9DA008D792F /* ISceneUserDataSerializer.h in Headers */, + 951547E3133CD9DA008D792F /* IShaderConstantSetCallBack.h in Headers */, + 951547E4133CD9DA008D792F /* IShadowVolumeSceneNode.h in Headers */, + 951547E5133CD9DA008D792F /* ISkinnedMesh.h in Headers */, + 951547E6133CD9DA008D792F /* ITerrainSceneNode.h in Headers */, + 951547E7133CD9DA008D792F /* ITextSceneNode.h in Headers */, + 951547E8133CD9DA008D792F /* ITexture.h in Headers */, + 951547E9133CD9DA008D792F /* ITimer.h in Headers */, + 951547EA133CD9DA008D792F /* ITriangleSelector.h in Headers */, + 951547EB133CD9DA008D792F /* IVideoDriver.h in Headers */, + 951547EC133CD9DA008D792F /* IVideoModeList.h in Headers */, + 951547ED133CD9DA008D792F /* IWriteFile.h in Headers */, + 951547EE133CD9DA008D792F /* IXMLReader.h in Headers */, + 951547EF133CD9DA008D792F /* IXMLWriter.h in Headers */, + 951547F0133CD9DA008D792F /* Keycodes.h in Headers */, + 951547F1133CD9DA008D792F /* line2d.h in Headers */, + 951547F2133CD9DA008D792F /* line3d.h in Headers */, + 951547F3133CD9DA008D792F /* matrix4.h in Headers */, + 951547F4133CD9DA008D792F /* plane3d.h in Headers */, + 951547F5133CD9DA008D792F /* position2d.h in Headers */, + 951547F6133CD9DA008D792F /* quaternion.h in Headers */, + 951547F7133CD9DA008D792F /* rect.h in Headers */, + 951547F8133CD9DA008D792F /* S3DVertex.h in Headers */, + 951547F9133CD9DA008D792F /* SAnimatedMesh.h in Headers */, + 951547FA133CD9DA008D792F /* SceneParameters.h in Headers */, + 951547FB133CD9DA008D792F /* SColor.h in Headers */, + 951547FC133CD9DA008D792F /* SExposedVideoData.h in Headers */, + 951547FD133CD9DA008D792F /* SIrrCreationParameters.h in Headers */, + 951547FE133CD9DA008D792F /* SKeyMap.h in Headers */, + 951547FF133CD9DA008D792F /* SLight.h in Headers */, + 95154800133CD9DA008D792F /* SMaterial.h in Headers */, + 95154801133CD9DA008D792F /* SMaterialLayer.h in Headers */, + 95154802133CD9DA008D792F /* SMesh.h in Headers */, + 95154803133CD9DA008D792F /* SMeshBuffer.h in Headers */, + 95154804133CD9DA008D792F /* SMeshBufferLightMap.h in Headers */, + 95154805133CD9DA008D792F /* SMeshBufferTangents.h in Headers */, + 95154806133CD9DA008D792F /* SParticle.h in Headers */, + 95154807133CD9DA008D792F /* SSharedMeshBuffer.h in Headers */, + 95154808133CD9DA008D792F /* SSkinMeshBuffer.h in Headers */, + 95154809133CD9DA008D792F /* SViewFrustum.h in Headers */, + 9515480A133CD9DA008D792F /* triangle3d.h in Headers */, + 9515480B133CD9DA008D792F /* vector2d.h in Headers */, + 9515480C133CD9DA008D792F /* vector3d.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC07A0554694100DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 5DD4804F0C7D91DF00728AA9 /* CDepthBuffer.h in Headers */, + 5DD480530C7D936700728AA9 /* IBurningShader.h in Headers */, + 5DD480550C7D93AB00728AA9 /* IDepthBuffer.h in Headers */, + 5DD4805B0C7D945800728AA9 /* CAnimatedMeshMD3.h in Headers */, + 5DD4805D0C7D945800728AA9 /* CDefaultGUIElementFactory.h in Headers */, + 5DD480650C7D947B00728AA9 /* CGUIColorSelectDialog.h in Headers */, + 5DD480670C7D947B00728AA9 /* CGUISpinBox.h in Headers */, + 5DD480690C7D947B00728AA9 /* CGUISpriteBank.h in Headers */, + 5DD480720C7D94AC00728AA9 /* CQuake3ShaderSceneNode.h in Headers */, + 5DD480770C7D94AC00728AA9 /* glxext.h in Headers */, + 5DD480C70C7DA66800728AA9 /* COpenGLExtensionHandler.h in Headers */, + 5DD480C80C7DA66800728AA9 /* CMD3MeshFileLoader.h in Headers */, + 5DD480C90C7DA66800728AA9 /* CIrrDeviceSDL.h in Headers */, + 096840480D0F1A2300333EFD /* CB3DMeshFileLoader.h in Headers */, + 0968404A0D0F1A2300333EFD /* CBoneSceneNode.h in Headers */, + 0968404C0D0F1A2300333EFD /* CBSPMeshFileLoader.h in Headers */, + 0968404F0D0F1A2300333EFD /* CColladaMeshWriter.h in Headers */, + 096840510D0F1A2300333EFD /* CImageLoaderPPM.h in Headers */, + 096840550D0F1A2300333EFD /* CIrrMeshFileLoader.h in Headers */, + 096840570D0F1A2300333EFD /* CIrrMeshWriter.h in Headers */, + 096840590D0F1A2300333EFD /* CMD2MeshFileLoader.h in Headers */, + 0968405B0D0F1A2300333EFD /* CMS3DMeshFileLoader.h in Headers */, + 0968405D0D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.h in Headers */, + 0968405F0D0F1A2300333EFD /* CParticleAttractionAffector.h in Headers */, + 096840610D0F1A2300333EFD /* CParticleCylinderEmitter.h in Headers */, + 096840630D0F1A2300333EFD /* CParticleMeshEmitter.h in Headers */, + 096840650D0F1A2300333EFD /* CParticleRingEmitter.h in Headers */, + 096840670D0F1A2300333EFD /* CParticleRotationAffector.h in Headers */, + 096840690D0F1A2300333EFD /* CParticleSphereEmitter.h in Headers */, + 0968406B0D0F1A2300333EFD /* CSkinnedMesh.h in Headers */, + 0968406D0D0F1A2300333EFD /* CSTLMeshFileLoader.h in Headers */, + 0968406F0D0F1A2300333EFD /* CSTLMeshWriter.h in Headers */, + 0910B9E00D1F5D4100D46B04 /* CGUITable.h in Headers */, + 0910B9E20D1F5D4100D46B04 /* CImageLoaderWAL.h in Headers */, + 0910BA240D1F64B300D46B04 /* CMeshBuffer.h in Headers */, + 0910BA250D1F64B300D46B04 /* coreutil.h in Headers */, + 0910BA260D1F64B300D46B04 /* ECullingTypes.h in Headers */, + 0910BA270D1F64B300D46B04 /* EDebugSceneTypes.h in Headers */, + 0910BA280D1F64B300D46B04 /* EDriverFeatures.h in Headers */, + 0910BA290D1F64B300D46B04 /* EGUIAlignment.h in Headers */, + 0910BA2A0D1F64B300D46B04 /* EHardwareBufferFlags.h in Headers */, + 0910BA2B0D1F64B300D46B04 /* EMaterialFlags.h in Headers */, + 0910BA2C0D1F64B300D46B04 /* EMaterialTypes.h in Headers */, + 0910BA2D0D1F64B300D46B04 /* EMeshWriterEnums.h in Headers */, + 0910BA2E0D1F64B300D46B04 /* EMessageBoxFlags.h in Headers */, + 0910BA2F0D1F64B300D46B04 /* ETerrainElements.h in Headers */, + 0910BA300D1F64B300D46B04 /* IAnimatedMeshMD3.h in Headers */, + 0910BA310D1F64B300D46B04 /* IBoneSceneNode.h in Headers */, + 0910BA320D1F64B300D46B04 /* IGUIColorSelectDialog.h in Headers */, + 0910BA330D1F64B300D46B04 /* IGUIElementFactory.h in Headers */, + 0910BA340D1F64B300D46B04 /* IGUIFontBitmap.h in Headers */, + 0910BA350D1F64B300D46B04 /* IGUISpinBox.h in Headers */, + 0910BA360D1F64B300D46B04 /* IGUISpriteBank.h in Headers */, + 0910BA370D1F64B300D46B04 /* IGUITable.h in Headers */, + 0910BA380D1F64B300D46B04 /* IMeshWriter.h in Headers */, + 0910BA390D1F64B300D46B04 /* IParticleAnimatedMeshSceneNodeEmitter.h in Headers */, + 0910BA3A0D1F64B300D46B04 /* IParticleAttractionAffector.h in Headers */, + 0910BA3B0D1F64B300D46B04 /* IParticleBoxEmitter.h in Headers */, + 0910BA3C0D1F64B300D46B04 /* IParticleCylinderEmitter.h in Headers */, + 0910BA3D0D1F64B300D46B04 /* IParticleFadeOutAffector.h in Headers */, + 0910BA3E0D1F64B300D46B04 /* IParticleGravityAffector.h in Headers */, + 0910BA3F0D1F64B300D46B04 /* IParticleMeshEmitter.h in Headers */, + 0910BA400D1F64B300D46B04 /* IParticleRingEmitter.h in Headers */, + 0910BA410D1F64B300D46B04 /* IParticleRotationAffector.h in Headers */, + 0910BA420D1F64B300D46B04 /* IParticleSphereEmitter.h in Headers */, + 0910BA430D1F64B300D46B04 /* IQ3Shader.h in Headers */, + 0910BA440D1F64B300D46B04 /* IReferenceCounted.h in Headers */, + 0910BA450D1F64B300D46B04 /* irrMap.h in Headers */, + 0910BA460D1F64B300D46B04 /* ISkinnedMesh.h in Headers */, + 0910BA470D1F64B300D46B04 /* SMaterialLayer.h in Headers */, + 0910BA480D1F64B300D46B04 /* SSharedMeshBuffer.h in Headers */, + 0910BA490D1F64B300D46B04 /* SSkinMeshBuffer.h in Headers */, + 0910BA4A0D1F64B300D46B04 /* SViewFrustum.h in Headers */, + 090FBC830D31085E0076D847 /* CVolumeLightSceneNode.h in Headers */, + 09C638730D4F1A69000B6A18 /* CLWOMeshFileLoader.h in Headers */, + 093973C10E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.h in Headers */, + 093973C30E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.h in Headers */, + 096F8E3E0EA2EFBA00907EC5 /* COBJMeshWriter.h in Headers */, + 096CC0E10ECE65B500C81DC7 /* CParticleScaleAffector.h in Headers */, + 3484C4E10F48D1B000C81F60 /* CGUIImageList.h in Headers */, + 3484C4EE0F48D3A100C81F60 /* CGUITreeView.h in Headers */, + 3484C4FD0F48D4CB00C81F60 /* CMemoryFile.h in Headers */, + 34EC243C0F59272E0037BC3A /* CIrrDeviceConsole.h in Headers */, + 34EF91D20F65FCA6000B5651 /* CImageLoaderRGB.h in Headers */, + 34EF91D70F65FCF6000B5651 /* CPLYMeshFileLoader.h in Headers */, + 34EF91DC0F65FD14000B5651 /* CPLYMeshWriter.h in Headers */, + 3430E4D61022C391006271FD /* CTarReader.h in Headers */, + 344FD4A71039E98C0045FD3F /* CMountPointReader.h in Headers */, + 0E2E3C4A1103B224002DE8D7 /* Octree.h in Headers */, + 0E2E3C4E1103B247002DE8D7 /* COctreeSceneNode.h in Headers */, + 0E2E3C521103B261002DE8D7 /* COctreeTriangleSelector.h in Headers */, + 0E2E3C561103B27D002DE8D7 /* CNPKReader.h in Headers */, + 0E2E3C5C1103B2AE002DE8D7 /* CIrrDeviceFB.h in Headers */, + 0E2E3C5E1103B2AE002DE8D7 /* CIrrDeviceWinCE.h in Headers */, + 95E5857812FCE2CB004946C6 /* CAnimatedMeshHalfLife.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 09022C520EA0E97F00CD54EE /* GUIEditor */ = { + isa = PBXNativeTarget; + buildConfigurationList = 09022C5F0EA0E97F00CD54EE /* Build configuration list for PBXNativeTarget "GUIEditor" */; + buildPhases = ( + 09022C550EA0E97F00CD54EE /* Resources */, + 09022C580EA0E97F00CD54EE /* Sources */, + 09022C5A0EA0E97F00CD54EE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 09022C530EA0E97F00CD54EE /* PBXTargetDependency */, + ); + name = GUIEditor; + productName = DemoApp; + productReference = 09022C620EA0E97F00CD54EE /* GUIEditor_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 0946CCA30EC99BBE00D945A5 /* 19.MouseAndJoystick */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0946CCB10EC99BBE00D945A5 /* Build configuration list for PBXNativeTarget "19.MouseAndJoystick" */; + buildPhases = ( + 0946CCA60EC99BBE00D945A5 /* Resources */, + 0946CCA90EC99BBE00D945A5 /* Sources */, + 0946CCAB0EC99BBE00D945A5 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 0946CCA40EC99BBE00D945A5 /* PBXTargetDependency */, + ); + name = 19.MouseAndJoystick; + productName = DemoApp; + productReference = 0946CCB40EC99BBE00D945A5 /* MouseAndJoystick_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 09F648F40D2CDED9001E0599 /* 01.HelloWorld */ = { + isa = PBXNativeTarget; + buildConfigurationList = 09F649000D2CDED9001E0599 /* Build configuration list for PBXNativeTarget "01.HelloWorld" */; + buildPhases = ( + 09F648F70D2CDED9001E0599 /* Resources */, + 09F648FA0D2CDED9001E0599 /* Sources */, + 09F648FC0D2CDED9001E0599 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 09F648F50D2CDED9001E0599 /* PBXTargetDependency */, + ); + name = 01.HelloWorld; + productName = DemoApp; + productReference = 09F649030D2CDED9001E0599 /* HelloWorld_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 09F6492F0D2CE03E001E0599 /* 15.LoadIrrFile */ = { + isa = PBXNativeTarget; + buildConfigurationList = 09F6493B0D2CE03E001E0599 /* Build configuration list for PBXNativeTarget "15.LoadIrrFile" */; + buildPhases = ( + 09F649320D2CE03E001E0599 /* Resources */, + 09F649350D2CE03E001E0599 /* Sources */, + 09F649370D2CE03E001E0599 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 09F649300D2CE03E001E0599 /* PBXTargetDependency */, + ); + name = 15.LoadIrrFile; + productName = DemoApp; + productReference = 09F6493E0D2CE03E001E0599 /* LoadIrrFile_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 09F649560D2CE206001E0599 /* 16.Quake3Shader */ = { + isa = PBXNativeTarget; + buildConfigurationList = 09F649620D2CE206001E0599 /* Build configuration list for PBXNativeTarget "16.Quake3Shader" */; + buildPhases = ( + 09F649590D2CE206001E0599 /* Resources */, + 09F6495C0D2CE206001E0599 /* Sources */, + 09F6495E0D2CE206001E0599 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 09F649570D2CE206001E0599 /* PBXTargetDependency */, + ); + name = 16.Quake3Shader; + productName = DemoApp; + productReference = 09F649650D2CE206001E0599 /* Quake3Shader_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 0E2E3CEB1103E294002DE8D7 /* 18.SplitScreen */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0E2E3CF91103E294002DE8D7 /* Build configuration list for PBXNativeTarget "18.SplitScreen" */; + buildPhases = ( + 0E2E3CEE1103E294002DE8D7 /* Resources */, + 0E2E3CF11103E294002DE8D7 /* Sources */, + 0E2E3CF31103E294002DE8D7 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 0E2E3CEC1103E294002DE8D7 /* PBXTargetDependency */, + ); + name = 18.SplitScreen; + productName = DemoApp; + productReference = 0E2E3CFC1103E294002DE8D7 /* SplitScreen_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 0E2E3D2C1103E3F4002DE8D7 /* 20.ManagedLights */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0E2E3D391103E3F4002DE8D7 /* Build configuration list for PBXNativeTarget "20.ManagedLights" */; + buildPhases = ( + 0E2E3D2F1103E3F4002DE8D7 /* Resources */, + 0E2E3D321103E3F4002DE8D7 /* Sources */, + 0E2E3D331103E3F4002DE8D7 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 0E2E3D2D1103E3F4002DE8D7 /* PBXTargetDependency */, + ); + name = 20.ManagedLights; + productName = DemoApp; + productReference = 0E2E3D3C1103E3F4002DE8D7 /* ManagedLights_dbg.app */; + productType = "com.apple.product-type.application"; + }; + 959726FC12C18FFB00BF73D3 /* IrrFramework */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9597270112C18FFD00BF73D3 /* Build configuration list for PBXNativeTarget "IrrFramework" */; + buildPhases = ( + 959726F812C18FFB00BF73D3 /* Headers */, + 959726F912C18FFB00BF73D3 /* Resources */, + 959726FA12C18FFB00BF73D3 /* Sources */, + 959726FB12C18FFB00BF73D3 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IrrFramework; + productName = IrrFramework; + productReference = 959726FD12C18FFC00BF73D3 /* IrrFramework.framework */; + productType = "com.apple.product-type.framework"; + }; + B81CFDFE097FD9F50057C06F /* 06.2DGraphics */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFE0C097FD9F50057C06F /* Build configuration list for PBXNativeTarget "06.2DGraphics" */; + buildPhases = ( + B81CFE01097FD9F50057C06F /* Resources */, + B81CFE03097FD9F50057C06F /* Sources */, + B81CFE08097FD9F50057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFDFF097FD9F50057C06F /* PBXTargetDependency */, + ); + name = 06.2DGraphics; + productName = DemoApp; + productReference = 4CA25BAC0A485D9800B4E469 /* 2DGraphics_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFE82097FDDE20057C06F /* 07.Collision */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFE8D097FDDE20057C06F /* Build configuration list for PBXNativeTarget "07.Collision" */; + buildPhases = ( + B81CFE85097FDDE20057C06F /* Resources */, + B81CFE87097FDDE20057C06F /* Sources */, + B81CFE89097FDDE20057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFE83097FDDE20057C06F /* PBXTargetDependency */, + ); + name = 07.Collision; + productName = DemoApp; + productReference = 4CA25BAE0A485D9800B4E469 /* Collision_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFEA4097FDE900057C06F /* 11.PerPixelLightning */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFEAF097FDE900057C06F /* Build configuration list for PBXNativeTarget "11.PerPixelLightning" */; + buildPhases = ( + B81CFEA7097FDE900057C06F /* Resources */, + B81CFEA9097FDE900057C06F /* Sources */, + B81CFEAB097FDE900057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFEA5097FDE900057C06F /* PBXTargetDependency */, + ); + name = 11.PerPixelLightning; + productName = DemoApp; + productReference = 4CA25BA00A485D9800B4E469 /* PerPixelLighting_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFEC2097FDF020057C06F /* 12.TerrainRendering */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFECD097FDF020057C06F /* Build configuration list for PBXNativeTarget "12.TerrainRendering" */; + buildPhases = ( + B81CFEC5097FDF020057C06F /* Resources */, + B81CFEC7097FDF020057C06F /* Sources */, + B81CFEC9097FDF020057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFEC3097FDF020057C06F /* PBXTargetDependency */, + ); + name = 12.TerrainRendering; + productName = DemoApp; + productReference = 4CA25BAA0A485D9800B4E469 /* TerrainRendering_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFEE8097FE05F0057C06F /* 08.SpecialFx */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFEF3097FE05F0057C06F /* Build configuration list for PBXNativeTarget "08.SpecialFx" */; + buildPhases = ( + B81CFEEB097FE05F0057C06F /* Resources */, + B81CFEED097FE05F0057C06F /* Sources */, + B81CFEEF097FE05F0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFEE9097FE05F0057C06F /* PBXTargetDependency */, + ); + name = 08.SpecialFx; + productName = DemoApp; + productReference = 4CA25BA80A485D9800B4E469 /* SpecialFx_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF07097FE13E0057C06F /* 05.UserInterface */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF12097FE13E0057C06F /* Build configuration list for PBXNativeTarget "05.UserInterface" */; + buildPhases = ( + B81CFF0A097FE13E0057C06F /* Resources */, + B81CFF0C097FE13E0057C06F /* Sources */, + B81CFF0E097FE13E0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF08097FE13E0057C06F /* PBXTargetDependency */, + ); + name = 05.UserInterface; + productName = DemoApp; + productReference = 4CA25B9E0A485D9800B4E469 /* UserInterface_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF1E097FE1E00057C06F /* 03.CustomSceneNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF29097FE1E00057C06F /* Build configuration list for PBXNativeTarget "03.CustomSceneNode" */; + buildPhases = ( + B81CFF21097FE1E00057C06F /* Resources */, + B81CFF23097FE1E00057C06F /* Sources */, + B81CFF25097FE1E00057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF1F097FE1E00057C06F /* PBXTargetDependency */, + ); + name = 03.CustomSceneNode; + productName = DemoApp; + productReference = 4CA25B980A485D9800B4E469 /* CustomSceneNode_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF33097FE25F0057C06F /* 02.Quake3Map */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF3E097FE25F0057C06F /* Build configuration list for PBXNativeTarget "02.Quake3Map" */; + buildPhases = ( + B81CFF36097FE25F0057C06F /* Resources */, + B81CFF38097FE25F0057C06F /* Sources */, + B81CFF3A097FE25F0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF34097FE25F0057C06F /* PBXTargetDependency */, + ); + name = 02.Quake3Map; + productName = DemoApp; + productReference = 4C53E2520A4850550014E966 /* Quake3Map_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF4A097FE3050057C06F /* 10.Shaders */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF55097FE3050057C06F /* Build configuration list for PBXNativeTarget "10.Shaders" */; + buildPhases = ( + B81CFF4D097FE3050057C06F /* Resources */, + B81CFF4F097FE3050057C06F /* Sources */, + B81CFF51097FE3050057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF4B097FE3050057C06F /* PBXTargetDependency */, + ); + name = 10.Shaders; + productName = DemoApp; + productReference = 4CA25BA60A485D9800B4E469 /* Shaders_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF78097FE3DC0057C06F /* 04.Movement */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF83097FE3DC0057C06F /* Build configuration list for PBXNativeTarget "04.Movement" */; + buildPhases = ( + B81CFF7B097FE3DC0057C06F /* Resources */, + B81CFF7D097FE3DC0057C06F /* Sources */, + B81CFF7F097FE3DC0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF79097FE3DC0057C06F /* PBXTargetDependency */, + ); + name = 04.Movement; + productName = DemoApp; + productReference = 4CA25BA40A485D9800B4E469 /* Movement_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFF91097FE45E0057C06F /* 09.MeshViewer */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFF9C097FE45E0057C06F /* Build configuration list for PBXNativeTarget "09.MeshViewer" */; + buildPhases = ( + B81CFF94097FE45E0057C06F /* Resources */, + B81CFF96097FE45E0057C06F /* Sources */, + B81CFF98097FE45E0057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFF92097FE45E0057C06F /* PBXTargetDependency */, + ); + name = 09.MeshViewer; + productName = DemoApp; + productReference = 4CA25B9A0A485D9800B4E469 /* MeshViewer_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B81CFFAF097FE5F80057C06F /* 13.RenderToTexture */ = { + isa = PBXNativeTarget; + buildConfigurationList = B81CFFBA097FE5F80057C06F /* Build configuration list for PBXNativeTarget "13.RenderToTexture" */; + buildPhases = ( + B81CFFB2097FE5F80057C06F /* Resources */, + B81CFFB4097FE5F80057C06F /* Sources */, + B81CFFB6097FE5F80057C06F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B81CFFB0097FE5F80057C06F /* PBXTargetDependency */, + ); + name = 13.RenderToTexture; + productName = DemoApp; + productReference = 4CA25B9C0A485D9800B4E469 /* RenderToTexture_dbg.app */; + productType = "com.apple.product-type.application"; + }; + B8DEF35C0950229200FDEA7E /* Demo */ = { + isa = PBXNativeTarget; + buildConfigurationList = B8DEF3600950229300FDEA7E /* Build configuration list for PBXNativeTarget "Demo" */; + buildPhases = ( + B8DEF3590950229200FDEA7E /* Resources */, + B8DEF35A0950229200FDEA7E /* Sources */, + B8DEF35B0950229200FDEA7E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + B8DEF375095024F600FDEA7E /* PBXTargetDependency */, + ); + name = Demo; + productName = DemoApp; + productReference = 4CA25BA20A485D9800B4E469 /* Demo_dbg.app */; + productType = "com.apple.product-type.application"; + }; + D2AAC07D0554694100DB518D /* libIrrlicht.a */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "libIrrlicht.a" */; + buildPhases = ( + D2AAC07A0554694100DB518D /* Headers */, + D2AAC07B0554694100DB518D /* Sources */, + D2AAC07C0554694100DB518D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = libIrrlicht.a; + productName = MacOSX; + productReference = 4C53E24D0A4850120014E966 /* libIrrlicht.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0867D690FE84028FC02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + }; + buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "MacOSX" */; + compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 0867D691FE84028FC02AAC07 /* MacOSX */; + productRefGroup = 0867D691FE84028FC02AAC07 /* MacOSX */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D2AAC07D0554694100DB518D /* libIrrlicht.a */, + 09F648F40D2CDED9001E0599 /* 01.HelloWorld */, + B81CFF33097FE25F0057C06F /* 02.Quake3Map */, + B81CFF1E097FE1E00057C06F /* 03.CustomSceneNode */, + B81CFF78097FE3DC0057C06F /* 04.Movement */, + B81CFF07097FE13E0057C06F /* 05.UserInterface */, + B81CFDFE097FD9F50057C06F /* 06.2DGraphics */, + B81CFE82097FDDE20057C06F /* 07.Collision */, + B81CFEE8097FE05F0057C06F /* 08.SpecialFx */, + B81CFF91097FE45E0057C06F /* 09.MeshViewer */, + B81CFF4A097FE3050057C06F /* 10.Shaders */, + B81CFEA4097FDE900057C06F /* 11.PerPixelLightning */, + B81CFEC2097FDF020057C06F /* 12.TerrainRendering */, + B81CFFAF097FE5F80057C06F /* 13.RenderToTexture */, + 09F6492F0D2CE03E001E0599 /* 15.LoadIrrFile */, + 09F649560D2CE206001E0599 /* 16.Quake3Shader */, + 0E2E3CEB1103E294002DE8D7 /* 18.SplitScreen */, + 0946CCA30EC99BBE00D945A5 /* 19.MouseAndJoystick */, + 0E2E3D2C1103E3F4002DE8D7 /* 20.ManagedLights */, + B8DEF35C0950229200FDEA7E /* Demo */, + 09022C520EA0E97F00CD54EE /* GUIEditor */, + B81CFFC6097FE9980057C06F /* All */, + 959726FC12C18FFB00BF73D3 /* IrrFramework */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 09022C550EA0E97F00CD54EE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09022C560EA0E97F00CD54EE /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0946CCA60EC99BBE00D945A5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0946CCA70EC99BBE00D945A5 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F648F70D2CDED9001E0599 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F648F80D2CDED9001E0599 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F649320D2CE03E001E0599 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F649330D2CE03E001E0599 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F649590D2CE206001E0599 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F6495A0D2CE206001E0599 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0E2E3CEE1103E294002DE8D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2E3CEF1103E294002DE8D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0E2E3D2F1103E3F4002DE8D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2E3D301103E3F4002DE8D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 959726F912C18FFB00BF73D3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE01097FD9F50057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF146F60A486651006EBA03 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE85097FDDE20057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF1470B0A486704006EBA03 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEA7097FDE900057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB30A486A1300ADB3D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEC5097FDF020057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB60A486A2200ADB3D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEEB097FE05F0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF147180A48676A006EBA03 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF0A097FE13E0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C8B0A48626600B4E469 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF21097FE1E00057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C360A48610400B4E469 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF36097FE25F0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C53E3890A48559C0014E966 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF4D097FE3050057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBA70A4869C600ADB3D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF7B097FE3DC0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C6A0A4861D800B4E469 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF94097FE45E0057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBA90A4869DD00ADB3D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFFB2097FE5F80057C06F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB90A486A3100ADB3D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8DEF3590950229200FDEA7E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBE0A486A4F00ADB3D7 /* MainMenu.nib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 09022C580EA0E97F00CD54EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09022C7E0EA0EA9D00CD54EE /* CGUIAttributeEditor.cpp in Sources */, + 09022C7F0EA0EA9D00CD54EE /* CGUIEditFactory.cpp in Sources */, + 09022C800EA0EA9D00CD54EE /* CGUIEditWindow.cpp in Sources */, + 09022C810EA0EA9D00CD54EE /* CGUIEditWorkspace.cpp in Sources */, + 09022C820EA0EA9D00CD54EE /* CGUIPanel.cpp in Sources */, + 09022C830EA0EA9D00CD54EE /* CGUITextureCacheBrowser.cpp in Sources */, + 09022C840EA0EA9D00CD54EE /* CMemoryReadWriteFile.cpp in Sources */, + 09022C850EA0EA9D00CD54EE /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0946CCA90EC99BBE00D945A5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0946CCCB0EC99C6E00D945A5 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F648FA0D2CDED9001E0599 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F6491A0D2CDF9A001E0599 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F649350D2CE03E001E0599 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F460EB0D3223ED00D0A9B0 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 09F6495C0D2CE206001E0599 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09F649740D2CE2D0001E0599 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0E2E3CF11103E294002DE8D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2E3D701103E6C6002DE8D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0E2E3D321103E3F4002DE8D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2E3D811103E6E4002DE8D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 959726FA12C18FFB00BF73D3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 959729E912C192DA00BF73D3 /* jcapimin.c in Sources */, + 959729EA12C192DA00BF73D3 /* jcapistd.c in Sources */, + 959729EB12C192DA00BF73D3 /* jccoefct.c in Sources */, + 959729EC12C192DA00BF73D3 /* jccolor.c in Sources */, + 959729ED12C192DA00BF73D3 /* jcdctmgr.c in Sources */, + 959729EE12C192DA00BF73D3 /* jchuff.c in Sources */, + 959729EF12C192DA00BF73D3 /* jcinit.c in Sources */, + 959729F012C192DA00BF73D3 /* jcmainct.c in Sources */, + 959729F112C192DA00BF73D3 /* jcmarker.c in Sources */, + 959729F212C192DA00BF73D3 /* jcmaster.c in Sources */, + 959729F312C192DA00BF73D3 /* jcomapi.c in Sources */, + 959729F412C192DA00BF73D3 /* jcparam.c in Sources */, + 959729F512C192DA00BF73D3 /* jcprepct.c in Sources */, + 959729F612C192DA00BF73D3 /* jcsample.c in Sources */, + 959729F712C192DA00BF73D3 /* jctrans.c in Sources */, + 959729F812C192DA00BF73D3 /* jdapimin.c in Sources */, + 959729F912C192DA00BF73D3 /* jdapistd.c in Sources */, + 959729FA12C192DA00BF73D3 /* jdatadst.c in Sources */, + 959729FB12C192DA00BF73D3 /* jdatasrc.c in Sources */, + 959729FC12C192DA00BF73D3 /* jdcoefct.c in Sources */, + 959729FD12C192DA00BF73D3 /* jdcolor.c in Sources */, + 959729FE12C192DA00BF73D3 /* jddctmgr.c in Sources */, + 959729FF12C192DA00BF73D3 /* jdhuff.c in Sources */, + 95972A0012C192DA00BF73D3 /* jdinput.c in Sources */, + 95972A0112C192DA00BF73D3 /* jdmainct.c in Sources */, + 95972A0212C192DA00BF73D3 /* jdmarker.c in Sources */, + 95972A0312C192DA00BF73D3 /* jdmaster.c in Sources */, + 95972A0412C192DA00BF73D3 /* jdmerge.c in Sources */, + 95972A0512C192DA00BF73D3 /* jdpostct.c in Sources */, + 95972A0612C192DA00BF73D3 /* jdsample.c in Sources */, + 95972A0712C192DA00BF73D3 /* jdtrans.c in Sources */, + 95972A0812C192DA00BF73D3 /* jerror.c in Sources */, + 95972A0912C192DA00BF73D3 /* jfdctflt.c in Sources */, + 95972A0A12C192DA00BF73D3 /* jfdctfst.c in Sources */, + 95972A0B12C192DA00BF73D3 /* jfdctint.c in Sources */, + 95972A0C12C192DA00BF73D3 /* jidctflt.c in Sources */, + 95972A0D12C192DA00BF73D3 /* jidctfst.c in Sources */, + 95972A0E12C192DA00BF73D3 /* jidctint.c in Sources */, + 95972A0F12C192DA00BF73D3 /* jmemmgr.c in Sources */, + 95972A1012C192DA00BF73D3 /* jmemnobs.c in Sources */, + 95972A1112C192DA00BF73D3 /* jquant1.c in Sources */, + 95972A1212C192DA00BF73D3 /* jquant2.c in Sources */, + 95972A1312C192DA00BF73D3 /* jutils.c in Sources */, + 95972A2212C192DA00BF73D3 /* inffast.c in Sources */, + 95972A2312C192DA00BF73D3 /* inftrees.c in Sources */, + 95972A2412C192DA00BF73D3 /* uncompr.c in Sources */, + 95972A2512C192DA00BF73D3 /* compress.c in Sources */, + 95972A2612C192DA00BF73D3 /* crc32.c in Sources */, + 95972A2712C192DA00BF73D3 /* zutil.c in Sources */, + 95972A2812C192DA00BF73D3 /* trees.c in Sources */, + 95972A2912C192DA00BF73D3 /* deflate.c in Sources */, + 95972A2A12C192DA00BF73D3 /* adler32.c in Sources */, + 95972A2B12C192DA00BF73D3 /* CImageLoaderPNG.cpp in Sources */, + 95972A2C12C192DA00BF73D3 /* CColorConverter.cpp in Sources */, + 95972A2D12C192DA00BF73D3 /* CSceneManager.cpp in Sources */, + 95972A2E12C192DA00BF73D3 /* CTRTextureGouraudAdd2.cpp in Sources */, + 95972A2F12C192DA00BF73D3 /* CNullDriver.cpp in Sources */, + 95972A3012C192DA00BF73D3 /* CCSMLoader.cpp in Sources */, + 95972A3112C192DA00BF73D3 /* irrXML.cpp in Sources */, + 95972A3212C192DA00BF73D3 /* CGUIListBox.cpp in Sources */, + 95972A3312C192DA00BF73D3 /* CTRGouraudWire.cpp in Sources */, + 95972A3412C192DA00BF73D3 /* CIrrDeviceStub.cpp in Sources */, + 95972A3512C192DA00BF73D3 /* CGUIMessageBox.cpp in Sources */, + 95972A3612C192DA00BF73D3 /* CMeshSceneNode.cpp in Sources */, + 95972A3712C192DA00BF73D3 /* CGUIStaticText.cpp in Sources */, + 95972A3812C192DA00BF73D3 /* os.cpp in Sources */, + 95972A3912C192DA00BF73D3 /* COCTLoader.cpp in Sources */, + 95972A3A12C192DA00BF73D3 /* CGUIContextMenu.cpp in Sources */, + 95972A3B12C192DA00BF73D3 /* CSceneNodeAnimatorFlyCircle.cpp in Sources */, + 95972A3C12C192DA00BF73D3 /* CDefaultSceneNodeFactory.cpp in Sources */, + 95972A3D12C192DA00BF73D3 /* CD3D9Driver.cpp in Sources */, + 95972A3E12C192DA00BF73D3 /* CTRGouraud.cpp in Sources */, + 95972A3F12C192DA00BF73D3 /* C3DSMeshFileLoader.cpp in Sources */, + 95972A4012C192DA00BF73D3 /* COgreMeshFileLoader.cpp in Sources */, + 95972A4112C192DA00BF73D3 /* CMY3DMeshFileLoader.cpp in Sources */, + 95972A4212C192DA00BF73D3 /* CLMTSMeshFileLoader.cpp in Sources */, + 95972A4312C192DA00BF73D3 /* CGUIFileOpenDialog.cpp in Sources */, + 95972A4412C192DA00BF73D3 /* CSceneNodeAnimatorDelete.cpp in Sources */, + 95972A4512C192DA00BF73D3 /* CTRGouraudAlphaNoZ2.cpp in Sources */, + 95972A4612C192DA00BF73D3 /* CGeometryCreator.cpp in Sources */, + 95972A4712C192DA00BF73D3 /* CD3D8Texture.cpp in Sources */, + 95972A4812C192DA00BF73D3 /* CSkyBoxSceneNode.cpp in Sources */, + 95972A4912C192DA00BF73D3 /* CMeshManipulator.cpp in Sources */, + 95972A4A12C192DA00BF73D3 /* CTextSceneNode.cpp in Sources */, + 95972A4B12C192DA00BF73D3 /* CTRTextureDetailMap2.cpp in Sources */, + 95972A4C12C192DA00BF73D3 /* CTRTextureGouraudAddNoZ2.cpp in Sources */, + 95972A4D12C192DA00BF73D3 /* CTRTextureGouraudNoZ.cpp in Sources */, + 95972A4E12C192DA00BF73D3 /* CGUIScrollBar.cpp in Sources */, + 95972A4F12C192DA00BF73D3 /* CSceneCollisionManager.cpp in Sources */, + 95972A5012C192DA00BF73D3 /* CGUICheckBox.cpp in Sources */, + 95972A5112C192DA00BF73D3 /* CQ3LevelMesh.cpp in Sources */, + 95972A5212C192DA00BF73D3 /* CParticleGravityAffector.cpp in Sources */, + 95972A5312C192DA00BF73D3 /* CSoftwareDriver2.cpp in Sources */, + 95972A5412C192DA00BF73D3 /* CD3D9ParallaxMapRenderer.cpp in Sources */, + 95972A5512C192DA00BF73D3 /* CD3D8ParallaxMapRenderer.cpp in Sources */, + 95972A5612C192DA00BF73D3 /* CAnimatedMeshMD2.cpp in Sources */, + 95972A5712C192DA00BF73D3 /* CSceneNodeAnimatorFlyStraight.cpp in Sources */, + 95972A5812C192DA00BF73D3 /* CImageLoaderPCX.cpp in Sources */, + 95972A5912C192DA00BF73D3 /* CAnimatedMeshSceneNode.cpp in Sources */, + 95972A5A12C192DA00BF73D3 /* CTriangleSelector.cpp in Sources */, + 95972A5B12C192DA00BF73D3 /* CTRTextureGouraudVertexAlpha2.cpp in Sources */, + 95972A5C12C192DA00BF73D3 /* CTRTextureWire2.cpp in Sources */, + 95972A5D12C192DA00BF73D3 /* CTRTextureFlatWire.cpp in Sources */, + 95972A5E12C192DA00BF73D3 /* CTRGouraud2.cpp in Sources */, + 95972A5F12C192DA00BF73D3 /* CEmptySceneNode.cpp in Sources */, + 95972A6012C192DA00BF73D3 /* CTRTextureLightMap2_Add.cpp in Sources */, + 95972A6112C192DA00BF73D3 /* CReadFile.cpp in Sources */, + 95972A6212C192DA00BF73D3 /* COpenGLTexture.cpp in Sources */, + 95972A6312C192DA00BF73D3 /* COSOperator.cpp in Sources */, + 95972A6412C192DA00BF73D3 /* CColladaFileLoader.cpp in Sources */, + 95972A6512C192DA00BF73D3 /* CCameraSceneNode.cpp in Sources */, + 95972A6612C192DA00BF73D3 /* CMetaTriangleSelector.cpp in Sources */, + 95972A6712C192DA00BF73D3 /* CTRTextureFlat.cpp in Sources */, + 95972A6812C192DA00BF73D3 /* CVideoModeList.cpp in Sources */, + 95972A6912C192DA00BF73D3 /* CXMLReader.cpp in Sources */, + 95972A6A12C192DA00BF73D3 /* COpenGLParallaxMapRenderer.cpp in Sources */, + 95972A6B12C192DA00BF73D3 /* CTRTextureGouraudNoZ2.cpp in Sources */, + 95972A6C12C192DA00BF73D3 /* CTRTextureGouraudWire.cpp in Sources */, + 95972A6D12C192DA00BF73D3 /* CParticlePointEmitter.cpp in Sources */, + 95972A6E12C192DA00BF73D3 /* CGUIWindow.cpp in Sources */, + 95972A6F12C192DA00BF73D3 /* CGUIModalScreen.cpp in Sources */, + 95972A7012C192DA00BF73D3 /* CImageLoaderPSD.cpp in Sources */, + 95972A7112C192DA00BF73D3 /* CWaterSurfaceSceneNode.cpp in Sources */, + 95972A7212C192DA00BF73D3 /* CXMeshFileLoader.cpp in Sources */, + 95972A7312C192DA00BF73D3 /* CIrrDeviceLinux.cpp in Sources */, + 95972A7412C192DA00BF73D3 /* CLightSceneNode.cpp in Sources */, + 95972A7512C192DA00BF73D3 /* CTRTextureGouraudAdd.cpp in Sources */, + 95972A7612C192DA00BF73D3 /* CTRTextureGouraud2.cpp in Sources */, + 95972A7712C192DA00BF73D3 /* CSoftwareDriver.cpp in Sources */, + 95972A7812C192DA00BF73D3 /* CTRFlatWire.cpp in Sources */, + 95972A7912C192DA00BF73D3 /* CTRGouraudAlpha2.cpp in Sources */, + 95972A7A12C192DA00BF73D3 /* CSoftwareTexture2.cpp in Sources */, + 95972A7B12C192DA00BF73D3 /* CZipReader.cpp in Sources */, + 95972A7C12C192DA00BF73D3 /* COpenGLNormalMapRenderer.cpp in Sources */, + 95972A7D12C192DA00BF73D3 /* CTRTextureLightMap2_M1.cpp in Sources */, + 95972A7E12C192DA00BF73D3 /* CTRTextureLightMap2_M4.cpp in Sources */, + 95972A7F12C192DA00BF73D3 /* CGUISkin.cpp in Sources */, + 95972A8012C192DA00BF73D3 /* CD3D8Driver.cpp in Sources */, + 95972A8112C192DA00BF73D3 /* CIrrDeviceWin32.cpp in Sources */, + 95972A8212C192DA00BF73D3 /* CFileSystem.cpp in Sources */, + 95972A8312C192DA00BF73D3 /* CGUIMeshViewer.cpp in Sources */, + 95972A8412C192DA00BF73D3 /* CGUIComboBox.cpp in Sources */, + 95972A8512C192DA00BF73D3 /* CSceneNodeAnimatorRotation.cpp in Sources */, + 95972A8612C192DA00BF73D3 /* CSceneNodeAnimatorTexture.cpp in Sources */, + 95972A8712C192DA00BF73D3 /* CParticleSystemSceneNode.cpp in Sources */, + 95972A8812C192DA00BF73D3 /* CTerrainSceneNode.cpp in Sources */, + 95972A8912C192DA00BF73D3 /* CGUIFont.cpp in Sources */, + 95972A8A12C192DA00BF73D3 /* CParticleFadeOutAffector.cpp in Sources */, + 95972A8B12C192DA00BF73D3 /* CDummyTransformationSceneNode.cpp in Sources */, + 95972A8C12C192DA00BF73D3 /* CFileList.cpp in Sources */, + 95972A8D12C192DA00BF73D3 /* CImageLoaderTGA.cpp in Sources */, + 95972A8E12C192DA00BF73D3 /* CXMLWriter.cpp in Sources */, + 95972A8F12C192DA00BF73D3 /* CSceneNodeAnimatorFollowSpline.cpp in Sources */, + 95972A9012C192DA00BF73D3 /* CZBuffer.cpp in Sources */, + 95972A9112C192DA00BF73D3 /* CDMFLoader.cpp in Sources */, + 95972A9212C192DA00BF73D3 /* CD3D9Texture.cpp in Sources */, + 95972A9312C192DA00BF73D3 /* COpenGLShaderMaterialRenderer.cpp in Sources */, + 95972A9412C192DA00BF73D3 /* Irrlicht.cpp in Sources */, + 95972A9512C192DA00BF73D3 /* CGUIEditBox.cpp in Sources */, + 95972A9612C192DA00BF73D3 /* COpenGLSLMaterialRenderer.cpp in Sources */, + 95972A9712C192DA00BF73D3 /* CD3D9HLSLMaterialRenderer.cpp in Sources */, + 95972A9812C192DA00BF73D3 /* CSoftwareTexture.cpp in Sources */, + 95972A9912C192DA00BF73D3 /* CCubeSceneNode.cpp in Sources */, + 95972A9A12C192DA00BF73D3 /* CTriangleBBSelector.cpp in Sources */, + 95972A9B12C192DA00BF73D3 /* CD3D9ShaderMaterialRenderer.cpp in Sources */, + 95972A9C12C192DA00BF73D3 /* CD3D8ShaderMaterialRenderer.cpp in Sources */, + 95972A9D12C192DA00BF73D3 /* CGUIButton.cpp in Sources */, + 95972A9E12C192DA00BF73D3 /* CGUIToolBar.cpp in Sources */, + 95972A9F12C192DA00BF73D3 /* CDefaultSceneNodeAnimatorFactory.cpp in Sources */, + 95972AA012C192DA00BF73D3 /* CBillboardSceneNode.cpp in Sources */, + 95972AA112C192DA00BF73D3 /* CSceneNodeAnimatorCollisionResponse.cpp in Sources */, + 95972AA212C192DA00BF73D3 /* CLogger.cpp in Sources */, + 95972AA312C192DA00BF73D3 /* CGUIInOutFader.cpp in Sources */, + 95972AA412C192DA00BF73D3 /* CWriteFile.cpp in Sources */, + 95972AA512C192DA00BF73D3 /* CTRTextureGouraud.cpp in Sources */, + 95972AA612C192DA00BF73D3 /* CTRFlat.cpp in Sources */, + 95972AA712C192DA00BF73D3 /* CTerrainTriangleSelector.cpp in Sources */, + 95972AA812C192DA00BF73D3 /* CGUITabControl.cpp in Sources */, + 95972AA912C192DA00BF73D3 /* CParticleBoxEmitter.cpp in Sources */, + 95972AAA12C192DA00BF73D3 /* CGUIMenu.cpp in Sources */, + 95972AAB12C192DA00BF73D3 /* CImage.cpp in Sources */, + 95972AAC12C192DA00BF73D3 /* CShadowVolumeSceneNode.cpp in Sources */, + 95972AAD12C192DA00BF73D3 /* CGUIEnvironment.cpp in Sources */, + 95972AAE12C192DA00BF73D3 /* CLimitReadFile.cpp in Sources */, + 95972AAF12C192DA00BF73D3 /* CAttributes.cpp in Sources */, + 95972AB012C192DA00BF73D3 /* COpenGLDriver.cpp in Sources */, + 95972AB112C192DA00BF73D3 /* CTRTextureLightMap2_M2.cpp in Sources */, + 95972AB212C192DA00BF73D3 /* CGUIImage.cpp in Sources */, + 95972AB312C192DA00BF73D3 /* CD3D9NormalMapRenderer.cpp in Sources */, + 95972AB412C192DA00BF73D3 /* CD3D8NormalMapRenderer.cpp in Sources */, + 95972AB512C192DA00BF73D3 /* CMeshCache.cpp in Sources */, + 95972AB612C192DA00BF73D3 /* CImageLoaderJPG.cpp in Sources */, + 95972AB712C192DA00BF73D3 /* CFPSCounter.cpp in Sources */, + 95972AB812C192DA00BF73D3 /* OSXClipboard.mm in Sources */, + 95972AB912C192DA00BF73D3 /* CIrrDeviceMacOSX.mm in Sources */, + 95972ABA12C192DA00BF73D3 /* AppDelegate.mm in Sources */, + 95972ABB12C192DA00BF73D3 /* inflate.c in Sources */, + 95972ABC12C192DA00BF73D3 /* CSphereSceneNode.cpp in Sources */, + 95972ABD12C192DA00BF73D3 /* COBJMeshFileLoader.cpp in Sources */, + 95972ABE12C192DA00BF73D3 /* CPakReader.cpp in Sources */, + 95972ABF12C192DA00BF73D3 /* CImageLoaderBMP.cpp in Sources */, + 95972AC012C192DA00BF73D3 /* CImageWriterBMP.cpp in Sources */, + 95972AC112C192DA00BF73D3 /* CImageWriterJPG.cpp in Sources */, + 95972AC212C192DA00BF73D3 /* CImageWriterPCX.cpp in Sources */, + 95972AC312C192DA00BF73D3 /* CImageWriterPNG.cpp in Sources */, + 95972AC412C192DA00BF73D3 /* CImageWriterPPM.cpp in Sources */, + 95972AC512C192DA00BF73D3 /* CImageWriterPSD.cpp in Sources */, + 95972AC612C192DA00BF73D3 /* CImageWriterTGA.cpp in Sources */, + 95972AC712C192DA00BF73D3 /* CSkyDomeSceneNode.cpp in Sources */, + 95972AC812C192DA00BF73D3 /* CDepthBuffer.cpp in Sources */, + 95972AC912C192DA00BF73D3 /* IBurningShader.cpp in Sources */, + 95972ACA12C192DA00BF73D3 /* CAnimatedMeshMD3.cpp in Sources */, + 95972ACB12C192DA00BF73D3 /* CDefaultGUIElementFactory.cpp in Sources */, + 95972ACC12C192DA00BF73D3 /* CGUIColorSelectDialog.cpp in Sources */, + 95972ACD12C192DA00BF73D3 /* CGUISpinBox.cpp in Sources */, + 95972ACE12C192DA00BF73D3 /* CGUISpriteBank.cpp in Sources */, + 95972ACF12C192DA00BF73D3 /* CQuake3ShaderSceneNode.cpp in Sources */, + 95972AD012C192DA00BF73D3 /* CTRTextureBlend.cpp in Sources */, + 95972AD112C192DA00BF73D3 /* CTRTextureGouraudAlpha.cpp in Sources */, + 95972AD212C192DA00BF73D3 /* CTRTextureGouraudAlphaNoZ.cpp in Sources */, + 95972AD312C192DA00BF73D3 /* CTRTextureLightMapGouraud2_M4.cpp in Sources */, + 95972AD412C192DA00BF73D3 /* CIrrDeviceSDL.cpp in Sources */, + 95972AD512C192DA00BF73D3 /* COpenGLExtensionHandler.cpp in Sources */, + 95972AD612C192DA00BF73D3 /* CMD3MeshFileLoader.cpp in Sources */, + 95972AD712C192DA00BF73D3 /* CB3DMeshFileLoader.cpp in Sources */, + 95972AD812C192DA00BF73D3 /* CBoneSceneNode.cpp in Sources */, + 95972AD912C192DA00BF73D3 /* CBSPMeshFileLoader.cpp in Sources */, + 95972ADA12C192DA00BF73D3 /* CColladaMeshWriter.cpp in Sources */, + 95972ADB12C192DA00BF73D3 /* CImageLoaderPPM.cpp in Sources */, + 95972ADC12C192DA00BF73D3 /* CIrrMeshFileLoader.cpp in Sources */, + 95972ADD12C192DA00BF73D3 /* CIrrMeshWriter.cpp in Sources */, + 95972ADE12C192DA00BF73D3 /* CMD2MeshFileLoader.cpp in Sources */, + 95972ADF12C192DA00BF73D3 /* CMS3DMeshFileLoader.cpp in Sources */, + 95972AE012C192DA00BF73D3 /* CParticleAnimatedMeshSceneNodeEmitter.cpp in Sources */, + 95972AE112C192DA00BF73D3 /* CParticleAttractionAffector.cpp in Sources */, + 95972AE212C192DA00BF73D3 /* CParticleCylinderEmitter.cpp in Sources */, + 95972AE312C192DA00BF73D3 /* CParticleMeshEmitter.cpp in Sources */, + 95972AE412C192DA00BF73D3 /* CParticleRingEmitter.cpp in Sources */, + 95972AE512C192DA00BF73D3 /* CParticleRotationAffector.cpp in Sources */, + 95972AE612C192DA00BF73D3 /* CParticleSphereEmitter.cpp in Sources */, + 95972AE712C192DA00BF73D3 /* CSkinnedMesh.cpp in Sources */, + 95972AE812C192DA00BF73D3 /* CSTLMeshFileLoader.cpp in Sources */, + 95972AE912C192DA00BF73D3 /* CSTLMeshWriter.cpp in Sources */, + 95972AEA12C192DA00BF73D3 /* CBurningShader_Raster_Reference.cpp in Sources */, + 95972AEB12C192DA00BF73D3 /* CGUITable.cpp in Sources */, + 95972AEC12C192DA00BF73D3 /* CImageLoaderWAL.cpp in Sources */, + 95972AED12C192DA00BF73D3 /* CVolumeLightSceneNode.cpp in Sources */, + 95972AEE12C192DA00BF73D3 /* CLWOMeshFileLoader.cpp in Sources */, + 95972AEF12C192DA00BF73D3 /* CSceneNodeAnimatorCameraFPS.cpp in Sources */, + 95972AF012C192DA00BF73D3 /* CSceneNodeAnimatorCameraMaya.cpp in Sources */, + 95972AF112C192DA00BF73D3 /* COBJMeshWriter.cpp in Sources */, + 95972AF212C192DA00BF73D3 /* CParticleScaleAffector.cpp in Sources */, + 95972AF312C192DA00BF73D3 /* png.c in Sources */, + 95972AF412C192DA00BF73D3 /* pngerror.c in Sources */, + 95972AF612C192DA00BF73D3 /* pngget.c in Sources */, + 95972AF712C192DA00BF73D3 /* pngmem.c in Sources */, + 95972AF812C192DA00BF73D3 /* pngpread.c in Sources */, + 95972AF912C192DA00BF73D3 /* pngread.c in Sources */, + 95972AFA12C192DA00BF73D3 /* pngrio.c in Sources */, + 95972AFB12C192DA00BF73D3 /* pngrtran.c in Sources */, + 95972AFC12C192DA00BF73D3 /* pngrutil.c in Sources */, + 95972AFD12C192DA00BF73D3 /* pngset.c in Sources */, + 95972AFE12C192DA00BF73D3 /* pngtrans.c in Sources */, + 95972AFF12C192DA00BF73D3 /* pngwio.c in Sources */, + 95972B0012C192DA00BF73D3 /* pngwrite.c in Sources */, + 95972B0112C192DA00BF73D3 /* pngwtran.c in Sources */, + 95972B0212C192DA00BF73D3 /* pngwutil.c in Sources */, + 95972B0312C192DA00BF73D3 /* CGUIImageList.cpp in Sources */, + 95972B0412C192DA00BF73D3 /* CGUITreeView.cpp in Sources */, + 95972B0512C192DA00BF73D3 /* CMemoryFile.cpp in Sources */, + 95972B0612C192DA00BF73D3 /* CIrrDeviceConsole.cpp in Sources */, + 95972B0712C192DA00BF73D3 /* CImageLoaderRGB.cpp in Sources */, + 95972B0812C192DA00BF73D3 /* CPLYMeshFileLoader.cpp in Sources */, + 95972B0912C192DA00BF73D3 /* CPLYMeshWriter.cpp in Sources */, + 95972B0A12C192DA00BF73D3 /* CTarReader.cpp in Sources */, + 95972B0B12C192DA00BF73D3 /* CMountPointReader.cpp in Sources */, + 95972B0C12C192DA00BF73D3 /* jaricom.c in Sources */, + 95972B0D12C192DA00BF73D3 /* jcarith.c in Sources */, + 95972B0E12C192DA00BF73D3 /* jdarith.c in Sources */, + 95972B0F12C192DA00BF73D3 /* COctreeSceneNode.cpp in Sources */, + 95972B1012C192DA00BF73D3 /* COctreeTriangleSelector.cpp in Sources */, + 95972B1112C192DA00BF73D3 /* CNPKReader.cpp in Sources */, + 95972B1212C192DA00BF73D3 /* CIrrDeviceFB.cpp in Sources */, + 95972B1312C192DA00BF73D3 /* CIrrDeviceWinCE.cpp in Sources */, + 95972B1412C192DA00BF73D3 /* LzmaDec.c in Sources */, + 95972B1512C192DA00BF73D3 /* blocksort.c in Sources */, + 95972B1612C192DA00BF73D3 /* bzcompress.c in Sources */, + 95972B1712C192DA00BF73D3 /* crctable.c in Sources */, + 95972B1812C192DA00BF73D3 /* decompress.c in Sources */, + 95972B1912C192DA00BF73D3 /* huffman.c in Sources */, + 95972B1A12C192DA00BF73D3 /* randtable.c in Sources */, + 95972B1B12C192DA00BF73D3 /* bzlib.c in Sources */, + 95972B1C12C192DA00BF73D3 /* aescrypt.cpp in Sources */, + 95972B1D12C192DA00BF73D3 /* aeskey.cpp in Sources */, + 95972B1E12C192DA00BF73D3 /* aestab.cpp in Sources */, + 95972B1F12C192DA00BF73D3 /* fileenc.cpp in Sources */, + 95972B2012C192DA00BF73D3 /* hmac.cpp in Sources */, + 95972B2112C192DA00BF73D3 /* prng.cpp in Sources */, + 95972B2212C192DA00BF73D3 /* pwd2key.cpp in Sources */, + 95972B2312C192DA00BF73D3 /* sha1.cpp in Sources */, + 95972B2412C192DA00BF73D3 /* sha2.cpp in Sources */, + 95E5857212FCE277004946C6 /* CWADReader.cpp in Sources */, + 95E5857912FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp in Sources */, + 95E5857D12FCE2DE004946C6 /* CSceneLoaderIrr.cpp in Sources */, + 95E5858E12FCE388004946C6 /* CTRNormalMap.cpp in Sources */, + 95E5859312FCE3A1004946C6 /* CTRStencilShadow.cpp in Sources */, + 95E5859612FCE3F5004946C6 /* CSMFMeshFileLoader.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE03097FD9F50057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF146F70A486668006EBA03 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFE87097FDDE20057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF147100A486709006EBA03 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEA9097FDE900057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB20A486A0D00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEC7097FDF020057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB50A486A1F00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFEED097FE05F0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CF1471A0A486774006EBA03 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF0C097FE13E0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C8C0A48627600B4E469 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF23097FE1E00057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C350A4860EE00B4E469 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF38097FE25F0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C53E2500A48504D0014E966 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF4F097FE3050057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB00A4869FD00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF7D097FE3DC0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25C690A4861D100B4E469 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFF96097FE45E0057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBAE0A4869E600ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B81CFFB4097FE5F80057C06F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBB80A486A2E00ADB3D7 /* main.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B8DEF35A0950229200FDEA7E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA5CBBB0A486A4C00ADB3D7 /* CMainMenu.cpp in Sources */, + 4CA5CBBC0A486A4C00ADB3D7 /* main.cpp in Sources */, + 4CA5CBBD0A486A4C00ADB3D7 /* CDemo.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC07B0554694100DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CA25BCE0A485EAD00B4E469 /* jcapimin.c in Sources */, + 4CA25BCF0A485EAD00B4E469 /* jcapistd.c in Sources */, + 4CA25BD00A485EAD00B4E469 /* jccoefct.c in Sources */, + 4CA25BD10A485EAD00B4E469 /* jccolor.c in Sources */, + 4CA25BD20A485EAD00B4E469 /* jcdctmgr.c in Sources */, + 4CA25BD30A485EAD00B4E469 /* jchuff.c in Sources */, + 4CA25BD50A485EAD00B4E469 /* jcinit.c in Sources */, + 4CA25BD60A485EAD00B4E469 /* jcmainct.c in Sources */, + 4CA25BD70A485EAD00B4E469 /* jcmarker.c in Sources */, + 4CA25BD80A485EAD00B4E469 /* jcmaster.c in Sources */, + 4CA25BD90A485EAD00B4E469 /* jcomapi.c in Sources */, + 4CA25BDB0A485EAD00B4E469 /* jcparam.c in Sources */, + 4CA25BDD0A485EAD00B4E469 /* jcprepct.c in Sources */, + 4CA25BDE0A485EAD00B4E469 /* jcsample.c in Sources */, + 4CA25BDF0A485EAD00B4E469 /* jctrans.c in Sources */, + 4CA25BE00A485EAD00B4E469 /* jdapimin.c in Sources */, + 4CA25BE10A485EAD00B4E469 /* jdapistd.c in Sources */, + 4CA25BE20A485EAD00B4E469 /* jdatadst.c in Sources */, + 4CA25BE30A485EAD00B4E469 /* jdatasrc.c in Sources */, + 4CA25BE40A485EAD00B4E469 /* jdcoefct.c in Sources */, + 4CA25BE50A485EAD00B4E469 /* jdcolor.c in Sources */, + 4CA25BE70A485EAD00B4E469 /* jddctmgr.c in Sources */, + 4CA25BE80A485EAD00B4E469 /* jdhuff.c in Sources */, + 4CA25BEA0A485EAD00B4E469 /* jdinput.c in Sources */, + 4CA25BEB0A485EAD00B4E469 /* jdmainct.c in Sources */, + 4CA25BEC0A485EAD00B4E469 /* jdmarker.c in Sources */, + 4CA25BED0A485EAD00B4E469 /* jdmaster.c in Sources */, + 4CA25BEE0A485EAD00B4E469 /* jdmerge.c in Sources */, + 4CA25BF00A485EAD00B4E469 /* jdpostct.c in Sources */, + 4CA25BF10A485EAD00B4E469 /* jdsample.c in Sources */, + 4CA25BF20A485EAD00B4E469 /* jdtrans.c in Sources */, + 4CA25BF30A485EAD00B4E469 /* jerror.c in Sources */, + 4CA25BF50A485EAD00B4E469 /* jfdctflt.c in Sources */, + 4CA25BF60A485EAD00B4E469 /* jfdctfst.c in Sources */, + 4CA25BF70A485EAD00B4E469 /* jfdctint.c in Sources */, + 4CA25BF80A485EAD00B4E469 /* jidctflt.c in Sources */, + 4CA25BF90A485EAD00B4E469 /* jidctfst.c in Sources */, + 4CA25BFA0A485EAD00B4E469 /* jidctint.c in Sources */, + 4CA25C000A485EAD00B4E469 /* jmemmgr.c in Sources */, + 4CA25C020A485EAD00B4E469 /* jmemnobs.c in Sources */, + 4CA25C080A485EAD00B4E469 /* jquant1.c in Sources */, + 4CA25C090A485EAD00B4E469 /* jquant2.c in Sources */, + 4CA25C0A0A485EAD00B4E469 /* jutils.c in Sources */, + 4C53E3D80A4856B30014E966 /* inffast.c in Sources */, + 4C53E3DC0A4856B30014E966 /* inftrees.c in Sources */, + 4C53E3E40A4856B30014E966 /* uncompr.c in Sources */, + 4C53E3F30A4856B30014E966 /* compress.c in Sources */, + 4C53E3F60A4856B30014E966 /* crc32.c in Sources */, + 4C53E3FE0A4856B30014E966 /* zutil.c in Sources */, + 4C53E4010A4856B30014E966 /* trees.c in Sources */, + 4C53E40A0A4856B30014E966 /* deflate.c in Sources */, + 4C53E4150A4856B30014E966 /* adler32.c in Sources */, + 4C53E4280A4856B30014E966 /* CImageLoaderPNG.cpp in Sources */, + 4C53E4290A4856B30014E966 /* CColorConverter.cpp in Sources */, + 4C53E42A0A4856B30014E966 /* CSceneManager.cpp in Sources */, + 4C53E42B0A4856B30014E966 /* CTRTextureGouraudAdd2.cpp in Sources */, + 4C53E42C0A4856B30014E966 /* CNullDriver.cpp in Sources */, + 4C53E42D0A4856B30014E966 /* CCSMLoader.cpp in Sources */, + 4C53E42E0A4856B30014E966 /* irrXML.cpp in Sources */, + 4C53E42F0A4856B30014E966 /* CGUIListBox.cpp in Sources */, + 4C53E4300A4856B30014E966 /* CTRGouraudWire.cpp in Sources */, + 4C53E4310A4856B30014E966 /* CIrrDeviceStub.cpp in Sources */, + 4C53E4320A4856B30014E966 /* CGUIMessageBox.cpp in Sources */, + 4C53E4330A4856B30014E966 /* CMeshSceneNode.cpp in Sources */, + 4C53E4340A4856B30014E966 /* CGUIStaticText.cpp in Sources */, + 4C53E4350A4856B30014E966 /* os.cpp in Sources */, + 4C53E4360A4856B30014E966 /* COCTLoader.cpp in Sources */, + 4C53E4370A4856B30014E966 /* CGUIContextMenu.cpp in Sources */, + 4C53E4390A4856B30014E966 /* CSceneNodeAnimatorFlyCircle.cpp in Sources */, + 4C53E43A0A4856B30014E966 /* CDefaultSceneNodeFactory.cpp in Sources */, + 4C53E43B0A4856B30014E966 /* CD3D9Driver.cpp in Sources */, + 4C53E43C0A4856B30014E966 /* CTRGouraud.cpp in Sources */, + 4C53E43D0A4856B30014E966 /* C3DSMeshFileLoader.cpp in Sources */, + 4C53E43E0A4856B30014E966 /* COgreMeshFileLoader.cpp in Sources */, + 4C53E43F0A4856B30014E966 /* CMY3DMeshFileLoader.cpp in Sources */, + 4C53E4400A4856B30014E966 /* CLMTSMeshFileLoader.cpp in Sources */, + 4C53E4410A4856B30014E966 /* CGUIFileOpenDialog.cpp in Sources */, + 4C53E4420A4856B30014E966 /* CSceneNodeAnimatorDelete.cpp in Sources */, + 4C53E4430A4856B30014E966 /* CTRGouraudAlphaNoZ2.cpp in Sources */, + 4C53E4440A4856B30014E966 /* CGeometryCreator.cpp in Sources */, + 4C53E4450A4856B30014E966 /* CD3D8Texture.cpp in Sources */, + 4C53E4460A4856B30014E966 /* CSkyBoxSceneNode.cpp in Sources */, + 4C53E4470A4856B30014E966 /* CMeshManipulator.cpp in Sources */, + 4C53E4480A4856B30014E966 /* CTextSceneNode.cpp in Sources */, + 4C53E4490A4856B30014E966 /* CTRTextureDetailMap2.cpp in Sources */, + 4C53E44A0A4856B30014E966 /* CTRTextureGouraudAddNoZ2.cpp in Sources */, + 4C53E44C0A4856B30014E966 /* CTRTextureGouraudNoZ.cpp in Sources */, + 4C53E44E0A4856B30014E966 /* CGUIScrollBar.cpp in Sources */, + 4C53E44F0A4856B30014E966 /* CSceneCollisionManager.cpp in Sources */, + 4C53E4500A4856B30014E966 /* CGUICheckBox.cpp in Sources */, + 4C53E4510A4856B30014E966 /* CQ3LevelMesh.cpp in Sources */, + 4C53E4520A4856B30014E966 /* CParticleGravityAffector.cpp in Sources */, + 4C53E4530A4856B30014E966 /* CSoftwareDriver2.cpp in Sources */, + 4C53E4540A4856B30014E966 /* CD3D9ParallaxMapRenderer.cpp in Sources */, + 4C53E4550A4856B30014E966 /* CD3D8ParallaxMapRenderer.cpp in Sources */, + 4C53E4560A4856B30014E966 /* CAnimatedMeshMD2.cpp in Sources */, + 4C53E4570A4856B30014E966 /* CSceneNodeAnimatorFlyStraight.cpp in Sources */, + 4C53E4580A4856B30014E966 /* CImageLoaderPCX.cpp in Sources */, + 4C53E4590A4856B30014E966 /* CAnimatedMeshSceneNode.cpp in Sources */, + 4C53E45A0A4856B30014E966 /* CTriangleSelector.cpp in Sources */, + 4C53E45B0A4856B30014E966 /* CTRTextureGouraudVertexAlpha2.cpp in Sources */, + 4C53E45C0A4856B30014E966 /* CTRTextureWire2.cpp in Sources */, + 4C53E45D0A4856B30014E966 /* CTRTextureFlatWire.cpp in Sources */, + 4C53E45E0A4856B30014E966 /* CTRGouraud2.cpp in Sources */, + 4C53E45F0A4856B30014E966 /* CEmptySceneNode.cpp in Sources */, + 4C53E4600A4856B30014E966 /* CTRTextureLightMap2_Add.cpp in Sources */, + 4C53E4610A4856B30014E966 /* CReadFile.cpp in Sources */, + 4C53E4620A4856B30014E966 /* COpenGLTexture.cpp in Sources */, + 4C53E4640A4856B30014E966 /* COSOperator.cpp in Sources */, + 4C53E4660A4856B30014E966 /* CColladaFileLoader.cpp in Sources */, + 4C53E4670A4856B30014E966 /* CCameraSceneNode.cpp in Sources */, + 4C53E4680A4856B30014E966 /* CMetaTriangleSelector.cpp in Sources */, + 4C53E4690A4856B30014E966 /* CTRTextureFlat.cpp in Sources */, + 4C53E46A0A4856B30014E966 /* CVideoModeList.cpp in Sources */, + 4C53E46B0A4856B30014E966 /* CXMLReader.cpp in Sources */, + 4C53E46C0A4856B30014E966 /* COpenGLParallaxMapRenderer.cpp in Sources */, + 4C53E46E0A4856B30014E966 /* CTRTextureGouraudNoZ2.cpp in Sources */, + 4C53E46F0A4856B30014E966 /* CTRTextureGouraudWire.cpp in Sources */, + 4C53E4700A4856B30014E966 /* CParticlePointEmitter.cpp in Sources */, + 4C53E4710A4856B30014E966 /* CGUIWindow.cpp in Sources */, + 4C53E4720A4856B30014E966 /* CGUIModalScreen.cpp in Sources */, + 4C53E4730A4856B30014E966 /* CImageLoaderPSD.cpp in Sources */, + 4C53E4740A4856B30014E966 /* CWaterSurfaceSceneNode.cpp in Sources */, + 4C53E4750A4856B30014E966 /* CXMeshFileLoader.cpp in Sources */, + 4C53E4760A4856B30014E966 /* CIrrDeviceLinux.cpp in Sources */, + 4C53E4770A4856B30014E966 /* CLightSceneNode.cpp in Sources */, + 4C53E4780A4856B30014E966 /* CTRTextureGouraudAdd.cpp in Sources */, + 4C53E4790A4856B30014E966 /* CTRTextureGouraud2.cpp in Sources */, + 4C53E47A0A4856B30014E966 /* CSoftwareDriver.cpp in Sources */, + 4C53E47B0A4856B30014E966 /* CTRFlatWire.cpp in Sources */, + 4C53E47C0A4856B30014E966 /* CTRGouraudAlpha2.cpp in Sources */, + 4C53E47D0A4856B30014E966 /* CSoftwareTexture2.cpp in Sources */, + 4C53E47E0A4856B30014E966 /* CZipReader.cpp in Sources */, + 4C53E47F0A4856B30014E966 /* COpenGLNormalMapRenderer.cpp in Sources */, + 4C53E4800A4856B30014E966 /* CTRTextureLightMap2_M1.cpp in Sources */, + 4C53E4810A4856B30014E966 /* CTRTextureLightMap2_M4.cpp in Sources */, + 4C53E4820A4856B30014E966 /* CGUISkin.cpp in Sources */, + 4C53E4830A4856B30014E966 /* CD3D8Driver.cpp in Sources */, + 4C53E4840A4856B30014E966 /* CIrrDeviceWin32.cpp in Sources */, + 4C53E4850A4856B30014E966 /* CFileSystem.cpp in Sources */, + 4C53E4860A4856B30014E966 /* CGUIMeshViewer.cpp in Sources */, + 4C53E4870A4856B30014E966 /* CGUIComboBox.cpp in Sources */, + 4C53E4880A4856B30014E966 /* CSceneNodeAnimatorRotation.cpp in Sources */, + 4C53E4890A4856B30014E966 /* CSceneNodeAnimatorTexture.cpp in Sources */, + 4C53E48B0A4856B30014E966 /* CParticleSystemSceneNode.cpp in Sources */, + 4C53E48C0A4856B30014E966 /* CTerrainSceneNode.cpp in Sources */, + 4C53E48E0A4856B30014E966 /* CGUIFont.cpp in Sources */, + 4C53E48F0A4856B30014E966 /* CParticleFadeOutAffector.cpp in Sources */, + 4C53E4910A4856B30014E966 /* CDummyTransformationSceneNode.cpp in Sources */, + 4C53E4920A4856B30014E966 /* CFileList.cpp in Sources */, + 4C53E4930A4856B30014E966 /* CImageLoaderTGA.cpp in Sources */, + 4C53E4940A4856B30014E966 /* CXMLWriter.cpp in Sources */, + 4C53E4950A4856B30014E966 /* CSceneNodeAnimatorFollowSpline.cpp in Sources */, + 4C53E4960A4856B30014E966 /* CZBuffer.cpp in Sources */, + 4C53E4970A4856B30014E966 /* CDMFLoader.cpp in Sources */, + 4C53E4980A4856B30014E966 /* CD3D9Texture.cpp in Sources */, + 4C53E4990A4856B30014E966 /* COpenGLShaderMaterialRenderer.cpp in Sources */, + 4C53E49A0A4856B30014E966 /* Irrlicht.cpp in Sources */, + 4C53E49B0A4856B30014E966 /* CGUIEditBox.cpp in Sources */, + 4C53E49C0A4856B30014E966 /* COpenGLSLMaterialRenderer.cpp in Sources */, + 4C53E49D0A4856B30014E966 /* CD3D9HLSLMaterialRenderer.cpp in Sources */, + 4C53E49E0A4856B30014E966 /* CSoftwareTexture.cpp in Sources */, + 4C53E49F0A4856B30014E966 /* CCubeSceneNode.cpp in Sources */, + 4C53E4A00A4856B30014E966 /* CTriangleBBSelector.cpp in Sources */, + 4C53E4A10A4856B30014E966 /* CD3D9ShaderMaterialRenderer.cpp in Sources */, + 4C53E4A20A4856B30014E966 /* CD3D8ShaderMaterialRenderer.cpp in Sources */, + 4C53E4A30A4856B30014E966 /* CGUIButton.cpp in Sources */, + 4C53E4A40A4856B30014E966 /* CGUIToolBar.cpp in Sources */, + 4C53E4A50A4856B30014E966 /* CDefaultSceneNodeAnimatorFactory.cpp in Sources */, + 4C53E4A60A4856B30014E966 /* CBillboardSceneNode.cpp in Sources */, + 4C53E4A70A4856B30014E966 /* CSceneNodeAnimatorCollisionResponse.cpp in Sources */, + 4C53E4A80A4856B30014E966 /* CLogger.cpp in Sources */, + 4C53E4A90A4856B30014E966 /* CGUIInOutFader.cpp in Sources */, + 4C53E4AA0A4856B30014E966 /* CWriteFile.cpp in Sources */, + 4C53E4AD0A4856B30014E966 /* CTRTextureGouraud.cpp in Sources */, + 4C53E4AE0A4856B30014E966 /* CTRFlat.cpp in Sources */, + 4C53E4AF0A4856B30014E966 /* CTerrainTriangleSelector.cpp in Sources */, + 4C53E4B10A4856B30014E966 /* CGUITabControl.cpp in Sources */, + 4C53E4B20A4856B30014E966 /* CParticleBoxEmitter.cpp in Sources */, + 4C53E4B30A4856B30014E966 /* CGUIMenu.cpp in Sources */, + 4C53E4B40A4856B30014E966 /* CImage.cpp in Sources */, + 4C53E4B50A4856B30014E966 /* CShadowVolumeSceneNode.cpp in Sources */, + 4C53E4B70A4856B30014E966 /* CGUIEnvironment.cpp in Sources */, + 4C53E4B80A4856B30014E966 /* CLimitReadFile.cpp in Sources */, + 4C53E4B90A4856B30014E966 /* CAttributes.cpp in Sources */, + 4C53E4BA0A4856B30014E966 /* COpenGLDriver.cpp in Sources */, + 4C53E4BB0A4856B30014E966 /* CTRTextureLightMap2_M2.cpp in Sources */, + 4C53E4BC0A4856B30014E966 /* CGUIImage.cpp in Sources */, + 4C53E4BD0A4856B30014E966 /* CD3D9NormalMapRenderer.cpp in Sources */, + 4C53E4BE0A4856B30014E966 /* CD3D8NormalMapRenderer.cpp in Sources */, + 4C53E4BF0A4856B30014E966 /* CMeshCache.cpp in Sources */, + 4C53E4C00A4856B30014E966 /* CImageLoaderJPG.cpp in Sources */, + 4C53E4C10A4856B30014E966 /* CFPSCounter.cpp in Sources */, + 4C53E57E0A4856B30014E966 /* OSXClipboard.mm in Sources */, + 4C53E57F0A4856B30014E966 /* CIrrDeviceMacOSX.mm in Sources */, + 4C53E5800A4856B30014E966 /* AppDelegate.mm in Sources */, + 4C6DC9B70A48715A0017A6E5 /* inflate.c in Sources */, + 4CC36B0F0A6B61DB0076C4B2 /* CSphereSceneNode.cpp in Sources */, + 4C364EA40A6C6DC2004CFBB4 /* COBJMeshFileLoader.cpp in Sources */, + 4C43EEC00A74A5C800F942FC /* CPakReader.cpp in Sources */, + 4CFA7BEE0A88735A00B03626 /* CImageLoaderBMP.cpp in Sources */, + 4CFA7BF00A88735A00B03626 /* CImageWriterBMP.cpp in Sources */, + 4CFA7BF20A88735A00B03626 /* CImageWriterJPG.cpp in Sources */, + 4CFA7BF40A88735A00B03626 /* CImageWriterPCX.cpp in Sources */, + 4CFA7BF60A88735A00B03626 /* CImageWriterPNG.cpp in Sources */, + 4CFA7BF80A88735A00B03626 /* CImageWriterPPM.cpp in Sources */, + 4CFA7BFA0A88735A00B03626 /* CImageWriterPSD.cpp in Sources */, + 4CFA7BFC0A88735A00B03626 /* CImageWriterTGA.cpp in Sources */, + 4CFA7BFE0A88735A00B03626 /* CSkyDomeSceneNode.cpp in Sources */, + 5DD4804E0C7D91DF00728AA9 /* CDepthBuffer.cpp in Sources */, + 5DD480520C7D936700728AA9 /* IBurningShader.cpp in Sources */, + 5DD4805A0C7D945800728AA9 /* CAnimatedMeshMD3.cpp in Sources */, + 5DD4805C0C7D945800728AA9 /* CDefaultGUIElementFactory.cpp in Sources */, + 5DD480640C7D947B00728AA9 /* CGUIColorSelectDialog.cpp in Sources */, + 5DD480660C7D947B00728AA9 /* CGUISpinBox.cpp in Sources */, + 5DD480680C7D947B00728AA9 /* CGUISpriteBank.cpp in Sources */, + 5DD480710C7D94AC00728AA9 /* CQuake3ShaderSceneNode.cpp in Sources */, + 5DD480730C7D94AC00728AA9 /* CTRTextureBlend.cpp in Sources */, + 5DD480740C7D94AC00728AA9 /* CTRTextureGouraudAlpha.cpp in Sources */, + 5DD480750C7D94AC00728AA9 /* CTRTextureGouraudAlphaNoZ.cpp in Sources */, + 5DD480760C7D94AC00728AA9 /* CTRTextureLightMapGouraud2_M4.cpp in Sources */, + 5DD480CA0C7DA66800728AA9 /* CIrrDeviceSDL.cpp in Sources */, + 5DD480CB0C7DA66800728AA9 /* COpenGLExtensionHandler.cpp in Sources */, + 5DD480CC0C7DA66800728AA9 /* CMD3MeshFileLoader.cpp in Sources */, + 096840470D0F1A2300333EFD /* CB3DMeshFileLoader.cpp in Sources */, + 096840490D0F1A2300333EFD /* CBoneSceneNode.cpp in Sources */, + 0968404B0D0F1A2300333EFD /* CBSPMeshFileLoader.cpp in Sources */, + 0968404E0D0F1A2300333EFD /* CColladaMeshWriter.cpp in Sources */, + 096840500D0F1A2300333EFD /* CImageLoaderPPM.cpp in Sources */, + 096840540D0F1A2300333EFD /* CIrrMeshFileLoader.cpp in Sources */, + 096840560D0F1A2300333EFD /* CIrrMeshWriter.cpp in Sources */, + 096840580D0F1A2300333EFD /* CMD2MeshFileLoader.cpp in Sources */, + 0968405A0D0F1A2300333EFD /* CMS3DMeshFileLoader.cpp in Sources */, + 0968405C0D0F1A2300333EFD /* CParticleAnimatedMeshSceneNodeEmitter.cpp in Sources */, + 0968405E0D0F1A2300333EFD /* CParticleAttractionAffector.cpp in Sources */, + 096840600D0F1A2300333EFD /* CParticleCylinderEmitter.cpp in Sources */, + 096840620D0F1A2300333EFD /* CParticleMeshEmitter.cpp in Sources */, + 096840640D0F1A2300333EFD /* CParticleRingEmitter.cpp in Sources */, + 096840660D0F1A2300333EFD /* CParticleRotationAffector.cpp in Sources */, + 096840680D0F1A2300333EFD /* CParticleSphereEmitter.cpp in Sources */, + 0968406A0D0F1A2300333EFD /* CSkinnedMesh.cpp in Sources */, + 0968406C0D0F1A2300333EFD /* CSTLMeshFileLoader.cpp in Sources */, + 0968406E0D0F1A2300333EFD /* CSTLMeshWriter.cpp in Sources */, + 0910B9DE0D1F5D4100D46B04 /* CBurningShader_Raster_Reference.cpp in Sources */, + 0910B9DF0D1F5D4100D46B04 /* CGUITable.cpp in Sources */, + 0910B9E10D1F5D4100D46B04 /* CImageLoaderWAL.cpp in Sources */, + 090FBC820D31085E0076D847 /* CVolumeLightSceneNode.cpp in Sources */, + 09C638720D4F1A69000B6A18 /* CLWOMeshFileLoader.cpp in Sources */, + 093973C00E0458B200E0C987 /* CSceneNodeAnimatorCameraFPS.cpp in Sources */, + 093973C20E0458B200E0C987 /* CSceneNodeAnimatorCameraMaya.cpp in Sources */, + 096F8E3D0EA2EFBA00907EC5 /* COBJMeshWriter.cpp in Sources */, + 096CC0E00ECE65B500C81DC7 /* CParticleScaleAffector.cpp in Sources */, + 09293C3E0ED32029003B8C9C /* png.c in Sources */, + 09293C3F0ED32029003B8C9C /* pngerror.c in Sources */, + 09293C410ED32029003B8C9C /* pngget.c in Sources */, + 09293C420ED32029003B8C9C /* pngmem.c in Sources */, + 09293C430ED32029003B8C9C /* pngpread.c in Sources */, + 09293C440ED32029003B8C9C /* pngread.c in Sources */, + 09293C450ED32029003B8C9C /* pngrio.c in Sources */, + 09293C460ED32029003B8C9C /* pngrtran.c in Sources */, + 09293C470ED32029003B8C9C /* pngrutil.c in Sources */, + 09293C480ED32029003B8C9C /* pngset.c in Sources */, + 09293C4A0ED32029003B8C9C /* pngtrans.c in Sources */, + 09293C4C0ED32029003B8C9C /* pngwio.c in Sources */, + 09293C4D0ED32029003B8C9C /* pngwrite.c in Sources */, + 09293C4E0ED32029003B8C9C /* pngwtran.c in Sources */, + 09293C4F0ED32029003B8C9C /* pngwutil.c in Sources */, + 3484C4E20F48D1B000C81F60 /* CGUIImageList.cpp in Sources */, + 3484C4EF0F48D3A100C81F60 /* CGUITreeView.cpp in Sources */, + 3484C4FE0F48D4CB00C81F60 /* CMemoryFile.cpp in Sources */, + 34EC243D0F59272E0037BC3A /* CIrrDeviceConsole.cpp in Sources */, + 34EF91D30F65FCA6000B5651 /* CImageLoaderRGB.cpp in Sources */, + 34EF91D80F65FCF6000B5651 /* CPLYMeshFileLoader.cpp in Sources */, + 34EF91DD0F65FD14000B5651 /* CPLYMeshWriter.cpp in Sources */, + 3430E4D71022C391006271FD /* CTarReader.cpp in Sources */, + 344FD4A61039E98C0045FD3F /* CMountPointReader.cpp in Sources */, + 0E2E3C461103B1B5002DE8D7 /* jaricom.c in Sources */, + 0E2E3C471103B1B5002DE8D7 /* jcarith.c in Sources */, + 0E2E3C481103B1B5002DE8D7 /* jdarith.c in Sources */, + 0E2E3C4D1103B247002DE8D7 /* COctreeSceneNode.cpp in Sources */, + 0E2E3C511103B261002DE8D7 /* COctreeTriangleSelector.cpp in Sources */, + 0E2E3C551103B27D002DE8D7 /* CNPKReader.cpp in Sources */, + 0E2E3C5B1103B2AE002DE8D7 /* CIrrDeviceFB.cpp in Sources */, + 0E2E3C5D1103B2AE002DE8D7 /* CIrrDeviceWinCE.cpp in Sources */, + 0E2E3C641103B384002DE8D7 /* LzmaDec.c in Sources */, + 0E2E3C6F1103B3B9002DE8D7 /* blocksort.c in Sources */, + 0E2E3C701103B3B9002DE8D7 /* bzcompress.c in Sources */, + 0E2E3C731103B3B9002DE8D7 /* crctable.c in Sources */, + 0E2E3C741103B3B9002DE8D7 /* decompress.c in Sources */, + 0E2E3C751103B3B9002DE8D7 /* huffman.c in Sources */, + 0E2E3C771103B3B9002DE8D7 /* randtable.c in Sources */, + 0E2E3C7C1103B4E1002DE8D7 /* bzlib.c in Sources */, + 0E2E3C871103B53C002DE8D7 /* aescrypt.cpp in Sources */, + 0E2E3C881103B53C002DE8D7 /* aeskey.cpp in Sources */, + 0E2E3C891103B53C002DE8D7 /* aestab.cpp in Sources */, + 0E2E3C8A1103B53C002DE8D7 /* fileenc.cpp in Sources */, + 0E2E3C8B1103B53C002DE8D7 /* hmac.cpp in Sources */, + 0E2E3C8C1103B53C002DE8D7 /* prng.cpp in Sources */, + 0E2E3C8D1103B53C002DE8D7 /* pwd2key.cpp in Sources */, + 0E2E3C8E1103B53C002DE8D7 /* sha1.cpp in Sources */, + 0E2E3C8F1103B53C002DE8D7 /* sha2.cpp in Sources */, + 95E5857112FCE277004946C6 /* CWADReader.cpp in Sources */, + 95E5857712FCE2CB004946C6 /* CAnimatedMeshHalfLife.cpp in Sources */, + 95E5857C12FCE2DE004946C6 /* CSceneLoaderIrr.cpp in Sources */, + 95E5858D12FCE388004946C6 /* CTRNormalMap.cpp in Sources */, + 95E5859212FCE3A1004946C6 /* CTRStencilShadow.cpp in Sources */, + 95E5859512FCE3F5004946C6 /* CSMFMeshFileLoader.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 09022C530EA0E97F00CD54EE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 09022C540EA0E97F00CD54EE /* PBXContainerItemProxy */; + }; + 0946CCA40EC99BBE00D945A5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 0946CCA50EC99BBE00D945A5 /* PBXContainerItemProxy */; + }; + 0946CCD90EC99D8C00D945A5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 09022C520EA0E97F00CD54EE /* GUIEditor */; + targetProxy = 0946CCD80EC99D8C00D945A5 /* PBXContainerItemProxy */; + }; + 09F648F50D2CDED9001E0599 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 09F648F60D2CDED9001E0599 /* PBXContainerItemProxy */; + }; + 09F649210D2CDFF0001E0599 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 09F648F40D2CDED9001E0599 /* 01.HelloWorld */; + targetProxy = 09F649200D2CDFF0001E0599 /* PBXContainerItemProxy */; + }; + 09F649300D2CE03E001E0599 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 09F649310D2CE03E001E0599 /* PBXContainerItemProxy */; + }; + 09F649570D2CE206001E0599 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 09F649580D2CE206001E0599 /* PBXContainerItemProxy */; + }; + 0E2E3CEC1103E294002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 0E2E3CED1103E294002DE8D7 /* PBXContainerItemProxy */; + }; + 0E2E3D2D1103E3F4002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = 0E2E3D2E1103E3F4002DE8D7 /* PBXContainerItemProxy */; + }; + 0E2E3D8C1103EB12002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0E2E3D2C1103E3F4002DE8D7 /* 20.ManagedLights */; + targetProxy = 0E2E3D8B1103EB12002DE8D7 /* PBXContainerItemProxy */; + }; + 0E2E3D8E1103EB1A002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0E2E3CEB1103E294002DE8D7 /* 18.SplitScreen */; + targetProxy = 0E2E3D8D1103EB1A002DE8D7 /* PBXContainerItemProxy */; + }; + 0E2E3D901103EB32002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 09F6492F0D2CE03E001E0599 /* 15.LoadIrrFile */; + targetProxy = 0E2E3D8F1103EB32002DE8D7 /* PBXContainerItemProxy */; + }; + 0E2E3D921103EB39002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 09F649560D2CE206001E0599 /* 16.Quake3Shader */; + targetProxy = 0E2E3D911103EB39002DE8D7 /* PBXContainerItemProxy */; + }; + 0E2E3D941103EB41002DE8D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0946CCA30EC99BBE00D945A5 /* 19.MouseAndJoystick */; + targetProxy = 0E2E3D931103EB41002DE8D7 /* PBXContainerItemProxy */; + }; + 4CA5CB820A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B8DEF35C0950229200FDEA7E /* Demo */; + targetProxy = 4CA5CB810A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB840A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFFAF097FE5F80057C06F /* 13.RenderToTexture */; + targetProxy = 4CA5CB830A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB860A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFEC2097FDF020057C06F /* 12.TerrainRendering */; + targetProxy = 4CA5CB850A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB880A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFEA4097FDE900057C06F /* 11.PerPixelLightning */; + targetProxy = 4CA5CB870A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB8A0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF4A097FE3050057C06F /* 10.Shaders */; + targetProxy = 4CA5CB890A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB8C0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF91097FE45E0057C06F /* 09.MeshViewer */; + targetProxy = 4CA5CB8B0A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB8E0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFEE8097FE05F0057C06F /* 08.SpecialFx */; + targetProxy = 4CA5CB8D0A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB900A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFE82097FDDE20057C06F /* 07.Collision */; + targetProxy = 4CA5CB8F0A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB920A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFDFE097FD9F50057C06F /* 06.2DGraphics */; + targetProxy = 4CA5CB910A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB940A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF07097FE13E0057C06F /* 05.UserInterface */; + targetProxy = 4CA5CB930A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB960A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF78097FE3DC0057C06F /* 04.Movement */; + targetProxy = 4CA5CB950A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB980A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF1E097FE1E00057C06F /* 03.CustomSceneNode */; + targetProxy = 4CA5CB970A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + 4CA5CB9A0A4868B500ADB3D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B81CFF33097FE25F0057C06F /* 02.Quake3Map */; + targetProxy = 4CA5CB990A4868B500ADB3D7 /* PBXContainerItemProxy */; + }; + B81CFDFF097FD9F50057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFE00097FD9F50057C06F /* PBXContainerItemProxy */; + }; + B81CFE83097FDDE20057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFE84097FDDE20057C06F /* PBXContainerItemProxy */; + }; + B81CFEA5097FDE900057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFEA6097FDE900057C06F /* PBXContainerItemProxy */; + }; + B81CFEC3097FDF020057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFEC4097FDF020057C06F /* PBXContainerItemProxy */; + }; + B81CFEE9097FE05F0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFEEA097FE05F0057C06F /* PBXContainerItemProxy */; + }; + B81CFF08097FE13E0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF09097FE13E0057C06F /* PBXContainerItemProxy */; + }; + B81CFF1F097FE1E00057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF20097FE1E00057C06F /* PBXContainerItemProxy */; + }; + B81CFF34097FE25F0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF35097FE25F0057C06F /* PBXContainerItemProxy */; + }; + B81CFF4B097FE3050057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF4C097FE3050057C06F /* PBXContainerItemProxy */; + }; + B81CFF79097FE3DC0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF7A097FE3DC0057C06F /* PBXContainerItemProxy */; + }; + B81CFF92097FE45E0057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFF93097FE45E0057C06F /* PBXContainerItemProxy */; + }; + B81CFFB0097FE5F80057C06F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B81CFFB1097FE5F80057C06F /* PBXContainerItemProxy */; + }; + B8DEF375095024F600FDEA7E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC07D0554694100DB518D /* libIrrlicht.a */; + targetProxy = B8DEF374095024F600FDEA7E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 09022C600EA0E97F00CD54EE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = GUIEditor_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 09022C610EA0E97F00CD54EE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = GUIEditor; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 0946CCB20EC99BBE00D945A5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = MouseAndJoystick_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 0946CCB30EC99BBE00D945A5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = MouseAndJoystick; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 09F649010D2CDED9001E0599 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = HelloWorld_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 09F649020D2CDED9001E0599 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = HelloWorld; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 09F6493C0D2CE03E001E0599 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = LoadIrrFile_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 09F6493D0D2CE03E001E0599 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = LoadIrrFile; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 09F649630D2CE206001E0599 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Quake3Shader_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 09F649640D2CE206001E0599 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Quake3Shader; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 0E2E3CFA1103E294002DE8D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = SplitScreen_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 0E2E3CFB1103E294002DE8D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = SplitScreen; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 0E2E3D3A1103E3F4002DE8D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = ManagedLights_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + 0E2E3D3B1103E3F4002DE8D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = ManagedLights; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + 1DEB921F08733DC00010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = MacOSX_Prefix.pch; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = Irrlicht; + ZERO_LINK = NO; + }; + name = Debug; + }; + 1DEB922008733DC00010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = MacOSX_Prefix.pch; + INSTALL_PATH = /usr/local/lib; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_NAME = Irrlicht; + }; + name = Release; + }; + 1DEB922308733DC00010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = NO; + HEADER_SEARCH_PATHS = ../../../include; + OTHER_CFLAGS = ( + "-DMACOSX", + "-D_DEBUG", + ); + PREBINDING = NO; + SDKROOT = ""; + }; + name = Debug; + }; + 1DEB922408733DC00010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + GCC_DYNAMIC_NO_PIC = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = NO; + HEADER_SEARCH_PATHS = ../../../include; + INSTALL_MODE_FLAG = "a+rwx"; + OTHER_CFLAGS = "-DMACOSX"; + PREBINDING = NO; + SDKROOT = ""; + }; + name = Release; + }; + 959726FF12C18FFD00BF73D3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = "IrrFramework-Info.plist"; + INSTALL_PATH = "@executable_path/../Frameworks"; + OTHER_CFLAGS = ( + "-read_only_relocs", + suppress, + ); + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + "-read_only_relocs", + suppress, + ); + PREBINDING = NO; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_NAME = IrrFramework; + SHARED_PRECOMPS_DIR = ""; + }; + name = Debug; + }; + 9597270012C18FFD00BF73D3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + INFOPLIST_FILE = "IrrFramework-Info.plist"; + INSTALL_PATH = "@executable_path/../Frameworks"; + OTHER_CFLAGS = ( + "-read_only_relocs", + suppress, + ); + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + "-read_only_relocs", + suppress, + ); + PREBINDING = NO; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_NAME = IrrFramework; + SHARED_PRECOMPS_DIR = ""; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFE0D097FD9F50057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = 2DGraphics_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFE0E097FD9F50057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = 2DGraphics; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFE8E097FDDE20057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Collision_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFE8F097FDDE20057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Collision; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFEB0097FDE900057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = PerPixelLighting_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFEB1097FDE900057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_MODE_FLAG = "a+rwx"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = PerPixelLighting; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFECE097FDF020057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = TerrainRendering_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFECF097FDF020057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = TerrainRendering; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFEF4097FE05F0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = SpecialFx_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFEF5097FE05F0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = SpecialFx; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF13097FE13E0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = UserInterface_dbg; + SDKROOT = ""; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF14097FE13E0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = UserInterface; + SDKROOT = ""; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF2A097FE1E00057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = CustomSceneNode_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF2B097FE1E00057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = CustomSceneNode; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF3F097FE25F0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Quake3Map_dbg; + SDKROOT = ""; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF40097FE25F0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/build/Debug\""; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Quake3Map; + SDKROOT = ""; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF56097FE3050057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Shaders_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF57097FE3050057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Shaders; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF84097FE3DC0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Movement_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF85097FE3DC0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Movement; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFF9D097FE45E0057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = MeshViewer_dbg; + SDKROOT = ""; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFF9E097FE45E0057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = MeshViewer; + SDKROOT = ""; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFFBB097FE5F80057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = RenderToTexture_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B81CFFBC097FE5F80057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = RenderToTexture; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; + B81CFFE9097FE9C30057C06F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = ALL; + }; + name = Debug; + }; + B81CFFEA097FE9C30057C06F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + PRODUCT_NAME = ALL; + ZERO_LINK = NO; + }; + name = Release; + }; + B8DEF3610950229300FDEA7E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEPLOYMENT_LOCATION = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Demo_dbg; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + B8DEF3620950229300FDEA7E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_LOCATION = YES; + DEPLOYMENT_POSTPROCESSING = YES; + DSTROOT = ../../../bin/MacOSX; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + INFOPLIST_FILE = "DemoApp-Info.plist"; + INSTALL_PATH = /; + ONLY_LINK_ESSENTIAL_SYMBOLS = YES; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Demo; + SEPARATE_STRIP = YES; + STRIP_INSTALLED_PRODUCT = YES; + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 09022C5F0EA0E97F00CD54EE /* Build configuration list for PBXNativeTarget "GUIEditor" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 09022C600EA0E97F00CD54EE /* Debug */, + 09022C610EA0E97F00CD54EE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0946CCB10EC99BBE00D945A5 /* Build configuration list for PBXNativeTarget "19.MouseAndJoystick" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0946CCB20EC99BBE00D945A5 /* Debug */, + 0946CCB30EC99BBE00D945A5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 09F649000D2CDED9001E0599 /* Build configuration list for PBXNativeTarget "01.HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 09F649010D2CDED9001E0599 /* Debug */, + 09F649020D2CDED9001E0599 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 09F6493B0D2CE03E001E0599 /* Build configuration list for PBXNativeTarget "15.LoadIrrFile" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 09F6493C0D2CE03E001E0599 /* Debug */, + 09F6493D0D2CE03E001E0599 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 09F649620D2CE206001E0599 /* Build configuration list for PBXNativeTarget "16.Quake3Shader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 09F649630D2CE206001E0599 /* Debug */, + 09F649640D2CE206001E0599 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0E2E3CF91103E294002DE8D7 /* Build configuration list for PBXNativeTarget "18.SplitScreen" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0E2E3CFA1103E294002DE8D7 /* Debug */, + 0E2E3CFB1103E294002DE8D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0E2E3D391103E3F4002DE8D7 /* Build configuration list for PBXNativeTarget "20.ManagedLights" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0E2E3D3A1103E3F4002DE8D7 /* Debug */, + 0E2E3D3B1103E3F4002DE8D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "libIrrlicht.a" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB921F08733DC00010E9CD /* Debug */, + 1DEB922008733DC00010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "MacOSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB922308733DC00010E9CD /* Debug */, + 1DEB922408733DC00010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9597270112C18FFD00BF73D3 /* Build configuration list for PBXNativeTarget "IrrFramework" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 959726FF12C18FFD00BF73D3 /* Debug */, + 9597270012C18FFD00BF73D3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFE0C097FD9F50057C06F /* Build configuration list for PBXNativeTarget "06.2DGraphics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFE0D097FD9F50057C06F /* Debug */, + B81CFE0E097FD9F50057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFE8D097FDDE20057C06F /* Build configuration list for PBXNativeTarget "07.Collision" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFE8E097FDDE20057C06F /* Debug */, + B81CFE8F097FDDE20057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFEAF097FDE900057C06F /* Build configuration list for PBXNativeTarget "11.PerPixelLightning" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFEB0097FDE900057C06F /* Debug */, + B81CFEB1097FDE900057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFECD097FDF020057C06F /* Build configuration list for PBXNativeTarget "12.TerrainRendering" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFECE097FDF020057C06F /* Debug */, + B81CFECF097FDF020057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFEF3097FE05F0057C06F /* Build configuration list for PBXNativeTarget "08.SpecialFx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFEF4097FE05F0057C06F /* Debug */, + B81CFEF5097FE05F0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF12097FE13E0057C06F /* Build configuration list for PBXNativeTarget "05.UserInterface" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF13097FE13E0057C06F /* Debug */, + B81CFF14097FE13E0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF29097FE1E00057C06F /* Build configuration list for PBXNativeTarget "03.CustomSceneNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF2A097FE1E00057C06F /* Debug */, + B81CFF2B097FE1E00057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF3E097FE25F0057C06F /* Build configuration list for PBXNativeTarget "02.Quake3Map" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF3F097FE25F0057C06F /* Debug */, + B81CFF40097FE25F0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF55097FE3050057C06F /* Build configuration list for PBXNativeTarget "10.Shaders" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF56097FE3050057C06F /* Debug */, + B81CFF57097FE3050057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF83097FE3DC0057C06F /* Build configuration list for PBXNativeTarget "04.Movement" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF84097FE3DC0057C06F /* Debug */, + B81CFF85097FE3DC0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFF9C097FE45E0057C06F /* Build configuration list for PBXNativeTarget "09.MeshViewer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFF9D097FE45E0057C06F /* Debug */, + B81CFF9E097FE45E0057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFFBA097FE5F80057C06F /* Build configuration list for PBXNativeTarget "13.RenderToTexture" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFFBB097FE5F80057C06F /* Debug */, + B81CFFBC097FE5F80057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B81CFFE8097FE9C30057C06F /* Build configuration list for PBXAggregateTarget "All" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B81CFFE9097FE9C30057C06F /* Debug */, + B81CFFEA097FE9C30057C06F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B8DEF3600950229300FDEA7E /* Build configuration list for PBXNativeTarget "Demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B8DEF3610950229300FDEA7E /* Debug */, + B8DEF3620950229300FDEA7E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0867D690FE84028FC02AAC07 /* Project object */; +} diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX_Prefix.pch b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX_Prefix.pch new file mode 100644 index 0000000..b3ea109 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MacOSX_Prefix.pch @@ -0,0 +1,5 @@ +// +// Prefix header for all source files of the 'MacOSX' target in the 'MacOSX' project. +// + +#include diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/classes.nib b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/classes.nib new file mode 100644 index 0000000..b9b4b09 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/classes.nib @@ -0,0 +1,4 @@ +{ + IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }); + IBVersion = 1; +} \ No newline at end of file diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/info.nib b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/info.nib new file mode 100644 index 0000000..d4de41f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/info.nib @@ -0,0 +1,17 @@ + + + + + IBDocumentLocation + 195 413 356 240 0 0 1680 1028 + IBEditorPositions + + 29 + 62 343 338 44 0 0 1680 1028 + + IBFramework Version + 443.0 + IBSystem Version + 8F46 + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000..1a56102 Binary files /dev/null and b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/MainMenu.nib/keyedobjects.nib differ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.h b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.h new file mode 100644 index 0000000..68f598d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.h @@ -0,0 +1,15 @@ +// Copyright (C) 2005-2006 Etienne Petitjean +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifdef __cplusplus +extern "C" { +#endif + + void OSXCopyToClipboard(const char *text); + char* OSXCopyFromClipboard(); + +#ifdef __cplusplus +} +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.mm b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.mm new file mode 100644 index 0000000..d549911 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/OSXClipboard.mm @@ -0,0 +1,36 @@ +// Copyright (C) 2005-2006 Etienne Petitjean +// Copyright (C) 2007-2012 Christian Stehno +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#include "OSXClipboard.h" +#import + +void OSXCopyToClipboard(const char *text) +{ + NSString *str; + NSPasteboard *board; + + if ((text != NULL) && (strlen(text) > 0)) + { + str = [NSString stringWithCString:text encoding:NSWindowsCP1252StringEncoding]; + board = [NSPasteboard generalPasteboard]; + [board declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:NSApp]; + [board setString:str forType:NSStringPboardType]; + } +} + +char* OSXCopyFromClipboard() +{ + NSString* str; + NSPasteboard* board; + char* result; + + result = NULL; + board = [NSPasteboard generalPasteboard]; + str = [board stringForType:NSStringPboardType]; + if (str != nil) + result = (char*)[str cStringUsingEncoding:NSWindowsCP1252StringEncoding]; + return (result); +} + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/irrFramework-Info.plist b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/irrFramework-Info.plist new file mode 100644 index 0000000..fd4ba51 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/MacOSX/irrFramework-Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.irrlichtengine.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.6 + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Makefile b/src/others/irrlicht-1.8.1/source/Irrlicht/Makefile new file mode 100644 index 0000000..5ba4ced --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Makefile @@ -0,0 +1,203 @@ +VERSION_MAJOR = 1 +VERSION_MINOR = 8 +VERSION_RELEASE = 1 +# Irrlicht Engine 1.8.1 +# Makefile for Linux +# +# To use, just run: +# +# make +# +# This will compile Irrlicht, create a static lib (libIrrlicht.a), and copy it +# into the subdirectory lib/Linux. That's all. +# +# If you want Irrlicht to be compiled as shared lib (libIrrlicht.so.versionnumber), then run: +# +# make sharedlib +# make install +# +# If you want to compile in release mode run: +# +# make NDEBUG=1 +# +# For cross-compilation for Win32 under Linux, just use the win32 targets. You have to set +# at least CXX, CC, and AR to the proper binaries. +# +# For compiling on MinGW you can run it with: +# +# make win32 +# + +#List of object files, separated based on engine architecture +IRRMESHLOADER = CBSPMeshFileLoader.o CMD2MeshFileLoader.o CMD3MeshFileLoader.o CMS3DMeshFileLoader.o CB3DMeshFileLoader.o C3DSMeshFileLoader.o COgreMeshFileLoader.o COBJMeshFileLoader.o CColladaFileLoader.o CCSMLoader.o CDMFLoader.o CLMTSMeshFileLoader.o CMY3DMeshFileLoader.o COCTLoader.o CXMeshFileLoader.o CIrrMeshFileLoader.o CSTLMeshFileLoader.o CLWOMeshFileLoader.o CPLYMeshFileLoader.o CSMFMeshFileLoader.o +IRRMESHWRITER = CColladaMeshWriter.o CIrrMeshWriter.o CSTLMeshWriter.o COBJMeshWriter.o CPLYMeshWriter.o +IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) \ + CSkinnedMesh.o CBoneSceneNode.o CMeshSceneNode.o \ + CAnimatedMeshSceneNode.o CAnimatedMeshMD2.o CAnimatedMeshMD3.o \ + CQ3LevelMesh.o CQuake3ShaderSceneNode.o CAnimatedMeshHalfLife.o +IRROBJ = CBillboardSceneNode.o CCameraSceneNode.o CDummyTransformationSceneNode.o CEmptySceneNode.o CGeometryCreator.o CLightSceneNode.o CMeshManipulator.o CMetaTriangleSelector.o COctreeSceneNode.o COctreeTriangleSelector.o CSceneCollisionManager.o CSceneManager.o CShadowVolumeSceneNode.o CSkyBoxSceneNode.o CSkyDomeSceneNode.o CTerrainSceneNode.o CTerrainTriangleSelector.o CVolumeLightSceneNode.o CCubeSceneNode.o CSphereSceneNode.o CTextSceneNode.o CTriangleBBSelector.o CTriangleSelector.o CWaterSurfaceSceneNode.o CMeshCache.o CDefaultSceneNodeAnimatorFactory.o CDefaultSceneNodeFactory.o CSceneLoaderIrr.o +IRRPARTICLEOBJ = CParticleAnimatedMeshSceneNodeEmitter.o CParticleBoxEmitter.o CParticleCylinderEmitter.o CParticleMeshEmitter.o CParticlePointEmitter.o CParticleRingEmitter.o CParticleSphereEmitter.o CParticleAttractionAffector.o CParticleFadeOutAffector.o CParticleGravityAffector.o CParticleRotationAffector.o CParticleSystemSceneNode.o CParticleScaleAffector.o +IRRANIMOBJ = CSceneNodeAnimatorCameraFPS.o CSceneNodeAnimatorCameraMaya.o CSceneNodeAnimatorCollisionResponse.o CSceneNodeAnimatorDelete.o CSceneNodeAnimatorFlyCircle.o CSceneNodeAnimatorFlyStraight.o CSceneNodeAnimatorFollowSpline.o CSceneNodeAnimatorRotation.o CSceneNodeAnimatorTexture.o +IRRDRVROBJ = CNullDriver.o COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLShaderMaterialRenderer.o COpenGLTexture.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D8Driver.o CD3D8NormalMapRenderer.o CD3D8ParallaxMapRenderer.o CD3D8ShaderMaterialRenderer.o CD3D8Texture.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o +IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderTGA.o CImageLoaderPPM.o CImageLoaderWAL.o CImageLoaderRGB.o \ + CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o +IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ) +IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o +IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CWADReader.o CZipReader.o CPakReader.o CNPKReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o lzma/LzmaDec.o +IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CIrrDeviceFB.o CLogger.o COSOperator.o Irrlicht.o os.o +IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o +ZLIBOBJ = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/uncompr.o zlib/zutil.o +JPEGLIBOBJ = jpeglib/jcapimin.o jpeglib/jcapistd.o jpeglib/jccoefct.o jpeglib/jccolor.o jpeglib/jcdctmgr.o jpeglib/jchuff.o jpeglib/jcinit.o jpeglib/jcmainct.o jpeglib/jcmarker.o jpeglib/jcmaster.o jpeglib/jcomapi.o jpeglib/jcparam.o jpeglib/jcprepct.o jpeglib/jcsample.o jpeglib/jctrans.o jpeglib/jdapimin.o jpeglib/jdapistd.o jpeglib/jdatadst.o jpeglib/jdatasrc.o jpeglib/jdcoefct.o jpeglib/jdcolor.o jpeglib/jddctmgr.o jpeglib/jdhuff.o jpeglib/jdinput.o jpeglib/jdmainct.o jpeglib/jdmarker.o jpeglib/jdmaster.o jpeglib/jdmerge.o jpeglib/jdpostct.o jpeglib/jdsample.o jpeglib/jdtrans.o jpeglib/jerror.o jpeglib/jfdctflt.o jpeglib/jfdctfst.o jpeglib/jfdctint.o jpeglib/jidctflt.o jpeglib/jidctfst.o jpeglib/jidctint.o jpeglib/jmemmgr.o jpeglib/jmemnobs.o jpeglib/jquant1.o jpeglib/jquant2.o jpeglib/jutils.o jpeglib/jcarith.o jpeglib/jdarith.o jpeglib/jaricom.o +LIBPNGOBJ = libpng/png.o libpng/pngerror.o libpng/pngget.o libpng/pngmem.o libpng/pngpread.o libpng/pngread.o libpng/pngrio.o libpng/pngrtran.o libpng/pngrutil.o libpng/pngset.o libpng/pngtrans.o libpng/pngwio.o libpng/pngwrite.o libpng/pngwtran.o libpng/pngwutil.o +LIBAESGM = aesGladman/aescrypt.o aesGladman/aeskey.o aesGladman/aestab.o aesGladman/fileenc.o aesGladman/hmac.o aesGladman/prng.o aesGladman/pwd2key.o aesGladman/sha1.o aesGladman/sha2.o +BZIP2OBJ = bzip2/blocksort.o bzip2/huffman.o bzip2/crctable.o bzip2/randtable.o bzip2/bzcompress.o bzip2/decompress.o bzip2/bzlib.o + +# Next variable is for additional scene nodes etc. of customized Irrlicht versions +EXTRAOBJ = +# onefang changes start +#LINKOBJ = $(IRRMESHOBJ) $(IRROBJ) $(IRRPARTICLEOBJ) $(IRRANIMOBJ) \ +# $(IRRVIDEOOBJ) $(IRRSWRENDEROBJ) $(IRRIOOBJ) $(IRROTHEROBJ) \ +# $(IRRGUIOBJ) $(ZLIBOBJ) $(JPEGLIBOBJ) $(LIBPNGOBJ) $(LIBAESGM) \ +# $(BZIP2OBJ) $(EXTRAOBJ) +LINKOBJ = $(IRRMESHOBJ) $(IRROBJ) $(IRRPARTICLEOBJ) $(IRRANIMOBJ) $(IRRVIDEOOBJ) $(IRRSWRENDEROBJ) $(IRRIOOBJ) $(IRROTHEROBJ) $(LIBAESGM) $(EXTRAOBJ) +# onefang changes end + +############### +#Compiler flags +# onefang changes start +#CXXINCS = -I../../include -Izlib -Ijpeglib -Ilibpng +#CPPFLAGS += $(CXXINCS) -DIRRLICHT_EXPORTS=1 +CXXINCS = -I../../include +CPPFLAGS += $(CXXINCS) -DIRRLICHT_EXPORTS=1 -DNO_IRR_COMPILE_WITH_GUI_=1 -DNO_IRR_USE_NON_SYSTEM_JPEG_LIB_=1 -DNO_IRR_USE_NON_SYSTEM_LIB_PNG_=1 -DNO_IRR_USE_NON_SYSTEM_BZIP2_=1 -DNO_IRR_USE_NON_SYSTEM_ZLIB_=1 +# onefang changes end +CXXFLAGS += -Wall -pipe -fno-exceptions -fno-rtti -fstrict-aliasing +ifndef NDEBUG +CXXFLAGS += -g -D_DEBUG +else +CXXFLAGS += -fexpensive-optimizations -O3 +endif +ifdef PROFILE +CXXFLAGS += -pg +endif +CFLAGS := -O3 -fexpensive-optimizations -DPNG_THREAD_UNSAFE_OK -DPNG_NO_MMX_CODE -DPNG_NO_MNG_FEATURES + +sharedlib sharedlib_osx: CXXFLAGS += -fPIC +sharedlib sharedlib_osx: CFLAGS += -fPIC + +#multilib handling +ifeq ($(HOSTTYPE), x86_64) +LIBSELECT=64 +endif + +#Linux specific options +staticlib sharedlib install: SYSTEM = Linux +STATIC_LIB = libIrrlicht.a +LIB_PATH = ../../lib/$(SYSTEM) +INSTALL_DIR = /usr/local/lib +sharedlib install: SHARED_LIB = libIrrlicht.so +sharedlib: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm +staticlib sharedlib: CXXINCS += -I/usr/X11R6/include + +#OSX specific options +staticlib_osx sharedlib_osx install_osx: SYSTEM = MacOSX +staticlib_osx sharedlib_osx: IRROTHEROBJ += MacOSX/CIrrDeviceMacOSX.o MacOSX/OSXClipboard.o MacOSX/AppDelegate.o +staticlib_osx sharedlib_osx: CXXINCS += -IMacOSX -I/usr/X11R6/include +sharedlib_osx install_osx: SHARED_LIB = libIrrlicht.dylib +staticlib_osx sharedlib_osx: LDFLAGS += --no-export-all-symbols --add-stdcall-alias +sharedlib_osx: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm +# for non-X11 app +#sharedlib_osx: LDFLAGS += -framework cocoa -framework carbon -framework opengl -framework IOKit + +#Windows specific options +IRRLICHT_DLL := ../../bin/Win32-gcc/Irrlicht.dll +sharedlib_win32 staticlib_win32: SYSTEM = Win32-gcc +sharedlib_win32: LDFLAGS += -lgdi32 -lopengl32 -ld3dx9d -lwinmm -Wl,--add-stdcall-alias +#choose either -DIRR_COMPILE_WITH_DX9_DEV_PACK or -DNO_IRR_COMPILE_WITH_DIRECT3D_9_ depending if you need dx9 +#sharedlib_win32 staticlib_win32: CPPFLAGS += -DIRR_COMPILE_WITH_DX9_DEV_PACK +sharedlib_win32 staticlib_win32: CPPFLAGS += -DNO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ -DNO_IRR_COMPILE_WITH_DIRECT3D_9_ +sharedlib_win32 staticlib_win32: CPPFLAGS += -DIRR_COMPILE_WITH_DX9_DEV_PACK -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL +staticlib_win32: CPPFLAGS += -D_IRR_STATIC_LIB_ + +VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE) +SHARED_FULLNAME = $(SHARED_LIB).$(VERSION) +SONAME = $(SHARED_LIB).$(VERSION_MAJOR).$(VERSION_MINOR) + +#################### +# All target, builds Irrlicht as static lib (libIrrlicht.a) and copies it into lib/Linux +all linux: staticlib + +# Builds Irrlicht as shared lib (libIrrlicht.so.versionNumber) and copies it into lib/Linux +sharedlib: $(LINKOBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,$(SONAME) -o $(SHARED_FULLNAME) $^ $(LDFLAGS) + mkdir -p $(LIB_PATH) + cp $(SHARED_FULLNAME) $(LIB_PATH) + +# Builds Irrlicht as static lib (libIrrlicht.a) +$(STATIC_LIB): $(LINKOBJ) + $(AR) rs $@ $^ + +# Copies static lib into lib/Linux +staticlib staticlib_osx: $(STATIC_LIB) + mkdir -p $(LIB_PATH) + cp $^ $(LIB_PATH) + +# Builds Irrlicht as dll (Irrlicht.dll) into ../../bin/Win32-gcc +all_win32 win32: sharedlib_win32 +sharedlib_win32: $(IRRLICHT_DLL) +../../bin/Win32-gcc/Irrlicht.dll: $(LINKOBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -o $@ $^ $(LDFLAGS) -Wl,--out-implib,../../lib/Win32-gcc/$(STATIC_LIB) +# Copies static lib into /lib/Win32-gcc +staticlib_win32: $(STATIC_LIB) + cp $^ $(LIB_PATH) + +# Builds Irrlicht as shared lib (libIrrlicht.so.versionNumber) and copies it into /lib/MacOSX +sharedlib_osx: $(LINKOBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -dynamiclib -Wl,-install_name,$(SONAME) -o $(SHARED_FULLNAME) $^ $(LDFLAGS) + cp $(SHARED_FULLNAME) $(LIB_PATH) + +# Installs Irrlicht if it was created as shared lib +install install_osx: + $(RM) -r $(INSTALL_DIR)/../include/irrlicht + mkdir -p $(INSTALL_DIR)/../include/irrlicht + cp ../../include/*.h $(INSTALL_DIR)/../include/irrlicht/ + cp $(LIB_PATH)/$(SHARED_FULLNAME) $(INSTALL_DIR) + cd $(INSTALL_DIR) && ln -s -f $(SHARED_FULLNAME) $(SONAME) + cd $(INSTALL_DIR) && ln -s -f $(SONAME) $(SHARED_LIB) +# ldconfig -n $(INSTALL_DIR) + +TAGS: + ctags *.cpp ../../include/*.h *.h + +# Create dependency files for automatic recompilation +%.d:%.cpp + $(CXX) $(CPPFLAGS) -MM -MF $@ $< + +# Create dependency files for automatic recompilation +%.d:%.c + $(CC) $(CPPFLAGS) -MM -MF $@ $< + +# Create object files from objective-c code +%.o:%.mm + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< + +ifneq ($(MAKECMDGOALS),clean) +-include $(LINKOBJ:.o=.d) +endif + +help: + @echo "Available targets for Irrlicht" + @echo " sharedlib: Build shared library Irrlicht.so for Linux" + @echo " staticlib: Build static library Irrlicht.a for Linux" + @echo " install: Copy shared library to /usr/local/lib" + @echo "" + @echo " sharedlib_win32: Build shared library Irrlicht.dll for Windows" + @echo " staticlib_win32: Build static library Irrlicht.a for Windows" + @echo "" + @echo " clean: Clean up directory" + +# Cleans all temporary files and compilation results. +clean: + $(RM) $(LINKOBJ) $(SHARED_FULLNAME) $(STATIC_LIB) $(LINKOBJ:.o=.d) + +.PHONY: all sharedlib staticlib sharedlib_win32 staticlib_win32 help install clean + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/Octree.h b/src/others/irrlicht-1.8.1/source/Irrlicht/Octree.h new file mode 100644 index 0000000..2bb879d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/Octree.h @@ -0,0 +1,388 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __C_OCTREE_H_INCLUDED__ +#define __C_OCTREE_H_INCLUDED__ + +#include "SViewFrustum.h" +#include "S3DVertex.h" +#include "aabbox3d.h" +#include "irrArray.h" +#include "CMeshBuffer.h" + +/** + Flags for Octree +*/ +//! use meshbuffer for drawing, enables VBO usage +#define OCTREE_USE_HARDWARE false +//! use visibility information together with VBOs +#define OCTREE_USE_VISIBILITY true +//! use bounding box or frustum for calculate polys +#define OCTREE_BOX_BASED true +//! bypass full invisible/visible test +#define OCTREE_PARENTTEST + +namespace irr +{ + +//! template octree. +/** T must be a vertex type which has a member +called .Pos, which is a core::vertex3df position. */ +template +class Octree +{ +public: + + struct SMeshChunk : public scene::CMeshBuffer + { + SMeshChunk () + : scene::CMeshBuffer(), MaterialId(0) + { + scene::CMeshBuffer::grab(); + } + + virtual ~SMeshChunk () + { + //removeAllHardwareBuffers + } + + s32 MaterialId; + }; + + struct SIndexChunk + { + core::array Indices; + s32 MaterialId; + }; + + struct SIndexData + { + u16* Indices; + s32 CurrentSize; + s32 MaxSize; + }; + + + //! Constructor + Octree(const core::array& meshes, s32 minimalPolysPerNode=128) : + IndexData(0), IndexDataCount(meshes.size()), NodeCount(0) + { + IndexData = new SIndexData[IndexDataCount]; + + // construct array of all indices + + core::array* indexChunks = new core::array; + indexChunks->reallocate(meshes.size()); + for (u32 i=0; i!=meshes.size(); ++i) + { + IndexData[i].CurrentSize = 0; + IndexData[i].MaxSize = meshes[i].Indices.size(); + IndexData[i].Indices = new u16[IndexData[i].MaxSize]; + + indexChunks->push_back(SIndexChunk()); + SIndexChunk& tic = indexChunks->getLast(); + + tic.MaterialId = meshes[i].MaterialId; + tic.Indices = meshes[i].Indices; + } + + // create tree + Root = new OctreeNode(NodeCount, 0, meshes, indexChunks, minimalPolysPerNode); + } + + //! returns all ids of polygons partially or fully enclosed + //! by this bounding box. + void calculatePolys(const core::aabbox3d& box) + { + for (u32 i=0; i!=IndexDataCount; ++i) + IndexData[i].CurrentSize = 0; + + Root->getPolys(box, IndexData, 0); + } + + //! returns all ids of polygons partially or fully enclosed + //! by a view frustum. + void calculatePolys(const scene::SViewFrustum& frustum) + { + for (u32 i=0; i!=IndexDataCount; ++i) + IndexData[i].CurrentSize = 0; + + Root->getPolys(frustum, IndexData, 0); + } + + const SIndexData* getIndexData() const + { + return IndexData; + } + + u32 getIndexDataCount() const + { + return IndexDataCount; + } + + u32 getNodeCount() const + { + return NodeCount; + } + + //! for debug purposes only, collects the bounding boxes of the tree + void getBoundingBoxes(const core::aabbox3d& box, + core::array< const core::aabbox3d* >&outBoxes) const + { + Root->getBoundingBoxes(box, outBoxes); + } + + //! destructor + ~Octree() + { + for (u32 i=0; i& allmeshdata, + core::array* indices, + s32 minimalPolysPerNode) : IndexData(0), + Depth(currentdepth+1) + { + ++nodeCount; + + u32 i; // new ISO for scoping problem with different compilers + + for (i=0; i!=8; ++i) + Children[i] = 0; + + if (indices->empty()) + { + delete indices; + return; + } + + bool found = false; + + // find first point for bounding box + + for (i=0; isize(); ++i) + { + if (!(*indices)[i].Indices.empty()) + { + Box.reset(allmeshdata[i].Vertices[(*indices)[i].Indices[0]].Pos); + found = true; + break; + } + } + + if (!found) + { + delete indices; + return; + } + + s32 totalPrimitives = 0; + + // now lets calculate our bounding box + for (i=0; isize(); ++i) + { + totalPrimitives += (*indices)[i].Indices.size(); + for (u32 j=0; j<(*indices)[i].Indices.size(); ++j) + Box.addInternalPoint(allmeshdata[i].Vertices[(*indices)[i].Indices[j]].Pos); + } + + core::vector3df middle = Box.getCenter(); + core::vector3df edges[8]; + Box.getEdges(edges); + + // calculate all children + core::aabbox3d box; + core::array keepIndices; + + if (totalPrimitives > minimalPolysPerNode && !Box.isEmpty()) + for (u32 ch=0; ch!=8; ++ch) + { + box.reset(middle); + box.addInternalPoint(edges[ch]); + + // create indices for child + bool added = false; + core::array* cindexChunks = new core::array; + cindexChunks->reallocate(allmeshdata.size()); + for (i=0; ipush_back(SIndexChunk()); + SIndexChunk& tic = cindexChunks->getLast(); + tic.MaterialId = allmeshdata[i].MaterialId; + + for (u32 t=0; t<(*indices)[i].Indices.size(); t+=3) + { + if (box.isPointInside(allmeshdata[i].Vertices[(*indices)[i].Indices[t]].Pos) && + box.isPointInside(allmeshdata[i].Vertices[(*indices)[i].Indices[t+1]].Pos) && + box.isPointInside(allmeshdata[i].Vertices[(*indices)[i].Indices[t+2]].Pos)) + { + tic.Indices.push_back((*indices)[i].Indices[t]); + tic.Indices.push_back((*indices)[i].Indices[t+1]); + tic.Indices.push_back((*indices)[i].Indices[t+2]); + + added = true; + } + else + { + keepIndices.push_back((*indices)[i].Indices[t]); + keepIndices.push_back((*indices)[i].Indices[t+1]); + keepIndices.push_back((*indices)[i].Indices[t+2]); + } + } + + (*indices)[i].Indices.set_used(keepIndices.size()); + memcpy( (*indices)[i].Indices.pointer(), keepIndices.pointer(), keepIndices.size()*sizeof(u16)); + keepIndices.set_used(0); + } + + if (added) + Children[ch] = new OctreeNode(nodeCount, Depth, + allmeshdata, cindexChunks, minimalPolysPerNode); + else + delete cindexChunks; + + } // end for all possible children + + IndexData = indices; + } + + // destructor + ~OctreeNode() + { + delete IndexData; + + for (u32 i=0; i<8; ++i) + delete Children[i]; + } + + // returns all ids of polygons partially or full enclosed + // by this bounding box. + void getPolys(const core::aabbox3d& box, SIndexData* idxdata, u32 parentTest ) const + { +#if defined (OCTREE_PARENTTEST ) + // if not full inside + if ( parentTest != 2 ) + { + // partially inside ? + if (!Box.intersectsWithBox(box)) + return; + + // fully inside ? + parentTest = Box.isFullInside(box)?2:1; + } +#else + if (Box.intersectsWithBox(box)) +#endif + { + const u32 cnt = IndexData->size(); + u32 i; // new ISO for scoping problem in some compilers + + for (i=0; igetPolys(box, idxdata,parentTest); + } + } + + // returns all ids of polygons partially or full enclosed + // by the view frustum. + void getPolys(const scene::SViewFrustum& frustum, SIndexData* idxdata,u32 parentTest) const + { + u32 i; // new ISO for scoping problem in some compilers + + // if parent is fully inside, no further check for the children is needed +#if defined (OCTREE_PARENTTEST ) + if ( parentTest != 2 ) +#endif + { +#if defined (OCTREE_PARENTTEST ) + parentTest = 2; +#endif + for (i=0; i!=scene::SViewFrustum::VF_PLANE_COUNT; ++i) + { + core::EIntersectionRelation3D r = Box.classifyPlaneRelation(frustum.planes[i]); + if ( r == core::ISREL3D_FRONT ) + return; +#if defined (OCTREE_PARENTTEST ) + if ( r == core::ISREL3D_CLIPPED ) + parentTest = 1; // must still check children +#endif + } + } + + + const u32 cnt = IndexData->size(); + + for (i=0; i!=cnt; ++i) + { + s32 idxcnt = (*IndexData)[i].Indices.size(); + + if (idxcnt) + { + memcpy(&idxdata[i].Indices[idxdata[i].CurrentSize], + &(*IndexData)[i].Indices[0], idxcnt * sizeof(s16)); + idxdata[i].CurrentSize += idxcnt; + } + } + + for (i=0; i!=8; ++i) + if (Children[i]) + Children[i]->getPolys(frustum, idxdata,parentTest); + } + + //! for debug purposes only, collects the bounding boxes of the node + void getBoundingBoxes(const core::aabbox3d& box, + core::array< const core::aabbox3d* >&outBoxes) const + { + if (Box.intersectsWithBox(box)) + { + outBoxes.push_back(&Box); + + for (u32 i=0; i!=8; ++i) + if (Children[i]) + Children[i]->getBoundingBoxes(box, outBoxes); + } + } + + private: + + core::aabbox3df Box; + core::array* IndexData; + OctreeNode* Children[8]; + u32 Depth; + }; + + OctreeNode* Root; + SIndexData* IndexData; + u32 IndexDataCount; + u32 NodeCount; +}; + +} // end namespace + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/S2DVertex.h b/src/others/irrlicht-1.8.1/source/Irrlicht/S2DVertex.h new file mode 100644 index 0000000..f6f6a88 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/S2DVertex.h @@ -0,0 +1,30 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_K_2D_VERTEX_H_INCLUDED__ +#define __S_K_2D_VERTEX_H_INCLUDED__ + +#include "vector2d.h" + +typedef signed short TZBufferType; + +namespace irr +{ +namespace video +{ + + struct S2DVertex + { + core::vector2d Pos; // position + core::vector2d TCoords; // texture coordinates + TZBufferType ZValue; // zvalue + u16 Color; + }; + + +} // end namespace video +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/S4DVertex.h b/src/others/irrlicht-1.8.1/source/Irrlicht/S4DVertex.h new file mode 100644 index 0000000..3b80919 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/S4DVertex.h @@ -0,0 +1,693 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + + +#ifndef __S_4D_VERTEX_H_INCLUDED__ +#define __S_4D_VERTEX_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "SoftwareDriver2_helper.h" +#include "irrAllocator.h" + +namespace irr +{ + +namespace video +{ + +struct sVec2 +{ + f32 x; + f32 y; + + sVec2 () {} + + sVec2 ( f32 s) : x ( s ), y ( s ) {} + sVec2 ( f32 _x, f32 _y ) + : x ( _x ), y ( _y ) {} + + void set ( f32 _x, f32 _y ) + { + x = _x; + y = _y; + } + + // f = a * t + b * ( 1 - t ) + void interpolate(const sVec2& a, const sVec2& b, const f32 t) + { + x = b.x + ( ( a.x - b.x ) * t ); + y = b.y + ( ( a.y - b.y ) * t ); + } + + sVec2 operator-(const sVec2& other) const + { + return sVec2(x - other.x, y - other.y); + } + + sVec2 operator+(const sVec2& other) const + { + return sVec2(x + other.x, y + other.y); + } + + void operator+=(const sVec2& other) + { + x += other.x; + y += other.y; + } + + sVec2 operator*(const f32 s) const + { + return sVec2(x * s , y * s); + } + + void operator*=( const f32 s) + { + x *= s; + y *= s; + } + + void operator=(const sVec2& other) + { + x = other.x; + y = other.y; + } + +}; + +// A8R8G8B8 +struct sVec4; +struct sCompressedVec4 +{ + u32 argb; + + void setA8R8G8B8 ( u32 value ) + { + argb = value; + } + + void setColorf ( const video::SColorf & color ) + { + argb = core::floor32 ( color.a * 255.f ) << 24 | + core::floor32 ( color.r * 255.f ) << 16 | + core::floor32 ( color.g * 255.f ) << 8 | + core::floor32 ( color.b * 255.f ); + } + + void setVec4 ( const sVec4 & v ); + + // f = a * t + b * ( 1 - t ) + void interpolate(const sCompressedVec4& a, const sCompressedVec4& b, const f32 t) + { + argb = PixelBlend32 ( b.argb, a.argb, core::floor32 ( t * 256.f ) ); + } + + +}; + + +struct sVec4 +{ + union + { + struct { f32 x, y, z, w; }; + struct { f32 a, r, g, b; }; +// struct { sVec2 xy, zw; }; // sorry, this does not compile with gcc + }; + + + + sVec4 () {} + + sVec4 ( f32 s) : x ( s ), y ( s ), z ( s ), w ( s ) {} + + sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w ) + : x ( _x ), y ( _y ), z( _z ), w ( _w ){} + + void set ( f32 _x, f32 _y, f32 _z, f32 _w ) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + + void setA8R8G8B8 ( u32 argb ) + { + x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f ); + y = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f ); + z = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f ); + w = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f ); + } + + + void setColorf ( const video::SColorf & color ) + { + x = color.a; + y = color.r; + z = color.g; + w = color.b; + } + + + // f = a * t + b * ( 1 - t ) + void interpolate(const sVec4& a, const sVec4& b, const f32 t) + { + x = b.x + ( ( a.x - b.x ) * t ); + y = b.y + ( ( a.y - b.y ) * t ); + z = b.z + ( ( a.z - b.z ) * t ); + w = b.w + ( ( a.w - b.w ) * t ); + } + + + f32 dotProduct(const sVec4& other) const + { + return x*other.x + y*other.y + z*other.z + w*other.w; + } + + f32 dot_xyz( const sVec4& other) const + { + return x*other.x + y*other.y + z*other.z; + } + + f32 get_length_xyz_square () const + { + return x * x + y * y + z * z; + } + + f32 get_length_xyz () const + { + return core::squareroot ( x * x + y * y + z * z ); + } + + void normalize_xyz () + { + const f32 l = core::reciprocal_squareroot ( x * x + y * y + z * z ); + + x *= l; + y *= l; + z *= l; + } + + void project_xyz () + { + w = core::reciprocal ( w ); + x *= w; + y *= w; + z *= w; + } + + sVec4 operator-(const sVec4& other) const + { + return sVec4(x - other.x, y - other.y, z - other.z,w - other.w); + } + + sVec4 operator+(const sVec4& other) const + { + return sVec4(x + other.x, y + other.y, z + other.z,w + other.w); + } + + void operator+=(const sVec4& other) + { + x += other.x; + y += other.y; + z += other.z; + w += other.w; + } + + sVec4 operator*(const f32 s) const + { + return sVec4(x * s , y * s, z * s,w * s); + } + + sVec4 operator*(const sVec4 &other) const + { + return sVec4(x * other.x , y * other.y, z * other.z,w * other.w); + } + + void mulReciprocal ( f32 s ) + { + const f32 i = core::reciprocal ( s ); + x = (f32) ( x * i ); + y = (f32) ( y * i ); + z = (f32) ( z * i ); + w = (f32) ( w * i ); + } + + void mul ( const f32 s ) + { + x *= s; + y *= s; + z *= s; + w *= s; + } + +/* + void operator*=(f32 s) + { + x *= s; + y *= s; + z *= s; + w *= s; + } +*/ + void operator*=(const sVec4 &other) + { + x *= other.x; + y *= other.y; + z *= other.z; + w *= other.w; + } + + void operator=(const sVec4& other) + { + x = other.x; + y = other.y; + z = other.z; + w = other.w; + } +}; + +struct sVec3 +{ + union + { + struct { f32 r, g, b; }; + struct { f32 x, y, z; }; + }; + + + sVec3 () {} + sVec3 ( f32 _x, f32 _y, f32 _z ) + : r ( _x ), g ( _y ), b( _z ) {} + + sVec3 ( const sVec4 &v ) + : r ( v.x ), g ( v.y ), b( v.z ) {} + + void set ( f32 _r, f32 _g, f32 _b ) + { + r = _r; + g = _g; + b = _b; + } + + void setR8G8B8 ( u32 argb ) + { + r = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f ); + g = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f ); + b = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f ); + } + + void setColorf ( const video::SColorf & color ) + { + r = color.r; + g = color.g; + b = color.b; + } + + void add (const sVec3& other) + { + r += other.r; + g += other.g; + b += other.b; + } + + void mulAdd(const sVec3& other, const f32 v) + { + r += other.r * v; + g += other.g * v; + b += other.b * v; + } + + void mulAdd(const sVec3& v0, const sVec3& v1) + { + r += v0.r * v1.r; + g += v0.g * v1.g; + b += v0.b * v1.b; + } + + void saturate ( sVec4 &dest, u32 argb ) + { + dest.x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f ); + dest.y = core::min_ ( r, 1.f ); + dest.z = core::min_ ( g, 1.f ); + dest.w = core::min_ ( b, 1.f ); + } + + // f = a * t + b * ( 1 - t ) + void interpolate(const sVec3& v0, const sVec3& v1, const f32 t) + { + r = v1.r + ( ( v0.r - v1.r ) * t ); + g = v1.g + ( ( v0.g - v1.g ) * t ); + b = v1.b + ( ( v0.b - v1.b ) * t ); + } + + sVec3 operator-(const sVec3& other) const + { + return sVec3(r - other.r, b - other.b, g - other.g); + } + + sVec3 operator+(const sVec3& other) const + { + return sVec3(r + other.r, g + other.g, b + other.b); + } + + sVec3 operator*(const f32 s) const + { + return sVec3(r * s , g * s, b * s); + } + + sVec3 operator/(const f32 s) const + { + f32 inv = 1.f / s; + return sVec3(r * inv , g * inv, b * inv); + } + + sVec3 operator*(const sVec3 &other) const + { + return sVec3(r * other.r , b * other.b, g * other.g); + } + + void operator+=(const sVec3& other) + { + r += other.r; + g += other.g; + b += other.b; + } + + void setLength ( f32 len ) + { + const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b ); + + r *= l; + g *= l; + b *= l; + } + +}; + + + +inline void sCompressedVec4::setVec4 ( const sVec4 & v ) +{ + argb = core::floor32 ( v.x * 255.f ) << 24 | + core::floor32 ( v.y * 255.f ) << 16 | + core::floor32 ( v.z * 255.f ) << 8 | + core::floor32 ( v.w * 255.f ); +} + + +enum e4DVertexFlag +{ + VERTEX4D_INSIDE = 0x0000003F, + VERTEX4D_CLIPMASK = 0x0000003F, + VERTEX4D_PROJECTED = 0x00000100, + + VERTEX4D_FORMAT_MASK = 0xFFFF0000, + + VERTEX4D_FORMAT_MASK_TEXTURE = 0x000F0000, + VERTEX4D_FORMAT_TEXTURE_1 = 0x00010000, + VERTEX4D_FORMAT_TEXTURE_2 = 0x00020000, + VERTEX4D_FORMAT_TEXTURE_3 = 0x00030000, + VERTEX4D_FORMAT_TEXTURE_4 = 0x00040000, + + VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000, + VERTEX4D_FORMAT_COLOR_1 = 0x00100000, + VERTEX4D_FORMAT_COLOR_2 = 0x00200000, + + VERTEX4D_FORMAT_MASK_BUMP = 0x0F000000, + VERTEX4D_FORMAT_BUMP_DOT3 = 0x01000000, + +}; + +const u32 MATERIAL_MAX_COLORS = 1; +const u32 BURNING_MATERIAL_MAX_TEXTURES = 2; +const u32 BURNING_MATERIAL_MAX_TANGENT = 1; + +// dummy Vertex. used for calculation vertex memory size +struct s4DVertex_proxy +{ + u32 flag; + sVec4 Pos; + sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + sVec4 Color[MATERIAL_MAX_COLORS]; +#endif + + sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT]; + +}; + +#define SIZEOF_SVERTEX 64 +#define SIZEOF_SVERTEX_LOG2 6 + +/*! + Internal BurningVideo Vertex +*/ +struct s4DVertex +{ + u32 flag; + + sVec4 Pos; + sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ]; + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + sVec4 Color[ MATERIAL_MAX_COLORS ]; +#endif + + sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT]; + + //u8 fill [ SIZEOF_SVERTEX - sizeof (s4DVertex_proxy) ]; + + // f = a * t + b * ( 1 - t ) + void interpolate(const s4DVertex& b, const s4DVertex& a, const f32 t) + { + u32 i; + u32 size; + + Pos.interpolate ( a.Pos, b.Pos, t ); + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20; + for ( i = 0; i!= size; ++i ) + { + Color[i].interpolate ( a.Color[i], b.Color[i], t ); + } +#endif + + size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16; + for ( i = 0; i!= size; ++i ) + { + Tex[i].interpolate ( a.Tex[i], b.Tex[i], t ); + } + + size = (flag & VERTEX4D_FORMAT_MASK_BUMP) >> 24; + for ( i = 0; i!= size; ++i ) + { + LightTangent[i].interpolate ( a.LightTangent[i], b.LightTangent[i], t ); + } + + } +}; + +// ----------------- Vertex Cache --------------------------- + +struct SAlignedVertex +{ + SAlignedVertex ( u32 element, u32 aligned ) + : ElementSize ( element ) + { + u32 byteSize = (ElementSize << SIZEOF_SVERTEX_LOG2 ) + aligned; + mem = new u8 [ byteSize ]; + data = (s4DVertex*) mem; + } + + virtual ~SAlignedVertex () + { + delete [] mem; + } + + s4DVertex *data; + u8 *mem; + u32 ElementSize; +}; + + +// hold info for different Vertex Types +struct SVSize +{ + u32 Format; + u32 Pitch; + u32 TexSize; +}; + + +// a cache info +struct SCacheInfo +{ + u32 index; + u32 hit; +}; + +#define VERTEXCACHE_ELEMENT 16 +#define VERTEXCACHE_MISS 0xFFFFFFFF +struct SVertexCache +{ + SVertexCache (): mem ( VERTEXCACHE_ELEMENT * 2, 128 ) {} + + SCacheInfo info[VERTEXCACHE_ELEMENT]; + + + // Transformed and lite, clipping state + // + Clipped, Projected + SAlignedVertex mem; + + // source + const void* vertices; + u32 vertexCount; + + const void* indices; + u32 indexCount; + u32 indicesIndex; + + u32 indicesRun; + + // primitives consist of x vertices + u32 primitivePitch; + + u32 vType; //E_VERTEX_TYPE + u32 pType; //scene::E_PRIMITIVE_TYPE + u32 iType; //E_INDEX_TYPE iType + +}; + + +// swap 2 pointer +REALINLINE void swapVertexPointer(const s4DVertex** v1, const s4DVertex** v2) +{ + const s4DVertex* b = *v1; + *v1 = *v2; + *v2 = b; +} + + +// ------------------------ Internal Scanline Rasterizer ----------------------------- + + + +// internal scan convert +struct sScanConvertData +{ + u8 left; // major edge left/right + u8 right; // !left + + f32 invDeltaY[3]; // inverse edge delta y + + f32 x[2]; // x coordinate + f32 slopeX[2]; // x slope along edges + +#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT ) + f32 w[2]; // w coordinate + fp24 slopeW[2]; // w slope along edges +#else + f32 z[2]; // z coordinate + f32 slopeZ[2]; // z slope along edges +#endif + + sVec4 c[MATERIAL_MAX_COLORS][2]; // color + sVec4 slopeC[MATERIAL_MAX_COLORS][2]; // color slope along edges + + sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture + sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture slope along edges + + sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2]; // Light Tangent + sVec3 slopeL[BURNING_MATERIAL_MAX_TEXTURES][2]; // tanget slope along edges +}; + +// passed to scan Line +struct sScanLineData +{ + s32 y; // y position of scanline + f32 x[2]; // x start, x end of scanline + +#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT ) + f32 w[2]; // w start, w end of scanline +#else + f32 z[2]; // z start, z end of scanline +#endif + +#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + sVec4 c[MATERIAL_MAX_COLORS][2]; // color start, color end of scanline +#endif + + sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture start, texture end of scanline + sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2]; // Light Tangent start, end +}; + +// passed to pixel Shader +struct sPixelShaderData +{ + tVideoSample *dst; + fp24 *z; + + s32 xStart; + s32 xEnd; + s32 dx; + s32 i; +}; + +/* + load a color value +*/ +inline void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sVec4 &v + ) +{ + r = tofix ( v.y ); + g = tofix ( v.z ); + b = tofix ( v.w ); +} + +/* + load a color value +*/ +inline void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sVec4 &v + ) +{ + a = tofix ( v.x ); + r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL); + g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL); + b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL); +} + +/* + load a color value +*/ +inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v ) +{ + r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL); + g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL); + b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL); +} + +/* + load a color value +*/ +inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sVec4 &v, const f32 mulby ) +{ + r = tofix ( v.y, mulby); + g = tofix ( v.z, mulby); + b = tofix ( v.w, mulby); +} + + + +} + +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/SConstruct b/src/others/irrlicht-1.8.1/source/Irrlicht/SConstruct new file mode 100644 index 0000000..1117fef --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/SConstruct @@ -0,0 +1,102 @@ +import os +import sys + +USE_GCC = 1; +NDEBUG = 1; +PROFILE = 0; + +APPLICATION_NAME = 'Irrlicht'; +LIBRARIES = ['gdi32', 'opengl32', 'd3dx9d', 'winmm']; +if USE_GCC==1 and PROFILE==1: + LIBRARIES += ['gmon']; + +CXXINCS = ['../../include/', 'zlib/', 'jpeglib/', 'libpng/']; + +if USE_GCC==0: + env = Environment(ENV = { + 'PATH': os.environ['PATH'] + }, CPPPATH=CXXINCS); +else: + env = Environment(ENV = { + 'PATH': os.environ['PATH'] + }, tools = ['mingw'], CPPPATH=CXXINCS); + +IRRMESHLOADER = ['CBSPMeshFileLoader.cpp', 'CMD2MeshFileLoader.cpp', 'CMD3MeshFileLoader.cpp', 'CMS3DMeshFileLoader.cpp', 'CB3DMeshFileLoader.cpp', 'C3DSMeshFileLoader.cpp', 'COgreMeshFileLoader.cpp', 'COBJMeshFileLoader.cpp', 'CColladaFileLoader.cpp', 'CCSMLoader.cpp', 'CDMFLoader.cpp', 'CLMTSMeshFileLoader.cpp', 'CMY3DMeshFileLoader.cpp', 'COCTLoader.cpp', 'CXMeshFileLoader.cpp', 'CIrrMeshFileLoader.cpp', 'CSTLMeshFileLoader.cpp', 'CLWOMeshFileLoader.cpp']; + +IRRMESHWRITER = ['CColladaMeshWriter.cpp', 'CIrrMeshWriter.cpp', 'COBJMeshWriter.cpp', 'CSTLMeshWriter.cpp']; + +IRRMESHOBJ = IRRMESHLOADER + IRRMESHWRITER + ['CSkinnedMesh.cpp', 'CBoneSceneNode.cpp', 'CMeshSceneNode.cpp', 'CAnimatedMeshSceneNode.cpp', 'CAnimatedMeshMD2.cpp', 'CAnimatedMeshMD3.cpp', 'CQ3LevelMesh.cpp', 'CQuake3ShaderSceneNode.cpp']; + +IRROBJ = ['CBillboardSceneNode.cpp', 'CCameraSceneNode.cpp', 'CDummyTransformationSceneNode.cpp', 'CEmptySceneNode.cpp', 'CGeometryCreator.cpp', 'CLightSceneNode.cpp', 'CMeshManipulator.cpp', 'CMetaTriangleSelector.cpp', 'COctreeSceneNode.cpp', 'COctreeTriangleSelector.cpp', 'CSceneCollisionManager.cpp', 'CSceneManager.cpp', 'CShadowVolumeSceneNode.cpp', 'CSkyBoxSceneNode.cpp', 'CSkyDomeSceneNode.cpp', 'CTerrainSceneNode.cpp', 'CTerrainTriangleSelector.cpp', 'CVolumeLightSceneNode.cpp', 'CCubeSceneNode.cpp', 'CSphereSceneNode.cpp', 'CTextSceneNode.cpp', 'CTriangleBBSelector.cpp', 'CTriangleSelector.cpp', 'CWaterSurfaceSceneNode.cpp', 'CMeshCache.cpp', 'CDefaultSceneNodeAnimatorFactory.cpp', 'CDefaultSceneNodeFactory.cpp']; + +IRRPARTICLEOBJ = ['CParticleAnimatedMeshSceneNodeEmitter.cpp', 'CParticleBoxEmitter.cpp', 'CParticleCylinderEmitter.cpp', 'CParticleMeshEmitter.cpp', 'CParticlePointEmitter.cpp', 'CParticleRingEmitter.cpp', 'CParticleSphereEmitter.cpp', 'CParticleAttractionAffector.cpp', 'CParticleFadeOutAffector.cpp', 'CParticleGravityAffector.cpp', 'CParticleRotationAffector.cpp', 'CParticleSystemSceneNode.cpp', 'CParticleScaleAffector.cpp']; + +IRRANIMOBJ = ['CSceneNodeAnimatorCameraFPS.cpp', 'CSceneNodeAnimatorCameraMaya.cpp', 'CSceneNodeAnimatorCollisionResponse.cpp', 'CSceneNodeAnimatorDelete.cpp', 'CSceneNodeAnimatorFlyCircle.cpp', 'CSceneNodeAnimatorFlyStraight.cpp', 'CSceneNodeAnimatorFollowSpline.cpp', 'CSceneNodeAnimatorRotation.cpp', 'CSceneNodeAnimatorTexture.cpp']; + +IRRDRVROBJ = ['CNullDriver.cpp', 'COpenGLDriver.cpp', 'COpenGLNormalMapRenderer.cpp', 'COpenGLParallaxMapRenderer.cpp', 'COpenGLShaderMaterialRenderer.cpp', 'COpenGLTexture.cpp', 'COpenGLSLMaterialRenderer.cpp', 'COpenGLExtensionHandler.cpp', 'CD3D8Driver.cpp', 'CD3D8NormalMapRenderer.cpp', 'CD3D8ParallaxMapRenderer.cpp', 'CD3D8ShaderMaterialRenderer.cpp', 'CD3D8Texture.cpp', 'CD3D9Driver.cpp', 'CD3D9HLSLMaterialRenderer.cpp', 'CD3D9NormalMapRenderer.cpp', 'CD3D9ParallaxMapRenderer.cpp', 'CD3D9ShaderMaterialRenderer.cpp', 'CD3D9Texture.cpp']; + +IRRIMAGEOBJ = ['CColorConverter.cpp', 'CImage.cpp', 'CImageLoaderBMP.cpp', 'CImageLoaderJPG.cpp', 'CImageLoaderPCX.cpp', 'CImageLoaderPNG.cpp', 'CImageLoaderPSD.cpp', 'CImageLoaderTGA.cpp', 'CImageLoaderPPM.cpp', 'CImageLoaderWAL.cpp', 'CImageWriterBMP.cpp', 'CImageWriterJPG.cpp', 'CImageWriterPCX.cpp', 'CImageWriterPNG.cpp', 'CImageWriterPPM.cpp', 'CImageWriterPSD.cpp', 'CImageWriterTGA.cpp']; + +IRRVIDEOOBJ = ['CVideoModeList.cpp', 'CFPSCounter.cpp'] + IRRDRVROBJ + IRRIMAGEOBJ; + +IRRSWRENDEROBJ = ['CSoftwareDriver.cpp', 'CSoftwareTexture.cpp', 'CTRFlat.cpp', 'CTRFlatWire.cpp', 'CTRGouraud.cpp', 'CTRGouraudWire.cpp', 'CTRTextureFlat.cpp', 'CTRTextureFlatWire.cpp', 'CTRTextureGouraud.cpp', 'CTRTextureGouraudAdd.cpp', 'CTRTextureGouraudNoZ.cpp', 'CTRTextureGouraudWire.cpp', 'CZBuffer.cpp', 'CTRTextureGouraudVertexAlpha2.cpp', 'CTRTextureGouraudNoZ2.cpp', 'CTRTextureLightMap2_M2.cpp', 'CTRTextureLightMap2_M4.cpp', 'CTRTextureLightMap2_M1.cpp', 'CSoftwareDriver2.cpp', 'CSoftwareTexture2.cpp', 'CTRTextureGouraud2.cpp', 'CTRGouraud2.cpp', 'CTRGouraudAlpha2.cpp', 'CTRGouraudAlphaNoZ2.cpp', 'CTRTextureDetailMap2.cpp', 'CTRTextureGouraudAdd2.cpp', 'CTRTextureGouraudAddNoZ2.cpp', 'CTRTextureWire2.cpp', 'CTRTextureLightMap2_Add.cpp', 'CTRTextureLightMapGouraud2_M4.cpp', 'IBurningShader.cpp', 'CTRTextureBlend.cpp', 'CTRTextureGouraudAlpha.cpp', 'CTRTextureGouraudAlphaNoZ.cpp', 'CDepthBuffer.cpp', 'CBurningShader_Raster_Reference.cpp']; + +IRRIOOBJ = ['CFileList.cpp', 'CFileSystem.cpp', 'CLimitReadFile.cpp', 'CMemoryReadFile.cpp', 'CReadFile.cpp', 'CWriteFile.cpp', 'CXMLReader.cpp', 'CXMLWriter.cpp', 'CZipReader.cpp', 'CPakReader.cpp', 'CNPKReader.cpp', 'irrXML.cpp', 'CAttributes.cpp', 'lzma/LzmaDec.c']; + +IRROTHEROBJ = ['CIrrDeviceSDL.cpp', 'CIrrDeviceLinux.cpp', 'CIrrDeviceStub.cpp', 'CIrrDeviceWin32.cpp', 'CLogger.cpp', 'COSOperator.cpp', 'Irrlicht.cpp', 'os.cpp']; + +IRRGUIOBJ = ['CGUIButton.cpp', 'CGUICheckBox.cpp', 'CGUIComboBox.cpp', 'CGUIContextMenu.cpp', 'CGUIEditBox.cpp', 'CGUIEnvironment.cpp', 'CGUIFileOpenDialog.cpp', 'CGUIFont.cpp', 'CGUIImage.cpp', 'CGUIInOutFader.cpp', 'CGUIListBox.cpp', 'CGUIMenu.cpp', 'CGUIMeshViewer.cpp', 'CGUIMessageBox.cpp', 'CGUIModalScreen.cpp', 'CGUIScrollBar.cpp', 'CGUISpinBox.cpp', 'CGUISkin.cpp', 'CGUIStaticText.cpp', 'CGUITabControl.cpp', 'CGUITable.cpp', 'CGUIToolBar.cpp', 'CGUIWindow.cpp', 'CGUIColorSelectDialog.cpp', 'CDefaultGUIElementFactory.cpp', 'CGUISpriteBank.cpp']; + +ZLIB_PREFIX = 'zlib/'; +ZLIBNAMES = ['adler32.c', 'compress.c', 'crc32.c', 'deflate.c', 'inffast.c', 'inflate.c', 'inftrees.c', 'trees.c', 'uncompr.c', 'zutil.c']; +ZLIBOBJ = []; +for fileName in ZLIBNAMES: + ZLIBOBJ += [ZLIB_PREFIX + fileName]; + +JPEGLIB_PREFIX = 'jpeglib/'; +JPEGLIBNAMES = ['jaricom.c', 'jcapimin.c', 'jcapistd.c', 'jcarith.c', 'jccoefct.c', 'jccolor.c', 'jcdctmgr.c', 'jchuff.c', 'jcinit.c', 'jcmainct.c', 'jcmarker.c', 'jcmaster.c', 'jcomapi.c', 'jcparam.c', 'jcprepct.c', 'jcsample.c', 'jctrans.c', 'jdapimin.c', 'jdapistd.c', 'jdarith.c', 'jdatadst.c', 'jdatasrc.c', 'jdcoefct.c', 'jdcolor.c', 'jddctmgr.c', 'jdhuff.c', 'jdinput.c', 'jdmainct.c', 'jdmarker.c', 'jdmaster.c', 'jdmerge.c', 'jdpostct.c', 'jdsample.c', 'jdtrans.c', 'jerror.c', 'jfdctflt.c', 'jfdctfst.c', 'jfdctint.c', 'jidctflt.c', 'jidctfst.c', 'jidctint.c', 'jmemmgr.c', 'jmemnobs.c', 'jquant1.c', 'jquant2.c', 'jutils.c']; +JPEGLIBOBJ = []; +for fileName in JPEGLIBNAMES: + JPEGLIBOBJ += [JPEGLIB_PREFIX + fileName]; + +LIBPNG_PREFIX = 'libpng/'; +LIBPNGNAMES = ['png.c', 'pngerror.c', 'pngget.c', 'pngmem.c', 'pngpread.c', 'pngread.c', 'pngrio.c', 'pngrtran.c', 'pngrutil.c', 'pngset.c', 'pngtrans.c', 'pngwio.c', 'pngwrite.c', 'pngwtran.c', 'pngwutil.c']; +LIBPNGOBJ = []; +for fileName in LIBPNGNAMES: + LIBPNGOBJ += [LIBPNG_PREFIX + fileName]; + +AESGLADMAN_PREFIX = 'aesGladman/'; +AESGLADMANNAMES = ['aescrypt.cpp', 'aeskey.cpp', 'aestab.cpp', 'fileenc.cpp', 'hmac.cpp', 'prng.cpp', 'pwd2key.cpp', 'sha1.cpp', 'sha2.cpp']; +AESGLADMANOBJ = []; +for fileName in AESGLADMANNAMES: + AESGLADMANOBJ += [AESGLADMAN_PREFIX + fileName]; + +BZIP2_PREFIX = 'bzip2/'; +BZIP2NAMES = ['blocksort.c', 'bzcompress.c', 'bzlib.c', 'crctable.c', 'decompress.c', 'huffman.c', 'randtable.c']; +BZIP2OBJ = []; +for fileName in BZIP2NAMES: + BZIP2OBJ += [BZIP2_PREFIX + fileName]; + +# Next variable is for additional scene nodes etc. of customized Irrlicht versions +EXTRAOBJ = []; + +LINKOBJ = IRRMESHOBJ + IRROBJ + IRRPARTICLEOBJ + IRRANIMOBJ + IRRVIDEOOBJ + IRRSWRENDEROBJ + IRRIOOBJ + IRROTHEROBJ + IRRGUIOBJ + ZLIBOBJ + JPEGLIBOBJ + LIBPNGOBJ + AESGLADMANOBJ + EXTRAOBJ; + +env.Append(LIBS = LIBRARIES, LIBPATH = CXXINCS); + +CXXFLAGS = ['-Wall']; +if NDEBUG: + CXXFLAGS += ['-fexpensive-optimizations', '-O3']; +else: + CXXFLAGS += ['-g', '-D_DEBUG']; + +if PROFILE: + CXXFLAGS += ['-pg']; + +CXXFLAGS += ['-DPNG_NO_MMX_CODE', '-DPNG_NO_MNG_FEATURES', '-DIRRLICHT_EXPORTS=1', '-D_IRR_STATIC_LIB_']; +if USE_GCC: + CXXFLAGS += ['-D__GNUWIN32__=1']; + +env.Append(CCFLAGS = CXXFLAGS); + +IrrlichtLibrary = env.SharedLibrary("Irrlicht.dll", LINKOBJ); diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_compile_config.h b/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_compile_config.h new file mode 100644 index 0000000..60d5f62 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_compile_config.h @@ -0,0 +1,104 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__ +#define __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__ + +#include "IrrCompileConfig.h" + + +// Generic Render Flags for burning's video rasterizer +// defined now in irrlicht compile config + + +#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL + #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #define SOFTWARE_DRIVER_2_SUBTEXEL + #define SOFTWARE_DRIVER_2_BILINEAR + #define SOFTWARE_DRIVER_2_LIGHTING + #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #define SOFTWARE_DRIVER_2_32BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + #define SOFTWARE_DRIVER_2_USE_WBUFFER + #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM + #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0 +#endif + +//! Set Flags for Windows Mobile +#ifdef BURNINGVIDEO_RENDERER_CE + #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #define SOFTWARE_DRIVER_2_SUBTEXEL + //#define SOFTWARE_DRIVER_2_BILINEAR + //#define SOFTWARE_DRIVER_2_LIGHTING + #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #define SOFTWARE_DRIVER_2_16BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + #define SOFTWARE_DRIVER_2_USE_WBUFFER + //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM + #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128 +#endif + +#ifdef BURNINGVIDEO_RENDERER_FAST + #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #define SOFTWARE_DRIVER_2_SUBTEXEL + //#define SOFTWARE_DRIVER_2_BILINEAR + //#define SOFTWARE_DRIVER_2_LIGHTING + //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + #define SOFTWARE_DRIVER_2_32BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + #define SOFTWARE_DRIVER_2_USE_WBUFFER + #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0 +#endif + +#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST + #define BURNINGVIDEO_RENDERER_FAST + + //#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + #define SOFTWARE_DRIVER_2_SUBTEXEL + //#define SOFTWARE_DRIVER_2_BILINEAR + //#define SOFTWARE_DRIVER_2_LIGHTING + //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR + //#define SOFTWARE_DRIVER_2_32BIT + #define SOFTWARE_DRIVER_2_MIPMAPPING + #define SOFTWARE_DRIVER_2_USE_WBUFFER + #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0 +#endif + +// Derivate flags + +// texture format +#ifdef SOFTWARE_DRIVER_2_32BIT + #define BURNINGSHADER_COLOR_FORMAT ECF_A8R8G8B8 +#else + #define BURNINGSHADER_COLOR_FORMAT ECF_A1R5G5B5 +#endif + +// mip mapping +#if defined ( SOFTWARE_DRIVER_2_MIPMAPPING ) + #if defined( BURNINGVIDEO_RENDERER_BEAUTIFUL ) + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0 + #elif defined ( BURNINGVIDEO_RENDERER_CE ) + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0 + #else + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0 + #endif +#else + #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1 + #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0 +#endif + +#define SOFTWARE_DRIVER_2_MIPMAPPING_SCALE (8/SOFTWARE_DRIVER_2_MIPMAPPING_MAX) + +#ifndef REALINLINE + #ifdef _MSC_VER + #define REALINLINE __forceinline + #else + #define REALINLINE inline + #endif +#endif + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h b/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h new file mode 100644 index 0000000..263548b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h @@ -0,0 +1,1042 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +/* + History: + - changed behavior for log2 textures ( replaced multiplies by shift ) +*/ + +#ifndef __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__ +#define __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__ + +#include "SoftwareDriver2_compile_config.h" +#include "irrMath.h" +#include "CSoftwareTexture2.h" +#include "SMaterial.h" + + + +namespace irr +{ + +// supporting different packed pixel needs many defines... + +#ifdef SOFTWARE_DRIVER_2_32BIT + typedef u32 tVideoSample; + + #define MASK_A 0xFF000000 + #define MASK_R 0x00FF0000 + #define MASK_G 0x0000FF00 + #define MASK_B 0x000000FF + + #define SHIFT_A 24 + #define SHIFT_R 16 + #define SHIFT_G 8 + #define SHIFT_B 0 + + #define COLOR_MAX 0xFF + #define COLOR_MAX_LOG2 8 + #define COLOR_BRIGHT_WHITE 0xFFFFFFFF + + #define VIDEO_SAMPLE_GRANULARITY 2 + +#else + typedef u16 tVideoSample; + + #define MASK_A 0x8000 + #define MASK_R 0x7C00 + #define MASK_G 0x03E0 + #define MASK_B 0x001F + + #define SHIFT_A 15 + #define SHIFT_R 10 + #define SHIFT_G 5 + #define SHIFT_B 0 + + #define COLOR_MAX 0x1F + #define COLOR_MAX_LOG2 5 + #define COLOR_BRIGHT_WHITE 0xFFFF + #define VIDEO_SAMPLE_GRANULARITY 1 + +#endif + + + + +// ----------------------- Generic ---------------------------------- + +//! a more useful memset for pixel +// (standard memset only works with 8-bit values) +inline void memset32(void * dest, const u32 value, u32 bytesize) +{ + u32 * d = (u32*) dest; + + u32 i; + + // loops unrolled to reduce the number of increments by factor ~8. + i = bytesize >> (2 + 3); + while (i) + { + d[0] = value; + d[1] = value; + d[2] = value; + d[3] = value; + + d[4] = value; + d[5] = value; + d[6] = value; + d[7] = value; + + d += 8; + i -= 1; + } + + i = (bytesize >> 2 ) & 7; + while (i) + { + d[0] = value; + d += 1; + i -= 1; + } +} + +//! a more useful memset for pixel +// (standard memset only works with 8-bit values) +inline void memset16(void * dest, const u16 value, u32 bytesize) +{ + u16 * d = (u16*) dest; + + u32 i; + + // loops unrolled to reduce the number of increments by factor ~8. + i = bytesize >> (1 + 3); + while (i) + { + d[0] = value; + d[1] = value; + d[2] = value; + d[3] = value; + + d[4] = value; + d[5] = value; + d[6] = value; + d[7] = value; + + d += 8; + --i; + } + + i = (bytesize >> 1 ) & 7; + while (i) + { + d[0] = value; + ++d; + --i; + } +} + +/* + use biased loop counter + --> 0 byte copy is forbidden +*/ +REALINLINE void memcpy32_small ( void * dest, const void *source, u32 bytesize ) +{ + u32 c = bytesize >> 2; + + do + { + ((u32*) dest ) [ c-1 ] = ((u32*) source) [ c-1 ]; + } while ( --c ); + +} + + + +// integer log2 of a float ieee 754. TODO: non ieee floating point +static inline s32 s32_log2_f32( f32 f) +{ + u32 x = IR ( f ); + return ((x & 0x7F800000) >> 23) - 127; +} + +static inline s32 s32_log2_s32(u32 x) +{ + return s32_log2_f32( (f32) x); +} + +static inline s32 s32_abs(s32 x) +{ + s32 b = x >> 31; + return (x ^ b ) - b; +} + + +//! conditional set based on mask and arithmetic shift +REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b ) +{ + return ( mask & ( a ^ b ) ) ^ b; +} + +// ------------------ Video--------------------------------------- +/*! + Pixel = dest * ( 1 - alpha ) + source * alpha + alpha [0;256] +*/ +REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha ) +{ + u32 srcRB = c1 & 0x00FF00FF; + u32 srcXG = c1 & 0x0000FF00; + + u32 dstRB = c2 & 0x00FF00FF; + u32 dstXG = c2 & 0x0000FF00; + + + u32 rb = srcRB - dstRB; + u32 xg = srcXG - dstXG; + + rb *= alpha; + xg *= alpha; + rb >>= 8; + xg >>= 8; + + rb += dstRB; + xg += dstXG; + + rb &= 0x00FF00FF; + xg &= 0x0000FF00; + + return rb | xg; +} + +/*! + Pixel = dest * ( 1 - alpha ) + source * alpha + alpha [0;32] +*/ +inline u16 PixelBlend16 ( const u16 c2, const u32 c1, const u16 alpha ) +{ + const u16 srcRB = c1 & 0x7C1F; + const u16 srcXG = c1 & 0x03E0; + + const u16 dstRB = c2 & 0x7C1F; + const u16 dstXG = c2 & 0x03E0; + + u32 rb = srcRB - dstRB; + u32 xg = srcXG - dstXG; + + rb *= alpha; + xg *= alpha; + rb >>= 5; + xg >>= 5; + + rb += dstRB; + xg += dstXG; + + rb &= 0x7C1F; + xg &= 0x03E0; + + return (u16)(rb | xg); +} + +/* + Pixel = c0 * (c1/31). c0 Alpha retain +*/ +inline u16 PixelMul16 ( const u16 c0, const u16 c1) +{ + return (u16)((( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 ) | + (( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 ) | + (( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 ) | + (c0 & 0x8000)); +} + +/* + Pixel = c0 * (c1/31). +*/ +inline u16 PixelMul16_2 ( u16 c0, u16 c1) +{ + return (u16)(( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 | + ( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 | + ( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 | + ( c0 & c1 & 0x8000)); +} + +/* + Pixel = c0 * (c1/255). c0 Alpha Retain +*/ +REALINLINE u32 PixelMul32 ( const u32 c0, const u32 c1) +{ + return (c0 & 0xFF000000) | + (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) | + (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) | + (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF); +} + +/* + Pixel = c0 * (c1/255). +*/ +REALINLINE u32 PixelMul32_2 ( const u32 c0, const u32 c1) +{ + return (( ( (c0 & 0xFF000000) >> 16 ) * ( (c1 & 0xFF000000) >> 16 ) ) & 0xFF000000 ) | + (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) | + (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) | + (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF); +} + +/* + Pixel = clamp ( c0 + c1, 0, 255 ) +*/ +REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1) +{ + u32 sum = ( c2 & 0x00FFFFFF ) + ( c1 & 0x00FFFFFF ); + u32 low_bits = ( c2 ^ c1 ) & 0x00010101; + s32 carries = ( sum - low_bits ) & 0x01010100; + u32 modulo = sum - carries; + u32 clamp = carries - ( carries >> 8 ); + return modulo | clamp; +} + +#if 0 + +// 1 - Bit Alpha Blending +inline u16 PixelBlend16 ( const u16 destination, const u16 source ) +{ + if((source & 0x8000) == 0x8000) + return source; // The source is visible, so use it. + else + return destination; // The source is transparent, so use the destination. +} + +// 1 - Bit Alpha Blending 16Bit SIMD +inline u32 PixelBlend16_simd ( const u32 destination, const u32 source ) +{ + switch(source & 0x80008000) + { + case 0x80008000: // Both source pixels are visible + return source; + + case 0x80000000: // Only the first source pixel is visible + return (source & 0xFFFF0000) | (destination & 0x0000FFFF); + + case 0x00008000: // Only the second source pixel is visible. + return (destination & 0xFFFF0000) | (source & 0x0000FFFF); + + default: // Neither source pixel is visible. + return destination; + } +} +#else + +// 1 - Bit Alpha Blending +inline u16 PixelBlend16 ( const u16 c2, const u16 c1 ) +{ + u16 mask = ((c1 & 0x8000) >> 15 ) + 0x7fff; + return (c2 & mask ) | ( c1 & ~mask ); +} + +// 1 - Bit Alpha Blending 16Bit SIMD +inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 ) +{ + u32 mask = ((c1 & 0x80008000) >> 15 ) + 0x7fff7fff; + return (c2 & mask ) | ( c1 & ~mask ); +} + +#endif + +/*! + Pixel = dest * ( 1 - SourceAlpha ) + source * SourceAlpha +*/ +inline u32 PixelBlend32 ( const u32 c2, const u32 c1 ) +{ + // alpha test + u32 alpha = c1 & 0xFF000000; + + if ( 0 == alpha ) + return c2; + + if ( 0xFF000000 == alpha ) + { + return c1; + } + + alpha >>= 24; + + // add highbit alpha, if ( alpha > 127 ) alpha += 1; + alpha += ( alpha >> 7); + + u32 srcRB = c1 & 0x00FF00FF; + u32 srcXG = c1 & 0x0000FF00; + + u32 dstRB = c2 & 0x00FF00FF; + u32 dstXG = c2 & 0x0000FF00; + + + u32 rb = srcRB - dstRB; + u32 xg = srcXG - dstXG; + + rb *= alpha; + xg *= alpha; + rb >>= 8; + xg >>= 8; + + rb += dstRB; + xg += dstXG; + + rb &= 0x00FF00FF; + xg &= 0x0000FF00; + + return (c1 & 0xFF000000) | rb | xg; +} + + + +// ------------------ Fix Point ---------------------------------- + +typedef s32 tFixPoint; +typedef u32 tFixPointu; + +// Fix Point 12 +#if 0 + #define FIX_POINT_PRE 12 + #define FIX_POINT_FRACT_MASK 0xFFF + #define FIX_POINT_SIGNED_MASK 0xFFFFF000 + #define FIX_POINT_UNSIGNED_MASK 0x7FFFF000 + #define FIX_POINT_ONE 0x1000 + #define FIX_POINT_ZERO_DOT_FIVE 0x0800 + #define FIX_POINT_F32_MUL 4096.f +#endif + +// Fix Point 10 +#if 1 + #define FIX_POINT_PRE 10 + #define FIX_POINT_FRACT_MASK 0x3FF + #define FIX_POINT_SIGNED_MASK 0xFFFFFC00 + #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00 + #define FIX_POINT_ONE 0x400 + #define FIX_POINT_ZERO_DOT_FIVE 0x200 + #define FIX_POINT_F32_MUL 1024.f +#endif + +// Fix Point 9 +#if 0 + #define FIX_POINT_PRE 9 + #define FIX_POINT_FRACT_MASK 0x1FF + #define FIX_POINT_SIGNED_MASK 0xFFFFFE00 + #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00 + #define FIX_POINT_ONE 0x200 + #define FIX_POINT_ZERO_DOT_FIVE 0x100 + #define FIX_POINT_F32_MUL 512.f +#endif + +// Fix Point 7 +#if 0 + #define FIX_POINT_PRE 7 + #define FIX_POINT_FRACT_MASK 0x7F + #define FIX_POINT_SIGNED_MASK 0xFFFFFF80 + #define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80 + #define FIX_POINT_ONE 0x80 + #define FIX_POINT_ZERO_DOT_FIVE 0x40 + #define FIX_POINT_F32_MUL 128.f +#endif + +#define FIXPOINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE ) +#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) ) + + +/* + convert signed integer to fixpoint +*/ +inline tFixPoint s32_to_fixPoint (const s32 x) +{ + return x << FIX_POINT_PRE; +} + +inline tFixPointu u32_to_fixPoint (const u32 x) +{ + return x << FIX_POINT_PRE; +} + +inline u32 fixPointu_to_u32 (const tFixPointu x) +{ + return x >> FIX_POINT_PRE; +} + + +// 1/x * FIX_POINT +REALINLINE f32 fix_inverse32 ( const f32 x ) +{ + return FIX_POINT_F32_MUL / x; +} + + +/* + convert float to fixpoint + fast convert (fistp on x86) HAS to be used.. + hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different + others should use their favourite assembler.. +*/ +static inline int f_round2(f32 f) +{ + f += (3<<22); + return IR(f) - 0x4b400000; +} + +/* + convert f32 to Fix Point. + multiply is needed anyway, so scale mulby +*/ +REALINLINE tFixPoint tofix (const f32 x, const f32 mulby = FIX_POINT_F32_MUL ) +{ + return (tFixPoint) (x * mulby); +} + + +/* + Fix Point , Fix Point Multiply +*/ +REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y) +{ + return (x * y) >> (tFixPointu) FIX_POINT_PRE; +} + +/* + Fix Point , Fix Point Multiply +*/ +REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y) +{ + return ( x * y) >> ( FIX_POINT_PRE ); +} + +/* + Fix Point , Fix Point Multiply x * y * 2 +*/ +REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y) +{ + return ( x * y) >> ( FIX_POINT_PRE -1 ); +} + + +/* + Multiply x * y * 1 +*/ +REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y) +{ + return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 4 ); +} + +/* + Multiply x * y * 2 +*/ +REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y) +{ + return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 3 ); +} + +/* + Multiply x * y * 4 +*/ +REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y) +{ +#ifdef SOFTWARE_DRIVER_2_32BIT + return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 ); +#else + return ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) ); +#endif +} + +/*! + clamp FixPoint to maxcolor in FixPoint, min(a,31) +*/ +REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a) +{ + tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31; + return (a & c) | ( FIXPOINT_COLOR_MAX & ~c); +} + +/*! + clamp FixPoint to 0 in FixPoint, max(a,0) +*/ +REALINLINE tFixPoint clampfix_mincolor ( const tFixPoint a) +{ + return a - ( a & ( a >> 31 ) ); +} + +REALINLINE tFixPoint saturateFix ( const tFixPoint a) +{ + return clampfix_mincolor ( clampfix_maxcolor ( a ) ); +} + + +// rount fixpoint to int +inline s32 roundFix ( const tFixPoint x ) +{ + return ( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE; +} + + + +// x in [0;1[ +inline s32 f32_to_23Bits(const f32 x) +{ + f32 y = x + 1.f; + return IR(y) & 0x7FFFFF; // last 23 bits +} + +/*! + return VideoSample from fixpoint +*/ +REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, const tFixPoint b ) +{ +#ifdef __BIG_ENDIAN__ + return FIXPOINT_COLOR_MAX | + ( r & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - 8) | + ( g & FIXPOINT_COLOR_MAX) << ( 16 - FIX_POINT_PRE ) | + ( b & FIXPOINT_COLOR_MAX) << ( 24 - FIX_POINT_PRE ); +#else + return ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) | + ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) | + ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) | + ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B ); +#endif +} + + +/*! + return VideoSample from fixpoint +*/ +REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b ) +{ +#ifdef __BIG_ENDIAN__ + return ( a & (FIX_POINT_FRACT_MASK - 1 )) >> ( FIX_POINT_PRE ) | + ( r & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - 8) | + ( g & FIXPOINT_COLOR_MAX) << ( 16 - FIX_POINT_PRE ) | + ( b & FIXPOINT_COLOR_MAX) << ( 24 - FIX_POINT_PRE ); +#else + return ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) | + ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) | + ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) | + ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B ); +#endif + +} + +/*! + return fixpoint from VideoSample granularity COLOR_MAX +*/ +inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +{ + (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE ); + (tFixPointu&) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); +} + +/*! + return fixpoint from VideoSample granularity COLOR_MAX +*/ +inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +{ + (tFixPointu&) a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE ); + (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE ); + (tFixPointu&) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); +} + +/*! + return fixpoint from VideoSample granularity 0..FIX_POINT_ONE +*/ +inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +{ + (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE ); + (tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE ); + (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 ); +} + +/*! + return fixpoint from VideoSample granularity 0..FIX_POINT_ONE +*/ +inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +{ + (tFixPointu&) a = (t00 & MASK_A) >> ( SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE ); + (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE ); + (tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE ); + (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 ); +} + + + +// ----- FP24 ---- floating point z-buffer + +#if 1 +typedef f32 fp24; +#else +struct fp24 +{ + u32 v; + + fp24() {} + + fp24 ( const f32 f ) + { + f32 y = f + 1.f; + v = ((u32&)y) & 0x7FFFFF; // last 23 bits + } + + void operator=(const f32 f ) + { + f32 y = f + 1.f; + v = ((u32&)y) & 0x7FFFFF; // last 23 bits + } + + void operator+=(const fp24 &other ) + { + v += other.v; + } + + operator f32 () const + { + f32 r = FR ( v ); + return r + 1.f; + } + +}; +#endif + + +// ------------------------ Internal Texture ----------------------------- + +struct sInternalTexture +{ + u32 textureXMask; + u32 textureYMask; + + u32 pitchlog2; + void *data; + + video::CSoftwareTexture2 *Texture; + s32 lodLevel; +}; + + + +// get video sample plain +inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + return *((tVideoSample*)( (u8*) t->data + ofs )); +} + +// get video sample to fix +inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + +} + +// get video sample to fixpoint +REALINLINE void getTexel_fix ( tFixPoint &a, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE); +} + + +inline void getSample_texture_dither ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty, + const u32 x, const u32 y + ) +{ + static const tFixPointu dithermask[] = + { + 0x00,0x80,0x20,0xa0, + 0xc0,0x40,0xe0,0x60, + 0x30,0xb0,0x10,0x90, + 0xf0,0x70,0xd0,0x50 + }; + + const u32 index = (y & 3 ) << 2 | (x & 3); + + const tFixPointu _ntx = (tx + dithermask [ index ] ) & t->textureXMask; + const tFixPointu _nty = (ty + dithermask [ index ] ) & t->textureYMask; + + u32 ofs; + ofs = ( ( _nty ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( _ntx ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + +} + +/* + load a sample from internal texture at position tx,ty to fixpoint +*/ +#ifndef SOFTWARE_DRIVER_2_BILINEAR + +// get Sample linear == getSample_fixpoint + +inline void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); +} + +inline void getSample_texture ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + (tFixPointu &)a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE); + (tFixPointu &)r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); + (tFixPointu &)g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); + (tFixPointu &)b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); +} + + +#else + + +// get sample linear +REALINLINE void getSample_linear ( tFixPointu &r, tFixPointu &g, tFixPointu &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + r = (t00 & MASK_R) >> SHIFT_R; + g = (t00 & MASK_G) >> SHIFT_G; + b = (t00 & MASK_B); +} + +// get Sample bilinear +REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + + tFixPointu r00,g00,b00; + tFixPointu r01,g01,b01; + tFixPointu r10,g10,b10; + tFixPointu r11,g11,b11; + +#if 0 + getSample_linear ( r00, g00, b00, t, tx,ty ); + getSample_linear ( r10, g10, b10, t, tx + FIX_POINT_ONE,ty ); + getSample_linear ( r01, g01, b01, t, tx,ty + FIX_POINT_ONE ); + getSample_linear ( r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE ); +#else + u32 o0, o1,o2,o3; + tVideoSample t00; + + o0 = ( ( (ty) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + o1 = ( ( (ty+FIX_POINT_ONE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + o2 = ( (tx) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + o3 = ( (tx+FIX_POINT_ONE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o2 ) )); + r00 = (t00 & MASK_R) >> SHIFT_R; g00 = (t00 & MASK_G) >> SHIFT_G; b00 = (t00 & MASK_B); + + t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o3 ) )); + r10 = (t00 & MASK_R) >> SHIFT_R; g10 = (t00 & MASK_G) >> SHIFT_G; b10 = (t00 & MASK_B); + + t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o2 ) )); + r01 = (t00 & MASK_R) >> SHIFT_R; g01 = (t00 & MASK_G) >> SHIFT_G; b01 = (t00 & MASK_B); + + t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o3 ) )); + r11 = (t00 & MASK_R) >> SHIFT_R; g11 = (t00 & MASK_G) >> SHIFT_G; b11 = (t00 & MASK_B); + +#endif + + const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK; + const tFixPointu txFractInv = FIX_POINT_ONE - txFract; + + const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK; + const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract; + + const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv ); + const tFixPointu w10 = imulFixu ( txFract , tyFractInv ); + const tFixPointu w01 = imulFixu ( txFractInv, tyFract ); + const tFixPointu w11 = imulFixu ( txFract , tyFract ); + + r = (r00 * w00 ) + + (r01 * w01 ) + + (r10 * w10 ) + + (r11 * w11 ); + + g = (g00 * w00 ) + + (g01 * w01 ) + + (g10 * w10 ) + + (g11 * w11 ); + + b = (b00 * w00 ) + + (b01 * w01 ) + + (b10 * w10 ) + + (b11 * w11 ); + +} + + +// get sample linear +REALINLINE void getSample_linear ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + u32 ofs; + + ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; + ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + + a = (t00 & MASK_A) >> SHIFT_A; + r = (t00 & MASK_R) >> SHIFT_R; + g = (t00 & MASK_G) >> SHIFT_G; + b = (t00 & MASK_B); +} + +// get Sample bilinear +REALINLINE void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, + const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty + ) +{ + + tFixPointu a00, r00,g00,b00; + tFixPointu a01, r01,g01,b01; + tFixPointu a10, r10,g10,b10; + tFixPointu a11, r11,g11,b11; + + getSample_linear ( a00, r00, g00, b00, t, tx,ty ); + getSample_linear ( a10, r10, g10, b10, t, tx + FIX_POINT_ONE,ty ); + getSample_linear ( a01, r01, g01, b01, t, tx,ty + FIX_POINT_ONE ); + getSample_linear ( a11, r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE ); + + const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK; + const tFixPointu txFractInv = FIX_POINT_ONE - txFract; + + const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK; + const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract; + + const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv ); + const tFixPointu w10 = imulFixu ( txFract , tyFractInv ); + const tFixPointu w01 = imulFixu ( txFractInv, tyFract ); + const tFixPointu w11 = imulFixu ( txFract , tyFract ); + + a = (a00 * w00 ) + + (a01 * w01 ) + + (a10 * w10 ) + + (a11 * w11 ); + + r = (r00 * w00 ) + + (r01 * w01 ) + + (r10 * w10 ) + + (r11 * w11 ); + + g = (g00 * w00 ) + + (g01 * w01 ) + + (g10 * w10 ) + + (g11 * w11 ); + + b = (b00 * w00 ) + + (b01 * w01 ) + + (b10 * w10 ) + + (b11 * w11 ); + +} + + +#endif + +// some 2D Defines +struct AbsRectangle +{ + s32 x0; + s32 y0; + s32 x1; + s32 y1; +}; + +//! 2D Intersection test +inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRectangle& b) +{ + dest.x0 = core::s32_max( a.x0, b.x0 ); + dest.y0 = core::s32_max( a.y0, b.y0 ); + dest.x1 = core::s32_min( a.x1, b.x1 ); + dest.y1 = core::s32_min( a.y1, b.y1 ); + return dest.x0 < dest.x1 && dest.y0 < dest.y1; +} + +// some 1D defines +struct sIntervall +{ + s32 start; + s32 end; +}; + +// returning intersection width +inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b) +{ + return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start ); +} + + +} // end namespace irr + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/Readme.txt b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/Readme.txt new file mode 100644 index 0000000..86842c2 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/Readme.txt @@ -0,0 +1,25 @@ +A File Encryption Utility - VC++ 7.1 project Instructions + +1. Unzip the enclosed files into a suitable VC++ project directory. +2. Obtain the bzip2 source code from http://sources.redhat.com/bzip2/ + and unzip the files into the bzip2 sub-directory. +3. Compile the bzip2 project to give a static library +4. Compile the encfile project. +5. The executable encfile.exe is now ready for use: + + enfile password filename + + If the filename does not have the extension 'enc', it is assumed to + be a normal file that will then be encrypted to a file with the same + name but with an added extension 'enc'. + + If the filename has the extension 'enc' its is assumed to be an + encrypted file that will be decrypted to a file with the same name + but without the 'enc' extension. + +The default HASH function is SHA1, which is set up by defining USE_SHA1 in +compiling the project. If USE_SHA256 is defined instead then SHA256 is used. + +Brian Gladman + + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aes.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aes.h new file mode 100644 index 0000000..127c886 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aes.h @@ -0,0 +1,137 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2003, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This file contains the definitions required to use AES in C. See aesopt.h + for optimisation details. +*/ + +#ifndef _AES_H +#define _AES_H + +#include "irrMath.h" + +#define AES_128 /* define if AES with 128 bit keys is needed */ +#define AES_192 /* define if AES with 192 bit keys is needed */ +#define AES_256 /* define if AES with 256 bit keys is needed */ +#define AES_VAR /* define if a variable key size is needed */ + +/* The following must also be set in assembler files if being used */ + +#define AES_ENCRYPT /* if support for encryption is needed */ +#define AES_DECRYPT /* if support for decryption is needed */ +#define AES_ERR_CHK /* for parameter checks & error return codes */ + +typedef irr::u8 aes_08t; +typedef irr::u32 aes_32t; + +#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ +#define N_COLS 4 /* the number of columns in the state */ + +/* a maximum of 60 32-bit words are needed for the key schedule */ +#define KS_LENGTH 64 + +#ifdef AES_ERR_CHK +#define aes_ret int +#define aes_good 0 +#define aes_error -1 +#else +#define aes_ret void +#endif + +#ifndef AES_DLL /* implement normal/DLL functions */ +#define aes_rval aes_ret +#else +#define aes_rval aes_ret __declspec(dllexport) _stdcall +#endif + +/* This routine must be called before first use if non-static */ +/* tables are being used */ + +void gen_tabs(void); + +/* The key length (klen) is input in bytes when it is in the range */ +/* 16 <= klen <= 32 or in bits when in the range 128 <= klen <= 256 */ + +#ifdef AES_ENCRYPT + +typedef struct +{ + aes_32t ks[KS_LENGTH]; +} aes_encrypt_ctx; + +#if defined(AES_128) || defined(AES_VAR) +aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1]); +#endif + +#if defined(AES_192) || defined(AES_VAR) +aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1]); +#endif + +#if defined(AES_256) || defined(AES_VAR) +aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1]); +#endif + +#if defined(AES_VAR) +aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1]); +#endif + +aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1]); +#endif + +#ifdef AES_DECRYPT + +typedef struct +{ + aes_32t ks[KS_LENGTH]; +} aes_decrypt_ctx; + +#if defined(AES_128) || defined(AES_VAR) +aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1]); +#endif + +#if defined(AES_192) || defined(AES_VAR) +aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1]); +#endif + +#if defined(AES_256) || defined(AES_VAR) +aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1]); +#endif + +#if defined(AES_VAR) +aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1]); +#endif + +aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1]); +#endif + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aescrypt.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aescrypt.cpp new file mode 100644 index 0000000..8d1feee --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aescrypt.cpp @@ -0,0 +1,303 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2003, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This file contains the code for implementing encryption and decryption + for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It + can optionally be replaced by code written in assembler using NASM. For + further details see the file aesopt.h +*/ + +#include "aesopt.h" + +#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c]) +#define so(y,x,c) word_out(y, c, s(x,c)) + +#if defined(ARRAYS) +#define locals(y,x) x[4],y[4] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 +#endif + +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) + +#if defined(ENCRYPTION) && !defined(AES_ASM) + +/* Visual C++ .Net v7.1 provides the fastest encryption code when using + Pentium optimization with small code but this is poor for decryption + so we need to control this with the following VC++ pragmas +*/ + +#if defined(_MSC_VER) +#pragma optimize( "s", on ) +#endif + +/* Given the column (c) of the output state variable, the following + macros give the input state variables which are needed in its + computation for each row (r) of the state. All the alternative + macros give the same end values but expand into different ways + of calculating these values. In particular the complex macro + used for dynamically variable block sizes is designed to expand + to a compile time constant whenever possible but will expand to + conditional clauses on some branches (I am grateful to Frank + Yellin for this construction) +*/ + +#define fwd_var(x,r,c)\ + ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ + : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\ + : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ + : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) + +#if defined(FT4_SET) +#undef dec_fmvars +#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) +#elif defined(FT1_SET) +#undef dec_fmvars +#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c)) +#else +#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c))) +#endif + +#if defined(FL4_SET) +#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c)) +#elif defined(FL1_SET) +#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c)) +#else +#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c)) +#endif + +aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1]) +{ aes_32t locals(b0, b1); + const aes_32t *kp = cx->ks; +#ifdef dec_fmvars + dec_fmvars; /* declare variables for fwd_mcol() if needed */ +#endif + + aes_32t nr = (kp[45] ^ kp[52] ^ kp[53] ? kp[52] : 14); + +#ifdef AES_ERR_CHK + if( (nr != 10 || !(kp[0] | kp[3] | kp[4])) + && (nr != 12 || !(kp[0] | kp[5] | kp[6])) + && (nr != 14 || !(kp[0] | kp[7] | kp[8])) ) + return aes_error; +#endif + + state_in(b0, in_blk, kp); + +#if (ENC_UNROLL == FULL) + + switch(nr) + { + case 14: + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + kp += 2 * N_COLS; + case 12: + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + kp += 2 * N_COLS; + case 10: + round(fwd_rnd, b1, b0, kp + 1 * N_COLS); + round(fwd_rnd, b0, b1, kp + 2 * N_COLS); + round(fwd_rnd, b1, b0, kp + 3 * N_COLS); + round(fwd_rnd, b0, b1, kp + 4 * N_COLS); + round(fwd_rnd, b1, b0, kp + 5 * N_COLS); + round(fwd_rnd, b0, b1, kp + 6 * N_COLS); + round(fwd_rnd, b1, b0, kp + 7 * N_COLS); + round(fwd_rnd, b0, b1, kp + 8 * N_COLS); + round(fwd_rnd, b1, b0, kp + 9 * N_COLS); + round(fwd_lrnd, b0, b1, kp +10 * N_COLS); + } + +#else + +#if (ENC_UNROLL == PARTIAL) + { aes_32t rnd; + for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd) + { + kp += N_COLS; + round(fwd_rnd, b1, b0, kp); + kp += N_COLS; + round(fwd_rnd, b0, b1, kp); + } + kp += N_COLS; + round(fwd_rnd, b1, b0, kp); +#else + { aes_32t rnd; + for(rnd = 0; rnd < nr - 1; ++rnd) + { + kp += N_COLS; + round(fwd_rnd, b1, b0, kp); + l_copy(b0, b1); + } +#endif + kp += N_COLS; + round(fwd_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(DECRYPTION) && !defined(AES_ASM) + +/* Visual C++ .Net v7.1 provides the fastest encryption code when using + Pentium optimization with small code but this is poor for decryption + so we need to control this with the following VC++ pragmas +*/ + +#if defined(_MSC_VER) +#pragma optimize( "t", on ) +#endif + +/* Given the column (c) of the output state variable, the following + macros give the input state variables which are needed in its + computation for each row (r) of the state. All the alternative + macros give the same end values but expand into different ways + of calculating these values. In particular the complex macro + used for dynamically variable block sizes is designed to expand + to a compile time constant whenever possible but will expand to + conditional clauses on some branches (I am grateful to Frank + Yellin for this construction) +*/ + +#define inv_var(x,r,c)\ + ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ + : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\ + : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ + : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))) + +#if defined(IT4_SET) +#undef dec_imvars +#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c)) +#elif defined(IT1_SET) +#undef dec_imvars +#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c)) +#else +#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))) +#endif + +#if defined(IL4_SET) +#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c)) +#elif defined(IL1_SET) +#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c)) +#else +#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)) +#endif + +aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1]) +{ aes_32t locals(b0, b1); +#ifdef dec_imvars + dec_imvars; /* declare variables for inv_mcol() if needed */ +#endif + + aes_32t nr = (cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] ? cx->ks[52] : 14); + const aes_32t *kp = cx->ks + nr * N_COLS; + +#ifdef AES_ERR_CHK + if( (nr != 10 || !(cx->ks[0] | cx->ks[3] | cx->ks[4])) + && (nr != 12 || !(cx->ks[0] | cx->ks[5] | cx->ks[6])) + && (nr != 14 || !(cx->ks[0] | cx->ks[7] | cx->ks[8])) ) + return aes_error; +#endif + + state_in(b0, in_blk, kp); + +#if (DEC_UNROLL == FULL) + + switch(nr) + { + case 14: + round(inv_rnd, b1, b0, kp - 1 * N_COLS); + round(inv_rnd, b0, b1, kp - 2 * N_COLS); + kp -= 2 * N_COLS; + case 12: + round(inv_rnd, b1, b0, kp - 1 * N_COLS); + round(inv_rnd, b0, b1, kp - 2 * N_COLS); + kp -= 2 * N_COLS; + case 10: + round(inv_rnd, b1, b0, kp - 1 * N_COLS); + round(inv_rnd, b0, b1, kp - 2 * N_COLS); + round(inv_rnd, b1, b0, kp - 3 * N_COLS); + round(inv_rnd, b0, b1, kp - 4 * N_COLS); + round(inv_rnd, b1, b0, kp - 5 * N_COLS); + round(inv_rnd, b0, b1, kp - 6 * N_COLS); + round(inv_rnd, b1, b0, kp - 7 * N_COLS); + round(inv_rnd, b0, b1, kp - 8 * N_COLS); + round(inv_rnd, b1, b0, kp - 9 * N_COLS); + round(inv_lrnd, b0, b1, kp - 10 * N_COLS); + } + +#else + +#if (DEC_UNROLL == PARTIAL) + { aes_32t rnd; + for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd) + { + kp -= N_COLS; + round(inv_rnd, b1, b0, kp); + kp -= N_COLS; + round(inv_rnd, b0, b1, kp); + } + kp -= N_COLS; + round(inv_rnd, b1, b0, kp); +#else + { aes_32t rnd; + for(rnd = 0; rnd < nr - 1; ++rnd) + { + kp -= N_COLS; + round(inv_rnd, b1, b0, kp); + l_copy(b0, b1); + } +#endif + kp -= N_COLS; + round(inv_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aeskey.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aeskey.cpp new file mode 100644 index 0000000..12d4cbb --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aeskey.cpp @@ -0,0 +1,455 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2003, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This file contains the code for implementing the key schedule for AES + (Rijndael) for block and key sizes of 16, 24, and 32 bytes. See aesopt.h + for further details including optimisation. +*/ + +#include "aesopt.h" + +/* Initialise the key schedule from the user supplied key. The key + length can be specified in bytes, with legal values of 16, 24 + and 32, or in bits, with legal values of 128, 192 and 256. These + values correspond with Nk values of 4, 6 and 8 respectively. + + The following macros implement a single cycle in the key + schedule generation process. The number of cycles needed + for each cx->n_col and nk value is: + + nk = 4 5 6 7 8 + ------------------------------ + cx->n_col = 4 10 9 8 7 7 + cx->n_col = 5 14 11 10 9 9 + cx->n_col = 6 19 15 12 11 11 + cx->n_col = 7 21 19 16 13 14 + cx->n_col = 8 29 23 19 17 14 +*/ + +#define ke4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +} +#define kel4(k,i) \ +{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \ + k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \ +} + +#define ke6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ + k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \ +} +#define kel6(k,i) \ +{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \ + k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \ +} + +#define ke8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ + k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \ + k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \ +} +#define kel8(k,i) \ +{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \ + k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \ +} + +#if defined(ENCRYPTION_KEY_SCHEDULE) + +#if defined(AES_128) || defined(AES_VAR) + +aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1]) +{ aes_32t ss[4]; + + cx->ks[0] = ss[0] = word_in(in_key, 0); + cx->ks[1] = ss[1] = word_in(in_key, 1); + cx->ks[2] = ss[2] = word_in(in_key, 2); + cx->ks[3] = ss[3] = word_in(in_key, 3); + +#if ENC_UNROLL == NONE + { aes_32t i; + + for(i = 0; i < ((11 * N_COLS - 1) / 4); ++i) + ke4(cx->ks, i); + } +#else + ke4(cx->ks, 0); ke4(cx->ks, 1); + ke4(cx->ks, 2); ke4(cx->ks, 3); + ke4(cx->ks, 4); ke4(cx->ks, 5); + ke4(cx->ks, 6); ke4(cx->ks, 7); + ke4(cx->ks, 8); kel4(cx->ks, 9); +#endif + + /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */ + /* key and must be non-zero for 128 and 192 bits keys */ + cx->ks[53] = cx->ks[45] = 0; + cx->ks[52] = 10; +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(AES_192) || defined(AES_VAR) + +aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1]) +{ aes_32t ss[6]; + + cx->ks[0] = ss[0] = word_in(in_key, 0); + cx->ks[1] = ss[1] = word_in(in_key, 1); + cx->ks[2] = ss[2] = word_in(in_key, 2); + cx->ks[3] = ss[3] = word_in(in_key, 3); + cx->ks[4] = ss[4] = word_in(in_key, 4); + cx->ks[5] = ss[5] = word_in(in_key, 5); + +#if ENC_UNROLL == NONE + { aes_32t i; + + for(i = 0; i < (13 * N_COLS - 1) / 6; ++i) + ke6(cx->ks, i); + } +#else + ke6(cx->ks, 0); ke6(cx->ks, 1); + ke6(cx->ks, 2); ke6(cx->ks, 3); + ke6(cx->ks, 4); ke6(cx->ks, 5); + ke6(cx->ks, 6); kel6(cx->ks, 7); +#endif + + /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */ + /* key and must be non-zero for 128 and 192 bits keys */ + cx->ks[53] = cx->ks[45]; + cx->ks[52] = 12; +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(AES_256) || defined(AES_VAR) + +aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1]) +{ aes_32t ss[8]; + + cx->ks[0] = ss[0] = word_in(in_key, 0); + cx->ks[1] = ss[1] = word_in(in_key, 1); + cx->ks[2] = ss[2] = word_in(in_key, 2); + cx->ks[3] = ss[3] = word_in(in_key, 3); + cx->ks[4] = ss[4] = word_in(in_key, 4); + cx->ks[5] = ss[5] = word_in(in_key, 5); + cx->ks[6] = ss[6] = word_in(in_key, 6); + cx->ks[7] = ss[7] = word_in(in_key, 7); + +#if ENC_UNROLL == NONE + { aes_32t i; + + for(i = 0; i < (15 * N_COLS - 1) / 8; ++i) + ke8(cx->ks, i); + } +#else + ke8(cx->ks, 0); ke8(cx->ks, 1); + ke8(cx->ks, 2); ke8(cx->ks, 3); + ke8(cx->ks, 4); ke8(cx->ks, 5); + kel8(cx->ks, 6); +#endif +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(AES_VAR) + +aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1]) +{ + switch(key_len) + { +#ifdef AES_ERR_CHK + case 16: case 128: return aes_encrypt_key128(in_key, cx); + case 24: case 192: return aes_encrypt_key192(in_key, cx); + case 32: case 256: return aes_encrypt_key256(in_key, cx); + default: return aes_error; +#else + case 16: case 128: aes_encrypt_key128(in_key, cx); return; + case 24: case 192: aes_encrypt_key192(in_key, cx); return; + case 32: case 256: aes_encrypt_key256(in_key, cx); return; +#endif + } +} + +#endif + +#endif + +#if defined(DECRYPTION_KEY_SCHEDULE) + +#if DEC_ROUND == NO_TABLES +#define ff(x) (x) +#else +#define ff(x) inv_mcol(x) +#ifdef dec_imvars +#define d_vars dec_imvars +#endif +#endif + +#if 1 +#define kdf4(k,i) \ +{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \ + ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ + ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \ + ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \ +} +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ + k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \ + k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \ +} +#define kdl4(k,i) \ +{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ + k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \ + k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \ +} +#else +#define kdf4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \ +} +#define kd4(k,i) \ +{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \ + ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \ + ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \ +} +#define kdl4(k,i) \ +{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \ + ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \ +} +#endif + +#define kdf6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \ + ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \ +} +#define kd6(k,i) \ +{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \ + ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \ + ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \ + ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \ + ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \ + ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \ +} +#define kdl6(k,i) \ +{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \ + ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \ +} + +#define kdf8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \ + ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \ + ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \ + ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \ +} +#define kd8(k,i) \ +{ aes_32t g = ls_box(ss[7],3) ^ t_use(r,c)[i]; \ + ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \ + ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \ + ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \ + ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \ + g = ls_box(ss[3],0); \ + ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \ + ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \ + ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \ + ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \ +} +#define kdl8(k,i) \ +{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \ + ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \ +} + +#if defined(AES_128) || defined(AES_VAR) + +aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1]) +{ aes_32t ss[5]; +#ifdef d_vars + d_vars; +#endif + cx->ks[0] = ss[0] = word_in(in_key, 0); + cx->ks[1] = ss[1] = word_in(in_key, 1); + cx->ks[2] = ss[2] = word_in(in_key, 2); + cx->ks[3] = ss[3] = word_in(in_key, 3); + +#if DEC_UNROLL == NONE + { aes_32t i; + + for(i = 0; i < (11 * N_COLS - 1) / 4; ++i) + ke4(cx->ks, i); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 10 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#else + kdf4(cx->ks, 0); kd4(cx->ks, 1); + kd4(cx->ks, 2); kd4(cx->ks, 3); + kd4(cx->ks, 4); kd4(cx->ks, 5); + kd4(cx->ks, 6); kd4(cx->ks, 7); + kd4(cx->ks, 8); kdl4(cx->ks, 9); +#endif + + /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */ + /* key and must be non-zero for 128 and 192 bits keys */ + cx->ks[53] = cx->ks[45] = 0; + cx->ks[52] = 10; +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(AES_192) || defined(AES_VAR) + +aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1]) +{ aes_32t ss[7]; +#ifdef d_vars + d_vars; +#endif + cx->ks[0] = ss[0] = word_in(in_key, 0); + cx->ks[1] = ss[1] = word_in(in_key, 1); + cx->ks[2] = ss[2] = word_in(in_key, 2); + cx->ks[3] = ss[3] = word_in(in_key, 3); + +#if DEC_UNROLL == NONE + cx->ks[4] = ss[4] = word_in(in_key, 4); + cx->ks[5] = ss[5] = word_in(in_key, 5); + { aes_32t i; + + for(i = 0; i < (13 * N_COLS - 1) / 6; ++i) + ke6(cx->ks, i); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 12 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#else + cx->ks[4] = ff(ss[4] = word_in(in_key, 4)); + cx->ks[5] = ff(ss[5] = word_in(in_key, 5)); + kdf6(cx->ks, 0); kd6(cx->ks, 1); + kd6(cx->ks, 2); kd6(cx->ks, 3); + kd6(cx->ks, 4); kd6(cx->ks, 5); + kd6(cx->ks, 6); kdl6(cx->ks, 7); +#endif + + /* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */ + /* key and must be non-zero for 128 and 192 bits keys */ + cx->ks[53] = cx->ks[45]; + cx->ks[52] = 12; +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(AES_256) || defined(AES_VAR) + +aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1]) +{ aes_32t ss[8]; +#ifdef d_vars + d_vars; +#endif + cx->ks[0] = ss[0] = word_in(in_key, 0); + cx->ks[1] = ss[1] = word_in(in_key, 1); + cx->ks[2] = ss[2] = word_in(in_key, 2); + cx->ks[3] = ss[3] = word_in(in_key, 3); + +#if DEC_UNROLL == NONE + cx->ks[4] = ss[4] = word_in(in_key, 4); + cx->ks[5] = ss[5] = word_in(in_key, 5); + cx->ks[6] = ss[6] = word_in(in_key, 6); + cx->ks[7] = ss[7] = word_in(in_key, 7); + { aes_32t i; + + for(i = 0; i < (15 * N_COLS - 1) / 8; ++i) + ke8(cx->ks, i); +#if !(DEC_ROUND == NO_TABLES) + for(i = N_COLS; i < 14 * N_COLS; ++i) + cx->ks[i] = inv_mcol(cx->ks[i]); +#endif + } +#else + cx->ks[4] = ff(ss[4] = word_in(in_key, 4)); + cx->ks[5] = ff(ss[5] = word_in(in_key, 5)); + cx->ks[6] = ff(ss[6] = word_in(in_key, 6)); + cx->ks[7] = ff(ss[7] = word_in(in_key, 7)); + kdf8(cx->ks, 0); kd8(cx->ks, 1); + kd8(cx->ks, 2); kd8(cx->ks, 3); + kd8(cx->ks, 4); kd8(cx->ks, 5); + kdl8(cx->ks, 6); +#endif +#ifdef AES_ERR_CHK + return aes_good; +#endif +} + +#endif + +#if defined(AES_VAR) + +aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1]) +{ + switch(key_len) + { +#ifdef AES_ERR_CHK + case 16: case 128: return aes_decrypt_key128(in_key, cx); + case 24: case 192: return aes_decrypt_key192(in_key, cx); + case 32: case 256: return aes_decrypt_key256(in_key, cx); + default: return aes_error; +#else + case 16: case 128: aes_decrypt_key128(in_key, cx); return; + case 24: case 192: aes_decrypt_key192(in_key, cx); return; + case 32: case 256: aes_decrypt_key256(in_key, cx); return; +#endif + } +} + +#endif + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aesopt.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aesopt.h new file mode 100644 index 0000000..9c0d842 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aesopt.h @@ -0,0 +1,955 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2003, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + My thanks go to Dag Arne Osvik for devising the schemes used here for key + length derivation from the form of the key schedule + + This file contains the compilation options for AES (Rijndael) and code + that is common across encryption, key scheduling and table generation. + + OPERATION + + These source code files implement the AES algorithm Rijndael designed by + Joan Daemen and Vincent Rijmen. This version is designed for the standard + block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24 + and 32 bytes). + + This version is designed for flexibility and speed using operations on + 32-bit words rather than operations on bytes. It can be compiled with + either big or little endian internal byte order but is faster when the + native byte order for the processor is used. + + THE CIPHER INTERFACE + + The cipher interface is implemented as an array of bytes in which lower + AES bit sequence indexes map to higher numeric significance within bytes. + + aes_08t (an unsigned 8-bit type) + aes_32t (an unsigned 32-bit type) + struct aes_encrypt_ctx (structure for the cipher encryption context) + struct aes_decrypt_ctx (structure for the cipher decryption context) + aes_rval the function return type + + C subroutine calls: + + aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1]); + aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1]); + aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1]); + aes_rval aes_encrypt(const void *in_blk, + void *out_blk, const aes_encrypt_ctx cx[1]); + + aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1]); + aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1]); + aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1]); + aes_rval aes_decrypt(const void *in_blk, + void *out_blk, const aes_decrypt_ctx cx[1]); + + IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that + you call genTabs() before AES is used so that the tables are initialised. + + C++ aes class subroutines: + + Class AESencrypt for encryption + + Construtors: + AESencrypt(void) + AESencrypt(const void *in_key) - 128 bit key + Members: + void key128(const void *in_key) + void key192(const void *in_key) + void key256(const void *in_key) + void encrypt(const void *in_blk, void *out_blk) const + + Class AESdecrypt for encryption + Construtors: + AESdecrypt(void) + AESdecrypt(const void *in_key) - 128 bit key + Members: + void key128(const void *in_key) + void key192(const void *in_key) + void key256(const void *in_key) + void decrypt(const void *in_blk, void *out_blk) const + + COMPILATION + + The files used to provide AES (Rijndael) are + + a. aes.h for the definitions needed for use in C. + b. aescpp.h for the definitions needed for use in C++. + c. aesopt.h for setting compilation options (also includes common code). + d. aescrypt.c for encryption and decrytpion, or + e. aeskey.c for key scheduling. + f. aestab.c for table loading or generation. + g. aescrypt.asm for encryption and decryption using assembler code. + h. aescrypt.mmx.asm for encryption and decryption using MMX assembler. + + To compile AES (Rijndael) for use in C code use aes.h and set the + defines here for the facilities you need (key lengths, encryption + and/or decryption). Do not define AES_DLL or AES_CPP. Set the options + for optimisations and table sizes here. + + To compile AES (Rijndael) for use in in C++ code use aescpp.h but do + not define AES_DLL + + To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use + aes.h and include the AES_DLL define. + + CONFIGURATION OPTIONS (here and in aes.h) + + a. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL + b. You may need to set PLATFORM_BYTE_ORDER to define the byte order. + c. If you want the code to run in a specific internal byte order, then + ALGORITHM_BYTE_ORDER must be set accordingly. + d. set other configuration options decribed below. +*/ + +#ifndef _AESOPT_H +#define _AESOPT_H + +#include "aes.h" + +/* CONFIGURATION - USE OF DEFINES + + Later in this section there are a number of defines that control the + operation of the code. In each section, the purpose of each define is + explained so that the relevant form can be included or excluded by + setting either 1's or 0's respectively on the branches of the related + #if clauses. +*/ + +/* BYTE ORDER IN 32-BIT WORDS + + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the byte order of the target machine. The following + block of code is an attempt to capture the most obvious ways in which + various environemnts define byte order. It may well fail, in which case + the definitions will need to be set by editing at the points marked + **** EDIT HERE IF NECESSARY **** below. My thanks to Peter Gutmann for + some of these defines (from cryptlib). +*/ + +#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ + +#ifdef __BIG_ENDIAN__ +#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN +#else +#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN +#endif + +/* SOME LOCAL DEFINITIONS */ + +#define NO_TABLES 0 +#define ONE_TABLE 1 +#define FOUR_TABLES 4 +#define NONE 0 +#define PARTIAL 1 +#define FULL 2 + +#define aes_sw32 Byteswap::byteswap + +/* 1. FUNCTIONS REQUIRED + + This implementation provides subroutines for encryption, decryption + and for setting the three key lengths (separately) for encryption + and decryption. When the assembler code is not being used the following + definition blocks allow the selection of the routines that are to be + included in the compilation. +*/ +#ifdef AES_ENCRYPT +#define ENCRYPTION +#define ENCRYPTION_KEY_SCHEDULE +#endif + +#ifdef AES_DECRYPT +#define DECRYPTION +#define DECRYPTION_KEY_SCHEDULE +#endif + +/* 2. ASSEMBLER SUPPORT + + This define (which can be on the command line) enables the use of the + assembler code routines for encryption and decryption with the C code + only providing key scheduling +*/ +#if 0 +#define AES_ASM +#endif + +/* 3. BYTE ORDER WITHIN 32 BIT WORDS + + The fundamental data processing units in Rijndael are 8-bit bytes. The + input, output and key input are all enumerated arrays of bytes in which + bytes are numbered starting at zero and increasing to one less than the + number of bytes in the array in question. This enumeration is only used + for naming bytes and does not imply any adjacency or order relationship + from one byte to another. When these inputs and outputs are considered + as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to + byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. + In this implementation bits are numbered from 0 to 7 starting at the + numerically least significant end of each byte (bit n represents 2^n). + + However, Rijndael can be implemented more efficiently using 32-bit + words by packing bytes into words so that bytes 4*n to 4*n+3 are placed + into word[n]. While in principle these bytes can be assembled into words + in any positions, this implementation only supports the two formats in + which bytes in adjacent positions within words also have adjacent byte + numbers. This order is called big-endian if the lowest numbered bytes + in words have the highest numeric significance and little-endian if the + opposite applies. + + This code can work in either order irrespective of the order used by the + machine on which it runs. Normally the internal byte order will be set + to the order of the processor on which the code is to be run but this + define can be used to reverse this in special situations + + NOTE: Assembler code versions rely on PLATFORM_BYTE_ORDER being set +*/ +#if 1 || defined(AES_ASM) +#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER +#elif 0 +#define ALGORITHM_BYTE_ORDER BRG_LITTLE_ENDIAN +#elif 0 +#define ALGORITHM_BYTE_ORDER BRG_BIG_ENDIAN +#else +#error The algorithm byte order is not defined +#endif + +/* 4. FAST INPUT/OUTPUT OPERATIONS. + + On some machines it is possible to improve speed by transferring the + bytes in the input and output arrays to and from the internal 32-bit + variables by addressing these arrays as if they are arrays of 32-bit + words. On some machines this will always be possible but there may + be a large performance penalty if the byte arrays are not aligned on + the normal word boundaries. On other machines this technique will + lead to memory access errors when such 32-bit word accesses are not + properly aligned. The option SAFE_IO avoids such problems but will + often be slower on those machines that support misaligned access + (especially so if care is taken to align the input and output byte + arrays on 32-bit word boundaries). If SAFE_IO is not defined it is + assumed that access to byte arrays as if they are arrays of 32-bit + words will not cause problems when such accesses are misaligned. +*/ +#if 1 && !defined(_MSC_VER) +#define SAFE_IO +#endif + +/* 5. LOOP UNROLLING + + The code for encryption and decrytpion cycles through a number of rounds + that can be implemented either in a loop or by expanding the code into a + long sequence of instructions, the latter producing a larger program but + one that will often be much faster. The latter is called loop unrolling. + There are also potential speed advantages in expanding two iterations in + a loop with half the number of iterations, which is called partial loop + unrolling. The following options allow partial or full loop unrolling + to be set independently for encryption and decryption +*/ +#if 1 +#define ENC_UNROLL FULL +#elif 0 +#define ENC_UNROLL PARTIAL +#else +#define ENC_UNROLL NONE +#endif + +#if 1 +#define DEC_UNROLL FULL +#elif 0 +#define DEC_UNROLL PARTIAL +#else +#define DEC_UNROLL NONE +#endif + +/* 6. FAST FINITE FIELD OPERATIONS + + If this section is included, tables are used to provide faster finite + field arithmetic (this has no effect if FIXED_TABLES is defined). +*/ +#if 0 +#define FF_TABLES +#endif + +/* 7. INTERNAL STATE VARIABLE FORMAT + + The internal state of Rijndael is stored in a number of local 32-bit + word varaibles which can be defined either as an array or as individual + names variables. Include this section if you want to store these local + varaibles in arrays. Otherwise individual local variables will be used. +*/ +#if 1 +#define ARRAYS +#endif + +/* In this implementation the columns of the state array are each held in + 32-bit words. The state array can be held in various ways: in an array + of words, in a number of individual word variables or in a number of + processor registers. The following define maps a variable name x and + a column number c to the way the state array variable is to be held. + The first define below maps the state into an array x[c] whereas the + second form maps the state into a number of individual variables x0, + x1, etc. Another form could map individual state colums to machine + register names. +*/ + +#if defined(ARRAYS) +#define s(x,c) x[c] +#else +#define s(x,c) x##c +#endif + +/* 8. FIXED OR DYNAMIC TABLES + + When this section is included the tables used by the code are compiled + statically into the binary file. Otherwise the subroutine gen_tabs() + must be called to compute them before the code is first used. +*/ +#if 1 +#define FIXED_TABLES +#define DO_TABLES +#endif + +/* 9. TABLE ALIGNMENT + + On some systems speed will be improved by aligning the AES large lookup + tables on particular boundaries. This define should be set to a power of + two giving the desired alignment. It can be left undefined if alignment + is not needed. This option is specific to the Microsft VC++ compiler - + it seems to sometimes cause trouble for the VC++ version 6 compiler. +*/ + +#if 0 && defined(_MSC_VER) && (_MSC_VER >= 1300) +#define TABLE_ALIGN 64 +#endif + +/* 10. INTERNAL TABLE CONFIGURATION + + This cipher proceeds by repeating in a number of cycles known as 'rounds' + which are implemented by a round function which can optionally be speeded + up using tables. The basic tables are each 256 32-bit words, with either + one or four tables being required for each round function depending on + how much speed is required. The encryption and decryption round functions + are different and the last encryption and decrytpion round functions are + different again making four different round functions in all. + + This means that: + 1. Normal encryption and decryption rounds can each use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + 2. The last encryption and decryption rounds can also use either 0, 1 + or 4 tables and table spaces of 0, 1024 or 4096 bytes each. + + Include or exclude the appropriate definitions below to set the number + of tables used by this implementation. +*/ + +#if 1 /* set tables for the normal encryption round */ +#define ENC_ROUND FOUR_TABLES +#elif 0 +#define ENC_ROUND ONE_TABLE +#else +#define ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last encryption round */ +#define LAST_ENC_ROUND FOUR_TABLES +#elif 0 +#define LAST_ENC_ROUND ONE_TABLE +#else +#define LAST_ENC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the normal decryption round */ +#define DEC_ROUND FOUR_TABLES +#elif 0 +#define DEC_ROUND ONE_TABLE +#else +#define DEC_ROUND NO_TABLES +#endif + +#if 1 /* set tables for the last decryption round */ +#define LAST_DEC_ROUND FOUR_TABLES +#elif 0 +#define LAST_DEC_ROUND ONE_TABLE +#else +#define LAST_DEC_ROUND NO_TABLES +#endif + +/* The decryption key schedule can be speeded up with tables in the same + way that the round functions can. Include or exclude the following + defines to set this requirement. +*/ +#if 1 +#define KEY_SCHED FOUR_TABLES +#elif 0 +#define KEY_SCHED ONE_TABLE +#else +#define KEY_SCHED NO_TABLES +#endif + +/* END OF CONFIGURATION OPTIONS */ + +#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) + +/* Disable or report errors on some combinations of options */ + +#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND NO_TABLES +#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES +#undef LAST_ENC_ROUND +#define LAST_ENC_ROUND ONE_TABLE +#endif + +#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE +#undef ENC_UNROLL +#define ENC_UNROLL NONE +#endif + +#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND NO_TABLES +#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES +#undef LAST_DEC_ROUND +#define LAST_DEC_ROUND ONE_TABLE +#endif + +#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE +#undef DEC_UNROLL +#define DEC_UNROLL NONE +#endif + +/* upr(x,n): rotates bytes within words by n positions, moving bytes to + higher index positions with wrap around into low positions + ups(x,n): moves bytes by n positions to higher index positions in + words but without wrap around + bval(x,n): extracts a byte from a word + + NOTE: The definitions given here are intended only for use with + unsigned variables and with shift counts that are compile + time constants +*/ + +#if (ALGORITHM_BYTE_ORDER == BRG_LITTLE_ENDIAN) +#define upr(x,n) (((aes_32t)(x) << (8 * (n))) | ((aes_32t)(x) >> (32 - 8 * (n)))) +#define ups(x,n) ((aes_32t) (x) << (8 * (n))) +#define bval(x,n) ((aes_08t)((x) >> (8 * (n)))) +#define bytes2word(b0, b1, b2, b3) \ + (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) | (b0)) +#endif + +#if (ALGORITHM_BYTE_ORDER == BRG_BIG_ENDIAN) +#define upr(x,n) (((aes_32t)(x) >> (8 * (n))) | ((aes_32t)(x) << (32 - 8 * (n)))) +#define ups(x,n) ((aes_32t) (x) >> (8 * (n)))) +#define bval(x,n) ((aes_08t)((x) >> (24 - 8 * (n)))) +#define bytes2word(b0, b1, b2, b3) \ + (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) | (b3)) +#endif + +#if defined(SAFE_IO) + +#define word_in(x,c) bytes2word(((aes_08t*)(x)+4*c)[0], ((aes_08t*)(x)+4*c)[1], \ + ((aes_08t*)(x)+4*c)[2], ((aes_08t*)(x)+4*c)[3]) +#define word_out(x,c,v) { ((aes_08t*)(x)+4*c)[0] = bval(v,0); ((aes_08t*)(x)+4*c)[1] = bval(v,1); \ + ((aes_08t*)(x)+4*c)[2] = bval(v,2); ((aes_08t*)(x)+4*c)[3] = bval(v,3); } + +#elif (ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER) + +#define word_in(x,c) (*((aes_32t*)(x)+(c))) +#define word_out(x,c,v) (*((aes_32t*)(x)+(c)) = (v)) + +#else + +#define word_in(x,c) aes_sw32(*((aes_32t*)(x)+(c))) +#define word_out(x,c,v) (*((aes_32t*)(x)+(c)) = aes_sw32(v)) + +#endif + +/* the finite field modular polynomial and elements */ + +#define WPOLY 0x011b +#define BPOLY 0x1b + +/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ + +#define m1 0x80808080 +#define m2 0x7f7f7f7f +#define gf_mulx(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY)) + +/* The following defines provide alternative definitions of gf_mulx that might + give improved performance if a fast 32-bit multiply is not available. Note + that a temporary variable u needs to be defined where gf_mulx is used. + +#define gf_mulx(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) +#define m4 (0x01010101 * BPOLY) +#define gf_mulx(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) +*/ + +/* Work out which tables are needed for the different options */ + +#ifdef AES_ASM +#ifdef ENC_ROUND +#undef ENC_ROUND +#endif +#define ENC_ROUND FOUR_TABLES +#ifdef LAST_ENC_ROUND +#undef LAST_ENC_ROUND +#endif +#define LAST_ENC_ROUND FOUR_TABLES +#ifdef DEC_ROUND +#undef DEC_ROUND +#endif +#define DEC_ROUND FOUR_TABLES +#ifdef LAST_DEC_ROUND +#undef LAST_DEC_ROUND +#endif +#define LAST_DEC_ROUND FOUR_TABLES +#ifdef KEY_SCHED +#undef KEY_SCHED +#define KEY_SCHED FOUR_TABLES +#endif +#endif + +#if defined(ENCRYPTION) || defined(AES_ASM) +#if ENC_ROUND == ONE_TABLE +#define FT1_SET +#elif ENC_ROUND == FOUR_TABLES +#define FT4_SET +#else +#define SBX_SET +#endif +#if LAST_ENC_ROUND == ONE_TABLE +#define FL1_SET +#elif LAST_ENC_ROUND == FOUR_TABLES +#define FL4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +#if defined(DECRYPTION) || defined(AES_ASM) +#if DEC_ROUND == ONE_TABLE +#define IT1_SET +#elif DEC_ROUND == FOUR_TABLES +#define IT4_SET +#else +#define ISB_SET +#endif +#if LAST_DEC_ROUND == ONE_TABLE +#define IL1_SET +#elif LAST_DEC_ROUND == FOUR_TABLES +#define IL4_SET +#elif !defined(ISB_SET) +#define ISB_SET +#endif +#endif + +#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE) +#if KEY_SCHED == ONE_TABLE +#define LS1_SET +#define IM1_SET +#elif KEY_SCHED == FOUR_TABLES +#define LS4_SET +#define IM4_SET +#elif !defined(SBX_SET) +#define SBX_SET +#endif +#endif + +/* generic definitions of Rijndael macros that use tables */ + +#define no_table(x,box,vf,rf,c) bytes2word( \ + box[bval(vf(x,0,c),rf(0,c))], \ + box[bval(vf(x,1,c),rf(1,c))], \ + box[bval(vf(x,2,c),rf(2,c))], \ + box[bval(vf(x,3,c),rf(3,c))]) + +#define one_table(x,op,tab,vf,rf,c) \ + ( tab[bval(vf(x,0,c),rf(0,c))] \ + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) + +#define four_tables(x,tab,vf,rf,c) \ + ( tab[0][bval(vf(x,0,c),rf(0,c))] \ + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ + ^ tab[3][bval(vf(x,3,c),rf(3,c))]) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((8+r-c)&3) + +/* perform forward and inverse column mix operation on four bytes in long word x in */ +/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ + +#if defined(FM4_SET) /* not currently used */ +#define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) +#elif defined(FM1_SET) /* not currently used */ +#define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0) +#else +#define dec_fmvars aes_32t g2 +#define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) +#endif + +#if defined(IM4_SET) +#define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0) +#elif defined(IM1_SET) +#define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0) +#else +#define dec_imvars aes_32t g2, g4, g9 +#define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \ + (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) +#endif + +#if defined(FL4_SET) +#define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c) +#elif defined(LS4_SET) +#define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c) +#elif defined(FL1_SET) +#define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c) +#elif defined(LS1_SET) +#define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c) +#else +#define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) +#endif + +/* If there are no global variables, the definitions here can be + used to put the AES tables in a structure so that a pointer + can then be added to the AES context to pass them to the AES + routines that need them. If this facility is used, the calling + program has to ensure that this pointer is managed appropriately. + In particular, the value of the t_dec(in,it) item in the table + structure must be set to zero in order to ensure that the tables + are initialised. In practice the three code sequences in aeskey.c + that control the calls to gen_tabs() and the gen_tabs() routine + itself will have to be changed for a specific implementation. If + global variables are available it will generally be preferable to + use them with the precomputed FIXED_TABLES option that uses static + global tables. + + The following defines can be used to control the way the tables + are defined, initialised and used in embedded environments that + require special features for these purposes + + the 't_dec' construction is used to declare fixed table arrays + the 't_set' construction is used to set fixed table values + the 't_use' construction is used to access fixed table values + + 256 byte tables: + + t_xxx(s,box) => forward S box + t_xxx(i,box) => inverse S box + + 256 32-bit word OR 4 x 256 32-bit word tables: + + t_xxx(f,n) => forward normal round + t_xxx(f,l) => forward last round + t_xxx(i,n) => inverse normal round + t_xxx(i,l) => inverse last round + t_xxx(l,s) => key schedule table + t_xxx(i,m) => key schedule table + + Other variables and tables: + + t_xxx(r,c) => the rcon table +*/ + +#define t_dec(m,n) t_##m##n +#define t_set(m,n) t_##m##n +#define t_use(m,n) t_##m##n + +#if defined(DO_TABLES) /* declare and instantiate tables */ + +/* finite field arithmetic operations for table generation */ + +#if defined(FIXED_TABLES) || !defined(FF_TABLES) + +#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) +#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) +#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ + ^ (((x>>5) & 4) * WPOLY)) +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) + +#else + +#define f2(x) ((x) ? pow[log[x] + 0x19] : 0) +#define f3(x) ((x) ? pow[log[x] + 0x01] : 0) +#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) +#define fb(x) ((x) ? pow[log[x] + 0x68] : 0) +#define fd(x) ((x) ? pow[log[x] + 0xee] : 0) +#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) +#define fi(x) ((x) ? pow[ 255 - log[x]] : 0) + +#endif + +#if defined(FIXED_TABLES) /* declare and set values for static tables */ + +#define sb_data(w) \ + w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ + w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ + w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ + w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ + w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ + w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ + w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ + w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ + w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ + w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ + w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ + w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ + w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ + w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ + w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ + w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ + w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ + w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ + w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ + w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ + w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ + w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ + w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ + w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ + w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ + w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ + w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ + w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ + w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ + w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ + w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ + w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) + +#define isb_data(w) \ + w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ + w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ + w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ + w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ + w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ + w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ + w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ + w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ + w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ + w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ + w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ + w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ + w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ + w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ + w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ + w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ + w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ + w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ + w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ + w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ + w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ + w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ + w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ + w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ + w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ + w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ + w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ + w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ + w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ + w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ + w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ + w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d), + +#define mm_data(w) \ + w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ + w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ + w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ + w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ + w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ + w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ + w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ + w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ + w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ + w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ + w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ + w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ + w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ + w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ + w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ + w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ + w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ + w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ + w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ + w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ + w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ + w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ + w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ + w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ + w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ + w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ + w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ + w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ + w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ + w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ + w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ + w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) + +#define h0(x) (x) + +/* These defines are used to ensure tables are generated in the + right format depending on the internal byte order required +*/ + +#define w0(p) bytes2word(p, 0, 0, 0) +#define w1(p) bytes2word(0, p, 0, 0) +#define w2(p) bytes2word(0, 0, p, 0) +#define w3(p) bytes2word(0, 0, 0, p) + +#define u0(p) bytes2word(f2(p), p, p, f3(p)) +#define u1(p) bytes2word(f3(p), f2(p), p, p) +#define u2(p) bytes2word(p, f3(p), f2(p), p) +#define u3(p) bytes2word(p, p, f3(p), f2(p)) + +#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) +#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) +#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) +#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) + +const aes_32t t_dec(r,c)[RC_LENGTH] = +{ + w0(0x01), w0(0x02), w0(0x04), w0(0x08), w0(0x10), + w0(0x20), w0(0x40), w0(0x80), w0(0x1b), w0(0x36) +}; + +#if defined(__BORLANDC__) + #define concat(s1, s2) s1##s2 + #define d_1(t,n,b,v) const t n[256] = { b(concat(v,0)) } + #define d_4(t,n,b,v) const t n[4][256] = { { b(concat(v,0)) }, { b(concat(v,1)) }, { b(concat(v,2)) }, { b(concat(v,3)) } } +#else + #define d_1(t,n,b,v) const t n[256] = { b(v##0) } + #define d_4(t,n,b,v) const t n[4][256] = { { b(v##0) }, { b(v##1) }, { b(v##2) }, { b(v##3) } } +#endif + +#else /* declare and instantiate tables for dynamic value generation in in tab.c */ + +aes_32t t_dec(r,c)[RC_LENGTH]; + +#define d_1(t,n,b,v) t n[256] +#define d_4(t,n,b,v) t n[4][256] + +#endif + +#else /* declare tables without instantiation */ + +#if defined(FIXED_TABLES) + +extern const aes_32t t_dec(r,c)[RC_LENGTH]; + +#if defined(_MSC_VER) && defined(TABLE_ALIGN) +#define d_1(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) const t n[256] +#define d_4(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) const t n[4][256] +#else +#define d_1(t,n,b,v) extern const t n[256] +#define d_4(t,n,b,v) extern const t n[4][256] +#endif +#else + +extern aes_32t t_dec(r,c)[RC_LENGTH]; + +#if defined(_MSC_VER) && defined(TABLE_ALIGN) +#define d_1(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) t n[256] +#define d_4(t,n,b,v) extern __declspec(align(TABLE_ALIGN)) t n[4][256] +#else +#define d_1(t,n,b,v) extern t n[256] +#define d_4(t,n,b,v) extern t n[4][256] +#endif +#endif + +#endif + +#ifdef SBX_SET + d_1(aes_08t, t_dec(s,box), sb_data, h); +#endif +#ifdef ISB_SET + d_1(aes_08t, t_dec(i,box), isb_data, h); +#endif + +#ifdef FT1_SET + d_1(aes_32t, t_dec(f,n), sb_data, u); +#endif +#ifdef FT4_SET + d_4(aes_32t, t_dec(f,n), sb_data, u); +#endif + +#ifdef FL1_SET + d_1(aes_32t, t_dec(f,l), sb_data, w); +#endif +#ifdef FL4_SET + d_4(aes_32t, t_dec(f,l), sb_data, w); +#endif + +#ifdef IT1_SET + d_1(aes_32t, t_dec(i,n), isb_data, v); +#endif +#ifdef IT4_SET + d_4(aes_32t, t_dec(i,n), isb_data, v); +#endif + +#ifdef IL1_SET + d_1(aes_32t, t_dec(i,l), isb_data, w); +#endif +#ifdef IL4_SET + d_4(aes_32t, t_dec(i,l), isb_data, w); +#endif + +#ifdef LS1_SET +#ifdef FL1_SET +#undef LS1_SET +#else + d_1(aes_32t, t_dec(l,s), sb_data, w); +#endif +#endif + +#ifdef LS4_SET +#ifdef FL4_SET +#undef LS4_SET +#else + d_4(aes_32t, t_dec(l,s), sb_data, w); +#endif +#endif + +#ifdef IM1_SET + d_1(aes_32t, t_dec(i,m), mm_data, v); +#endif +#ifdef IM4_SET + d_4(aes_32t, t_dec(i,m), mm_data, v); +#endif + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aestab.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aestab.cpp new file mode 100644 index 0000000..e94aa76 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/aestab.cpp @@ -0,0 +1,223 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2003, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + +*/ + +#define DO_TABLES + +#include "aesopt.h" + +#if defined(FIXED_TABLES) + +/* implemented in case of wrong call for fixed tables */ + +void gen_tabs(void) +{ +} + +#else /* dynamic table generation */ + +#if !defined(FF_TABLES) + +/* Generate the tables for the dynamic table option + + It will generally be sensible to use tables to compute finite + field multiplies and inverses but where memory is scarse this + code might sometimes be better. But it only has effect during + initialisation so its pretty unimportant in overall terms. +*/ + +/* return 2 ^ (n - 1) where n is the bit number of the highest bit + set in x with x in the range 1 < x < 0x00000200. This form is + used so that locals within fi can be bytes rather than words +*/ + +static aes_08t hibit(const aes_32t x) +{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2)); + + r |= (r >> 2); + r |= (r >> 4); + return (r + 1) >> 1; +} + +/* return the inverse of the finite field element x */ + +static aes_08t fi(const aes_08t x) +{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; + + if(x < 2) return x; + + for(;;) + { + if(!n1) return v1; + + while(n2 >= n1) + { + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); + } + + if(!n2) return v2; + + while(n1 >= n2) + { + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); + } + } +} + +#endif + +/* The forward and inverse affine transformations used in the S-box */ + +#define fwd_affine(x) \ + (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8))) + +#define inv_affine(x) \ + (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8))) + +static int init = 0; + +void gen_tabs(void) +{ aes_32t i, w; + +#if defined(FF_TABLES) + + aes_08t pow[512], log[256]; + + if(init) return; + /* log and power tables for GF(2^8) finite field with + WPOLY as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables + */ + + i = 0; w = 1; + do + { + pow[i] = (aes_08t)w; + pow[i + 255] = (aes_08t)w; + log[w] = (aes_08t)i++; + w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); + } + while (w != 1); + +#else + if(init) return; +#endif + + for(i = 0, w = 1; i < RC_LENGTH; ++i) + { + t_set(r,c)[i] = bytes2word(w, 0, 0, 0); + w = f2(w); + } + + for(i = 0; i < 256; ++i) + { aes_08t b; + + b = fwd_affine(fi((aes_08t)i)); + w = bytes2word(f2(b), b, b, f3(b)); + +#ifdef SBX_SET + t_set(s,box)[i] = b; +#endif + +#ifdef FT1_SET /* tables for a normal encryption round */ + t_set(f,n)[i] = w; +#endif +#ifdef FT4_SET + t_set(f,n)[0][i] = w; + t_set(f,n)[1][i] = upr(w,1); + t_set(f,n)[2][i] = upr(w,2); + t_set(f,n)[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); + +#ifdef FL1_SET /* tables for last encryption round (may also */ + t_set(f,l)[i] = w; /* be used in the key schedule) */ +#endif +#ifdef FL4_SET + t_set(f,l)[0][i] = w; + t_set(f,l)[1][i] = upr(w,1); + t_set(f,l)[2][i] = upr(w,2); + t_set(f,l)[3][i] = upr(w,3); +#endif + +#ifdef LS1_SET /* table for key schedule if t_set(f,l) above is */ + t_set(l,s)[i] = w; /* not of the required form */ +#endif +#ifdef LS4_SET + t_set(l,s)[0][i] = w; + t_set(l,s)[1][i] = upr(w,1); + t_set(l,s)[2][i] = upr(w,2); + t_set(l,s)[3][i] = upr(w,3); +#endif + + b = fi(inv_affine((aes_08t)i)); + w = bytes2word(fe(b), f9(b), fd(b), fb(b)); + +#ifdef IM1_SET /* tables for the inverse mix column operation */ + t_set(i,m)[b] = w; +#endif +#ifdef IM4_SET + t_set(i,m)[0][b] = w; + t_set(i,m)[1][b] = upr(w,1); + t_set(i,m)[2][b] = upr(w,2); + t_set(i,m)[3][b] = upr(w,3); +#endif + +#ifdef ISB_SET + t_set(i,box)[i] = b; +#endif +#ifdef IT1_SET /* tables for a normal decryption round */ + t_set(i,n)[i] = w; +#endif +#ifdef IT4_SET + t_set(i,n)[0][i] = w; + t_set(i,n)[1][i] = upr(w,1); + t_set(i,n)[2][i] = upr(w,2); + t_set(i,n)[3][i] = upr(w,3); +#endif + w = bytes2word(b, 0, 0, 0); +#ifdef IL1_SET /* tables for last decryption round */ + t_set(i,l)[i] = w; +#endif +#ifdef IL4_SET + t_set(i,l)[0][i] = w; + t_set(i,l)[1][i] = upr(w,1); + t_set(i,l)[2][i] = upr(w,2); + t_set(i,l)[3][i] = upr(w,3); +#endif + } + init = 1; +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.cpp new file mode 100644 index 0000000..4e76c77 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.cpp @@ -0,0 +1,140 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + ------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This file implements password based file encryption and authentication + using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password + based key derivation. + +*/ + +#include + +#include "fileenc.h" + +/* subroutine for data encryption/decryption */ +/* this could be speeded up a lot by aligning */ +/* buffers and using 32 bit operations */ + +static void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1]) +{ + unsigned long i = 0, pos = cx->encr_pos; + + while(i < d_len) + { + if(pos == BLOCK_SIZE) + { unsigned int j = 0; + /* increment encryption nonce */ + while(j < 8 && !++cx->nonce[j]) + ++j; + /* encrypt the nonce to form next xor buffer */ + aes_encrypt(cx->nonce, cx->encr_bfr, cx->encr_ctx); + pos = 0; + } + + data[i++] ^= cx->encr_bfr[pos++]; + } + + cx->encr_pos = pos; +} + +int fcrypt_init( + int mode, /* the mode to be used (input) */ + const unsigned char pwd[], /* the user specified password (input) */ + unsigned int pwd_len, /* the length of the password (input) */ + const unsigned char salt[], /* the salt (input) */ +#ifdef PASSWORD_VERIFIER + unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */ +#endif + fcrypt_ctx cx[1]) /* the file encryption context (output) */ +{ + unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH]; + + if(pwd_len > MAX_PWD_LENGTH) + return PASSWORD_TOO_LONG; + + if(mode < 1 || mode > 3) + return BAD_MODE; + + cx->mode = mode; + cx->pwd_len = pwd_len; + /* initialise the encryption nonce and buffer pos */ + cx->encr_pos = BLOCK_SIZE; + + /* if we need a random component in the encryption */ + /* nonce, this is where it would have to be set */ + memset(cx->nonce, 0, BLOCK_SIZE * sizeof(unsigned char)); + /* initialise for authentication */ + hmac_sha_begin(cx->auth_ctx); + + /* derive the encryption and authetication keys and the password verifier */ + derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS, + kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH); + /* set the encryption key */ + aes_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx); + /* set the authentication key */ + hmac_sha_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx); +#ifdef PASSWORD_VERIFIER + memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH); +#endif + /* clear the buffer holding the derived key values */ + memset(kbuf, 0, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH); + + return GOOD_RETURN; +} + +/* perform 'in place' encryption and authentication */ + +void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]) +{ + encr_data(data, data_len, cx); + hmac_sha_data(data, data_len, cx->auth_ctx); +} + +/* perform 'in place' authentication and decryption */ + +void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]) +{ + hmac_sha_data(data, data_len, cx->auth_ctx); + encr_data(data, data_len, cx); +} + +/* close encryption/decryption and return the MAC value */ + +int fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1]) +{ + unsigned int res = cx->mode; + + hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx); + memset(cx, 0, sizeof(fcrypt_ctx)); /* clear the encryption context */ + return MAC_LENGTH(res); /* return MAC length in bytes */ +} + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.h new file mode 100644 index 0000000..ba5cabc --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/fileenc.h @@ -0,0 +1,114 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 24/01/2003 + + This file contains the header file for fileenc.c, which implements password + based file encryption and authentication using AES in CTR mode, HMAC-SHA1 + authentication and RFC2898 password based key derivation. +*/ + +#ifndef _FENC_H +#define _FENC_H + +#include "aes.h" +#include "hmac.h" +#include "pwd2key.h" + +#define BLOCK_SIZE AES_BLOCK_SIZE +#define PASSWORD_VERIFIER + +#define MAX_KEY_LENGTH 32 +#define MAX_PWD_LENGTH 128 +#define MAX_SALT_LENGTH 16 +#define KEYING_ITERATIONS 1000 + +#ifdef PASSWORD_VERIFIER +#define PWD_VER_LENGTH 2 +#else +#define PWD_VER_LENGTH 0 +#endif + +#define GOOD_RETURN 0 +#define PASSWORD_TOO_LONG -100 +#define BAD_MODE -101 + +/* + Field lengths (in bytes) versus File Encryption Mode (0 < mode < 4) + + Mode Key Salt MAC Overhead + 1 16 8 10 18 + 2 24 12 10 22 + 3 32 16 10 26 + + The following macros assume that the mode value is correct. +*/ + +#define KEY_LENGTH(mode) (8 * (mode & 3) + 8) +#define SALT_LENGTH(mode) (4 * (mode & 3) + 4) +#define MAC_LENGTH(mode) (10) + +/* the context for file encryption */ + +typedef struct +{ unsigned char nonce[BLOCK_SIZE]; /* the CTR nonce */ + unsigned char encr_bfr[BLOCK_SIZE]; /* encrypt buffer */ + aes_encrypt_ctx encr_ctx[1]; /* encryption context */ + hmac_ctx auth_ctx[1]; /* authentication context */ + unsigned int encr_pos; /* block position (enc) */ + unsigned int pwd_len; /* password length */ + unsigned int mode; /* File encryption mode */ +} fcrypt_ctx; + +/* initialise file encryption or decryption */ + +int fcrypt_init( + int mode, /* the mode to be used (input) */ + const unsigned char pwd[], /* the user specified password (input) */ + unsigned int pwd_len, /* the length of the password (input) */ + const unsigned char salt[], /* the salt (input) */ +#ifdef PASSWORD_VERIFIER + unsigned char pwd_ver[PWD_VER_LENGTH], /* 2 byte password verifier (output) */ +#endif + fcrypt_ctx cx[1]); /* the file encryption context (output) */ + +/* perform 'in place' encryption or decryption and authentication */ + +void fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]); +void fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]); + +/* close encryption/decryption and return the MAC value */ +/* the return value is the length of the MAC */ + +int fcrypt_end(unsigned char mac[], /* the MAC value (output) */ + fcrypt_ctx cx[1]); /* the context (input) */ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.cpp new file mode 100644 index 0000000..b24294d --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.cpp @@ -0,0 +1,142 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + Includes a bugfix from Dr Brian Gladman made on 16/04/2012 for compiling on 64-bit + + This is an implementation of HMAC, the FIPS standard keyed hash function +*/ + + +#include "hmac.h" + +#define HMAC_IPAD (0x36 * (((unsigned long)-1) / 0xff)) +#define HMAC_OPAD (0x5c * (((unsigned long)-1) / 0xff)) + +/* initialise the HMAC context to zero */ +void hmac_sha_begin(hmac_ctx cx[1]) +{ + memset(cx, 0, sizeof(hmac_ctx)); +} + +/* input the HMAC key (can be called multiple times) */ +int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]) +{ + if(cx->klen == HMAC_IN_DATA) /* error if further key input */ + return HMAC_BAD_MODE; /* is attempted in data mode */ + + if(cx->klen + key_len > HMAC_HASH_INPUT_SIZE) /* if the key has to be hashed */ + { + if(cx->klen <= HMAC_HASH_INPUT_SIZE) /* if the hash has not yet been */ + { /* started, initialise it and */ + sha_begin(cx->ctx); /* hash stored key characters */ + sha_hash(cx->key, cx->klen, cx->ctx); + } + + sha_hash(key, key_len, cx->ctx); /* hash long key data into hash */ + } + else /* otherwise store key data */ + memcpy(cx->key + cx->klen, key, key_len); + + cx->klen += key_len; /* update the key length count */ + return HMAC_OK; +} + +/* input the HMAC data (can be called multiple times) - */ +/* note that this call terminates the key input phase */ +void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]) +{ unsigned int i; + + if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */ + { + if(cx->klen > HMAC_HASH_INPUT_SIZE) /* if key is being hashed */ + { /* complete the hash and */ + sha_end(cx->key, cx->ctx); /* store the result as the */ + cx->klen = HMAC_HASH_OUTPUT_SIZE; /* key and set new length */ + } + + /* pad the key if necessary */ + memset(cx->key + cx->klen, 0, HMAC_HASH_INPUT_SIZE - cx->klen); + + /* xor ipad into key value */ + for(i = 0; i < HMAC_HASH_INPUT_SIZE / sizeof(unsigned long); ++i) + ((unsigned long*)cx->key)[i] ^= HMAC_IPAD; + + /* and start hash operation */ + sha_begin(cx->ctx); + sha_hash(cx->key, HMAC_HASH_INPUT_SIZE, cx->ctx); + + /* mark as now in data mode */ + cx->klen = HMAC_IN_DATA; + } + + /* hash the data (if any) */ + if(data_len) + sha_hash(data, data_len, cx->ctx); +} + +/* compute and output the MAC value */ +void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]) +{ unsigned char dig[HMAC_HASH_OUTPUT_SIZE]; + unsigned int i; + + /* if no data has been entered perform a null data phase */ + if(cx->klen != HMAC_IN_DATA) + hmac_sha_data((const unsigned char*)0, 0, cx); + + sha_end(dig, cx->ctx); /* complete the inner hash */ + + /* set outer key value using opad and removing ipad */ + for(i = 0; i < HMAC_HASH_INPUT_SIZE / sizeof(unsigned long); ++i) + ((unsigned long*)cx->key)[i] ^= HMAC_OPAD ^ HMAC_IPAD; + + /* perform the outer hash operation */ + sha_begin(cx->ctx); + sha_hash(cx->key, HMAC_HASH_INPUT_SIZE, cx->ctx); + sha_hash(dig, HMAC_HASH_OUTPUT_SIZE, cx->ctx); + sha_end(dig, cx->ctx); + + /* output the hash value */ + for(i = 0; i < mac_len; ++i) + mac[i] = dig[i]; +} + +/* 'do it all in one go' subroutine */ +void hmac_sha(const unsigned char key[], unsigned long key_len, + const unsigned char data[], unsigned long data_len, + unsigned char mac[], unsigned long mac_len) +{ hmac_ctx cx[1]; + + hmac_sha_begin(cx); + hmac_sha_key(key, key_len, cx); + hmac_sha_data(data, data_len, cx); + hmac_sha_end(mac, mac_len, cx); +} + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.h new file mode 100644 index 0000000..284c50f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/hmac.h @@ -0,0 +1,95 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + Includes a bugfix from Dr Brian Gladman made on 16/04/2012 for compiling on 64-bit + + This is an implementation of HMAC, the FIPS standard keyed hash function +*/ + +#ifndef _HMAC_H +#define _HMAC_H + +#include + +#define USE_SHA1 // Irrlicht only cares about SHA1 for now +#if !defined(USE_SHA1) && !defined(USE_SHA256) +#error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm +#endif + +#ifdef USE_SHA1 + +#include "sha1.h" + +#define HMAC_HASH_INPUT_SIZE SHA1_BLOCK_SIZE +#define HMAC_HASH_OUTPUT_SIZE SHA1_DIGEST_SIZE +#define sha_ctx sha1_ctx +#define sha_begin sha1_begin +#define sha_hash sha1_hash +#define sha_end sha1_end + +#endif + +#ifdef USE_SHA256 + +#include "sha2.h" + +#define HMAC_HASH_INPUT_SIZE SHA256_BLOCK_SIZE +#define HMAC_HASH_OUTPUT_SIZE SHA256_DIGEST_SIZE +#define sha_ctx sha256_ctx +#define sha_begin sha256_begin +#define sha_hash sha256_hash +#define sha_end sha256_end + +#endif + +#define HMAC_OK 0 +#define HMAC_BAD_MODE -1 +#define HMAC_IN_DATA 0xffffffff + +typedef struct +{ unsigned char key[HMAC_HASH_INPUT_SIZE]; + sha_ctx ctx[1]; + unsigned long klen; +} hmac_ctx; + +void hmac_sha_begin(hmac_ctx cx[1]); + +int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]); + +void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]); + +void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]); + +void hmac_sha(const unsigned char key[], unsigned long key_len, + const unsigned char data[], unsigned long data_len, + unsigned char mac[], unsigned long mac_len); + +#endif diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.cpp new file mode 100644 index 0000000..d5800b3 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.cpp @@ -0,0 +1,146 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 24/01/2003 + + This file implements a random data pool based on the use of an external + entropy function. It is based on the ideas advocated by Peter Gutmann in + his work on pseudo random sequence generators. It is not a 'paranoid' + random sequence generator and no attempt is made to protect the pool + from prying eyes either by memory locking or by techniques to obscure + its location in memory. +*/ + +#include +#include "prng.h" + +/* mix a random data pool using the SHA1 compression function (as */ +/* suggested by Peter Gutmann in his paper on random pools) */ + +static void prng_mix(unsigned char buf[]) +{ unsigned int i, len; + sha1_ctx ctx[1]; + + /*lint -e{663} unusual array to pointer conversion */ + for(i = 0; i < PRNG_POOL_SIZE; i += SHA1_DIGEST_SIZE) + { + /* copy digest size pool block into SHA1 hash block */ + memcpy(ctx->hash, buf + (i ? i : PRNG_POOL_SIZE) + - SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE); + + /* copy data from pool into the SHA1 data buffer */ + len = PRNG_POOL_SIZE - i; + memcpy(ctx->wbuf, buf + i, (len > SHA1_BLOCK_SIZE ? SHA1_BLOCK_SIZE : len)); + + if(len < SHA1_BLOCK_SIZE) + memcpy(((char*)ctx->wbuf) + len, buf, SHA1_BLOCK_SIZE - len); + + /* compress using the SHA1 compression function */ + sha1_compile(ctx); + + /* put digest size block back into the random pool */ + memcpy(buf + i, ctx->hash, SHA1_DIGEST_SIZE); + } +} + +/* refresh the output buffer and update the random pool by adding */ +/* entropy and remixing */ + +static void update_pool(prng_ctx ctx[1]) +{ unsigned int i = 0; + + /* transfer random pool data to the output buffer */ + memcpy(ctx->obuf, ctx->rbuf, PRNG_POOL_SIZE); + + /* enter entropy data into the pool */ + while(i < PRNG_POOL_SIZE) + i += ctx->entropy(ctx->rbuf + i, PRNG_POOL_SIZE - i); + + /* invert and xor the original pool data into the pool */ + for(i = 0; i < PRNG_POOL_SIZE; ++i) + ctx->rbuf[i] ^= ~ctx->obuf[i]; + + /* mix the pool and the output buffer */ + prng_mix(ctx->rbuf); + prng_mix(ctx->obuf); +} + +void prng_init(prng_entropy_fn fun, prng_ctx ctx[1]) +{ int i; + + /* clear the buffers and the counter in the context */ + memset(ctx, 0, sizeof(prng_ctx)); + + /* set the pointer to the entropy collection function */ + ctx->entropy = fun; + + /* initialise the random data pool */ + update_pool(ctx); + + /* mix the pool a minimum number of times */ + for(i = 0; i < PRNG_MIN_MIX; ++i) + prng_mix(ctx->rbuf); + + /* update the pool to prime the pool output buffer */ + update_pool(ctx); +} + +/* provide random bytes from the random data pool */ + +void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]) +{ unsigned char *rp = data; + unsigned int len, pos = ctx->pos; + + while(data_len) + { + /* transfer 'data_len' bytes (or the number of bytes remaining */ + /* the pool output buffer if less) into the output */ + len = (data_len < PRNG_POOL_SIZE - pos ? data_len : PRNG_POOL_SIZE - pos); + memcpy(rp, ctx->obuf + pos, len); + rp += len; /* update ouput buffer position pointer */ + pos += len; /* update pool output buffer pointer */ + data_len -= len; /* update the remaining data count */ + + /* refresh the random pool if necessary */ + if(pos == PRNG_POOL_SIZE) + { + update_pool(ctx); pos = 0; + } + } + + ctx->pos = pos; +} + +void prng_end(prng_ctx ctx[1]) +{ + /* ensure the data in the context is destroyed */ + memset(ctx, 0, sizeof(prng_ctx)); +} + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.h new file mode 100644 index 0000000..a81ed8e --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/prng.h @@ -0,0 +1,74 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 24/01/2003 + + This is the header file for an implementation of a random data pool based on + the use of an external entropy function (inspired by Peter Gutmann's work). +*/ + +#ifndef _PRNG_H +#define _PRNG_H + +#include "sha1.h" + +#define PRNG_POOL_LEN 256 /* minimum random pool size */ +#define PRNG_MIN_MIX 20 /* min initial pool mixing iterations */ + +/* ensure that pool length is a multiple of the SHA1 digest size */ + +#define PRNG_POOL_SIZE (SHA1_DIGEST_SIZE * (1 + (PRNG_POOL_LEN - 1) / SHA1_DIGEST_SIZE)) + +/* A function for providing entropy is a parameter in the prng_init() */ +/* call. This function has the following form and returns a maximum */ +/* of 'len' bytes of pseudo random data in the buffer 'buf'. It can */ +/* return less than 'len' bytes but will be repeatedly called for more */ +/* data in this case. */ + +typedef int (*prng_entropy_fn)(unsigned char buf[], unsigned int len); + +typedef struct +{ unsigned char rbuf[PRNG_POOL_SIZE]; /* the random pool */ + unsigned char obuf[PRNG_POOL_SIZE]; /* pool output buffer */ + unsigned int pos; /* output buffer position */ + prng_entropy_fn entropy; /* entropy function pointer */ +} prng_ctx; + +/* initialise the random stream generator */ +void prng_init(prng_entropy_fn fun, prng_ctx ctx[1]); + +/* obtain random bytes from the generator */ +void prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]); + +/* close the random stream generator */ +void prng_end(prng_ctx ctx[1]); + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.cpp new file mode 100644 index 0000000..051e45b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.cpp @@ -0,0 +1,186 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is an implementation of RFC2898, which specifies key derivation from + a password and a salt value. +*/ + +#include +#include "hmac.h" + +void derive_key(const unsigned char pwd[], /* the PASSWORD */ + unsigned int pwd_len, /* and its length */ + const unsigned char salt[], /* the SALT and its */ + unsigned int salt_len, /* length */ + unsigned int iter, /* the number of iterations */ + unsigned char key[], /* space for the output key */ + unsigned int key_len)/* and its required length */ +{ + unsigned int i, j, k, n_blk; + unsigned char uu[HMAC_HASH_OUTPUT_SIZE], ux[HMAC_HASH_OUTPUT_SIZE]; + hmac_ctx c1[1], c2[1], c3[1]; + + /* set HMAC context (c1) for password */ + hmac_sha_begin(c1); + hmac_sha_key(pwd, pwd_len, c1); + + /* set HMAC context (c2) for password and salt */ + memcpy(c2, c1, sizeof(hmac_ctx)); + hmac_sha_data(salt, salt_len, c2); + + /* find the number of SHA blocks in the key */ + n_blk = 1 + (key_len - 1) / HMAC_HASH_OUTPUT_SIZE; + + for(i = 0; i < n_blk; ++i) /* for each block in key */ + { + /* ux[] holds the running xor value */ + memset(ux, 0, HMAC_HASH_OUTPUT_SIZE); + + /* set HMAC context (c3) for password and salt */ + memcpy(c3, c2, sizeof(hmac_ctx)); + + /* enter additional data for 1st block into uu */ + uu[0] = (unsigned char)((i + 1) >> 24); + uu[1] = (unsigned char)((i + 1) >> 16); + uu[2] = (unsigned char)((i + 1) >> 8); + uu[3] = (unsigned char)(i + 1); + + /* this is the key mixing iteration */ + for(j = 0, k = 4; j < iter; ++j) + { + /* add previous round data to HMAC */ + hmac_sha_data(uu, k, c3); + + /* obtain HMAC for uu[] */ + hmac_sha_end(uu, HMAC_HASH_OUTPUT_SIZE, c3); + + /* xor into the running xor block */ + for(k = 0; k < HMAC_HASH_OUTPUT_SIZE; ++k) + ux[k] ^= uu[k]; + + /* set HMAC context (c3) for password */ + memcpy(c3, c1, sizeof(hmac_ctx)); + } + + /* compile key blocks into the key output */ + j = 0; k = i * HMAC_HASH_OUTPUT_SIZE; + while(j < HMAC_HASH_OUTPUT_SIZE && k < key_len) + key[k++] = ux[j++]; + } +} + +#ifdef TEST + +#include + +struct +{ unsigned int pwd_len; + unsigned int salt_len; + unsigned int it_count; + unsigned char *pwd; + unsigned char salt[32]; + unsigned char key[32]; +} tests[] = +{ + { 8, 4, 5, (unsigned char*)"password", + { + 0x12, 0x34, 0x56, 0x78 + }, + { + 0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7, + 0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 + } + }, + { 8, 8, 5, (unsigned char*)"password", + { + 0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 + }, + { + 0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6, + 0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 + } + }, + { 8, 21, 1, (unsigned char*)"password", + { + "ATHENA.MIT.EDUraeburn" + }, + { + 0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01, + 0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15 + } + }, + { 8, 21, 2, (unsigned char*)"password", + { + "ATHENA.MIT.EDUraeburn" + }, + { + 0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e, + 0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d + } + }, + { 8, 21, 1200, (unsigned char*)"password", + { + "ATHENA.MIT.EDUraeburn" + }, + { + 0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e, + 0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b + } + } +}; + +int main() +{ unsigned int i, j, key_len = 256; + unsigned char key[256]; + + printf("\nTest of RFC2898 Password Based Key Derivation"); + for(i = 0; i < 5; ++i) + { + derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt, + tests[i].salt_len, tests[i].it_count, key, key_len); + + printf("\ntest %i: ", i + 1); + printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good"); + for(j = 0; j < key_len && j < 64; j += 4) + { + if(j % 16 == 0) + printf("\n"); + printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]); + } + printf(j < key_len ? " ... \n" : "\n"); + } + printf("\n"); + return 0; +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.h new file mode 100644 index 0000000..f5248ad --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/pwd2key.h @@ -0,0 +1,50 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is an implementation of RFC2898, which specifies key derivation from + a password and a salt value. +*/ + +#ifndef PWD2KEY_H +#define PWD2KEY_H + +void derive_key( + const unsigned char pwd[], /* the PASSWORD, and */ + unsigned int pwd_len, /* its length */ + const unsigned char salt[], /* the SALT and its */ + unsigned int salt_len, /* length */ + unsigned int iter, /* the number of iterations */ + unsigned char key[], /* space for the output key */ + unsigned int key_len); /* and its required length */ + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.cpp new file mode 100644 index 0000000..8a91768 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.cpp @@ -0,0 +1,237 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is a byte oriented version of SHA1 that operates on arrays of bytes + stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor +*/ + +#include /* for memcpy() etc. */ +#include /* for _lrotl with VC++ */ + +#include "sha1.h" +#include "../os.h" + +/* + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the order in which bytes are packed into such words. + The following block of code is an attempt to capture the most obvious + ways in which various environemnts specify their endian definitions. + It may well fail, in which case the definitions will need to be set by + editing at the points marked **** EDIT HERE IF NECESSARY **** below. +*/ + +/* BYTE ORDER IN 32-BIT WORDS + + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the byte order of the target machine. The following + block of code is an attempt to capture the most obvious ways in which + various environemnts define byte order. It may well fail, in which case + the definitions will need to be set by editing at the points marked + **** EDIT HERE IF NECESSARY **** below. My thanks to Peter Gutmann for + some of these defines (from cryptlib). +*/ + +#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ + +#ifdef __BIG_ENDIAN__ +#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN +#else +#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN +#endif + +#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) + +#if (PLATFORM_BYTE_ORDER == BRG_BIG_ENDIAN) +#define swap_b32(x) (x) +#else +#define swap_b32(x) irr::os::Byteswap::byteswap(x) +#endif + +#define SHA1_MASK (SHA1_BLOCK_SIZE - 1) + +#if 1 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Discovered Rich Schroeppel and Colin Plumb */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define parity(x,y,z) ((x) ^ (y) ^ (z)) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +/* A normal version as set out in the FIPS */ + +#define rnd(f,k) \ + t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \ + e = d; d = c; c = rotl32(b, 30); b = t + +void sha1_compile(sha1_ctx ctx[1]) +{ sha1_32t w[80], i, a, b, c, d, e, t; + + /* note that words are compiled from the buffer into 32-bit */ + /* words in big-endian order so an order reversal is needed */ + /* here on little endian machines */ + for(i = 0; i < SHA1_BLOCK_SIZE / 4; ++i) + w[i] = swap_b32(ctx->wbuf[i]); + + for(i = SHA1_BLOCK_SIZE / 4; i < 80; ++i) + w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); + + a = ctx->hash[0]; + b = ctx->hash[1]; + c = ctx->hash[2]; + d = ctx->hash[3]; + e = ctx->hash[4]; + + for(i = 0; i < 20; ++i) + { + rnd(ch, 0x5a827999); + } + + for(i = 20; i < 40; ++i) + { + rnd(parity, 0x6ed9eba1); + } + + for(i = 40; i < 60; ++i) + { + rnd(maj, 0x8f1bbcdc); + } + + for(i = 60; i < 80; ++i) + { + rnd(parity, 0xca62c1d6); + } + + ctx->hash[0] += a; + ctx->hash[1] += b; + ctx->hash[2] += c; + ctx->hash[3] += d; + ctx->hash[4] += e; +} + +void sha1_begin(sha1_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + ctx->hash[0] = 0x67452301; + ctx->hash[1] = 0xefcdab89; + ctx->hash[2] = 0x98badcfe; + ctx->hash[3] = 0x10325476; + ctx->hash[4] = 0xc3d2e1f0; +} + +/* SHA1 hash data in an array of bytes into hash buffer and */ +/* call the hash_compile function as required. */ + +void sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]) +{ sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK), + space = SHA1_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks if possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0; + sha1_compile(ctx); + } + + /*lint -e{803} conceivable data overrun */ + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA1 final padding and digest calculation */ + +#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN) +static sha1_32t mask[4] = + { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff }; +static sha1_32t bits[4] = + { 0x00000080, 0x00008000, 0x00800000, 0x80000000 }; +#else +static sha1_32t mask[4] = + { 0x00000000, 0xff000000, 0xffff0000, 0xffffff00 }; +static sha1_32t bits[4] = + { 0x80000000, 0x00800000, 0x00008000, 0x00000080 }; +#endif + +void sha1_end(unsigned char hval[], sha1_ctx ctx[1]) +{ sha1_32t i = (sha1_32t)(ctx->count[0] & SHA1_MASK); + + /* mask out the rest of any partial 32-bit word and then set */ + /* the next byte to 0x80. On big-endian machines any bytes in */ + /* the buffer will be at the top end of 32 bit words, on little */ + /* endian machines they will be at the bottom. Hence the AND */ + /* and OR masks above are reversed for little endian systems */ + /* Note that we can always add the first padding byte at this */ + /* point because the buffer always has at least one empty slot */ + ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & mask[i & 3]) | bits[i & 3]; + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if(i > SHA1_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha1_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* assemble the eight byte counter in in big-endian format */ + ctx->wbuf[14] = swap_b32((ctx->count[1] << 3) | (ctx->count[0] >> 29)); + ctx->wbuf[15] = swap_b32(ctx->count[0] << 3); + + sha1_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < SHA1_DIGEST_SIZE; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +void sha1(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha1_ctx cx[1]; + + sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); +} + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.h new file mode 100644 index 0000000..0b39f5c --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha1.h @@ -0,0 +1,68 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 +*/ + +#ifndef _SHA1_H +#define _SHA1_H + +#include + +#define SHA1_BLOCK_SIZE 64 +#define SHA1_DIGEST_SIZE 20 + +/* define an unsigned 32-bit type */ + +#if UINT_MAX == 0xffffffff + typedef unsigned int sha1_32t; +#elif ULONG_MAX == 0xffffffff + typedef unsigned long sha1_32t; +#else +#error Please define sha1_32t as an unsigned 32 bit type in sha2.h +#endif + +/* type to hold the SHA256 context */ + +typedef struct +{ sha1_32t count[2]; + sha1_32t hash[5]; + sha1_32t wbuf[16]; +} sha1_ctx; + +void sha1_compile(sha1_ctx ctx[1]); + +void sha1_begin(sha1_ctx ctx[1]); +void sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]); +void sha1_end(unsigned char hval[], sha1_ctx ctx[1]); +void sha1(unsigned char hval[], const unsigned char data[], unsigned long len); + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.cpp new file mode 100644 index 0000000..5be1bbf --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.cpp @@ -0,0 +1,626 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 + + This is a byte oriented version of SHA2 that operates on arrays of bytes + stored in memory. This code implements sha256, sha384 and sha512 but the + latter two functions rely on efficient 64-bit integer operations that + may not be very efficient on 32-bit machines + + The sha256 functions use a type 'sha256_ctx' to hold details of the + current hash state and uses the following three calls: + + void sha256_begin(sha256_ctx ctx[1]) + void sha256_hash(const unsigned char data[], + unsigned long len, sha256_ctx ctx[1]) + void sha256_end(unsigned char hval[], sha256_ctx ctx[1]) + + The first subroutine initialises a hash computation by setting up the + context in the sha256_ctx context. The second subroutine hashes 8-bit + bytes from array data[] into the hash state withinh sha256_ctx context, + the number of bytes to be hashed being given by the the unsigned long + integer len. The third subroutine completes the hash calculation and + places the resulting digest value in the array of 8-bit bytes hval[]. + + The sha384 and sha512 functions are similar and use the interfaces: + + void sha384_begin(sha384_ctx ctx[1]); + void sha384_hash(const unsigned char data[], + unsigned long len, sha384_ctx ctx[1]); + void sha384_end(unsigned char hval[], sha384_ctx ctx[1]); + + void sha512_begin(sha512_ctx ctx[1]); + void sha512_hash(const unsigned char data[], + unsigned long len, sha512_ctx ctx[1]); + void sha512_end(unsigned char hval[], sha512_ctx ctx[1]); + + In addition there is a function sha2 that can be used to call all these + functions using a call with a hash length parameter as follows: + + int sha2_begin(unsigned long len, sha2_ctx ctx[1]); + void sha2_hash(const unsigned char data[], + unsigned long len, sha2_ctx ctx[1]); + void sha2_end(unsigned char hval[], sha2_ctx ctx[1]); + + My thanks to Erik Andersen for testing this code + on big-endian systems and for his assistance with corrections +*/ + +/* define the hash functions that you need */ + +#define SHA_2 /* for dynamic hash length */ +#define SHA_256 +#define SHA_384 +#define SHA_512 + +#include /* for memcpy() etc. */ +#include /* for _lrotr with VC++ */ + +#include "sha2.h" +#include "../os.h" + +/* BYTE ORDER IN 32-BIT WORDS + + To obtain the highest speed on processors with 32-bit words, this code + needs to determine the byte order of the target machine. The following + block of code is an attempt to capture the most obvious ways in which + various environemnts define byte order. It may well fail, in which case + the definitions will need to be set by editing at the points marked + **** EDIT HERE IF NECESSARY **** below. My thanks to Peter Gutmann for + some of these defines (from cryptlib). +*/ + +#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ +#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ + +#ifdef __BIG_ENDIAN__ +#define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN +#else +#define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN +#endif + +#ifdef _MSC_VER +#pragma intrinsic(memcpy) +#endif + +#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) + +#if !defined(bswap_32) +#define bswap_32(x) irr::os::Byteswap::byteswap(x) +#endif + +#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN) +#define SWAP_BYTES +#else +#undef SWAP_BYTES +#endif + +#if defined(SHA_2) || defined(SHA_256) + +#define SHA256_MASK (SHA256_BLOCK_SIZE - 1) + +#if defined(SWAP_BYTES) +#define bsw_32(p,n) { int _i = (n); while(_i--) p[_i] = bswap_32(p[_i]); } +#else +#define bsw_32(p,n) +#endif + +/* SHA256 mixing function definitions */ + +#if 0 + +#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#else /* Thanks to Rich Schroeppel and Colin Plumb for the following */ + +#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) +#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) + +#endif + +#define s256_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22)) +#define s256_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25)) +#define g256_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3)) +#define g256_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10)) + +/* rotated SHA256 round definition. Rather than swapping variables as in */ +/* FIPS-180, different variables are 'rotated' on each round, returning */ +/* to their starting positions every eight rounds */ + +#define h2(i) p[i & 15] += \ + g256_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g256_0(p[(i + 1) & 15]) + +#define h2_cycle(i,j) \ + v[(7 - i) & 7] += (j ? h2(i) : p[i & 15]) + k256[i + j] \ + + s256_1(v[(4 - i) & 7]) + ch(v[(4 - i) & 7], v[(5 - i) & 7], v[(6 - i) & 7]); \ + v[(3 - i) & 7] += v[(7 - i) & 7]; \ + v[(7 - i) & 7] += s256_0(v[(0 - i) & 7]) + maj(v[(0 - i) & 7], v[(1 - i) & 7], v[(2 - i) & 7]) + +/* SHA256 mixing data */ + +const sha2_32t k256[64] = +{ n_u32(428a2f98), n_u32(71374491), n_u32(b5c0fbcf), n_u32(e9b5dba5), + n_u32(3956c25b), n_u32(59f111f1), n_u32(923f82a4), n_u32(ab1c5ed5), + n_u32(d807aa98), n_u32(12835b01), n_u32(243185be), n_u32(550c7dc3), + n_u32(72be5d74), n_u32(80deb1fe), n_u32(9bdc06a7), n_u32(c19bf174), + n_u32(e49b69c1), n_u32(efbe4786), n_u32(0fc19dc6), n_u32(240ca1cc), + n_u32(2de92c6f), n_u32(4a7484aa), n_u32(5cb0a9dc), n_u32(76f988da), + n_u32(983e5152), n_u32(a831c66d), n_u32(b00327c8), n_u32(bf597fc7), + n_u32(c6e00bf3), n_u32(d5a79147), n_u32(06ca6351), n_u32(14292967), + n_u32(27b70a85), n_u32(2e1b2138), n_u32(4d2c6dfc), n_u32(53380d13), + n_u32(650a7354), n_u32(766a0abb), n_u32(81c2c92e), n_u32(92722c85), + n_u32(a2bfe8a1), n_u32(a81a664b), n_u32(c24b8b70), n_u32(c76c51a3), + n_u32(d192e819), n_u32(d6990624), n_u32(f40e3585), n_u32(106aa070), + n_u32(19a4c116), n_u32(1e376c08), n_u32(2748774c), n_u32(34b0bcb5), + n_u32(391c0cb3), n_u32(4ed8aa4a), n_u32(5b9cca4f), n_u32(682e6ff3), + n_u32(748f82ee), n_u32(78a5636f), n_u32(84c87814), n_u32(8cc70208), + n_u32(90befffa), n_u32(a4506ceb), n_u32(bef9a3f7), n_u32(c67178f2), +}; + +/* SHA256 initialisation data */ + +const sha2_32t i256[8] = +{ + n_u32(6a09e667), n_u32(bb67ae85), n_u32(3c6ef372), n_u32(a54ff53a), + n_u32(510e527f), n_u32(9b05688c), n_u32(1f83d9ab), n_u32(5be0cd19) +}; + +sha2_void sha256_begin(sha256_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i256, 8 * sizeof(sha2_32t)); +} + +/* Compile 64 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream placed in this */ +/* buffer will now go to the high end of words on BOTH big */ +/* and little endian systems */ + +sha2_void sha256_compile(sha256_ctx ctx[1]) +{ sha2_32t v[8], j, *p = ctx->wbuf; + + memcpy(v, ctx->hash, 8 * sizeof(sha2_32t)); + + for(j = 0; j < 64; j += 16) + { + h2_cycle( 0, j); h2_cycle( 1, j); h2_cycle( 2, j); h2_cycle( 3, j); + h2_cycle( 4, j); h2_cycle( 5, j); h2_cycle( 6, j); h2_cycle( 7, j); + h2_cycle( 8, j); h2_cycle( 9, j); h2_cycle(10, j); h2_cycle(11, j); + h2_cycle(12, j); h2_cycle(13, j); h2_cycle(14, j); h2_cycle(15, j); + } + + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; +} + +/* SHA256 hash data in an array of bytes into hash buffer */ +/* and call the hash_compile function as required. */ + +sha2_void sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]) +{ sha2_32t pos = (sha2_32t)(ctx->count[0] & SHA256_MASK), + space = SHA256_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks while possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0; + bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2) + sha256_compile(ctx); + } + + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA256 Final padding and digest calculation */ + +static sha2_32t m1[4] = +{ + n_u32(00000000), n_u32(ff000000), n_u32(ffff0000), n_u32(ffffff00) +}; + +static sha2_32t b1[4] = +{ + n_u32(80000000), n_u32(00800000), n_u32(00008000), n_u32(00000080) +}; + +sha2_void sha256_end(unsigned char hval[], sha256_ctx ctx[1]) +{ sha2_32t i = (sha2_32t)(ctx->count[0] & SHA256_MASK); + + bsw_32(ctx->wbuf, (i + 3) >> 2) + /* bytes in the buffer are now in an order in which references */ + /* to 32-bit words will put bytes with lower addresses into the */ + /* top of 32 bit words on BOTH big and little endian machines */ + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. */ + ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & m1[i & 3]) | b1[i & 3]; + + /* we need 9 or more empty positions, one for the padding byte */ + /* (above) and eight for the length count. If there is not */ + /* enough space pad and empty the buffer */ + if(i > SHA256_BLOCK_SIZE - 9) + { + if(i < 60) ctx->wbuf[15] = 0; + sha256_compile(ctx); + i = 0; + } + else /* compute a word index for the empty buffer positions */ + i = (i >> 2) + 1; + + while(i < 14) /* and zero pad all but last two positions */ + ctx->wbuf[i++] = 0; + + /* the following 32-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 32-bit */ + /* word values. */ + + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29); + ctx->wbuf[15] = ctx->count[0] << 3; + + sha256_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* mislaigned for 32-bit words */ + for(i = 0; i < SHA256_DIGEST_SIZE; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3))); +} + +sha2_void sha256(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha256_ctx cx[1]; + + sha256_begin(cx); sha256_hash(data, len, cx); sha256_end(hval, cx); +} + +#endif + +#if defined(SHA_2) || defined(SHA_384) || defined(SHA_512) + +#define SHA512_MASK (SHA512_BLOCK_SIZE - 1) + +#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n))) + +#if !defined(bswap_64) +#define bswap_64(x) ((((sha2_64t)(bswap_32((sha2_32t)(x)))) << 32) | (bswap_32((sha2_32t)((x) >> 32)))) +#endif + +#if defined(SWAP_BYTES) +#define bsw_64(p,n) { int _i = (n); while(_i--) p[_i] = bswap_64(p[_i]); } +#else +#define bsw_64(p,n) +#endif + +/* SHA512 mixing function definitions */ + +#define s512_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39)) +#define s512_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41)) +#define g512_0(x) (rotr64((x), 1) ^ rotr64((x), 8) ^ ((x) >> 7)) +#define g512_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >> 6)) + +/* rotated SHA512 round definition. Rather than swapping variables as in */ +/* FIPS-180, different variables are 'rotated' on each round, returning */ +/* to their starting positions every eight rounds */ + +#define h5(i) ctx->wbuf[i & 15] += \ + g512_1(ctx->wbuf[(i + 14) & 15]) + ctx->wbuf[(i + 9) & 15] + g512_0(ctx->wbuf[(i + 1) & 15]) + +#define h5_cycle(i,j) \ + v[(7 - i) & 7] += (j ? h5(i) : ctx->wbuf[i & 15]) + k512[i + j] \ + + s512_1(v[(4 - i) & 7]) + ch(v[(4 - i) & 7], v[(5 - i) & 7], v[(6 - i) & 7]); \ + v[(3 - i) & 7] += v[(7 - i) & 7]; \ + v[(7 - i) & 7] += s512_0(v[(0 - i) & 7]) + maj(v[(0 - i) & 7], v[(1 - i) & 7], v[(2 - i) & 7]) + +/* SHA384/SHA512 mixing data */ + +const sha2_64t k512[80] = +{ + n_u64(428a2f98d728ae22), n_u64(7137449123ef65cd), + n_u64(b5c0fbcfec4d3b2f), n_u64(e9b5dba58189dbbc), + n_u64(3956c25bf348b538), n_u64(59f111f1b605d019), + n_u64(923f82a4af194f9b), n_u64(ab1c5ed5da6d8118), + n_u64(d807aa98a3030242), n_u64(12835b0145706fbe), + n_u64(243185be4ee4b28c), n_u64(550c7dc3d5ffb4e2), + n_u64(72be5d74f27b896f), n_u64(80deb1fe3b1696b1), + n_u64(9bdc06a725c71235), n_u64(c19bf174cf692694), + n_u64(e49b69c19ef14ad2), n_u64(efbe4786384f25e3), + n_u64(0fc19dc68b8cd5b5), n_u64(240ca1cc77ac9c65), + n_u64(2de92c6f592b0275), n_u64(4a7484aa6ea6e483), + n_u64(5cb0a9dcbd41fbd4), n_u64(76f988da831153b5), + n_u64(983e5152ee66dfab), n_u64(a831c66d2db43210), + n_u64(b00327c898fb213f), n_u64(bf597fc7beef0ee4), + n_u64(c6e00bf33da88fc2), n_u64(d5a79147930aa725), + n_u64(06ca6351e003826f), n_u64(142929670a0e6e70), + n_u64(27b70a8546d22ffc), n_u64(2e1b21385c26c926), + n_u64(4d2c6dfc5ac42aed), n_u64(53380d139d95b3df), + n_u64(650a73548baf63de), n_u64(766a0abb3c77b2a8), + n_u64(81c2c92e47edaee6), n_u64(92722c851482353b), + n_u64(a2bfe8a14cf10364), n_u64(a81a664bbc423001), + n_u64(c24b8b70d0f89791), n_u64(c76c51a30654be30), + n_u64(d192e819d6ef5218), n_u64(d69906245565a910), + n_u64(f40e35855771202a), n_u64(106aa07032bbd1b8), + n_u64(19a4c116b8d2d0c8), n_u64(1e376c085141ab53), + n_u64(2748774cdf8eeb99), n_u64(34b0bcb5e19b48a8), + n_u64(391c0cb3c5c95a63), n_u64(4ed8aa4ae3418acb), + n_u64(5b9cca4f7763e373), n_u64(682e6ff3d6b2b8a3), + n_u64(748f82ee5defb2fc), n_u64(78a5636f43172f60), + n_u64(84c87814a1f0ab72), n_u64(8cc702081a6439ec), + n_u64(90befffa23631e28), n_u64(a4506cebde82bde9), + n_u64(bef9a3f7b2c67915), n_u64(c67178f2e372532b), + n_u64(ca273eceea26619c), n_u64(d186b8c721c0c207), + n_u64(eada7dd6cde0eb1e), n_u64(f57d4f7fee6ed178), + n_u64(06f067aa72176fba), n_u64(0a637dc5a2c898a6), + n_u64(113f9804bef90dae), n_u64(1b710b35131c471b), + n_u64(28db77f523047d84), n_u64(32caab7b40c72493), + n_u64(3c9ebe0a15c9bebc), n_u64(431d67c49c100d4c), + n_u64(4cc5d4becb3e42b6), n_u64(597f299cfc657e2a), + n_u64(5fcb6fab3ad6faec), n_u64(6c44198c4a475817) +}; + +/* Compile 64 bytes of hash data into SHA384/SHA512 digest value */ + +sha2_void sha512_compile(sha512_ctx ctx[1]) +{ sha2_64t v[8]; + sha2_32t j; + + memcpy(v, ctx->hash, 8 * sizeof(sha2_64t)); + + for(j = 0; j < 80; j += 16) + { + h5_cycle( 0, j); h5_cycle( 1, j); h5_cycle( 2, j); h5_cycle( 3, j); + h5_cycle( 4, j); h5_cycle( 5, j); h5_cycle( 6, j); h5_cycle( 7, j); + h5_cycle( 8, j); h5_cycle( 9, j); h5_cycle(10, j); h5_cycle(11, j); + h5_cycle(12, j); h5_cycle(13, j); h5_cycle(14, j); h5_cycle(15, j); + } + + ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; + ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6]; ctx->hash[7] += v[7]; +} + +/* Compile 128 bytes of hash data into SHA256 digest value */ +/* NOTE: this routine assumes that the byte order in the */ +/* ctx->wbuf[] at this point is in such an order that low */ +/* address bytes in the ORIGINAL byte stream placed in this */ +/* buffer will now go to the high end of words on BOTH big */ +/* and little endian systems */ + +sha2_void sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]) +{ sha2_32t pos = (sha2_32t)(ctx->count[0] & SHA512_MASK), + space = SHA512_BLOCK_SIZE - pos; + const unsigned char *sp = data; + + if((ctx->count[0] += len) < len) + ++(ctx->count[1]); + + while(len >= space) /* tranfer whole blocks while possible */ + { + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space); + sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0; + bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3); + sha512_compile(ctx); + } + + memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len); +} + +/* SHA384/512 Final padding and digest calculation */ + +static sha2_64t m2[8] = +{ + n_u64(0000000000000000), n_u64(ff00000000000000), + n_u64(ffff000000000000), n_u64(ffffff0000000000), + n_u64(ffffffff00000000), n_u64(ffffffffff000000), + n_u64(ffffffffffff0000), n_u64(ffffffffffffff00) +}; + +static sha2_64t b2[8] = +{ + n_u64(8000000000000000), n_u64(0080000000000000), + n_u64(0000800000000000), n_u64(0000008000000000), + n_u64(0000000080000000), n_u64(0000000000800000), + n_u64(0000000000008000), n_u64(0000000000000080) +}; + +static void sha_end(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen) +{ sha2_32t i = (sha2_32t)(ctx->count[0] & SHA512_MASK); + + bsw_64(ctx->wbuf, (i + 7) >> 3); + + /* bytes in the buffer are now in an order in which references */ + /* to 64-bit words will put bytes with lower addresses into the */ + /* top of 64 bit words on BOTH big and little endian machines */ + + /* we now need to mask valid bytes and add the padding which is */ + /* a single 1 bit and as many zero bits as necessary. */ + ctx->wbuf[i >> 3] = (ctx->wbuf[i >> 3] & m2[i & 7]) | b2[i & 7]; + + /* we need 17 or more empty byte positions, one for the padding */ + /* byte (above) and sixteen for the length count. If there is */ + /* not enough space pad and empty the buffer */ + if(i > SHA512_BLOCK_SIZE - 17) + { + if(i < 120) ctx->wbuf[15] = 0; + sha512_compile(ctx); + i = 0; + } + else + i = (i >> 3) + 1; + + while(i < 14) + ctx->wbuf[i++] = 0; + + /* the following 64-bit length fields are assembled in the */ + /* wrong byte order on little endian machines but this is */ + /* corrected later since they are only ever used as 64-bit */ + /* word values. */ + + ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61); + ctx->wbuf[15] = ctx->count[0] << 3; + + sha512_compile(ctx); + + /* extract the hash value as bytes in case the hash buffer is */ + /* misaligned for 32-bit words */ + for(i = 0; i < hlen; ++i) + hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7))); +} + +#endif + +#if defined(SHA_2) || defined(SHA_384) + +/* SHA384 initialisation data */ + +const sha2_64t i384[80] = +{ + n_u64(cbbb9d5dc1059ed8), n_u64(629a292a367cd507), + n_u64(9159015a3070dd17), n_u64(152fecd8f70e5939), + n_u64(67332667ffc00b31), n_u64(8eb44a8768581511), + n_u64(db0c2e0d64f98fa7), n_u64(47b5481dbefa4fa4) +}; + +sha2_void sha384_begin(sha384_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i384, 8 * sizeof(sha2_64t)); +} + +sha2_void sha384_end(unsigned char hval[], sha384_ctx ctx[1]) +{ + sha_end(hval, ctx, SHA384_DIGEST_SIZE); +} + +sha2_void sha384(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha384_ctx cx[1]; + + sha384_begin(cx); sha384_hash(data, len, cx); sha384_end(hval, cx); +} + +#endif + +#if defined(SHA_2) || defined(SHA_512) + +/* SHA512 initialisation data */ + +const sha2_64t i512[80] = +{ + n_u64(6a09e667f3bcc908), n_u64(bb67ae8584caa73b), + n_u64(3c6ef372fe94f82b), n_u64(a54ff53a5f1d36f1), + n_u64(510e527fade682d1), n_u64(9b05688c2b3e6c1f), + n_u64(1f83d9abfb41bd6b), n_u64(5be0cd19137e2179) +}; + +sha2_void sha512_begin(sha512_ctx ctx[1]) +{ + ctx->count[0] = ctx->count[1] = 0; + memcpy(ctx->hash, i512, 8 * sizeof(sha2_64t)); +} + +sha2_void sha512_end(unsigned char hval[], sha512_ctx ctx[1]) +{ + sha_end(hval, ctx, SHA512_DIGEST_SIZE); +} + +sha2_void sha512(unsigned char hval[], const unsigned char data[], unsigned long len) +{ sha512_ctx cx[1]; + + sha512_begin(cx); sha512_hash(data, len, cx); sha512_end(hval, cx); +} + +#endif + +#if defined(SHA_2) + +#define CTX_256(x) ((x)->uu->ctx256) +#define CTX_384(x) ((x)->uu->ctx512) +#define CTX_512(x) ((x)->uu->ctx512) + +/* SHA2 initialisation */ + +sha2_int sha2_begin(unsigned long len, sha2_ctx ctx[1]) +{ unsigned long l = len; + switch(len) + { + case 256: l = len >> 3; + case 32: CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0; + memcpy(CTX_256(ctx)->hash, i256, 32); break; + case 384: l = len >> 3; + case 48: CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0; + memcpy(CTX_384(ctx)->hash, i384, 64); break; + case 512: l = len >> 3; + case 64: CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0; + memcpy(CTX_512(ctx)->hash, i512, 64); break; + default: return SHA2_BAD; + } + + ctx->sha2_len = l; return SHA2_GOOD; +} + +sha2_void sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]) +{ + switch(ctx->sha2_len) + { + case 32: sha256_hash(data, len, CTX_256(ctx)); return; + case 48: sha384_hash(data, len, CTX_384(ctx)); return; + case 64: sha512_hash(data, len, CTX_512(ctx)); return; + } +} + +sha2_void sha2_end(unsigned char hval[], sha2_ctx ctx[1]) +{ + switch(ctx->sha2_len) + { + case 32: sha256_end(hval, CTX_256(ctx)); return; + case 48: sha_end(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return; + case 64: sha_end(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return; + } +} + +sha2_int sha2(unsigned char hval[], unsigned long size, + const unsigned char data[], unsigned long len) +{ sha2_ctx cx[1]; + + if(sha2_begin(size, cx) == SHA2_GOOD) + { + sha2_hash(data, len, cx); sha2_end(hval, cx); return SHA2_GOOD; + } + else + return SHA2_BAD; +} + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.h b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.h new file mode 100644 index 0000000..d901b80 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/aesGladman/sha2.h @@ -0,0 +1,160 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. + All rights reserved. + + LICENSE TERMS + + The free distribution and use of this software in both source and binary + form is allowed (with or without changes) provided that: + + 1. distributions of this source code include the above copyright + notice, this list of conditions and the following disclaimer; + + 2. distributions in binary form include the above copyright + notice, this list of conditions and the following disclaimer + in the documentation and/or other associated materials; + + 3. the copyright holder's name is not used to endorse products + built using this software without specific written permission. + + ALTERNATIVELY, provided that this notice is retained in full, this product + may be distributed under the terms of the GNU General Public License (GPL), + in which case the provisions of the GPL apply INSTEAD OF those given above. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 26/08/2003 +*/ + +#ifndef _SHA2_H +#define _SHA2_H + +#include "irrMath.h" + +/* Defines for suffixes to 32 and 64 bit unsigned numeric values */ + +#define sfx_lo(x,y) x##y +#define sfx_hi(x,y) sfx_lo(x,y) +#define n_u32(p) sfx_hi(0x##p,s_u32) +#define n_u64(p) sfx_hi(0x##p,s_u64) + +/* define an unsigned 32-bit type */ + +#if UINT_MAX == 0xffffffff + typedef unsigned int sha2_32t; + #define s_u32 u +#elif ULONG_MAX == 0xffffffff + typedef unsigned long sha2_32t; + #define s_u32 ul +#else +#error Please define sha2_32t as an unsigned 32 bit type in sha2.h +#endif + +/* define an unsigned 64-bit type */ + +#if defined(_MSC_VER) || defined(__BORLANDC__) +#if (_MSC_VER < 1300) || (__BORLANDC__ < 0x582) + typedef unsigned __int64 sha2_64t; + #define s_u64 ui64 +#elif ULONG_MAX == 0xffffffffffffffff + typedef unsigned long sha2_64t; + #define s_u64 ul +#elif ULONG_MAX == 0xffffffff + typedef unsigned long long sha2_64t; /* a somewhat dangerous guess */ + #define s_u64 ull +#else +#error Please define sha2_64t as an unsigned 64 bit type in sha2.h +#endif +#else +#ifdef _IRR_SOLARIS_PLATFORM_ +#include +#else +#include +#endif + typedef int64_t sha2_64t; +#if __WORDSIZE==64 +#define s_u64 ul +#else +#define s_u64 ull +#endif +#endif + +#define SHA256_DIGEST_SIZE 32 +#define SHA384_DIGEST_SIZE 48 +#define SHA512_DIGEST_SIZE 64 + +#define SHA256_BLOCK_SIZE 64 +#define SHA384_BLOCK_SIZE 128 +#define SHA512_BLOCK_SIZE 128 + +#define SHA2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE + +#define SHA2_GOOD 0 +#define SHA2_BAD 1 + +/* type to hold the SHA256 context */ + +typedef struct +{ sha2_32t count[2]; + sha2_32t hash[8]; + sha2_32t wbuf[16]; +} sha256_ctx; + +/* type to hold the SHA384/512 context */ + +typedef struct +{ sha2_64t count[2]; + sha2_64t hash[8]; + sha2_64t wbuf[16]; +} sha512_ctx; + +typedef sha512_ctx sha384_ctx; + +/* type to hold a SHA2 context (256/384/512) */ + +typedef struct +{ union + { sha256_ctx ctx256[1]; + sha512_ctx ctx512[1]; + } uu[1]; + sha2_32t sha2_len; +} sha2_ctx; + +#ifndef SHA2_DLL /* implement normal or DLL functions */ +#define sha2_void void +#define sha2_int int +#else +#define sha2_void void __declspec(dllexport) _stdcall +#define sha2_int int __declspec(dllexport) _stdcall +#endif + +sha2_void sha256_compile(sha256_ctx ctx[1]); +sha2_void sha512_compile(sha512_ctx ctx[1]); + +sha2_void sha256_begin(sha256_ctx ctx[1]); +sha2_void sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]); +sha2_void sha256_end(unsigned char hval[], sha256_ctx ctx[1]); +sha2_void sha256(unsigned char hval[], const unsigned char data[], unsigned long len); + +sha2_void sha384_begin(sha384_ctx ctx[1]); +#define sha384_hash sha512_hash +sha2_void sha384_end(unsigned char hval[], sha384_ctx ctx[1]); +sha2_void sha384(unsigned char hval[], const unsigned char data[], unsigned long len); + +sha2_void sha512_begin(sha512_ctx ctx[1]); +sha2_void sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]); +sha2_void sha512_end(unsigned char hval[], sha512_ctx ctx[1]); +sha2_void sha512(unsigned char hval[], const unsigned char data[], unsigned long len); + +sha2_int sha2_begin(unsigned long size, sha2_ctx ctx[1]); +sha2_void sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]); +sha2_void sha2_end(unsigned char hval[], sha2_ctx ctx[1]); +sha2_int sha2(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len); + +#endif + diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/builtInFont.bmp b/src/others/irrlicht-1.8.1/source/Irrlicht/builtInFont.bmp new file mode 100644 index 0000000..7001c12 Binary files /dev/null and b/src/others/irrlicht-1.8.1/source/Irrlicht/builtInFont.bmp differ diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/CHANGES b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/CHANGES new file mode 100644 index 0000000..81e97ca --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/CHANGES @@ -0,0 +1,327 @@ + ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.6 of 6 September 2010 + Copyright (C) 1996-2010 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ + + +0.9.0 +~~~~~ +First version. + + +0.9.0a +~~~~~~ +Removed 'ranlib' from Makefile, since most modern Unix-es +don't need it, or even know about it. + + +0.9.0b +~~~~~~ +Fixed a problem with error reporting in bzip2.c. This does not effect +the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the +program proper) compress and decompress correctly, but give misleading +error messages (internal panics) when an I/O error occurs, instead of +reporting the problem correctly. This shouldn't give any data loss +(as far as I can see), but is confusing. + +Made the inline declarations disappear for non-GCC compilers. + + +0.9.0c +~~~~~~ +Fixed some problems in the library pertaining to some boundary cases. +This makes the library behave more correctly in those situations. The +fixes apply only to features (calls and parameters) not used by +bzip2.c, so the non-fixedness of them in previous versions has no +effect on reliability of bzip2.c. + +In bzlib.c: + * made zero-length BZ_FLUSH work correctly in bzCompress(). + * fixed bzWrite/bzRead to ignore zero-length requests. + * fixed bzread to correctly handle read requests after EOF. + * wrong parameter order in call to bzDecompressInit in + bzBuffToBuffDecompress. Fixed. + +In compress.c: + * changed setting of nGroups in sendMTFValues() so as to + do a bit better on small files. This _does_ effect + bzip2.c. + + +0.9.5a +~~~~~~ +Major change: add a fallback sorting algorithm (blocksort.c) +to give reasonable behaviour even for very repetitive inputs. +Nuked --repetitive-best and --repetitive-fast since they are +no longer useful. + +Minor changes: mostly a whole bunch of small changes/ +bugfixes in the driver (bzip2.c). Changes pertaining to the +user interface are: + + allow decompression of symlink'd files to stdout + decompress/test files even without .bz2 extension + give more accurate error messages for I/O errors + when compressing/decompressing to stdout, don't catch control-C + read flags from BZIP2 and BZIP environment variables + decline to break hard links to a file unless forced with -f + allow -c flag even with no filenames + preserve file ownerships as far as possible + make -s -1 give the expected block size (100k) + add a flag -q --quiet to suppress nonessential warnings + stop decoding flags after --, so files beginning in - can be handled + resolved inconsistent naming: bzcat or bz2cat ? + bzip2 --help now returns 0 + +Programming-level changes are: + + fixed syntax error in GET_LL4 for Borland C++ 5.02 + let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC} + fix overshoot of mode-string end in bzopen_or_bzdopen + wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... } + close file handles under all error conditions + added minor mods so it compiles with DJGPP out of the box + fixed Makefile so it doesn't give problems with BSD make + fix uninitialised memory reads in dlltest.c + +0.9.5b +~~~~~~ +Open stdin/stdout in binary mode for DJGPP. + +0.9.5c +~~~~~~ +Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1 +version could cause the sorted order to be wrong in some extremely +obscure cases. Also changed setting of quadrant in blocksort.c. + +0.9.5d +~~~~~~ +The only functional change is to make bzlibVersion() in the library +return the correct string. This has no effect whatsoever on the +functioning of the bzip2 program or library. Added a couple of casts +so the library compiles without warnings at level 3 in MS Visual +Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other +changes are minor documentation changes. + +1.0 +~~~ +Several minor bugfixes and enhancements: + +* Large file support. The library uses 64-bit counters to + count the volume of data passing through it. bzip2.c + is now compiled with -D_FILE_OFFSET_BITS=64 to get large + file support from the C library. -v correctly prints out + file sizes greater than 4 gigabytes. All these changes have + been made without assuming a 64-bit platform or a C compiler + which supports 64-bit ints, so, except for the C library + aspect, they are fully portable. + +* Decompression robustness. The library/program should be + robust to any corruption of compressed data, detecting and + handling _all_ corruption, instead of merely relying on + the CRCs. What this means is that the program should + never crash, given corrupted data, and the library should + always return BZ_DATA_ERROR. + +* Fixed an obscure race-condition bug only ever observed on + Solaris, in which, if you were very unlucky and issued + control-C at exactly the wrong time, both input and output + files would be deleted. + +* Don't run out of file handles on test/decompression when + large numbers of files have invalid magic numbers. + +* Avoid library namespace pollution. Prefix all exported + symbols with BZ2_. + +* Minor sorting enhancements from my DCC2000 paper. + +* Advance the version number to 1.0, so as to counteract the + (false-in-this-case) impression some people have that programs + with version numbers less than 1.0 are in some way, experimental, + pre-release versions. + +* Create an initial Makefile-libbz2_so to build a shared library. + Yes, I know I should really use libtool et al ... + +* Make the program exit with 2 instead of 0 when decompression + fails due to a bad magic number (ie, an invalid bzip2 header). + Also exit with 1 (as the manual claims :-) whenever a diagnostic + message would have been printed AND the corresponding operation + is aborted, for example + bzip2: Output file xx already exists. + When a diagnostic message is printed but the operation is not + aborted, for example + bzip2: Can't guess original name for wurble -- using wurble.out + then the exit value 0 is returned, unless some other problem is + also detected. + + I think it corresponds more closely to what the manual claims now. + + +1.0.1 +~~~~~ +* Modified dlltest.c so it uses the new BZ2_ naming scheme. +* Modified makefile-msc to fix minor build probs on Win2k. +* Updated README.COMPILATION.PROBLEMS. + +There are no functionality changes or bug fixes relative to version +1.0.0. This is just a documentation update + a fix for minor Win32 +build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is +utterly pointless. Don't bother. + + +1.0.2 +~~~~~ +A bug fix release, addressing various minor issues which have appeared +in the 18 or so months since 1.0.1 was released. Most of the fixes +are to do with file-handling or documentation bugs. To the best of my +knowledge, there have been no data-loss-causing bugs reported in the +compression/decompression engine of 1.0.0 or 1.0.1. + +Note that this release does not improve the rather crude build system +for Unix platforms. The general plan here is to autoconfiscate/ +libtoolise 1.0.2 soon after release, and release the result as 1.1.0 +or perhaps 1.2.0. That, however, is still just a plan at this point. + +Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in +parentheses. + +* Fix an infinite segfault loop in 1.0.1 when a directory is + encountered in -f (force) mode. + (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt) + +* Avoid double fclose() of output file on certain I/O error paths. + (Solar Designer) + +* Don't fail with internal error 1007 when fed a long stream (> 48MB) + of byte 251. Also print useful message suggesting that 1007s may be + caused by bad memory. + (noticed by Juan Pedro Vallejo, fixed by me) + +* Fix uninitialised variable silly bug in demo prog dlltest.c. + (Jorj Bauer) + +* Remove 512-MB limitation on recovered file size for bzip2recover + on selected platforms which support 64-bit ints. At the moment + all GCC supported platforms, and Win32. + (me, Alson van der Meulen) + +* Hard-code header byte values, to give correct operation on platforms + using EBCDIC as their native character set (IBM's OS/390). + (Leland Lucius) + +* Copy file access times correctly. + (Marty Leisner) + +* Add distclean and check targets to Makefile. + (Michael Carmack) + +* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS). + (Rich Ireland, Bo Thorsen) + +* Pass -p (create parent dirs as needed) to mkdir during make install. + (Jeremy Fusco) + +* Dereference symlinks when copying file permissions in -f mode. + (Volker Schmidt) + +* Majorly simplify implementation of uInt64_qrm10. + (Bo Lindbergh) + +* Check the input file still exists before deleting the output one, + when aborting in cleanUpAndFail(). + (Joerg Prante, Robert Linden, Matthias Krings) + +Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer +of bzip2: + +* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore. + +* Spelling changes and minor enhancements in bzip2.1. + +* Avoid race condition between creating the output file and setting its + interim permissions safely, by using fopen_output_safely(). + No changes to bzip2recover since there is no issue with file + permissions there. + +* do not print senseless report with -v when compressing an empty + file. + +* bzcat -f works on non-bzip2 files. + +* do not try to escape shell meta-characters on unix (the shell takes + care of these). + +* added --fast and --best aliases for -1 -9 for gzip compatibility. + + +1.0.3 (15 Feb 05) +~~~~~~~~~~~~~~~~~ +Fixes some minor bugs since the last version, 1.0.2. + +* Further robustification against corrupted compressed data. + There are currently no known bitstreams which can cause the + decompressor to crash, loop or access memory which does not + belong to it. If you are using bzip2 or the library to + decompress bitstreams from untrusted sources, an upgrade + to 1.0.3 is recommended. This fixes CAN-2005-1260. + +* The documentation has been converted to XML, from which html + and pdf can be derived. + +* Various minor bugs in the documentation have been fixed. + +* Fixes for various compilation warnings with newer versions of + gcc, and on 64-bit platforms. + +* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2. + This has been fixed. + + +1.0.4 (20 Dec 06) +~~~~~~~~~~~~~~~~~ +Fixes some minor bugs since the last version, 1.0.3. + +* Fix file permissions race problem (CAN-2005-0953). + +* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD + scan. + +* 'const'/prototype cleanups in the C code. + +* Change default install location to /usr/local, and handle multiple + 'make install's without error. + +* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758 + to the extent that applies to bzgrep. + +* Use 'mktemp' rather than 'tempfile' in bzdiff. + +* Tighten up a couple of assertions in blocksort.c following automated + analysis. + +* Fix minor doc/comment bugs. + + +1.0.5 (10 Dec 07) +~~~~~~~~~~~~~~~~~ +Security fix only. Fixes CERT-FI 20469 as it applies to bzip2. + + +1.0.6 (6 Sept 10) +~~~~~~~~~~~~~~~~~ + +* Security fix for CVE-2010-0405. This was reported by Mikolaj + Izdebski. + +* Make the documentation build on Ubuntu 10.04 diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/LICENSE b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/LICENSE new file mode 100644 index 0000000..cc61417 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/LICENSE @@ -0,0 +1,42 @@ + +-------------------------------------------------------------------------- + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2010 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, jseward@bzip.org +bzip2/libbzip2 version 1.0.6 of 6 September 2010 + +-------------------------------------------------------------------------- diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile new file mode 100644 index 0000000..9754ddf --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile @@ -0,0 +1,217 @@ +# ------------------------------------------------------------------ +# This file is part of bzip2/libbzip2, a program and library for +# lossless, block-sorting data compression. +# +# bzip2/libbzip2 version 1.0.6 of 6 September 2010 +# Copyright (C) 1996-2010 Julian Seward +# +# Please read the WARNING, DISCLAIMER and PATENTS sections in the +# README file. +# +# This program is released under the terms of the license contained +# in the file LICENSE. +# ------------------------------------------------------------------ + +SHELL=/bin/sh + +# To assist in cross-compiling +CC=gcc +AR=ar +RANLIB=ranlib +LDFLAGS= + +BIGFILES=-D_FILE_OFFSET_BITS=64 +CFLAGS=-Wall -Winline -O2 -g $(BIGFILES) + +# Where you want it installed when you do 'make install' +PREFIX=/usr/local + + +OBJS= blocksort.o \ + huffman.o \ + crctable.o \ + randtable.o \ + compress.o \ + decompress.o \ + bzlib.o + +all: libbz2.a bzip2 bzip2recover test + +bzip2: libbz2.a bzip2.o + $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2 bzip2.o -L. -lbz2 + +bzip2recover: bzip2recover.o + $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2recover bzip2recover.o + +libbz2.a: $(OBJS) + rm -f libbz2.a + $(AR) cq libbz2.a $(OBJS) + @if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \ + -f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \ + echo $(RANLIB) libbz2.a ; \ + $(RANLIB) libbz2.a ; \ + fi + +check: test +test: bzip2 + @cat words1 + ./bzip2 -1 < sample1.ref > sample1.rb2 + ./bzip2 -2 < sample2.ref > sample2.rb2 + ./bzip2 -3 < sample3.ref > sample3.rb2 + ./bzip2 -d < sample1.bz2 > sample1.tst + ./bzip2 -d < sample2.bz2 > sample2.tst + ./bzip2 -ds < sample3.bz2 > sample3.tst + cmp sample1.bz2 sample1.rb2 + cmp sample2.bz2 sample2.rb2 + cmp sample3.bz2 sample3.rb2 + cmp sample1.tst sample1.ref + cmp sample2.tst sample2.ref + cmp sample3.tst sample3.ref + @cat words3 + +install: bzip2 bzip2recover + if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi + if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi + if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi + if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi + if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi + cp -f bzip2 $(PREFIX)/bin/bzip2 + cp -f bzip2 $(PREFIX)/bin/bunzip2 + cp -f bzip2 $(PREFIX)/bin/bzcat + cp -f bzip2recover $(PREFIX)/bin/bzip2recover + chmod a+x $(PREFIX)/bin/bzip2 + chmod a+x $(PREFIX)/bin/bunzip2 + chmod a+x $(PREFIX)/bin/bzcat + chmod a+x $(PREFIX)/bin/bzip2recover + cp -f bzip2.1 $(PREFIX)/man/man1 + chmod a+r $(PREFIX)/man/man1/bzip2.1 + cp -f bzlib.h $(PREFIX)/include + chmod a+r $(PREFIX)/include/bzlib.h + cp -f libbz2.a $(PREFIX)/lib + chmod a+r $(PREFIX)/lib/libbz2.a + cp -f bzgrep $(PREFIX)/bin/bzgrep + ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzegrep + ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzfgrep + chmod a+x $(PREFIX)/bin/bzgrep + cp -f bzmore $(PREFIX)/bin/bzmore + ln -s -f $(PREFIX)/bin/bzmore $(PREFIX)/bin/bzless + chmod a+x $(PREFIX)/bin/bzmore + cp -f bzdiff $(PREFIX)/bin/bzdiff + ln -s -f $(PREFIX)/bin/bzdiff $(PREFIX)/bin/bzcmp + chmod a+x $(PREFIX)/bin/bzdiff + cp -f bzgrep.1 bzmore.1 bzdiff.1 $(PREFIX)/man/man1 + chmod a+r $(PREFIX)/man/man1/bzgrep.1 + chmod a+r $(PREFIX)/man/man1/bzmore.1 + chmod a+r $(PREFIX)/man/man1/bzdiff.1 + echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzegrep.1 + echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzfgrep.1 + echo ".so man1/bzmore.1" > $(PREFIX)/man/man1/bzless.1 + echo ".so man1/bzdiff.1" > $(PREFIX)/man/man1/bzcmp.1 + +clean: + rm -f *.o libbz2.a bzip2 bzip2recover \ + sample1.rb2 sample2.rb2 sample3.rb2 \ + sample1.tst sample2.tst sample3.tst + +blocksort.o: blocksort.c + @cat words0 + $(CC) $(CFLAGS) -c blocksort.c +huffman.o: huffman.c + $(CC) $(CFLAGS) -c huffman.c +crctable.o: crctable.c + $(CC) $(CFLAGS) -c crctable.c +randtable.o: randtable.c + $(CC) $(CFLAGS) -c randtable.c +compress.o: compress.c + $(CC) $(CFLAGS) -c compress.c +decompress.o: decompress.c + $(CC) $(CFLAGS) -c decompress.c +bzlib.o: bzlib.c + $(CC) $(CFLAGS) -c bzlib.c +bzip2.o: bzip2.c + $(CC) $(CFLAGS) -c bzip2.c +bzip2recover.o: bzip2recover.c + $(CC) $(CFLAGS) -c bzip2recover.c + + +distclean: clean + rm -f manual.ps manual.html manual.pdf + +DISTNAME=bzip2-1.0.6 +dist: check manual + rm -f $(DISTNAME) + ln -s -f . $(DISTNAME) + tar cvf $(DISTNAME).tar \ + $(DISTNAME)/blocksort.c \ + $(DISTNAME)/huffman.c \ + $(DISTNAME)/crctable.c \ + $(DISTNAME)/randtable.c \ + $(DISTNAME)/compress.c \ + $(DISTNAME)/decompress.c \ + $(DISTNAME)/bzlib.c \ + $(DISTNAME)/bzip2.c \ + $(DISTNAME)/bzip2recover.c \ + $(DISTNAME)/bzlib.h \ + $(DISTNAME)/bzlib_private.h \ + $(DISTNAME)/Makefile \ + $(DISTNAME)/LICENSE \ + $(DISTNAME)/bzip2.1 \ + $(DISTNAME)/bzip2.1.preformatted \ + $(DISTNAME)/bzip2.txt \ + $(DISTNAME)/words0 \ + $(DISTNAME)/words1 \ + $(DISTNAME)/words2 \ + $(DISTNAME)/words3 \ + $(DISTNAME)/sample1.ref \ + $(DISTNAME)/sample2.ref \ + $(DISTNAME)/sample3.ref \ + $(DISTNAME)/sample1.bz2 \ + $(DISTNAME)/sample2.bz2 \ + $(DISTNAME)/sample3.bz2 \ + $(DISTNAME)/dlltest.c \ + $(DISTNAME)/manual.html \ + $(DISTNAME)/manual.pdf \ + $(DISTNAME)/manual.ps \ + $(DISTNAME)/README \ + $(DISTNAME)/README.COMPILATION.PROBLEMS \ + $(DISTNAME)/README.XML.STUFF \ + $(DISTNAME)/CHANGES \ + $(DISTNAME)/libbz2.def \ + $(DISTNAME)/libbz2.dsp \ + $(DISTNAME)/dlltest.dsp \ + $(DISTNAME)/makefile.msc \ + $(DISTNAME)/unzcrash.c \ + $(DISTNAME)/spewG.c \ + $(DISTNAME)/mk251.c \ + $(DISTNAME)/bzdiff \ + $(DISTNAME)/bzdiff.1 \ + $(DISTNAME)/bzmore \ + $(DISTNAME)/bzmore.1 \ + $(DISTNAME)/bzgrep \ + $(DISTNAME)/bzgrep.1 \ + $(DISTNAME)/Makefile-libbz2_so \ + $(DISTNAME)/bz-common.xsl \ + $(DISTNAME)/bz-fo.xsl \ + $(DISTNAME)/bz-html.xsl \ + $(DISTNAME)/bzip.css \ + $(DISTNAME)/entities.xml \ + $(DISTNAME)/manual.xml \ + $(DISTNAME)/format.pl \ + $(DISTNAME)/xmlproc.sh + gzip -v $(DISTNAME).tar + +# For rebuilding the manual from sources on my SuSE 9.1 box + +MANUAL_SRCS= bz-common.xsl bz-fo.xsl bz-html.xsl bzip.css \ + entities.xml manual.xml + +manual: manual.html manual.ps manual.pdf + +manual.ps: $(MANUAL_SRCS) + ./xmlproc.sh -ps manual.xml + +manual.pdf: $(MANUAL_SRCS) + ./xmlproc.sh -pdf manual.xml + +manual.html: $(MANUAL_SRCS) + ./xmlproc.sh -html manual.xml diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile-libbz2_so b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile-libbz2_so new file mode 100644 index 0000000..e58791b --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/Makefile-libbz2_so @@ -0,0 +1,59 @@ + +# This Makefile builds a shared version of the library, +# libbz2.so.1.0.6, with soname libbz2.so.1.0, +# at least on x86-Linux (RedHat 7.2), +# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98). +# Please see the README file for some important info +# about building the library like this. + +# ------------------------------------------------------------------ +# This file is part of bzip2/libbzip2, a program and library for +# lossless, block-sorting data compression. +# +# bzip2/libbzip2 version 1.0.6 of 6 September 2010 +# Copyright (C) 1996-2010 Julian Seward +# +# Please read the WARNING, DISCLAIMER and PATENTS sections in the +# README file. +# +# This program is released under the terms of the license contained +# in the file LICENSE. +# ------------------------------------------------------------------ + + +SHELL=/bin/sh +CC=gcc +BIGFILES=-D_FILE_OFFSET_BITS=64 +CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES) + +OBJS= blocksort.o \ + huffman.o \ + crctable.o \ + randtable.o \ + compress.o \ + decompress.o \ + bzlib.o + +all: $(OBJS) + $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.6 $(OBJS) + $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.6 + rm -f libbz2.so.1.0 + ln -s libbz2.so.1.0.6 libbz2.so.1.0 + +clean: + rm -f $(OBJS) bzip2.o libbz2.so.1.0.6 libbz2.so.1.0 bzip2-shared + +blocksort.o: blocksort.c + $(CC) $(CFLAGS) -c blocksort.c +huffman.o: huffman.c + $(CC) $(CFLAGS) -c huffman.c +crctable.o: crctable.c + $(CC) $(CFLAGS) -c crctable.c +randtable.o: randtable.c + $(CC) $(CFLAGS) -c randtable.c +compress.o: compress.c + $(CC) $(CFLAGS) -c compress.c +decompress.o: decompress.c + $(CC) $(CFLAGS) -c decompress.c +bzlib.o: bzlib.c + $(CC) $(CFLAGS) -c bzlib.c diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README new file mode 100644 index 0000000..9fb0f63 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README @@ -0,0 +1,215 @@ + +This is the README for bzip2/libzip2. +This version is fully compatible with the previous public releases. + +------------------------------------------------------------------ +This file is part of bzip2/libbzip2, a program and library for +lossless, block-sorting data compression. + +bzip2/libbzip2 version 1.0.6 of 6 September 2010 +Copyright (C) 1996-2010 Julian Seward + +Please read the WARNING, DISCLAIMER and PATENTS sections in this file. + +This program is released under the terms of the license contained +in the file LICENSE. +------------------------------------------------------------------ + +Complete documentation is available in Postscript form (manual.ps), +PDF (manual.pdf) or html (manual.html). A plain-text version of the +manual page is available as bzip2.txt. + + +HOW TO BUILD -- UNIX + +Type 'make'. This builds the library libbz2.a and then the programs +bzip2 and bzip2recover. Six self-tests are run. If the self-tests +complete ok, carry on to installation: + +To install in /usr/local/bin, /usr/local/lib, /usr/local/man and +/usr/local/include, type + + make install + +To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type + + make install PREFIX=/xxx/yyy + +If you are (justifiably) paranoid and want to see what 'make install' +is going to do, you can first do + + make -n install or + make -n install PREFIX=/xxx/yyy respectively. + +The -n instructs make to show the commands it would execute, but not +actually execute them. + + +HOW TO BUILD -- UNIX, shared library libbz2.so. + +Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for +Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims +that it works for any other platform, though I suspect it probably +will work for most platforms employing both ELF and gcc. + +bzip2-shared, a client of the shared library, is also built, but not +self-tested. So I suggest you also build using the normal Makefile, +since that conducts a self-test. A second reason to prefer the +version statically linked to the library is that, on x86 platforms, +building shared objects makes a valuable register (%ebx) unavailable +to gcc, resulting in a slowdown of 10%-20%, at least for bzip2. + +Important note for people upgrading .so's from 0.9.0/0.9.5 to version +1.0.X. All the functions in the library have been renamed, from (eg) +bzCompress to BZ2_bzCompress, to avoid namespace pollution. +Unfortunately this means that the libbz2.so created by +Makefile-libbz2_so will not work with any program which used an older +version of the library. I do encourage library clients to make the +effort to upgrade to use version 1.0, since it is both faster and more +robust than previous versions. + + +HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc. + +It's difficult for me to support compilation on all these platforms. +My approach is to collect binaries for these platforms, and put them +on the master web site (http://www.bzip.org). Look there. However +(FWIW), bzip2-1.0.X is very standard ANSI C and should compile +unmodified with MS Visual C. If you have difficulties building, you +might want to read README.COMPILATION.PROBLEMS. + +At least using MS Visual C++ 6, you can build from the unmodified +sources by issuing, in a command shell: + + nmake -f makefile.msc + +(you may need to first run the MSVC-provided script VCVARS32.BAT + so as to set up paths to the MSVC tools correctly). + + +VALIDATION + +Correct operation, in the sense that a compressed file can always be +decompressed to reproduce the original, is obviously of paramount +importance. To validate bzip2, I used a modified version of Mark +Nelson's churn program. Churn is an automated test driver which +recursively traverses a directory structure, using bzip2 to compress +and then decompress each file it encounters, and checking that the +decompressed data is the same as the original. + + + +Please read and be aware of the following: + +WARNING: + + This program and library (attempts to) compress data by + performing several non-trivial transformations on it. + Unless you are 100% familiar with *all* the algorithms + contained herein, and with the consequences of modifying them, + you should NOT meddle with the compression or decompression + machinery. Incorrect changes can and very likely *will* + lead to disastrous loss of data. + + +DISCLAIMER: + + I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE + USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED. + + Every compression of a file implies an assumption that the + compressed file can be decompressed to reproduce the original. + Great efforts in design, coding and testing have been made to + ensure that this program works correctly. However, the complexity + of the algorithms, and, in particular, the presence of various + special cases in the code which occur with very low but non-zero + probability make it impossible to rule out the possibility of bugs + remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS + PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER + SMALL, THAT THE DATA WILL NOT BE RECOVERABLE. + + That is not to say this program is inherently unreliable. + Indeed, I very much hope the opposite is true. bzip2/libbzip2 + has been carefully constructed and extensively tested. + + +PATENTS: + + To the best of my knowledge, bzip2/libbzip2 does not use any + patented algorithms. However, I do not have the resources + to carry out a patent search. Therefore I cannot give any + guarantee of the above statement. + + + +WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ? + + * Approx 10% faster compression, 30% faster decompression + * -t (test mode) is a lot quicker + * Can decompress concatenated compressed files + * Programming interface, so programs can directly read/write .bz2 files + * Less restrictive (BSD-style) licensing + * Flag handling more compatible with GNU gzip + * Much more documentation, i.e., a proper user manual + * Hopefully, improved portability (at least of the library) + +WHAT'S NEW IN 0.9.5 ? + + * Compression speed is much less sensitive to the input + data than in previous versions. Specifically, the very + slow performance caused by repetitive data is fixed. + * Many small improvements in file and flag handling. + * A Y2K statement. + +WHAT'S NEW IN 1.0.0 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.2 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.3 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.4 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.5 ? + + See the CHANGES file. + +WHAT'S NEW IN 1.0.6 ? + + See the CHANGES file. + + +I hope you find bzip2 useful. Feel free to contact me at + jseward@bzip.org +if you have any suggestions or queries. Many people mailed me with +comments, suggestions and patches after the releases of bzip-0.15, +bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, +1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this +feedback. I thank you for your comments. + +bzip2's "home" is http://www.bzip.org/ + +Julian Seward +jseward@bzip.org +Cambridge, UK. + +18 July 1996 (version 0.15) +25 August 1996 (version 0.21) + 7 August 1997 (bzip2, version 0.1) +29 August 1997 (bzip2, version 0.1pl2) +23 August 1998 (bzip2, version 0.9.0) + 8 June 1999 (bzip2, version 0.9.5) + 4 Sept 1999 (bzip2, version 0.9.5d) + 5 May 2000 (bzip2, version 1.0pre8) +30 December 2001 (bzip2, version 1.0.2pre1) +15 February 2005 (bzip2, version 1.0.3) +20 December 2006 (bzip2, version 1.0.4) +10 December 2007 (bzip2, version 1.0.5) + 6 Sept 2010 (bzip2, version 1.0.6) diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.COMPILATION.PROBLEMS b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.COMPILATION.PROBLEMS new file mode 100644 index 0000000..667d0d6 --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.COMPILATION.PROBLEMS @@ -0,0 +1,58 @@ +------------------------------------------------------------------ +This file is part of bzip2/libbzip2, a program and library for +lossless, block-sorting data compression. + +bzip2/libbzip2 version 1.0.6 of 6 September 2010 +Copyright (C) 1996-2010 Julian Seward + +Please read the WARNING, DISCLAIMER and PATENTS sections in the +README file. + +This program is released under the terms of the license contained +in the file LICENSE. +------------------------------------------------------------------ + +bzip2-1.0.6 should compile without problems on the vast majority of +platforms. Using the supplied Makefile, I've built and tested it +myself for x86-linux and amd64-linux. With makefile.msc, Visual C++ +6.0 and nmake, you can build a native Win32 version too. Large file +support seems to work correctly on at least on amd64-linux. + +When I say "large file" I mean a file of size 2,147,483,648 (2^31) +bytes or above. Many older OSs can't handle files above this size, +but many newer ones can. Large files are pretty huge -- most files +you'll encounter are not Large Files. + +Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety +of platforms without difficulty, and I hope this version will continue +in that tradition. However, in order to support large files, I've had +to include the define -D_FILE_OFFSET_BITS=64 in the Makefile. This +can cause problems. + +The technique of adding -D_FILE_OFFSET_BITS=64 to get large file +support is, as far as I know, the Recommended Way to get correct large +file support. For more details, see the Large File Support +Specification, published by the Large File Summit, at + + http://ftp.sas.com/standards/large.file + +As a general comment, if you get compilation errors which you think +are related to large file support, try removing the above define from +the Makefile, ie, delete the line + + BIGFILES=-D_FILE_OFFSET_BITS=64 + +from the Makefile, and do 'make clean ; make'. This will give you a +version of bzip2 without large file support, which, for most +applications, is probably not a problem. + +Alternatively, try some of the platform-specific hints listed below. + +You can use the spewG.c program to generate huge files to test bzip2's +large file support, if you are feeling paranoid. Be aware though that +any compilation problems which affect bzip2 will also affect spewG.c, +alas. + +AIX: I have reports that for large file support, you need to specify +-D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64. I have not tested +this myself. diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.XML.STUFF b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.XML.STUFF new file mode 100644 index 0000000..3a57f3f --- /dev/null +++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/README.XML.STUFF @@ -0,0 +1,45 @@ + ---------------------------------------------------------------- + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.6 of 6 September 2010 + Copyright (C) 1996-2010 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ---------------------------------------------------------------- + +The script xmlproc.sh takes an xml file as input, +and processes it to create .pdf, .html or .ps output. +It uses format.pl, a perl script to format
 blocks nicely,
+ and add CDATA tags so writers do not have to use eg. < 
+
+The file "entities.xml" must be edited to reflect current
+version, year, etc.
+
+
+Usage:
+
+  ./xmlproc.sh -v manual.xml
+  Validates an xml file to ensure no dtd-compliance errors
+
+  ./xmlproc.sh -html manual.xml
+  Output: manual.html
+
+  ./xmlproc.sh -pdf manual.xml
+  Output: manual.pdf
+
+  ./xmlproc.sh -ps manual.xml
+  Output: manual.ps
+
+
+Notum bene: 
+- pdfxmltex barfs if given a filename with an underscore in it
+
+- xmltex won't work yet - there's a bug in passivetex
+    which we are all waiting for Sebastian to fix.
+  So we are going the xml -> pdf -> ps route for the time being,
+    using pdfxmltex.
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/blocksort.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/blocksort.c
new file mode 100644
index 0000000..d0d662c
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/blocksort.c
@@ -0,0 +1,1094 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+__inline__
+void fallbackSimpleSort ( UInt32* fmap, 
+                          UInt32* eclass, 
+                          Int32   lo, 
+                          Int32   hi )
+{
+   Int32 i, j, tmp;
+   UInt32 ec_tmp;
+
+   if (lo == hi) return;
+
+   if (hi - lo > 3) {
+      for ( i = hi-4; i >= lo; i-- ) {
+         tmp = fmap[i];
+         ec_tmp = eclass[tmp];
+         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+            fmap[j-4] = fmap[j];
+         fmap[j-4] = tmp;
+      }
+   }
+
+   for ( i = hi-1; i >= lo; i-- ) {
+      tmp = fmap[i];
+      ec_tmp = eclass[tmp];
+      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+         fmap[j-1] = fmap[j];
+      fmap[j-1] = tmp;
+   }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      fswap(fmap[yyp1], fmap[yyp2]);  \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+                       stackHi[sp] = hz; \
+                       sp++; }
+
+#define fpop(lz,hz) { sp--;              \
+                      lz = stackLo[sp];  \
+                      hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap, 
+                      UInt32* eclass,
+                      Int32   loSt, 
+                      Int32   hiSt )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m;
+   Int32 sp, lo, hi;
+   UInt32 med, r, r3;
+   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+   r = 0;
+
+   sp = 0;
+   fpush ( loSt, hiSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+      fpop ( lo, hi );
+      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+         fallbackSimpleSort ( fmap, eclass, lo, hi );
+         continue;
+      }
+
+      /* Random partitioning.  Median of 3 sometimes fails to
+         avoid bad cases.  Median of 9 seems to help but 
+         looks rather expensive.  This too seems to work but
+         is cheaper.  Guidance for the magic constants 
+         7621 and 32768 is taken from Sedgewick's algorithms
+         book, chapter 35.
+      */
+      r = ((r * 7621) + 1) % 32768;
+      r3 = r % 3;
+      if (r3 == 0) med = eclass[fmap[lo]]; else
+      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+                   med = eclass[fmap[hi]];
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (1) {
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unLo], fmap[ltLo]); 
+               ltLo++; unLo++; 
+               continue; 
+            };
+            if (n > 0) break;
+            unLo++;
+         }
+         while (1) {
+            if (unLo > unHi) break;
+            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unHi], fmap[gtHi]); 
+               gtHi--; unHi--; 
+               continue; 
+            };
+            if (n < 0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+      if (gtHi < ltLo) continue;
+
+      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      if (n - lo > hi - m) {
+         fpush ( lo, n );
+         fpush ( m, hi );
+      } else {
+         fpush ( m, hi );
+         fpush ( lo, n );
+      }
+   }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      eclass exists for [0 .. nblock-1]
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      All other areas of eclass destroyed
+      fmap [0 .. nblock-1] holds sorted order
+      bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define      WORD_BH(zz)  bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    UInt32* bhtab,
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   /*--
+      Initial 1-char radix sort to generate
+      initial fmap and initial BH bits.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        bucket sorting ...\n" );
+   for (i = 0; i < 257;    i++) ftab[i] = 0;
+   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i < nblock; i++) {
+      j = eclass8[i];
+      k = ftab[j] - 1;
+      ftab[j] = k;
+      fmap[k] = i;
+   }
+
+   nBhtab = 2 + (nblock / 32);
+   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+   /*--
+      Inductively refine the buckets.  Kind-of an
+      "exponential radix sort" (!), inspired by the
+      Manber-Myers suffix array construction algorithm.
+   --*/
+
+   /*-- set sentinel bits for block-end detection --*/
+   for (i = 0; i < 32; i++) { 
+      SET_BH(nblock + 2*i);
+      CLEAR_BH(nblock + 2*i + 1);
+   }
+
+   /*-- the log(N) loop --*/
+   H = 1;
+   while (1) {
+
+      if (verb >= 4) 
+         VPrintf1 ( "        depth %6d has ", H );
+
+      j = 0;
+      for (i = 0; i < nblock; i++) {
+         if (ISSET_BH(i)) j = i;
+         k = fmap[i] - H; if (k < 0) k += nblock;
+         eclass[k] = j;
+      }
+
+      nNotDone = 0;
+      r = -1;
+      while (1) {
+
+	 /*-- find the next non-singleton bucket --*/
+         k = r + 1;
+         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (ISSET_BH(k)) {
+            while (WORD_BH(k) == 0xffffffff) k += 32;
+            while (ISSET_BH(k)) k++;
+         }
+         l = k - 1;
+         if (l >= nblock) break;
+         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+         if (!ISSET_BH(k)) {
+            while (WORD_BH(k) == 0x00000000) k += 32;
+            while (!ISSET_BH(k)) k++;
+         }
+         r = k - 1;
+         if (r >= nblock) break;
+
+         /*-- now [l, r] bracket current bucket --*/
+         if (r > l) {
+            nNotDone += (r - l + 1);
+            fallbackQSort3 ( fmap, eclass, l, r );
+
+            /*-- scan bucket and generate header bits-- */
+            cc = -1;
+            for (i = l; i <= r; i++) {
+               cc1 = eclass[fmap[i]];
+               if (cc != cc1) { SET_BH(i); cc = cc1; };
+            }
+         }
+      }
+
+      if (verb >= 4) 
+         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+      H *= 2;
+      if (H > nblock || nNotDone == 0) break;
+   }
+
+   /*-- 
+      Reconstruct the original block in
+      eclass8 [0 .. nblock-1], since the
+      previous phase destroyed it.
+   --*/
+   if (verb >= 4)
+      VPrintf0 ( "        reconstructing block ...\n" );
+   j = 0;
+   for (i = 0; i < nblock; i++) {
+      while (ftabCopy[j] == 0) j++;
+      ftabCopy[j]--;
+      eclass8[fmap[i]] = (UChar)j;
+   }
+   AssertH ( j < 256, 1005 );
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for "normal"       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32  i1, 
+               UInt32  i2,
+               UChar*  block, 
+               UInt16* quadrant,
+               UInt32  nblock,
+               Int32*  budget )
+{
+   Int32  k;
+   UChar  c1, c2;
+   UInt16 s1, s2;
+
+   AssertD ( i1 != i2, "mainGtU" );
+   /* 1 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 2 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 3 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 4 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 5 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 6 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 7 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 8 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 9 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 10 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 11 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+   /* 12 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 > c2);
+   i1++; i2++;
+
+   k = nblock + 8;
+
+   do {
+      /* 1 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 2 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 3 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 4 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 5 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 6 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 7 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+      /* 8 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 > c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 > s2);
+      i1++; i2++;
+
+      if (i1 >= nblock) i1 -= nblock;
+      if (i2 >= nblock) i2 -= nblock;
+
+      k -= 8;
+      (*budget)--;
+   }
+      while (k >= 0);
+
+   return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Knuth's increments seem to work better
+   than Incerpi-Sedgewick here.  Possibly
+   because the number of elems to sort is
+   usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+                   9841, 29524, 88573, 265720,
+                   797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+                      UChar*  block,
+                      UInt16* quadrant,
+                      Int32   nblock,
+                      Int32   lo, 
+                      Int32   hi, 
+                      Int32   d,
+                      Int32*  budget )
+{
+   Int32 i, j, h, bigN, hp;
+   UInt32 v;
+
+   bigN = hi - lo + 1;
+   if (bigN < 2) return;
+
+   hp = 0;
+   while (incs[hp] < bigN) hp++;
+   hp--;
+
+   for (; hp >= 0; hp--) {
+      h = incs[hp];
+
+      i = lo + h;
+      while (True) {
+
+         /*-- copy 1 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 2 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 3 --*/
+         if (i > hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j <= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         if (*budget < 0) return;
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+/*--
+   The following is an implementation of
+   an elegant 3-way quicksort for strings,
+   described in a paper "Fast Algorithms for
+   Sorting and Searching Strings", by Robert
+   Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn > 0) {                  \
+      mswap(ptr[yyp1], ptr[yyp2]);    \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+static 
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+   UChar t;
+   if (a > b) { t = a; a = b; b = t; };
+   if (b > c) { 
+      b = c;
+      if (a > b) b = a;
+   }
+   return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+                          stackHi[sp] = hz; \
+                          stackD [sp] = dz; \
+                          sp++; }
+
+#define mpop(lz,hz,dz) { sp--;             \
+                         lz = stackLo[sp]; \
+                         hz = stackHi[sp]; \
+                         dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz)                                        \
+   { Int32 tz;                                                  \
+     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+                  UChar*  block,
+                  UInt16* quadrant,
+                  Int32   nblock,
+                  Int32   loSt, 
+                  Int32   hiSt, 
+                  Int32   dSt,
+                  Int32*  budget )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+   Int32 sp, lo, hi, d;
+
+   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+   Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+   Int32 nextLo[3];
+   Int32 nextHi[3];
+   Int32 nextD [3];
+
+   sp = 0;
+   mpush ( loSt, hiSt, dSt );
+
+   while (sp > 0) {
+
+      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+      mpop ( lo, hi, d );
+      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
+          d > MAIN_QSORT_DEPTH_THRESH) {
+         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+         if (*budget < 0) return;
+         continue;
+      }
+
+      med = (Int32) 
+            mmed3 ( block[ptr[ lo         ]+d],
+                    block[ptr[ hi         ]+d],
+                    block[ptr[ (lo+hi)>>1 ]+d] );
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (True) {
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unLo]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unLo], ptr[ltLo]); 
+               ltLo++; unLo++; continue; 
+            };
+            if (n >  0) break;
+            unLo++;
+         }
+         while (True) {
+            if (unLo > unHi) break;
+            n = ((Int32)block[ptr[unHi]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unHi], ptr[gtHi]); 
+               gtHi--; unHi--; continue; 
+            };
+            if (n <  0) break;
+            unHi--;
+         }
+         if (unLo > unHi) break;
+         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+      if (gtHi < ltLo) {
+         mpush(lo, hi, d+1 );
+         continue;
+      }
+
+      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+      mpush (nextLo[0], nextHi[0], nextD[0]);
+      mpush (nextLo[1], nextHi[1], nextD[1]);
+      mpush (nextLo[2], nextHi[2], nextD[2]);
+   }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > N_OVERSHOOT
+      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      All other areas of block32 destroyed
+      ftab [0 .. 65536 ] destroyed
+      ptr [0 .. nblock-1] holds sorted order
+      if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr, 
+                UChar*  block,
+                UInt16* quadrant, 
+                UInt32* ftab,
+                Int32   nblock,
+                Int32   verb,
+                Int32*  budget )
+{
+   Int32  i, j, k, ss, sb;
+   Int32  runningOrder[256];
+   Bool   bigDone[256];
+   Int32  copyStart[256];
+   Int32  copyEnd  [256];
+   UChar  c1;
+   Int32  numQSorted;
+   UInt16 s;
+   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
+
+   /*-- set up the 2-byte frequency table --*/
+   for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+   j = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+      quadrant[i-1] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+      ftab[j]++;
+      quadrant[i-2] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+      ftab[j]++;
+      quadrant[i-3] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+      ftab[j]++;
+   }
+   for (; i >= 0; i--) {
+      quadrant[i] = 0;
+      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+      ftab[j]++;
+   }
+
+   /*-- (emphasises close relationship of block & quadrant) --*/
+   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+      block   [nblock+i] = block[i];
+      quadrant[nblock+i] = 0;
+   }
+
+   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
+
+   /*-- Complete the initial radix sort --*/
+   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+   s = block[0] << 8;
+   i = nblock-1;
+   for (; i >= 3; i -= 4) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+      s = (s >> 8) | (block[i-1] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-1;
+      s = (s >> 8) | (block[i-2] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-2;
+      s = (s >> 8) | (block[i-3] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-3;
+   }
+   for (; i >= 0; i--) {
+      s = (s >> 8) | (block[i] << 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+   }
+
+   /*--
+      Now ftab contains the first loc of every small bucket.
+      Calculate the running order, from smallest to largest
+      big bucket.
+   --*/
+   for (i = 0; i <= 255; i++) {
+      bigDone     [i] = False;
+      runningOrder[i] = i;
+   }
+
+   {
+      Int32 vv;
+      Int32 h = 1;
+      do h = 3 * h + 1; while (h <= 256);
+      do {
+         h = h / 3;
+         for (i = h; i <= 255; i++) {
+            vv = runningOrder[i];
+            j = i;
+            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+               runningOrder[j] = runningOrder[j-h];
+               j = j - h;
+               if (j <= (h - 1)) goto zero;
+            }
+            zero:
+            runningOrder[j] = vv;
+         }
+      } while (h != 1);
+   }
+
+   /*--
+      The main sorting loop.
+   --*/
+
+   numQSorted = 0;
+
+   for (i = 0; i <= 255; i++) {
+
+      /*--
+         Process big buckets, starting with the least full.
+         Basically this is a 3-step process in which we call
+         mainQSort3 to sort the small buckets [ss, j], but
+         also make a big effort to avoid the calls if we can.
+      --*/
+      ss = runningOrder[i];
+
+      /*--
+         Step 1:
+         Complete the big bucket [ss] by quicksorting
+         any unsorted small buckets [ss, j], for j != ss.  
+         Hopefully previous pointer-scanning phases have already
+         completed many of the small buckets [ss, j], so
+         we don't have to sort them at all.
+      --*/
+      for (j = 0; j <= 255; j++) {
+         if (j != ss) {
+            sb = (ss << 8) + j;
+            if ( ! (ftab[sb] & SETMASK) ) {
+               Int32 lo = ftab[sb]   & CLEARMASK;
+               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+               if (hi > lo) {
+                  if (verb >= 4)
+                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
+                                "done %d   this %d\n",
+                                ss, j, numQSorted, hi - lo + 1 );
+                  mainQSort3 ( 
+                     ptr, block, quadrant, nblock, 
+                     lo, hi, BZ_N_RADIX, budget 
+                  );   
+                  numQSorted += (hi - lo + 1);
+                  if (*budget < 0) return;
+               }
+            }
+            ftab[sb] |= SETMASK;
+         }
+      }
+
+      AssertH ( !bigDone[ss], 1006 );
+
+      /*--
+         Step 2:
+         Now scan this big bucket [ss] so as to synthesise the
+         sorted order for small buckets [t, ss] for all t,
+         including, magically, the bucket [ss,ss] too.
+         This will avoid doing Real Work in subsequent Step 1's.
+      --*/
+      {
+         for (j = 0; j <= 255; j++) {
+            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
+            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+         }
+         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1])
+               ptr[ copyStart[c1]++ ] = k;
+         }
+         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+            k = ptr[j]-1; if (k < 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1]) 
+               ptr[ copyEnd[c1]-- ] = k;
+         }
+      }
+
+      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+                || 
+                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+                   Necessity for this case is demonstrated by compressing 
+                   a sequence of approximately 48.5 million of character 
+                   251; 1.0.0/1.0.1 will then die here. */
+                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+                1007 )
+
+      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+      /*--
+         Step 3:
+         The [ss] big bucket is now done.  Record this fact,
+         and update the quadrant descriptors.  Remember to
+         update quadrants in the overshoot area too, if
+         necessary.  The "if (i < 255)" test merely skips
+         this updating for the last bucket processed, since
+         updating for the last bucket is pointless.
+
+         The quadrant array provides a way to incrementally
+         cache sort orderings, as they appear, so as to 
+         make subsequent comparisons in fullGtU() complete
+         faster.  For repetitive blocks this makes a big
+         difference (but not big enough to be able to avoid
+         the fallback sorting mechanism, exponential radix sort).
+
+         The precise meaning is: at all times:
+
+            for 0 <= i < nblock and 0 <= j <= nblock
+
+            if block[i] != block[j], 
+
+               then the relative values of quadrant[i] and 
+                    quadrant[j] are meaningless.
+
+               else {
+                  if quadrant[i] < quadrant[j]
+                     then the string starting at i lexicographically
+                     precedes the string starting at j
+
+                  else if quadrant[i] > quadrant[j]
+                     then the string starting at j lexicographically
+                     precedes the string starting at i
+
+                  else
+                     the relative ordering of the strings starting
+                     at i and j has not yet been determined.
+               }
+      --*/
+      bigDone[ss] = True;
+
+      if (i < 255) {
+         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
+         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+         Int32 shifts   = 0;
+
+         while ((bbSize >> shifts) > 65534) shifts++;
+
+         for (j = bbSize-1; j >= 0; j--) {
+            Int32 a2update     = ptr[bbStart + j];
+            UInt16 qVal        = (UInt16)(j >> shifts);
+            quadrant[a2update] = qVal;
+            if (a2update < BZ_N_OVERSHOOT)
+               quadrant[a2update + nblock] = qVal;
+         }
+         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+      }
+
+   }
+
+   if (verb >= 4)
+      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
+                 nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock > 0
+      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)arr2)  [0 .. nblock-1] holds block
+      arr1 exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)arr2) [0 .. nblock-1] holds block
+      All other areas of block destroyed
+      ftab [ 0 .. 65536 ] destroyed
+      arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+   UInt32* ptr    = s->ptr; 
+   UChar*  block  = s->block;
+   UInt32* ftab   = s->ftab;
+   Int32   nblock = s->nblock;
+   Int32   verb   = s->verbosity;
+   Int32   wfact  = s->workFactor;
+   UInt16* quadrant;
+   Int32   budget;
+   Int32   budgetInit;
+   Int32   i;
+
+   if (nblock < 10000) {
+      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+   } else {
+      /* Calculate the location for quadrant, remembering to get
+         the alignment right.  Assumes that &(block[0]) is at least
+         2-byte aligned -- this should be ok since block is really
+         the first section of arr2.
+      */
+      i = nblock+BZ_N_OVERSHOOT;
+      if (i & 1) i++;
+      quadrant = (UInt16*)(&(block[i]));
+
+      /* (wfact-1) / 3 puts the default-factor-30
+         transition point at very roughly the same place as 
+         with v0.1 and v0.9.0.  
+         Not that it particularly matters any more, since the
+         resulting compressed stream is now the same regardless
+         of whether or not we use the main sort or fallback sort.
+      */
+      if (wfact < 1  ) wfact = 1;
+      if (wfact > 100) wfact = 100;
+      budgetInit = nblock * ((wfact-1) / 3);
+      budget = budgetInit;
+
+      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+      if (verb >= 3) 
+         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
+                    budgetInit - budget,
+                    nblock, 
+                    (float)(budgetInit - budget) /
+                    (float)(nblock==0 ? 1 : nblock) ); 
+      if (budget < 0) {
+         if (verb >= 2) 
+            VPrintf0 ( "    too repetitive; using fallback"
+                       " sorting algorithm\n" );
+         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+      }
+   }
+
+   s->origPtr = -1;
+   for (i = 0; i < s->nblock; i++)
+      if (ptr[i] == 0)
+         { s->origPtr = i; break; };
+
+   AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-common.xsl b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-common.xsl
new file mode 100644
index 0000000..66fcd6f
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-common.xsl
@@ -0,0 +1,39 @@
+ 
+
+
+
+ 
+
+
+
+ 
+ 
+   
+    
+      
+     
+  
+
+
+
+
+set       toc,title
+book      toc,title,figure,table,example,equation
+chapter   toc,title
+section   toc
+sect1     toc
+sect2     toc
+sect3     toc
+sect4     nop
+sect5     nop
+qandaset  toc
+qandadiv  nop
+appendix  toc,title
+article/appendix  nop
+article   toc,title
+preface   toc,title
+reference toc,title
+
+
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-fo.xsl b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-fo.xsl
new file mode 100644
index 0000000..ba3e301
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-fo.xsl
@@ -0,0 +1,276 @@
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+      
+     
+   
+
+
+
+
+ 
+
+
+
+
+
+
+  
+
+
+
+
+  blue
+
+
+
+
+  
+    
+  
+
+
+
+  
+    
+  
+
+
+
+
+  
+  
+  
+    
+      
+    
+  
+  
+    
+      
+        
+          
+          
+          
+        
+      
+    
+    
+          
+    
+  
+  
+    
+      
+        
+      
+    
+    
+      
+        
+      
+    
+  
+
+
+
+
+  
+  
+  
+    
+      
+        
+      
+    
+    
+          
+    
+  
+  
+    
+      
+        
+      
+    
+    
+      
+        
+      
+    
+  
+
+
+
+
+
+  
+    
+  
+    
+  
+  
+    
+      
+    
+  
+
+
+
+
+
+  
+  
+  
+  
+    
+      0pt
+    
+  
+  
+    
+      
+      
+      
+        
+          
+            baseline
+             
+               
+            
+          
+          
+            baseline
+            
+              
+                
+                
+                
+                
+              
+            
+          
+        
+      
+    
+  
+  
+  
+    
+      
+    
+    
+      
+    
+    
+      
+    
+  
+
+
+
+
+
+  
+  
+  
+  
+    
+      0pt
+    
+  
+  
+    
+      
+        
+        
+        
+      
+      
+      
+      
+        
+          
+            baseline
+            
+               
+            
+          
+          
+            baseline
+            
+              
+                
+                
+                
+                
+              
+            
+          
+        
+      
+    
+  
+  
+  
+    
+      
+    
+    
+      
+    
+    
+      
+    
+  
+
+
+
+
+
+
+  always
+  
+    
+  
+  
+    
+    pt
+  
+  
+    
+    pt
+  
+  false
+
+
+
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-html.xsl b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-html.xsl
new file mode 100644
index 0000000..1785fff
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bz-html.xsl
@@ -0,0 +1,20 @@
+ 
+ ]>
+
+
+
+
+
+
+
+
+
+
+  
+  
+
+
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzcompress.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzcompress.c
new file mode 100644
index 0000000..caf7696
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzcompress.c
@@ -0,0 +1,672 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s->bsLive = 0;
+   s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s->bsLive > 0) {
+      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+      s->numZ++;
+      s->bsBuff <<= 8;
+      s->bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s->bsLive >= 8) {                   \
+      s->zbits[s->numZ]                       \
+         = (UChar)(s->bsBuff >> 24);          \
+      s->numZ++;                              \
+      s->bsBuff <<= 8;                        \
+      s->bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s->bsBuff |= (v << (32 - s->bsLive - n));
+   s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u >> 24) & 0xffL );
+   bsW ( s, 8, (u >> 16) & 0xffL );
+   bsW ( s, 8, (u >>  8) & 0xffL );
+   bsW ( s, 8,  u        & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->unseqToSeq[i] = s->nInUse;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s->ptr;
+   UChar* block  = s->block;
+   UInt16* mtfv  = s->mtfv;
+
+   makeMaps_e ( s );
+   EOB = s->nInUse+1;
+
+   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i < s->nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr <= i, "generateMTFValues(1)" );
+      j = ptr[i]-1; if (j < 0) j += s->nblock;
+      ll_i = s->unseqToSeq[block[j]];
+      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend > 0) {
+            zPend--;
+            while (True) {
+               if (zPend & 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s->mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s->mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend < 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &(yy[0]);
+            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend > 0) {
+      zPend--;
+      while (True) {
+         if (zPend & 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s->mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s->mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend < 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+   s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s->mtfv;
+
+   if (s->verbosity >= 3)
+      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
+                "%d+2 syms in use\n", 
+                s->nblock, s->nMTF, s->nInUse );
+
+   alphaSize = s->nInUse+2;
+   for (t = 0; t < BZ_N_GROUPS; t++)
+      for (v = 0; v < alphaSize; v++)
+         s->len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s->nMTF > 0, 3001 );
+   if (s->nMTF < 200)  nGroups = 2; else
+   if (s->nMTF < 600)  nGroups = 3; else
+   if (s->nMTF < 1200) nGroups = 4; else
+   if (s->nMTF < 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s->nMTF;
+      gs = 0;
+      while (nPart > 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq < tFreq && ge < alphaSize-1) {
+            ge++;
+            aFreq += s->mtfFreq[ge];
+         }
+
+         if (ge > gs 
+             && nPart != nGroups && nPart != 1 
+             && ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s->mtfFreq[ge];
+            ge--;
+         }
+
+         if (s->verbosity >= 3)
+            VPrintf5( "      initial group %d, [%d .. %d], "
+                      "has %d syms (%4.1f%%)\n",
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
+ 
+         for (v = 0; v < alphaSize; v++)
+            if (v >= gs && v <= ge) 
+               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s->len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+      for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t < nGroups; t++)
+         for (v = 0; v < alphaSize; v++)
+            s->rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v < alphaSize; v++) {
+            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start & end marks. --*/
+         if (gs >= s->nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge >= s->nMTF) ge = s->nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s->len_pack[icv][0]; \
+               cost23 += s->len_pack[icv][1]; \
+               cost45 += s->len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t < nGroups; t++)
+            if (cost[t] < bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s->selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i <= ge; i++)
+               s->rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s->verbosity >= 3) {
+         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
+                   iter+1, totc/8 );
+         for (t = 0; t < nGroups; t++)
+            VPrintf1 ( "%d ", fave[t] );
+         VPrintf0 ( "\n" );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t < nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups < 8, 3002 );
+   AssertH( nSelectors < 32768 &&
+            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i < nGroups; i++) pos[i] = i;
+      for (i = 0; i < nSelectors; i++) {
+         ll_i = s->selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s->selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t < nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i < alphaSize; i++) {
+         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+         if (s->len[t][i] < minLen) minLen = s->len[t][i];
+      }
+      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen < 1),  3005 );
+      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i < 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j < 16; j++)
+             if (s->inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s->numZ;
+      for (i = 0; i < 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i < 16; i++)
+         if (inUse16[i])
+            for (j = 0; j < 16; j++) {
+               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s->verbosity >= 3) 
+         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s->numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i < nSelectors; i++) { 
+      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s->verbosity >= 3)
+      VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s->numZ;
+
+   for (t = 0; t < nGroups; t++) {
+      Int32 curr = s->len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i < alphaSize; i++) {
+         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s->verbosity >= 3)
+      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s->numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs >= s->nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge >= s->nMTF) ge = s->nMTF-1;
+      AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+      if (nGroups == 6 && 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &(s->len[s->selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &(s->code[s->selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i <= ge; i++) {
+            bsW ( s, 
+                  s->len  [s->selector[selCtr]] [mtfv[i]],
+                  s->code [s->selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s->verbosity >= 3)
+      VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s->nblock > 0) {
+
+      BZ_FINALISE_CRC ( s->blockCRC );
+      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+      s->combinedCRC ^= s->blockCRC;
+      if (s->blockNo > 1) s->numZ = 0;
+
+      if (s->verbosity >= 2)
+         VPrintf4( "    block %d: crc = 0x%08x, "
+                   "combined CRC = 0x%08x, size = %d\n",
+                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s->blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+   }
+
+   if (s->nblock > 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s->blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s->origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s->combinedCRC );
+      if (s->verbosity >= 2)
+         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff
new file mode 100644
index 0000000..6fc38f9
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff
@@ -0,0 +1,76 @@
+#!/bin/sh
+# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
+
+# Bzcmp/diff wrapped for bzip2, 
+# adapted from zdiff by Philippe Troin  for Debian GNU/Linux.
+
+# Bzcmp and bzdiff are used to invoke the cmp or the  diff  pro-
+# gram  on compressed files.  All options specified are passed
+# directly to cmp or diff.  If only 1 file is specified,  then
+# the  files  compared  are file1 and an uncompressed file1.gz.
+# If two files are specified, then they are  uncompressed  (if
+# necessary) and fed to cmp or diff.  The exit status from cmp
+# or diff is preserved.
+
+PATH="/usr/bin:/bin:$PATH"; export PATH
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+  *cmp) comp=${CMP-cmp}   ;;
+  *)    comp=${DIFF-diff} ;;
+esac
+
+OPTIONS=
+FILES=
+for ARG
+do
+    case "$ARG" in
+    -*)	OPTIONS="$OPTIONS $ARG";;
+     *)	if test -f "$ARG"; then
+            FILES="$FILES $ARG"
+        else
+            echo "${prog}: $ARG not found or not a regular file"
+	    exit 1
+        fi ;;
+    esac
+done
+if test -z "$FILES"; then
+	echo "Usage: $prog [${comp}_options] file [file]"
+	exit 1
+fi
+tmp=`mktemp ${TMPDIR:-/tmp}/bzdiff.XXXXXXXXXX` || {
+      echo 'cannot create a temporary file' >&2
+      exit 1
+}
+set $FILES
+if test $# -eq 1; then
+	FILE=`echo "$1" | sed 's/.bz2$//'`
+	bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
+	STAT="$?"
+
+elif test $# -eq 2; then
+	case "$1" in
+        *.bz2)
+                case "$2" in
+	        *.bz2)
+			F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
+                        bzip2 -cdfq "$2" > $tmp
+                        bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp
+                        STAT="$?"
+			/bin/rm -f $tmp;;
+
+                *)      bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
+                        STAT="$?";;
+                esac;;
+        *)      case "$2" in
+	        *.bz2)
+                        bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
+                        STAT="$?";;
+                *)      $comp $OPTIONS "$1" "$2"
+                        STAT="$?";;
+                esac;;
+	esac
+        exit "$STAT"
+else
+	echo "Usage: $prog [${comp}_options] file [file]"
+	exit 1
+fi
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff.1 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff.1
new file mode 100644
index 0000000..adb7a8e
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzdiff.1
@@ -0,0 +1,47 @@
+\"Shamelessly copied from zmore.1 by Philippe Troin 
+\"for Debian GNU/Linux
+.TH BZDIFF 1
+.SH NAME
+bzcmp, bzdiff \- compare bzip2 compressed files
+.SH SYNOPSIS
+.B bzcmp
+[ cmp_options ] file1
+[ file2 ]
+.br
+.B bzdiff
+[ diff_options ] file1
+[ file2 ]
+.SH DESCRIPTION
+.I  Bzcmp
+and 
+.I bzdiff
+are used to invoke the
+.I cmp
+or the
+.I diff
+program on bzip2 compressed files.  All options specified are passed
+directly to
+.I cmp
+or
+.IR diff "."
+If only 1 file is specified, then the files compared are
+.I file1
+and an uncompressed
+.IR file1 ".bz2."
+If two files are specified, then they are uncompressed if necessary and fed to
+.I cmp
+or
+.IR diff "."
+The exit status from 
+.I cmp
+or
+.I diff
+is preserved.
+.SH "SEE ALSO"
+cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1)
+.SH BUGS
+Messages from the
+.I cmp
+or
+.I diff
+programs refer to temporary filenames instead of those specified.
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep
new file mode 100644
index 0000000..9a04b83
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# Bzgrep wrapped for bzip2, 
+# adapted from zgrep by Philippe Troin  for Debian GNU/Linux.
+## zgrep notice:
+## zgrep -- a wrapper around a grep program that decompresses files as needed
+## Adapted from a version sent by Charles Levert 
+
+PATH="/usr/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+	*egrep)	grep=${EGREP-egrep}	;;
+	*fgrep)	grep=${FGREP-fgrep}	;;
+	*)	grep=${GREP-grep}	;;
+esac
+pat=""
+while test $# -ne 0; do
+  case "$1" in
+  -e | -f) opt="$opt $1"; shift; pat="$1"
+           if test "$grep" = grep; then  # grep is buggy with -e on SVR4
+             grep=egrep
+           fi;;
+  -A | -B) opt="$opt $1 $2"; shift;;
+  -*)	   opt="$opt $1";;
+   *)      if test -z "$pat"; then
+	     pat="$1"
+	   else
+	     break;
+           fi;;
+  esac
+  shift
+done
+
+if test -z "$pat"; then
+  echo "grep through bzip2 files"
+  echo "usage: $prog [grep_options] pattern [files]"
+  exit 1
+fi
+
+list=0
+silent=0
+op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
+case "$op" in
+  *l*) list=1
+esac
+case "$op" in
+  *h*) silent=1
+esac
+
+if test $# -eq 0; then
+  bzip2 -cdfq | $grep $opt "$pat"
+  exit $?
+fi
+
+res=0
+for i do
+  if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
+  if test $list -eq 1; then
+    bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
+    r=$?
+  elif test $# -eq 1 -o $silent -eq 1; then
+    bzip2 -cdfq "$i" | $grep $opt "$pat"
+    r=$?
+  else
+    j=${i//\\/\\\\}
+    j=${j//|/\\|}
+    j=${j//&/\\&}
+    j=`printf "%s" "$j" | tr '\n' ' '`
+    bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|"
+    r=$?
+  fi
+  test "$r" -ne 0 && res="$r"
+done
+exit $res
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep.1 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep.1
new file mode 100644
index 0000000..930af8c
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzgrep.1
@@ -0,0 +1,56 @@
+\"Shamelessly copied from zmore.1 by Philippe Troin 
+\"for Debian GNU/Linux
+.TH BZGREP 1
+.SH NAME
+bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression
+.SH SYNOPSIS
+.B bzgrep
+[ grep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.br
+.B bzegrep
+[ egrep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.br
+.B bzfgrep
+[ fgrep_options ]
+.BI  [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.SH DESCRIPTION
+.IR  Bzgrep
+is used to invoke the
+.I grep
+on bzip2-compressed files. All options specified are passed directly to
+.I grep.
+If no file is specified, then the standard input is decompressed
+if necessary and fed to grep.
+Otherwise the given files are uncompressed if necessary and fed to
+.I grep.
+.PP
+If
+.I bzgrep
+is invoked as
+.I bzegrep
+or
+.I bzfgrep
+then
+.I egrep
+or
+.I fgrep
+is used instead of
+.I grep.
+If the GREP environment variable is set,
+.I bzgrep
+uses it as the
+.I grep
+program to be invoked. For example:
+
+    for sh:  GREP=fgrep  bzgrep string files
+    for csh: (setenv GREP fgrep; bzgrep string files)
+.SH AUTHOR
+Charles Levert (charles@comm.polymtl.ca). Adapted to bzip2 by Philippe
+Troin  for Debian GNU/Linux.
+.SH "SEE ALSO"
+grep(1), egrep(1), fgrep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1)
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip.css b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip.css
new file mode 100644
index 0000000..43193d8
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip.css
@@ -0,0 +1,74 @@
+/* Colours:
+#74240f  dark brown      h1, h2, h3, h4
+#336699  medium blue     links
+#339999  turquoise       link hover colour
+#202020  almost black    general text
+#761596  purple          md5sum text
+#626262  dark gray       pre border
+#eeeeee  very light gray pre background
+#f2f2f9  very light blue nav table background
+#3366cc  medium blue     nav table border
+*/
+
+a, a:link, a:visited, a:active { color: #336699; }
+a:hover { color: #339999; }
+
+body { font: 80%/126% sans-serif; }
+h1, h2, h3, h4 { color: #74240f; }
+
+dt { color: #336699; font-weight: bold }
+dd { 
+ margin-left: 1.5em; 
+ padding-bottom: 0.8em;
+}
+
+/* -- ruler -- */
+div.hr_blue { 
+  height:  3px; 
+  background:#ffffff url("/images/hr_blue.png") repeat-x; }
+div.hr_blue hr { display:none; }
+
+/* release styles */
+#release p { margin-top: 0.4em; }
+#release .md5sum { color: #761596; }
+
+
+/* ------ styles for docs|manuals|howto ------ */
+/* -- lists -- */
+ul  { 
+ margin:     0px 4px 16px 16px;
+ padding:    0px;
+ list-style: url("/images/li-blue.png"); 
+}
+ul li { 
+ margin-bottom: 10px;
+}
+ul ul	{ 
+ list-style-type:  none; 
+ list-style-image: none; 
+ margin-left:      0px; 
+}
+
+/* header / footer nav tables */
+table.nav {
+ border:     solid 1px #3366cc;
+ background: #f2f2f9;
+ background-color: #f2f2f9;
+ margin-bottom: 0.5em;
+}
+/* don't have underlined links in chunked nav menus */
+table.nav a { text-decoration: none; }
+table.nav a:hover { text-decoration: underline; }
+table.nav td { font-size: 85%; }
+
+code, tt, pre { font-size: 120%; }
+code, tt { color: #761596; }
+
+div.literallayout, pre.programlisting, pre.screen {
+ color:      #000000;
+ padding:    0.5em;
+ background: #eeeeee;
+ border:     1px solid #626262;
+ background-color: #eeeeee;
+ margin: 4px 0px 4px 0px; 
+}
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1
new file mode 100644
index 0000000..ce3a78e
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1
@@ -0,0 +1,454 @@
+.PU
+.TH bzip2 1
+.SH NAME
+bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6
+.br
+bzcat \- decompresses files to stdout
+.br
+bzip2recover \- recovers data from damaged bzip2 files
+
+.SH SYNOPSIS
+.ll +8
+.B bzip2
+.RB [ " \-cdfkqstvzVL123456789 " ]
+[
+.I "filenames \&..."
+]
+.ll -8
+.br
+.B bunzip2
+.RB [ " \-fkvsVL " ]
+[ 
+.I "filenames \&..."
+]
+.br
+.B bzcat
+.RB [ " \-s " ]
+[ 
+.I "filenames \&..."
+]
+.br
+.B bzip2recover
+.I "filename"
+
+.SH DESCRIPTION
+.I bzip2
+compresses files using the Burrows-Wheeler block sorting
+text compression algorithm, and Huffman coding.  Compression is
+generally considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of the PPM
+family of statistical compressors.
+
+The command-line options are deliberately very similar to 
+those of 
+.I GNU gzip, 
+but they are not identical.
+
+.I bzip2
+expects a list of file names to accompany the
+command-line flags.  Each file is replaced by a compressed version of
+itself, with the name "original_name.bz2".  
+Each compressed file
+has the same modification date, permissions, and, when possible,
+ownership as the corresponding original, so that these properties can
+be correctly restored at decompression time.  File name handling is
+naive in the sense that there is no mechanism for preserving original
+file names, permissions, ownerships or dates in filesystems which lack
+these concepts, or have serious file name length restrictions, such as
+MS-DOS.
+
+.I bzip2
+and
+.I bunzip2
+will by default not overwrite existing
+files.  If you want this to happen, specify the \-f flag.
+
+If no file names are specified,
+.I bzip2
+compresses from standard
+input to standard output.  In this case,
+.I bzip2
+will decline to
+write compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.
+
+.I bunzip2
+(or
+.I bzip2 \-d) 
+decompresses all
+specified files.  Files which were not created by 
+.I bzip2
+will be detected and ignored, and a warning issued.  
+.I bzip2
+attempts to guess the filename for the decompressed file 
+from that of the compressed file as follows:
+
+       filename.bz2    becomes   filename
+       filename.bz     becomes   filename
+       filename.tbz2   becomes   filename.tar
+       filename.tbz    becomes   filename.tar
+       anyothername    becomes   anyothername.out
+
+If the file does not end in one of the recognised endings, 
+.I .bz2, 
+.I .bz, 
+.I .tbz2
+or
+.I .tbz, 
+.I bzip2 
+complains that it cannot
+guess the name of the original file, and uses the original name
+with
+.I .out
+appended.
+
+As with compression, supplying no
+filenames causes decompression from 
+standard input to standard output.
+
+.I bunzip2 
+will correctly decompress a file which is the
+concatenation of two or more compressed files.  The result is the
+concatenation of the corresponding uncompressed files.  Integrity
+testing (\-t) 
+of concatenated 
+compressed files is also supported.
+
+You can also compress or decompress files to the standard output by
+giving the \-c flag.  Multiple files may be compressed and
+decompressed like this.  The resulting outputs are fed sequentially to
+stdout.  Compression of multiple files 
+in this manner generates a stream
+containing multiple compressed file representations.  Such a stream
+can be decompressed correctly only by
+.I bzip2 
+version 0.9.0 or
+later.  Earlier versions of
+.I bzip2
+will stop after decompressing
+the first file in the stream.
+
+.I bzcat
+(or
+.I bzip2 -dc) 
+decompresses all specified files to
+the standard output.
+
+.I bzip2
+will read arguments from the environment variables
+.I BZIP2
+and
+.I BZIP,
+in that order, and will process them
+before any arguments read from the command line.  This gives a 
+convenient way to supply default arguments.
+
+Compression is always performed, even if the compressed 
+file is slightly
+larger than the original.  Files of less than about one hundred bytes
+tend to get larger, since the compression mechanism has a constant
+overhead in the region of 50 bytes.  Random data (including the output
+of most file compressors) is coded at about 8.05 bits per byte, giving
+an expansion of around 0.5%.
+
+As a self-check for your protection, 
+.I 
+bzip2
+uses 32-bit CRCs to
+make sure that the decompressed version of a file is identical to the
+original.  This guards against corruption of the compressed data, and
+against undetected bugs in
+.I bzip2
+(hopefully very unlikely).  The
+chances of data corruption going undetected is microscopic, about one
+chance in four billion for each file processed.  Be aware, though, that
+the check occurs upon decompression, so it can only tell you that
+something is wrong.  It can't help you 
+recover the original uncompressed
+data.  You can use 
+.I bzip2recover
+to try to recover data from
+damaged files.
+
+Return values: 0 for a normal exit, 1 for environmental problems (file
+not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
+compressed file, 3 for an internal consistency error (eg, bug) which
+caused
+.I bzip2
+to panic.
+
+.SH OPTIONS
+.TP
+.B \-c --stdout
+Compress or decompress to standard output.
+.TP
+.B \-d --decompress
+Force decompression.  
+.I bzip2, 
+.I bunzip2 
+and
+.I bzcat 
+are
+really the same program, and the decision about what actions to take is
+done on the basis of which name is used.  This flag overrides that
+mechanism, and forces 
+.I bzip2
+to decompress.
+.TP
+.B \-z --compress
+The complement to \-d: forces compression, regardless of the
+invocation name.
+.TP
+.B \-t --test
+Check integrity of the specified file(s), but don't decompress them.
+This really performs a trial decompression and throws away the result.
+.TP
+.B \-f --force
+Force overwrite of output files.  Normally,
+.I bzip2 
+will not overwrite
+existing output files.  Also forces 
+.I bzip2 
+to break hard links
+to files, which it otherwise wouldn't do.
+
+bzip2 normally declines to decompress files which don't have the
+correct magic header bytes.  If forced (-f), however, it will pass
+such files through unmodified.  This is how GNU gzip behaves.
+.TP
+.B \-k --keep
+Keep (don't delete) input files during compression
+or decompression.
+.TP
+.B \-s --small
+Reduce memory usage, for compression, decompression and testing.  Files
+are decompressed and tested using a modified algorithm which only
+requires 2.5 bytes per block byte.  This means any file can be
+decompressed in 2300k of memory, albeit at about half the normal speed.
+
+During compression, \-s selects a block size of 200k, which limits
+memory use to around the same figure, at the expense of your compression
+ratio.  In short, if your machine is low on memory (8 megabytes or
+less), use \-s for everything.  See MEMORY MANAGEMENT below.
+.TP
+.B \-q --quiet
+Suppress non-essential warning messages.  Messages pertaining to
+I/O errors and other critical events will not be suppressed.
+.TP
+.B \-v --verbose
+Verbose mode -- show the compression ratio for each file processed.
+Further \-v's increase the verbosity level, spewing out lots of
+information which is primarily of interest for diagnostic purposes.
+.TP
+.B \-L --license -V --version
+Display the software version, license terms and conditions.
+.TP
+.B \-1 (or \-\-fast) to \-9 (or \-\-best)
+Set the block size to 100 k, 200 k ..  900 k when compressing.  Has no
+effect when decompressing.  See MEMORY MANAGEMENT below.
+The \-\-fast and \-\-best aliases are primarily for GNU gzip 
+compatibility.  In particular, \-\-fast doesn't make things
+significantly faster.  
+And \-\-best merely selects the default behaviour.
+.TP
+.B \--
+Treats all subsequent arguments as file names, even if they start
+with a dash.  This is so you can handle files with names beginning
+with a dash, for example: bzip2 \-- \-myfilename.
+.TP
+.B \--repetitive-fast --repetitive-best
+These flags are redundant in versions 0.9.5 and above.  They provided
+some coarse control over the behaviour of the sorting algorithm in
+earlier versions, which was sometimes useful.  0.9.5 and above have an
+improved algorithm which renders these flags irrelevant.
+
+.SH MEMORY MANAGEMENT
+.I bzip2 
+compresses large files in blocks.  The block size affects
+both the compression ratio achieved, and the amount of memory needed for
+compression and decompression.  The flags \-1 through \-9
+specify the block size to be 100,000 bytes through 900,000 bytes (the
+default) respectively.  At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+.I bunzip2
+then allocates itself just enough memory to decompress
+the file.  Since block sizes are stored in compressed files, it follows
+that the flags \-1 to \-9 are irrelevant to and so ignored
+during decompression.
+
+Compression and decompression requirements, 
+in bytes, can be estimated as:
+
+       Compression:   400k + ( 8 x block size )
+
+       Decompression: 100k + ( 4 x block size ), or
+                      100k + ( 2.5 x block size )
+
+Larger block sizes give rapidly diminishing marginal returns.  Most of
+the compression comes from the first two or three hundred k of block
+size, a fact worth bearing in mind when using
+.I bzip2
+on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block size.
+
+For files compressed with the default 900k block size,
+.I bunzip2
+will require about 3700 kbytes to decompress.  To support decompression
+of any file on a 4 megabyte machine, 
+.I bunzip2
+has an option to
+decompress using approximately half this amount of memory, about 2300
+kbytes.  Decompression speed is also halved, so you should use this
+option only where necessary.  The relevant flag is -s.
+
+In general, try and use the largest block size memory constraints allow,
+since that maximises the compression achieved.  Compression and
+decompression speed are virtually unaffected by block size.
+
+Another significant point applies to files which fit in a single block
+-- that means most files you'd encounter using a large block size.  The
+amount of real memory touched is proportional to the size of the file,
+since the file is smaller than a block.  For example, compressing a file
+20,000 bytes long with the flag -9 will cause the compressor to
+allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
+kbytes of it.  Similarly, the decompressor will allocate 3700k but only
+touch 100k + 20000 * 4 = 180 kbytes.
+
+Here is a table which summarises the maximum memory usage for different
+block sizes.  Also recorded is the total compressed size for 14 files of
+the Calgary Text Compression Corpus totalling 3,141,622 bytes.  This
+column gives some feel for how compression varies with block size.
+These figures tend to understate the advantage of larger block sizes for
+larger files, since the Corpus is dominated by smaller files.
+
+           Compress   Decompress   Decompress   Corpus
+    Flag     usage      usage       -s usage     Size
+
+     -1      1200k       500k         350k      914704
+     -2      2000k       900k         600k      877703
+     -3      2800k      1300k         850k      860338
+     -4      3600k      1700k        1100k      846899
+     -5      4400k      2100k        1350k      845160
+     -6      5200k      2500k        1600k      838626
+     -7      6100k      2900k        1850k      834096
+     -8      6800k      3300k        2100k      828642
+     -9      7600k      3700k        2350k      828642
+
+.SH RECOVERING DATA FROM DAMAGED FILES
+.I bzip2
+compresses files in blocks, usually 900kbytes long.  Each
+block is handled independently.  If a media or transmission error causes
+a multi-block .bz2
+file to become damaged, it may be possible to
+recover data from the undamaged blocks in the file.
+
+The compressed representation of each block is delimited by a 48-bit
+pattern, which makes it possible to find the block boundaries with
+reasonable certainty.  Each block also carries its own 32-bit CRC, so
+damaged blocks can be distinguished from undamaged ones.
+
+.I bzip2recover
+is a simple program whose purpose is to search for
+blocks in .bz2 files, and write each block out into its own .bz2 
+file.  You can then use
+.I bzip2 
+\-t
+to test the
+integrity of the resulting files, and decompress those which are
+undamaged.
+
+.I bzip2recover
+takes a single argument, the name of the damaged file, 
+and writes a number of files "rec00001file.bz2",
+"rec00002file.bz2", etc, containing the  extracted  blocks.
+The  output  filenames  are  designed  so  that the use of
+wildcards in subsequent processing -- for example,  
+"bzip2 -dc  rec*file.bz2 > recovered_data" -- processes the files in
+the correct order.
+
+.I bzip2recover
+should be of most use dealing with large .bz2
+files,  as  these will contain many blocks.  It is clearly
+futile to use it on damaged single-block  files,  since  a
+damaged  block  cannot  be recovered.  If you wish to minimise 
+any potential data loss through media  or  transmission errors, 
+you might consider compressing with a smaller
+block size.
+
+.SH PERFORMANCE NOTES
+The sorting phase of compression gathers together similar strings in the
+file.  Because of this, files containing very long runs of repeated
+symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
+compress more slowly than normal.  Versions 0.9.5 and above fare much
+better than previous versions in this respect.  The ratio between
+worst-case and average-case compression time is in the region of 10:1.
+For previous versions, this figure was more like 100:1.  You can use the
+\-vvvv option to monitor progress in great detail, if you want.
+
+Decompression speed is unaffected by these phenomena.
+
+.I bzip2
+usually allocates several megabytes of memory to operate
+in, and then charges all over it in a fairly random fashion.  This means
+that performance, both for compressing and decompressing, is largely
+determined by the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss rate have
+been observed to give disproportionately large performance improvements.
+I imagine 
+.I bzip2
+will perform best on machines with very large caches.
+
+.SH CAVEATS
+I/O error messages are not as helpful as they could be.
+.I bzip2
+tries hard to detect I/O errors and exit cleanly, but the details of
+what the problem is sometimes seem rather misleading.
+
+This manual page pertains to version 1.0.6 of
+.I bzip2.  
+Compressed data created by this version is entirely forwards and
+backwards compatible with the previous public releases, versions
+0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and above, but with the following
+exception: 0.9.0 and above can correctly decompress multiple
+concatenated compressed files.  0.1pl2 cannot do this; it will stop
+after decompressing just the first file in the stream.
+
+.I bzip2recover
+versions prior to 1.0.2 used 32-bit integers to represent
+bit positions in compressed files, so they could not handle compressed
+files more than 512 megabytes long.  Versions 1.0.2 and above use
+64-bit ints on some platforms which support them (GNU supported
+targets, and Windows).  To establish whether or not bzip2recover was
+built with such a limitation, run it without arguments.  In any event
+you can build yourself an unlimited version if you can recompile it
+with MaybeUInt64 set to be an unsigned 64-bit integer.
+
+
+
+.SH AUTHOR
+Julian Seward, jsewardbzip.org.
+
+http://www.bzip.org
+
+The ideas embodied in
+.I bzip2
+are due to (at least) the following
+people: Michael Burrows and David Wheeler (for the block sorting
+transformation), David Wheeler (again, for the Huffman coder), Peter
+Fenwick (for the structured coding model in the original
+.I bzip,
+and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+.I bzip).  
+I am much
+indebted for their help, support and advice.  See the manual in the
+source distribution for pointers to sources of documentation.  Christian
+von Roques encouraged me to look for faster sorting algorithms, so as to
+speed up compression.  Bela Lubkin encouraged me to improve the
+worst-case compression performance.  
+Donna Robinson XMLised the documentation.
+The bz* scripts are derived from those of GNU gzip.
+Many people sent patches, helped
+with portability problems, lent machines, gave advice and were generally
+helpful.
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1.preformatted b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1.preformatted
new file mode 100644
index 0000000..63c33be
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.1.preformatted
@@ -0,0 +1,399 @@
+bzip2(1)                                                 bzip2(1)
+
+
+
+NNAAMMEE
+       bzip2, bunzip2 − a blockâ€sorting file compressor, v1.0.6
+       bzcat − decompresses files to stdout
+       bzip2recover − recovers data from damaged bzip2 files
+
+
+SSYYNNOOPPSSIISS
+       bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
+       bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
+       bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._.  ]
+       bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
+
+
+DDEESSCCRRIIPPTTIIOONN
+       _b_z_i_p_2  compresses  files  using  the Burrowsâ€Wheeler block
+       sorting text compression algorithm,  and  Huffman  coding.
+       Compression  is  generally  considerably  better than that
+       achieved by more conventional LZ77/LZ78â€based compressors,
+       and  approaches  the performance of the PPM family of sta­
+       tistical compressors.
+
+       The commandâ€line options are deliberately very similar  to
+       those of _G_N_U _g_z_i_p_, but they are not identical.
+
+       _b_z_i_p_2  expects  a list of file names to accompany the com­
+       mandâ€line flags.  Each file is replaced  by  a  compressed
+       version  of  itself,  with  the  name "original_name.bz2".
+       Each compressed file has the same modification date,  per­
+       missions, and, when possible, ownership as the correspond­
+       ing original, so that these properties  can  be  correctly
+       restored  at  decompression  time.   File name handling is
+       naive in the sense that there is no mechanism for preserv­
+       ing  original file names, permissions, ownerships or dates
+       in filesystems which lack these concepts, or have  serious
+       file name length restrictions, such as MSâ€DOS.
+
+       _b_z_i_p_2  and  _b_u_n_z_i_p_2 will by default not overwrite existing
+       files.  If you want this to happen, specify the −f flag.
+
+       If no file names  are  specified,  _b_z_i_p_2  compresses  from
+       standard  input  to  standard output.  In this case, _b_z_i_p_2
+       will decline to write compressed output to a terminal,  as
+       this  would  be  entirely  incomprehensible  and therefore
+       pointless.
+
+       _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses  all  specified  files.
+       Files which were not created by _b_z_i_p_2 will be detected and
+       ignored, and a warning issued.  _b_z_i_p_2  attempts  to  guess
+       the  filename  for  the decompressed file from that of the
+       compressed file as follows:
+
+              filename.bz2    becomes   filename
+              filename.bz     becomes   filename
+              filename.tbz2   becomes   filename.tar
+              filename.tbz    becomes   filename.tar
+              anyothername    becomes   anyothername.out
+
+       If the file does not end in one of the recognised endings,
+       _._b_z_2_,  _._b_z_,  _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
+       guess the name of the original file, and uses the original
+       name with _._o_u_t appended.
+
+       As  with compression, supplying no filenames causes decom­
+       pression from standard input to standard output.
+
+       _b_u_n_z_i_p_2 will correctly decompress a file which is the con­
+       catenation of two or more compressed files.  The result is
+       the concatenation of the corresponding uncompressed files.
+       Integrity testing (−t) of concatenated compressed files is
+       also supported.
+
+       You can also compress or decompress files to the  standard
+       output  by giving the −c flag.  Multiple files may be com­
+       pressed and decompressed like this.  The resulting outputs
+       are  fed  sequentially to stdout.  Compression of multiple
+       files in this manner generates a stream containing  multi­
+       ple compressed file representations.  Such a stream can be
+       decompressed correctly only  by  _b_z_i_p_2  version  0.9.0  or
+       later.   Earlier  versions of _b_z_i_p_2 will stop after decom­
+       pressing the first file in the stream.
+
+       _b_z_c_a_t (or _b_z_i_p_2 _â€_d_c_) decompresses all specified  files  to
+       the standard output.
+
+       _b_z_i_p_2  will  read arguments from the environment variables
+       _B_Z_I_P_2 and _B_Z_I_P_, in  that  order,  and  will  process  them
+       before  any  arguments  read  from the command line.  This
+       gives a convenient way to supply default arguments.
+
+       Compression is always performed, even  if  the  compressed
+       file  is slightly larger than the original.  Files of less
+       than about one hundred bytes tend to get larger, since the
+       compression  mechanism  has  a  constant  overhead  in the
+       region of 50 bytes.  Random data (including the output  of
+       most  file  compressors)  is  coded at about 8.05 bits per
+       byte, giving an expansion of around 0.5%.
+
+       As a selfâ€check for your  protection,  _b_z_i_p_2  uses  32â€bit
+       CRCs  to make sure that the decompressed version of a file
+       is identical to the original.  This guards against corrup­
+       tion  of  the compressed data, and against undetected bugs
+       in _b_z_i_p_2 (hopefully very unlikely).  The chances  of  data
+       corruption  going  undetected  is  microscopic,  about one
+       chance in four billion for each file processed.  Be aware,
+       though,  that  the  check occurs upon decompression, so it
+       can only tell you that something is wrong.  It can’t  help
+       you  recover  the original uncompressed data.  You can use
+       _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
+
+       Return values: 0 for a normal exit,  1  for  environmental
+       problems  (file not found, invalid flags, I/O errors, &c),
+       2 to indicate a corrupt compressed file, 3 for an internal
+       consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
+
+
+OOPPTTIIOONNSS
+       −−cc â€â€â€â€ssttddoouutt
+              Compress or decompress to standard output.
+
+       −−dd â€â€â€â€ddeeccoommpprreessss
+              Force  decompression.  _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
+              really the same program,  and  the  decision  about
+              what  actions to take is done on the basis of which
+              name is used.  This flag overrides that  mechanism,
+              and forces _b_z_i_p_2 to decompress.
+
+       −−zz â€â€â€â€ccoommpprreessss
+              The   complement   to   −d:   forces   compression,
+              regardless of the invocation name.
+
+       −−tt â€â€â€â€tteesstt
+              Check integrity of the specified file(s), but don’t
+              decompress  them.   This  really  performs  a trial
+              decompression and throws away the result.
+
+       −−ff â€â€â€â€ffoorrccee
+              Force overwrite of output files.   Normally,  _b_z_i_p_2
+              will  not  overwrite  existing  output files.  Also
+              forces _b_z_i_p_2 to break hard links to files, which it
+              otherwise wouldn’t do.
+
+              bzip2  normally  declines to decompress files which
+              don’t have the  correct  magic  header  bytes.   If
+              forced  (â€f),  however,  it  will  pass  such files
+              through unmodified.  This is how GNU gzip  behaves.
+
+       −−kk â€â€â€â€kkeeeepp
+              Keep  (don’t delete) input files during compression
+              or decompression.
+
+       −−ss â€â€â€â€ssmmaallll
+              Reduce memory usage, for compression, decompression
+              and  testing.   Files  are  decompressed and tested
+              using a modified algorithm which only requires  2.5
+              bytes  per  block byte.  This means any file can be
+              decompressed in 2300k of memory,  albeit  at  about
+              half the normal speed.
+
+              During  compression,  −s  selects  a  block size of
+              200k, which limits memory use to  around  the  same
+              figure,  at  the expense of your compression ratio.
+              In short, if your  machine  is  low  on  memory  (8
+              megabytes  or  less),  use  −s for everything.  See
+              MEMORY MANAGEMENT below.
+
+       −−qq â€â€â€â€qquuiieett
+              Suppress nonâ€essential warning messages.   Messages
+              pertaining  to I/O errors and other critical events
+              will not be suppressed.
+
+       −−vv â€â€â€â€vveerrbboossee
+              Verbose mode â€â€ show the compression ratio for each
+              file  processed.   Further  −v’s  increase the ver­
+              bosity level, spewing out lots of information which
+              is primarily of interest for diagnostic purposes.
+
+       −−LL â€â€â€â€lliicceennssee â€â€VV â€â€â€â€vveerrssiioonn
+              Display  the  software  version,  license terms and
+              conditions.
+
+       −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt))
+              Set the block size to 100 k, 200 k ..  900  k  when
+              compressing.   Has  no  effect  when decompressing.
+              See MEMORY MANAGEMENT below.  The −−fast and −−best
+              aliases  are  primarily for GNU gzip compatibility.
+              In particular, −−fast doesn’t make things  signifi­
+              cantly  faster.   And  −−best  merely  selects  the
+              default behaviour.
+
+       −−     Treats all subsequent arguments as file names, even
+              if they start with a dash.  This is so you can han­
+              dle files with names beginning  with  a  dash,  for
+              example: bzip2 −†−myfilename.
+
+       −−â€â€rreeppeettiittiivveeâ€â€ffaasstt â€â€â€â€rreeppeettiittiivveeâ€â€bbeesstt
+              These  flags  are  redundant  in versions 0.9.5 and
+              above.  They provided some coarse control over  the
+              behaviour  of the sorting algorithm in earlier ver­
+              sions, which was sometimes useful.  0.9.5 and above
+              have  an  improved  algorithm  which  renders these
+              flags irrelevant.
+
+
+MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
+       _b_z_i_p_2 compresses large files in blocks.   The  block  size
+       affects  both  the  compression  ratio  achieved,  and the
+       amount of memory needed for compression and decompression.
+       The  flags  −1  through  −9  specify  the block size to be
+       100,000 bytes through 900,000 bytes (the default)  respec­
+       tively.   At  decompression  time, the block size used for
+       compression is read from  the  header  of  the  compressed
+       file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
+       to decompress the file.  Since block sizes are  stored  in
+       compressed  files,  it follows that the flags −1 to −9 are
+       irrelevant to and so ignored during decompression.
+
+       Compression and decompression requirements, in bytes,  can
+       be estimated as:
+
+              Compression:   400k + ( 8 x block size )
+
+              Decompression: 100k + ( 4 x block size ), or
+                             100k + ( 2.5 x block size )
+
+       Larger  block  sizes  give  rapidly  diminishing  marginal
+       returns.  Most of the compression comes from the first two
+       or  three hundred k of block size, a fact worth bearing in
+       mind when using _b_z_i_p_2  on  small  machines.   It  is  also
+       important  to  appreciate  that  the  decompression memory
+       requirement is set at compression time by  the  choice  of
+       block size.
+
+       For  files  compressed  with  the default 900k block size,
+       _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress.   To
+       support decompression of any file on a 4 megabyte machine,
+       _b_u_n_z_i_p_2 has an option to  decompress  using  approximately
+       half this amount of memory, about 2300 kbytes.  Decompres­
+       sion speed is also halved, so you should use  this  option
+       only where necessary.  The relevant flag is â€s.
+
+       In general, try and use the largest block size memory con­
+       straints  allow,  since  that  maximises  the  compression
+       achieved.   Compression and decompression speed are virtu­
+       ally unaffected by block size.
+
+       Another significant point applies to files which fit in  a
+       single  block  â€â€  that  means  most files you’d encounter
+       using a large block  size.   The  amount  of  real  memory
+       touched is proportional to the size of the file, since the
+       file is smaller than a block.  For example, compressing  a
+       file  20,000  bytes  long  with the flag â€9 will cause the
+       compressor to allocate around 7600k of  memory,  but  only
+       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
+       decompressor will allocate 3700k but  only  touch  100k  +
+       20000 * 4 = 180 kbytes.
+
+       Here  is a table which summarises the maximum memory usage
+       for different block sizes.  Also  recorded  is  the  total
+       compressed  size for 14 files of the Calgary Text Compres­
+       sion Corpus totalling 3,141,622 bytes.  This column  gives
+       some  feel  for  how  compression  varies with block size.
+       These figures tend to understate the advantage  of  larger
+       block  sizes  for  larger files, since the Corpus is domi­
+       nated by smaller files.
+
+                  Compress   Decompress   Decompress   Corpus
+           Flag     usage      usage       â€s usage     Size
+
+            â€1      1200k       500k         350k      914704
+            â€2      2000k       900k         600k      877703
+            â€3      2800k      1300k         850k      860338
+            â€4      3600k      1700k        1100k      846899
+            â€5      4400k      2100k        1350k      845160
+            â€6      5200k      2500k        1600k      838626
+            â€7      6100k      2900k        1850k      834096
+            â€8      6800k      3300k        2100k      828642
+            â€9      7600k      3700k        2350k      828642
+
+
+RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
+       _b_z_i_p_2 compresses files in blocks, usually 900kbytes  long.
+       Each block is handled independently.  If a media or trans­
+       mission error causes a multiâ€block  .bz2  file  to  become
+       damaged,  it  may  be  possible  to  recover data from the
+       undamaged blocks in the file.
+
+       The compressed representation of each block  is  delimited
+       by  a  48â€bit pattern, which makes it possible to find the
+       block boundaries with reasonable  certainty.   Each  block
+       also  carries its own 32â€bit CRC, so damaged blocks can be
+       distinguished from undamaged ones.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r is a  simple  program  whose  purpose  is  to
+       search  for blocks in .bz2 files, and write each block out
+       into its own .bz2 file.  You can then use _b_z_i_p_2 −t to test
+       the integrity of the resulting files, and decompress those
+       which are undamaged.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­
+       aged    file,    and    writes    a    number   of   files
+       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
+       the   extracted   blocks.   The   output   filenames   are
+       designed  so  that the use of wildcards in subsequent pro­
+       cessing  â€â€ for example, "bzip2 â€dc  rec*file.bz2 > recov­
+       ered_data" â€â€ processes the files in the correct order.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
+       files,  as  these will contain many blocks.  It is clearly
+       futile to use it on damaged singleâ€block  files,  since  a
+       damaged  block  cannot  be recovered.  If you wish to min­
+       imise any potential data loss through media  or  transmis­
+       sion errors, you might consider compressing with a smaller
+       block size.
+
+
+PPEERRFFOORRMMAANNCCEE NNOOTTEESS
+       The sorting phase of compression gathers together  similar
+       strings  in  the  file.  Because of this, files containing
+       very long runs of  repeated  symbols,  like  "aabaabaabaab
+       ..."   (repeated  several hundred times) may compress more
+       slowly than normal.  Versions 0.9.5 and  above  fare  much
+       better  than previous versions in this respect.  The ratio
+       between worstâ€case and averageâ€case compression time is in
+       the  region  of  10:1.  For previous versions, this figure
+       was more like 100:1.  You can use the −vvvv option to mon­
+       itor progress in great detail, if you want.
+
+       Decompression speed is unaffected by these phenomena.
+
+       _b_z_i_p_2  usually  allocates  several  megabytes of memory to
+       operate in, and then charges all over it in a fairly  ran­
+       dom  fashion.   This means that performance, both for com­
+       pressing and decompressing, is largely determined  by  the
+       speed  at  which  your  machine  can service cache misses.
+       Because of this, small changes to the code to  reduce  the
+       miss  rate  have  been observed to give disproportionately
+       large performance improvements.  I imagine _b_z_i_p_2 will per­
+       form best on machines with very large caches.
+
+
+CCAAVVEEAATTSS
+       I/O  error  messages  are not as helpful as they could be.
+       _b_z_i_p_2 tries hard to detect I/O errors  and  exit  cleanly,
+       but  the  details  of  what  the problem is sometimes seem
+       rather misleading.
+
+       This manual page pertains to version 1.0.6 of _b_z_i_p_2_.  Com­
+       pressed  data created by this version is entirely forwards
+       and  backwards  compatible  with   the   previous   public
+       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1, 
+       1.0.2 and above, but with the  following  exception: 0.9.0
+       and above can  correctly decompress  multiple concatenated
+       compressed files.  0.1pl2  cannot do this;  it  will  stop 
+       after  decompressing just the first file in the stream.
+
+       _b_z_i_p_2_r_e_c_o_v_e_r  versions prior to 1.0.2 used 32â€bit integers
+       to represent bit positions in compressed  files,  so  they
+       could  not handle compressed files more than 512 megabytes
+       long.  Versions 1.0.2 and above use 64â€bit  ints  on  some
+       platforms  which  support them (GNU supported targets, and
+       Windows).  To establish whether or  not  bzip2recover  was
+       built  with  such  a limitation, run it without arguments.
+       In any event you can build yourself an  unlimited  version
+       if  you  can  recompile  it  with MaybeUInt64 set to be an
+       unsigned 64â€bit integer.
+
+
+
+
+AAUUTTHHOORR
+       Julian Seward, jsewardbzip.org.
+
+       http://www.bzip.org
+
+       The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­
+       lowing  people: Michael Burrows and David Wheeler (for the
+       block sorting transformation), David Wheeler  (again,  for
+       the Huffman coder), Peter Fenwick (for the structured cod­
+       ing model in the original _b_z_i_p_, and many refinements), and
+       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
+       arithmetic  coder  in  the  original  _b_z_i_p_)_.   I  am  much
+       indebted for their help, support and advice.  See the man­
+       ual in the source distribution for pointers to sources  of
+       documentation.  Christian von Roques encouraged me to look
+       for faster sorting algorithms, so as to speed up  compres­
+       sion.  Bela Lubkin encouraged me to improve the worstâ€case
+       compression performance.  Donna Robinson XMLised the docu­
+       mentation.   The bz* scripts are derived from those of GNU
+       gzip.  Many people sent patches, helped  with  portability
+       problems,  lent  machines,  gave advice and were generally
+       helpful.
+
+
+
+                                                         bzip2(1)
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.c
new file mode 100644
index 0000000..6de9d1d
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.c
@@ -0,0 +1,2034 @@
+
+/*-----------------------------------------------------------*/
+/*--- A block-sorting, lossless compressor        bzip2.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* Place a 1 beside your platform, and 0 elsewhere.
+   Generic 32-bit Unix.
+   Also works on 64-bit Unix boxes.
+   This is the default.
+*/
+#define BZ_UNIX      1
+
+/*--
+  Win32, as seen by Jacob Navia's excellent
+  port of (Chris Fraser & David Hanson)'s excellent
+  lcc compiler.  Or with MS Visual C.
+  This is selected automatically if compiled by a compiler which
+  defines _WIN32, not including the Cygwin GCC.
+--*/
+#define BZ_LCCWIN32  0
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef  BZ_LCCWIN32
+#define BZ_LCCWIN32 1
+#undef  BZ_UNIX
+#define BZ_UNIX 0
+#endif
+
+
+/*---------------------------------------------*/
+/*--
+  Some stuff for all platforms.
+--*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "bzlib.h"
+
+#define ERROR_IF_EOF(i)       { if ((i) == EOF)  ioError(); }
+#define ERROR_IF_NOT_ZERO(i)  { if ((i) != 0)    ioError(); }
+#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
+
+
+/*---------------------------------------------*/
+/*--
+   Platform-specific stuff.
+--*/
+
+#if BZ_UNIX
+#   include 
+#   include 
+#   include 
+#   include 
+#   include 
+#   include 
+
+#   define PATH_SEP    '/'
+#   define MY_LSTAT    lstat
+#   define MY_STAT     stat
+#   define MY_S_ISREG  S_ISREG
+#   define MY_S_ISDIR  S_ISDIR
+
+#   define APPEND_FILESPEC(root, name) \
+      root=snocString((root), (name))
+
+#   define APPEND_FLAG(root, name) \
+      root=snocString((root), (name))
+
+#   define SET_BINARY_MODE(fd) /**/
+
+#   ifdef __GNUC__
+#      define NORETURN __attribute__ ((noreturn))
+#   else
+#      define NORETURN /**/
+#   endif
+
+#   ifdef __DJGPP__
+#     include 
+#     include 
+#     undef MY_LSTAT
+#     undef MY_STAT
+#     define MY_LSTAT stat
+#     define MY_STAT stat
+#     undef SET_BINARY_MODE
+#     define SET_BINARY_MODE(fd)                        \
+        do {                                            \
+           int retVal = setmode ( fileno ( fd ),        \
+                                  O_BINARY );           \
+           ERROR_IF_MINUS_ONE ( retVal );               \
+        } while ( 0 )
+#   endif
+
+#   ifdef __CYGWIN__
+#     include 
+#     include 
+#     undef SET_BINARY_MODE
+#     define SET_BINARY_MODE(fd)                        \
+        do {                                            \
+           int retVal = setmode ( fileno ( fd ),        \
+                                  O_BINARY );           \
+           ERROR_IF_MINUS_ONE ( retVal );               \
+        } while ( 0 )
+#   endif
+#endif /* BZ_UNIX */
+
+
+
+#if BZ_LCCWIN32
+#   include 
+#   include 
+#   include 
+
+#   define NORETURN       /**/
+#   define PATH_SEP       '\\'
+#   define MY_LSTAT       _stat
+#   define MY_STAT        _stat
+#   define MY_S_ISREG(x)  ((x) & _S_IFREG)
+#   define MY_S_ISDIR(x)  ((x) & _S_IFDIR)
+
+#   define APPEND_FLAG(root, name) \
+      root=snocString((root), (name))
+
+#   define APPEND_FILESPEC(root, name)                \
+      root = snocString ((root), (name))
+
+#   define SET_BINARY_MODE(fd)                        \
+      do {                                            \
+         int retVal = setmode ( fileno ( fd ),        \
+                                O_BINARY );           \
+         ERROR_IF_MINUS_ONE ( retVal );               \
+      } while ( 0 )
+
+#endif /* BZ_LCCWIN32 */
+
+
+/*---------------------------------------------*/
+/*--
+  Some more stuff for all platforms :-)
+--*/
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+                                       
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+/*--
+  IntNative is your platform's `native' int size.
+  Only here to avoid probs with 64-bit platforms.
+--*/
+typedef int IntNative;
+
+
+/*---------------------------------------------------*/
+/*--- Misc (file handling) data decls             ---*/
+/*---------------------------------------------------*/
+
+Int32   verbosity;
+Bool    keepInputFiles, smallMode, deleteOutputOnInterrupt;
+Bool    forceOverwrite, testFailsExist, unzFailsExist, noisy;
+Int32   numFileNames, numFilesProcessed, blockSize100k;
+Int32   exitValue;
+
+/*-- source modes; F==file, I==stdin, O==stdout --*/
+#define SM_I2O           1
+#define SM_F2O           2
+#define SM_F2F           3
+
+/*-- operation modes --*/
+#define OM_Z             1
+#define OM_UNZ           2
+#define OM_TEST          3
+
+Int32   opMode;
+Int32   srcMode;
+
+#define FILE_NAME_LEN 1034
+
+Int32   longestFileName;
+Char    inName [FILE_NAME_LEN];
+Char    outName[FILE_NAME_LEN];
+Char    tmpName[FILE_NAME_LEN];
+Char    *progName;
+Char    progNameReally[FILE_NAME_LEN];
+FILE    *outputHandleJustInCase;
+Int32   workFactor;
+
+static void    panic                 ( const Char* ) NORETURN;
+static void    ioError               ( void )        NORETURN;
+static void    outOfMemory           ( void )        NORETURN;
+static void    configError           ( void )        NORETURN;
+static void    crcError              ( void )        NORETURN;
+static void    cleanUpAndFail        ( Int32 )       NORETURN;
+static void    compressedStreamEOF   ( void )        NORETURN;
+
+static void    copyFileName ( Char*, Char* );
+static void*   myMalloc     ( Int32 );
+static void    applySavedFileAttrToOutputFile ( IntNative fd );
+
+
+
+/*---------------------------------------------------*/
+/*--- An implementation of 64-bit ints.  Sigh.    ---*/
+/*--- Roll on widespread deployment of ANSI C9X ! ---*/
+/*---------------------------------------------------*/
+
+typedef
+   struct { UChar b[8]; } 
+   UInt64;
+
+
+static
+void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
+{
+   n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
+   n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
+   n->b[5] = (UChar)((hi32 >> 8)  & 0xFF);
+   n->b[4] = (UChar) (hi32        & 0xFF);
+   n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
+   n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
+   n->b[1] = (UChar)((lo32 >> 8)  & 0xFF);
+   n->b[0] = (UChar) (lo32        & 0xFF);
+}
+
+
+static
+double uInt64_to_double ( UInt64* n )
+{
+   Int32  i;
+   double base = 1.0;
+   double sum  = 0.0;
+   for (i = 0; i < 8; i++) {
+      sum  += base * (double)(n->b[i]);
+      base *= 256.0;
+   }
+   return sum;
+}
+
+
+static
+Bool uInt64_isZero ( UInt64* n )
+{
+   Int32 i;
+   for (i = 0; i < 8; i++)
+      if (n->b[i] != 0) return 0;
+   return 1;
+}
+
+
+/* Divide *n by 10, and return the remainder.  */
+static 
+Int32 uInt64_qrm10 ( UInt64* n )
+{
+   UInt32 rem, tmp;
+   Int32  i;
+   rem = 0;
+   for (i = 7; i >= 0; i--) {
+      tmp = rem * 256 + n->b[i];
+      n->b[i] = tmp / 10;
+      rem = tmp % 10;
+   }
+   return rem;
+}
+
+
+/* ... and the Whole Entire Point of all this UInt64 stuff is
+   so that we can supply the following function.
+*/
+static
+void uInt64_toAscii ( char* outbuf, UInt64* n )
+{
+   Int32  i, q;
+   UChar  buf[32];
+   Int32  nBuf   = 0;
+   UInt64 n_copy = *n;
+   do {
+      q = uInt64_qrm10 ( &n_copy );
+      buf[nBuf] = q + '0';
+      nBuf++;
+   } while (!uInt64_isZero(&n_copy));
+   outbuf[nBuf] = 0;
+   for (i = 0; i < nBuf; i++) 
+      outbuf[i] = buf[nBuf-i-1];
+}
+
+
+/*---------------------------------------------------*/
+/*--- Processing of complete files and streams    ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------*/
+static 
+void compressStream ( FILE *stream, FILE *zStream )
+{
+   BZFILE* bzf = NULL;
+   UChar   ibuf[5000];
+   Int32   nIbuf;
+   UInt32  nbytes_in_lo32, nbytes_in_hi32;
+   UInt32  nbytes_out_lo32, nbytes_out_hi32;
+   Int32   bzerr, bzerr_dummy, ret;
+
+   SET_BINARY_MODE(stream);
+   SET_BINARY_MODE(zStream);
+
+   if (ferror(stream)) goto errhandler_io;
+   if (ferror(zStream)) goto errhandler_io;
+
+   bzf = BZ2_bzWriteOpen ( &bzerr, zStream, 
+                           blockSize100k, verbosity, workFactor );   
+   if (bzerr != BZ_OK) goto errhandler;
+
+   if (verbosity >= 2) fprintf ( stderr, "\n" );
+
+   while (True) {
+
+      if (myfeof(stream)) break;
+      nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
+      if (ferror(stream)) goto errhandler_io;
+      if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
+      if (bzerr != BZ_OK) goto errhandler;
+
+   }
+
+   BZ2_bzWriteClose64 ( &bzerr, bzf, 0, 
+                        &nbytes_in_lo32, &nbytes_in_hi32,
+                        &nbytes_out_lo32, &nbytes_out_hi32 );
+   if (bzerr != BZ_OK) goto errhandler;
+
+   if (ferror(zStream)) goto errhandler_io;
+   ret = fflush ( zStream );
+   if (ret == EOF) goto errhandler_io;
+   if (zStream != stdout) {
+      Int32 fd = fileno ( zStream );
+      if (fd < 0) goto errhandler_io;
+      applySavedFileAttrToOutputFile ( fd );
+      ret = fclose ( zStream );
+      outputHandleJustInCase = NULL;
+      if (ret == EOF) goto errhandler_io;
+   }
+   outputHandleJustInCase = NULL;
+   if (ferror(stream)) goto errhandler_io;
+   ret = fclose ( stream );
+   if (ret == EOF) goto errhandler_io;
+
+   if (verbosity >= 1) {
+      if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
+	 fprintf ( stderr, " no data compressed.\n");
+      } else {
+	 Char   buf_nin[32], buf_nout[32];
+	 UInt64 nbytes_in,   nbytes_out;
+	 double nbytes_in_d, nbytes_out_d;
+	 uInt64_from_UInt32s ( &nbytes_in, 
+			       nbytes_in_lo32, nbytes_in_hi32 );
+	 uInt64_from_UInt32s ( &nbytes_out, 
+			       nbytes_out_lo32, nbytes_out_hi32 );
+	 nbytes_in_d  = uInt64_to_double ( &nbytes_in );
+	 nbytes_out_d = uInt64_to_double ( &nbytes_out );
+	 uInt64_toAscii ( buf_nin, &nbytes_in );
+	 uInt64_toAscii ( buf_nout, &nbytes_out );
+	 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
+		   "%5.2f%% saved, %s in, %s out.\n",
+		   nbytes_in_d / nbytes_out_d,
+		   (8.0 * nbytes_out_d) / nbytes_in_d,
+		   100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
+		   buf_nin,
+		   buf_nout
+		 );
+      }
+   }
+
+   return;
+
+   errhandler:
+   BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1, 
+                        &nbytes_in_lo32, &nbytes_in_hi32,
+                        &nbytes_out_lo32, &nbytes_out_hi32 );
+   switch (bzerr) {
+      case BZ_CONFIG_ERROR:
+         configError(); break;
+      case BZ_MEM_ERROR:
+         outOfMemory (); break;
+      case BZ_IO_ERROR:
+         errhandler_io:
+         ioError(); break;
+      default:
+         panic ( "compress:unexpected error" );
+   }
+
+   panic ( "compress:end" );
+   /*notreached*/
+}
+
+
+
+/*---------------------------------------------*/
+static 
+Bool uncompressStream ( FILE *zStream, FILE *stream )
+{
+   BZFILE* bzf = NULL;
+   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
+   UChar   obuf[5000];
+   UChar   unused[BZ_MAX_UNUSED];
+   Int32   nUnused;
+   void*   unusedTmpV;
+   UChar*  unusedTmp;
+
+   nUnused = 0;
+   streamNo = 0;
+
+   SET_BINARY_MODE(stream);
+   SET_BINARY_MODE(zStream);
+
+   if (ferror(stream)) goto errhandler_io;
+   if (ferror(zStream)) goto errhandler_io;
+
+   while (True) {
+
+      bzf = BZ2_bzReadOpen ( 
+               &bzerr, zStream, verbosity, 
+               (int)smallMode, unused, nUnused
+            );
+      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+      streamNo++;
+
+      while (bzerr == BZ_OK) {
+         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+         if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
+         if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
+            fwrite ( obuf, sizeof(UChar), nread, stream );
+         if (ferror(stream)) goto errhandler_io;
+      }
+      if (bzerr != BZ_STREAM_END) goto errhandler;
+
+      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+      unusedTmp = (UChar*)unusedTmpV;
+      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+      BZ2_bzReadClose ( &bzerr, bzf );
+      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+      if (nUnused == 0 && myfeof(zStream)) break;
+   }
+
+   closeok:
+   if (ferror(zStream)) goto errhandler_io;
+   if (stream != stdout) {
+      Int32 fd = fileno ( stream );
+      if (fd < 0) goto errhandler_io;
+      applySavedFileAttrToOutputFile ( fd );
+   }
+   ret = fclose ( zStream );
+   if (ret == EOF) goto errhandler_io;
+
+   if (ferror(stream)) goto errhandler_io;
+   ret = fflush ( stream );
+   if (ret != 0) goto errhandler_io;
+   if (stream != stdout) {
+      ret = fclose ( stream );
+      outputHandleJustInCase = NULL;
+      if (ret == EOF) goto errhandler_io;
+   }
+   outputHandleJustInCase = NULL;
+   if (verbosity >= 2) fprintf ( stderr, "\n    " );
+   return True;
+
+   trycat: 
+   if (forceOverwrite) {
+      rewind(zStream);
+      while (True) {
+      	 if (myfeof(zStream)) break;
+      	 nread = fread ( obuf, sizeof(UChar), 5000, zStream );
+      	 if (ferror(zStream)) goto errhandler_io;
+      	 if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
+      	 if (ferror(stream)) goto errhandler_io;
+      }
+      goto closeok;
+   }
+  
+   errhandler:
+   BZ2_bzReadClose ( &bzerr_dummy, bzf );
+   switch (bzerr) {
+      case BZ_CONFIG_ERROR:
+         configError(); break;
+      case BZ_IO_ERROR:
+         errhandler_io:
+         ioError(); break;
+      case BZ_DATA_ERROR:
+         crcError();
+      case BZ_MEM_ERROR:
+         outOfMemory();
+      case BZ_UNEXPECTED_EOF:
+         compressedStreamEOF();
+      case BZ_DATA_ERROR_MAGIC:
+         if (zStream != stdin) fclose(zStream);
+         if (stream != stdout) fclose(stream);
+         if (streamNo == 1) {
+            return False;
+         } else {
+            if (noisy)
+            fprintf ( stderr, 
+                      "\n%s: %s: trailing garbage after EOF ignored\n",
+                      progName, inName );
+            return True;       
+         }
+      default:
+         panic ( "decompress:unexpected error" );
+   }
+
+   panic ( "decompress:end" );
+   return True; /*notreached*/
+}
+
+
+/*---------------------------------------------*/
+static 
+Bool testStream ( FILE *zStream )
+{
+   BZFILE* bzf = NULL;
+   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
+   UChar   obuf[5000];
+   UChar   unused[BZ_MAX_UNUSED];
+   Int32   nUnused;
+   void*   unusedTmpV;
+   UChar*  unusedTmp;
+
+   nUnused = 0;
+   streamNo = 0;
+
+   SET_BINARY_MODE(zStream);
+   if (ferror(zStream)) goto errhandler_io;
+
+   while (True) {
+
+      bzf = BZ2_bzReadOpen ( 
+               &bzerr, zStream, verbosity, 
+               (int)smallMode, unused, nUnused
+            );
+      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+      streamNo++;
+
+      while (bzerr == BZ_OK) {
+         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+         if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
+      }
+      if (bzerr != BZ_STREAM_END) goto errhandler;
+
+      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+
+      unusedTmp = (UChar*)unusedTmpV;
+      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+      BZ2_bzReadClose ( &bzerr, bzf );
+      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+      if (nUnused == 0 && myfeof(zStream)) break;
+
+   }
+
+   if (ferror(zStream)) goto errhandler_io;
+   ret = fclose ( zStream );
+   if (ret == EOF) goto errhandler_io;
+
+   if (verbosity >= 2) fprintf ( stderr, "\n    " );
+   return True;
+
+   errhandler:
+   BZ2_bzReadClose ( &bzerr_dummy, bzf );
+   if (verbosity == 0) 
+      fprintf ( stderr, "%s: %s: ", progName, inName );
+   switch (bzerr) {
+      case BZ_CONFIG_ERROR:
+         configError(); break;
+      case BZ_IO_ERROR:
+         errhandler_io:
+         ioError(); break;
+      case BZ_DATA_ERROR:
+         fprintf ( stderr,
+                   "data integrity (CRC) error in data\n" );
+         return False;
+      case BZ_MEM_ERROR:
+         outOfMemory();
+      case BZ_UNEXPECTED_EOF:
+         fprintf ( stderr,
+                   "file ends unexpectedly\n" );
+         return False;
+      case BZ_DATA_ERROR_MAGIC:
+         if (zStream != stdin) fclose(zStream);
+         if (streamNo == 1) {
+          fprintf ( stderr, 
+                    "bad magic number (file not created by bzip2)\n" );
+            return False;
+         } else {
+            if (noisy)
+            fprintf ( stderr, 
+                      "trailing garbage after EOF ignored\n" );
+            return True;       
+         }
+      default:
+         panic ( "test:unexpected error" );
+   }
+
+   panic ( "test:end" );
+   return True; /*notreached*/
+}
+
+
+/*---------------------------------------------------*/
+/*--- Error [non-] handling grunge                ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+void setExit ( Int32 v )
+{
+   if (v > exitValue) exitValue = v;
+}
+
+
+/*---------------------------------------------*/
+static 
+void cadvise ( void )
+{
+   if (noisy)
+   fprintf (
+      stderr,
+      "\nIt is possible that the compressed file(s) have become corrupted.\n"
+        "You can use the -tvv option to test integrity of such files.\n\n"
+        "You can use the `bzip2recover' program to attempt to recover\n"
+        "data from undamaged sections of corrupted files.\n\n"
+    );
+}
+
+
+/*---------------------------------------------*/
+static 
+void showFileNames ( void )
+{
+   if (noisy)
+   fprintf (
+      stderr,
+      "\tInput file = %s, output file = %s\n",
+      inName, outName 
+   );
+}
+
+
+/*---------------------------------------------*/
+static 
+void cleanUpAndFail ( Int32 ec )
+{
+   IntNative      retVal;
+   struct MY_STAT statBuf;
+
+   if ( srcMode == SM_F2F 
+        && opMode != OM_TEST
+        && deleteOutputOnInterrupt ) {
+
+      /* Check whether input file still exists.  Delete output file
+         only if input exists to avoid loss of data.  Joerg Prante, 5
+         January 2002.  (JRS 06-Jan-2002: other changes in 1.0.2 mean
+         this is less likely to happen.  But to be ultra-paranoid, we
+         do the check anyway.)  */
+      retVal = MY_STAT ( inName, &statBuf );
+      if (retVal == 0) {
+         if (noisy)
+            fprintf ( stderr, 
+                      "%s: Deleting output file %s, if it exists.\n",
+                      progName, outName );
+         if (outputHandleJustInCase != NULL)
+            fclose ( outputHandleJustInCase );
+         retVal = remove ( outName );
+         if (retVal != 0)
+            fprintf ( stderr,
+                      "%s: WARNING: deletion of output file "
+                      "(apparently) failed.\n",
+                      progName );
+      } else {
+         fprintf ( stderr,
+                   "%s: WARNING: deletion of output file suppressed\n",
+                    progName );
+         fprintf ( stderr,
+                   "%s:    since input file no longer exists.  Output file\n",
+                   progName );
+         fprintf ( stderr,
+                   "%s:    `%s' may be incomplete.\n",
+                   progName, outName );
+         fprintf ( stderr, 
+                   "%s:    I suggest doing an integrity test (bzip2 -tv)"
+                   " of it.\n",
+                   progName );
+      }
+   }
+
+   if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
+      fprintf ( stderr, 
+                "%s: WARNING: some files have not been processed:\n"
+                "%s:    %d specified on command line, %d not processed yet.\n\n",
+                progName, progName,
+                numFileNames, numFileNames - numFilesProcessed );
+   }
+   setExit(ec);
+   exit(exitValue);
+}
+
+
+/*---------------------------------------------*/
+static 
+void panic ( const Char* s )
+{
+   fprintf ( stderr,
+             "\n%s: PANIC -- internal consistency error:\n"
+             "\t%s\n"
+             "\tThis is a BUG.  Please report it to me at:\n"
+             "\tjseward@bzip.org\n",
+             progName, s );
+   showFileNames();
+   cleanUpAndFail( 3 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void crcError ( void )
+{
+   fprintf ( stderr,
+             "\n%s: Data integrity error when decompressing.\n",
+             progName );
+   showFileNames();
+   cadvise();
+   cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void compressedStreamEOF ( void )
+{
+  if (noisy) {
+    fprintf ( stderr,
+	      "\n%s: Compressed file ends unexpectedly;\n\t"
+	      "perhaps it is corrupted?  *Possible* reason follows.\n",
+	      progName );
+    perror ( progName );
+    showFileNames();
+    cadvise();
+  }
+  cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void ioError ( void )
+{
+   fprintf ( stderr,
+             "\n%s: I/O or other error, bailing out.  "
+             "Possible reason follows.\n",
+             progName );
+   perror ( progName );
+   showFileNames();
+   cleanUpAndFail( 1 );
+}
+
+
+/*---------------------------------------------*/
+static 
+void mySignalCatcher ( IntNative n )
+{
+   fprintf ( stderr,
+             "\n%s: Control-C or similar caught, quitting.\n",
+             progName );
+   cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static 
+void mySIGSEGVorSIGBUScatcher ( IntNative n )
+{
+   if (opMode == OM_Z)
+      fprintf ( 
+      stderr,
+      "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
+      "\n"
+      "   Possible causes are (most likely first):\n"
+      "   (1) This computer has unreliable memory or cache hardware\n"
+      "       (a surprisingly common problem; try a different machine.)\n"
+      "   (2) A bug in the compiler used to create this executable\n"
+      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
+      "   (3) A real bug in bzip2 -- I hope this should never be the case.\n"
+      "   The user's manual, Section 4.3, has more info on (1) and (2).\n"
+      "   \n"
+      "   If you suspect this is a bug in bzip2, or are unsure about (1)\n"
+      "   or (2), feel free to report it to me at: jseward@bzip.org.\n"
+      "   Section 4.3 of the user's manual describes the info a useful\n"
+      "   bug report should have.  If the manual is available on your\n"
+      "   system, please try and read it before mailing me.  If you don't\n"
+      "   have the manual or can't be bothered to read it, mail me anyway.\n"
+      "\n",
+      progName );
+      else
+      fprintf ( 
+      stderr,
+      "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
+      "\n"
+      "   Possible causes are (most likely first):\n"
+      "   (1) The compressed data is corrupted, and bzip2's usual checks\n"
+      "       failed to detect this.  Try bzip2 -tvv my_file.bz2.\n"
+      "   (2) This computer has unreliable memory or cache hardware\n"
+      "       (a surprisingly common problem; try a different machine.)\n"
+      "   (3) A bug in the compiler used to create this executable\n"
+      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
+      "   (4) A real bug in bzip2 -- I hope this should never be the case.\n"
+      "   The user's manual, Section 4.3, has more info on (2) and (3).\n"
+      "   \n"
+      "   If you suspect this is a bug in bzip2, or are unsure about (2)\n"
+      "   or (3), feel free to report it to me at: jseward@bzip.org.\n"
+      "   Section 4.3 of the user's manual describes the info a useful\n"
+      "   bug report should have.  If the manual is available on your\n"
+      "   system, please try and read it before mailing me.  If you don't\n"
+      "   have the manual or can't be bothered to read it, mail me anyway.\n"
+      "\n",
+      progName );
+
+   showFileNames();
+   if (opMode == OM_Z)
+      cleanUpAndFail( 3 ); else
+      { cadvise(); cleanUpAndFail( 2 ); }
+}
+
+
+/*---------------------------------------------*/
+static 
+void outOfMemory ( void )
+{
+   fprintf ( stderr,
+             "\n%s: couldn't allocate enough memory\n",
+             progName );
+   showFileNames();
+   cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static 
+void configError ( void )
+{
+   fprintf ( stderr,
+             "bzip2: I'm not configured correctly for this platform!\n"
+             "\tI require Int32, Int16 and Char to have sizes\n"
+             "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
+             "\tProbably you can fix this by defining them correctly,\n"
+             "\tand recompiling.  Bye!\n" );
+   setExit(3);
+   exit(exitValue);
+}
+
+
+/*---------------------------------------------------*/
+/*--- The main driver machinery                   ---*/
+/*---------------------------------------------------*/
+
+/* All rather crufty.  The main problem is that input files
+   are stat()d multiple times before use.  This should be
+   cleaned up. 
+*/
+
+/*---------------------------------------------*/
+static 
+void pad ( Char *s )
+{
+   Int32 i;
+   if ( (Int32)strlen(s) >= longestFileName ) return;
+   for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
+      fprintf ( stderr, " " );
+}
+
+
+/*---------------------------------------------*/
+static 
+void copyFileName ( Char* to, Char* from ) 
+{
+   if ( strlen(from) > FILE_NAME_LEN-10 )  {
+      fprintf (
+         stderr,
+         "bzip2: file name\n`%s'\n"
+         "is suspiciously (more than %d chars) long.\n"
+         "Try using a reasonable file name instead.  Sorry! :-)\n",
+         from, FILE_NAME_LEN-10
+      );
+      setExit(1);
+      exit(exitValue);
+   }
+
+  strncpy(to,from,FILE_NAME_LEN-10);
+  to[FILE_NAME_LEN-10]='\0';
+}
+
+
+/*---------------------------------------------*/
+static 
+Bool fileExists ( Char* name )
+{
+   FILE *tmp   = fopen ( name, "rb" );
+   Bool exists = (tmp != NULL);
+   if (tmp != NULL) fclose ( tmp );
+   return exists;
+}
+
+
+/*---------------------------------------------*/
+/* Open an output file safely with O_EXCL and good permissions.
+   This avoids a race condition in versions < 1.0.2, in which
+   the file was first opened and then had its interim permissions
+   set safely.  We instead use open() to create the file with
+   the interim permissions required. (--- --- rw-).
+
+   For non-Unix platforms, if we are not worrying about
+   security issues, simple this simply behaves like fopen.
+*/
+static
+FILE* fopen_output_safely ( Char* name, const char* mode )
+{
+#  if BZ_UNIX
+   FILE*     fp;
+   IntNative fh;
+   fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
+   if (fh == -1) return NULL;
+   fp = fdopen(fh, mode);
+   if (fp == NULL) close(fh);
+   return fp;
+#  else
+   return fopen(name, mode);
+#  endif
+}
+
+
+/*---------------------------------------------*/
+/*--
+  if in doubt, return True
+--*/
+static 
+Bool notAStandardFile ( Char* name )
+{
+   IntNative      i;
+   struct MY_STAT statBuf;
+
+   i = MY_LSTAT ( name, &statBuf );
+   if (i != 0) return True;
+   if (MY_S_ISREG(statBuf.st_mode)) return False;
+   return True;
+}
+
+
+/*---------------------------------------------*/
+/*--
+  rac 11/21/98 see if file has hard links to it
+--*/
+static 
+Int32 countHardLinks ( Char* name )
+{  
+   IntNative      i;
+   struct MY_STAT statBuf;
+
+   i = MY_LSTAT ( name, &statBuf );
+   if (i != 0) return 0;
+   return (statBuf.st_nlink - 1);
+}
+
+
+/*---------------------------------------------*/
+/* Copy modification date, access date, permissions and owner from the
+   source to destination file.  We have to copy this meta-info off
+   into fileMetaInfo before starting to compress / decompress it,
+   because doing it afterwards means we get the wrong access time.
+
+   To complicate matters, in compress() and decompress() below, the
+   sequence of tests preceding the call to saveInputFileMetaInfo()
+   involves calling fileExists(), which in turn establishes its result
+   by attempting to fopen() the file, and if successful, immediately
+   fclose()ing it again.  So we have to assume that the fopen() call
+   does not cause the access time field to be updated.
+
+   Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
+   to imply that merely doing open() will not affect the access time.
+   Therefore we merely need to hope that the C library only does
+   open() as a result of fopen(), and not any kind of read()-ahead
+   cleverness.
+
+   It sounds pretty fragile to me.  Whether this carries across
+   robustly to arbitrary Unix-like platforms (or even works robustly
+   on this one, RedHat 7.2) is unknown to me.  Nevertheless ...  
+*/
+#if BZ_UNIX
+static 
+struct MY_STAT fileMetaInfo;
+#endif
+
+static 
+void saveInputFileMetaInfo ( Char *srcName )
+{
+#  if BZ_UNIX
+   IntNative retVal;
+   /* Note use of stat here, not lstat. */
+   retVal = MY_STAT( srcName, &fileMetaInfo );
+   ERROR_IF_NOT_ZERO ( retVal );
+#  endif
+}
+
+
+static 
+void applySavedTimeInfoToOutputFile ( Char *dstName )
+{
+#  if BZ_UNIX
+   IntNative      retVal;
+   struct utimbuf uTimBuf;
+
+   uTimBuf.actime = fileMetaInfo.st_atime;
+   uTimBuf.modtime = fileMetaInfo.st_mtime;
+
+   retVal = utime ( dstName, &uTimBuf );
+   ERROR_IF_NOT_ZERO ( retVal );
+#  endif
+}
+
+static 
+void applySavedFileAttrToOutputFile ( IntNative fd )
+{
+#  if BZ_UNIX
+   IntNative retVal;
+
+   retVal = fchmod ( fd, fileMetaInfo.st_mode );
+   ERROR_IF_NOT_ZERO ( retVal );
+
+   (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
+   /* chown() will in many cases return with EPERM, which can
+      be safely ignored.
+   */
+#  endif
+}
+
+
+/*---------------------------------------------*/
+static 
+Bool containsDubiousChars ( Char* name )
+{
+#  if BZ_UNIX
+   /* On unix, files can contain any characters and the file expansion
+    * is performed by the shell.
+    */
+   return False;
+#  else /* ! BZ_UNIX */
+   /* On non-unix (Win* platforms), wildcard characters are not allowed in 
+    * filenames.
+    */
+   for (; *name != '\0'; name++)
+      if (*name == '?' || *name == '*') return True;
+   return False;
+#  endif /* BZ_UNIX */
+}
+
+
+/*---------------------------------------------*/
+#define BZ_N_SUFFIX_PAIRS 4
+
+const Char* zSuffix[BZ_N_SUFFIX_PAIRS] 
+   = { ".bz2", ".bz", ".tbz2", ".tbz" };
+const Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 
+   = { "", "", ".tar", ".tar" };
+
+static 
+Bool hasSuffix ( Char* s, const Char* suffix )
+{
+   Int32 ns = strlen(s);
+   Int32 nx = strlen(suffix);
+   if (ns < nx) return False;
+   if (strcmp(s + ns - nx, suffix) == 0) return True;
+   return False;
+}
+
+static 
+Bool mapSuffix ( Char* name, 
+                 const Char* oldSuffix, 
+                 const Char* newSuffix )
+{
+   if (!hasSuffix(name,oldSuffix)) return False;
+   name[strlen(name)-strlen(oldSuffix)] = 0;
+   strcat ( name, newSuffix );
+   return True;
+}
+
+
+/*---------------------------------------------*/
+static 
+void compress ( Char *name )
+{
+   FILE  *inStr;
+   FILE  *outStr;
+   Int32 n, i;
+   struct MY_STAT statBuf;
+
+   deleteOutputOnInterrupt = False;
+
+   if (name == NULL && srcMode != SM_I2O)
+      panic ( "compress: bad modes\n" );
+
+   switch (srcMode) {
+      case SM_I2O: 
+         copyFileName ( inName, (Char*)"(stdin)" );
+         copyFileName ( outName, (Char*)"(stdout)" ); 
+         break;
+      case SM_F2F: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, name );
+         strcat ( outName, ".bz2" ); 
+         break;
+      case SM_F2O: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, (Char*)"(stdout)" ); 
+         break;
+   }
+
+   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+      if (noisy)
+      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                progName, inName, strerror(errno) );
+      setExit(1);
+      return;
+   }
+   for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
+      if (hasSuffix(inName, zSuffix[i])) {
+         if (noisy)
+         fprintf ( stderr, 
+                   "%s: Input file %s already has %s suffix.\n",
+                   progName, inName, zSuffix[i] );
+         setExit(1);
+         return;
+      }
+   }
+   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+      MY_STAT(inName, &statBuf);
+      if ( MY_S_ISDIR(statBuf.st_mode) ) {
+         fprintf( stderr,
+                  "%s: Input file %s is a directory.\n",
+                  progName,inName);
+         setExit(1);
+         return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+      if (noisy)
+      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+      if (forceOverwrite) {
+	 remove(outName);
+      } else {
+	 fprintf ( stderr, "%s: Output file %s already exists.\n",
+		   progName, outName );
+	 setExit(1);
+	 return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite &&
+        (n=countHardLinks ( inName )) > 0) {
+      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+                progName, inName, n, n > 1 ? "s" : "" );
+      setExit(1);
+      return;
+   }
+
+   if ( srcMode == SM_F2F ) {
+      /* Save the file's meta-info before we open it.  Doing it later
+         means we mess up the access times. */
+      saveInputFileMetaInfo ( inName );
+   }
+
+   switch ( srcMode ) {
+
+      case SM_I2O:
+         inStr = stdin;
+         outStr = stdout;
+         if ( isatty ( fileno ( stdout ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't write compressed data to a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2O:
+         inStr = fopen ( inName, "rb" );
+         outStr = stdout;
+         if ( isatty ( fileno ( stdout ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't write compressed data to a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         };
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                      progName, inName, strerror(errno) );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2F:
+         inStr = fopen ( inName, "rb" );
+         outStr = fopen_output_safely ( outName, "wb" );
+         if ( outStr == NULL) {
+            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+                      progName, outName, strerror(errno) );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         }
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                      progName, inName, strerror(errno) );
+            if ( outStr != NULL ) fclose ( outStr );
+            setExit(1);
+            return;
+         };
+         break;
+
+      default:
+         panic ( "compress: bad srcMode" );
+         break;
+   }
+
+   if (verbosity >= 1) {
+      fprintf ( stderr,  "  %s: ", inName );
+      pad ( inName );
+      fflush ( stderr );
+   }
+
+   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
+   outputHandleJustInCase = outStr;
+   deleteOutputOnInterrupt = True;
+   compressStream ( inStr, outStr );
+   outputHandleJustInCase = NULL;
+
+   /*--- If there was an I/O error, we won't get here. ---*/
+   if ( srcMode == SM_F2F ) {
+      applySavedTimeInfoToOutputFile ( outName );
+      deleteOutputOnInterrupt = False;
+      if ( !keepInputFiles ) {
+         IntNative retVal = remove ( inName );
+         ERROR_IF_NOT_ZERO ( retVal );
+      }
+   }
+
+   deleteOutputOnInterrupt = False;
+}
+
+
+/*---------------------------------------------*/
+static 
+void uncompress ( Char *name )
+{
+   FILE  *inStr;
+   FILE  *outStr;
+   Int32 n, i;
+   Bool  magicNumberOK;
+   Bool  cantGuess;
+   struct MY_STAT statBuf;
+
+   deleteOutputOnInterrupt = False;
+
+   if (name == NULL && srcMode != SM_I2O)
+      panic ( "uncompress: bad modes\n" );
+
+   cantGuess = False;
+   switch (srcMode) {
+      case SM_I2O: 
+         copyFileName ( inName, (Char*)"(stdin)" );
+         copyFileName ( outName, (Char*)"(stdout)" ); 
+         break;
+      case SM_F2F: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, name );
+         for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
+            if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
+               goto zzz; 
+         cantGuess = True;
+         strcat ( outName, ".out" );
+         break;
+      case SM_F2O: 
+         copyFileName ( inName, name );
+         copyFileName ( outName, (Char*)"(stdout)" ); 
+         break;
+   }
+
+   zzz:
+   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+      if (noisy)
+      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                progName, inName, strerror(errno) );
+      setExit(1);
+      return;
+   }
+   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+      MY_STAT(inName, &statBuf);
+      if ( MY_S_ISDIR(statBuf.st_mode) ) {
+         fprintf( stderr,
+                  "%s: Input file %s is a directory.\n",
+                  progName,inName);
+         setExit(1);
+         return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+      if (noisy)
+      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
+      if (noisy)
+      fprintf ( stderr, 
+                "%s: Can't guess original name for %s -- using %s\n",
+                progName, inName, outName );
+      /* just a warning, no return */
+   }   
+   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+      if (forceOverwrite) {
+	remove(outName);
+      } else {
+        fprintf ( stderr, "%s: Output file %s already exists.\n",
+                  progName, outName );
+        setExit(1);
+        return;
+      }
+   }
+   if ( srcMode == SM_F2F && !forceOverwrite &&
+        (n=countHardLinks ( inName ) ) > 0) {
+      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+                progName, inName, n, n > 1 ? "s" : "" );
+      setExit(1);
+      return;
+   }
+
+   if ( srcMode == SM_F2F ) {
+      /* Save the file's meta-info before we open it.  Doing it later
+         means we mess up the access times. */
+      saveInputFileMetaInfo ( inName );
+   }
+
+   switch ( srcMode ) {
+
+      case SM_I2O:
+         inStr = stdin;
+         outStr = stdout;
+         if ( isatty ( fileno ( stdin ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't read compressed data from a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2O:
+         inStr = fopen ( inName, "rb" );
+         outStr = stdout;
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+                      progName, inName, strerror(errno) );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         };
+         break;
+
+      case SM_F2F:
+         inStr = fopen ( inName, "rb" );
+         outStr = fopen_output_safely ( outName, "wb" );
+         if ( outStr == NULL) {
+            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+                      progName, outName, strerror(errno) );
+            if ( inStr != NULL ) fclose ( inStr );
+            setExit(1);
+            return;
+         }
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+                      progName, inName, strerror(errno) );
+            if ( outStr != NULL ) fclose ( outStr );
+            setExit(1);
+            return;
+         };
+         break;
+
+      default:
+         panic ( "uncompress: bad srcMode" );
+         break;
+   }
+
+   if (verbosity >= 1) {
+      fprintf ( stderr, "  %s: ", inName );
+      pad ( inName );
+      fflush ( stderr );
+   }
+
+   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
+   outputHandleJustInCase = outStr;
+   deleteOutputOnInterrupt = True;
+   magicNumberOK = uncompressStream ( inStr, outStr );
+   outputHandleJustInCase = NULL;
+
+   /*--- If there was an I/O error, we won't get here. ---*/
+   if ( magicNumberOK ) {
+      if ( srcMode == SM_F2F ) {
+         applySavedTimeInfoToOutputFile ( outName );
+         deleteOutputOnInterrupt = False;
+         if ( !keepInputFiles ) {
+            IntNative retVal = remove ( inName );
+            ERROR_IF_NOT_ZERO ( retVal );
+         }
+      }
+   } else {
+      unzFailsExist = True;
+      deleteOutputOnInterrupt = False;
+      if ( srcMode == SM_F2F ) {
+         IntNative retVal = remove ( outName );
+         ERROR_IF_NOT_ZERO ( retVal );
+      }
+   }
+   deleteOutputOnInterrupt = False;
+
+   if ( magicNumberOK ) {
+      if (verbosity >= 1)
+         fprintf ( stderr, "done\n" );
+   } else {
+      setExit(2);
+      if (verbosity >= 1)
+         fprintf ( stderr, "not a bzip2 file.\n" ); else
+         fprintf ( stderr,
+                   "%s: %s is not a bzip2 file.\n",
+                   progName, inName );
+   }
+
+}
+
+
+/*---------------------------------------------*/
+static 
+void testf ( Char *name )
+{
+   FILE *inStr;
+   Bool allOK;
+   struct MY_STAT statBuf;
+
+   deleteOutputOnInterrupt = False;
+
+   if (name == NULL && srcMode != SM_I2O)
+      panic ( "testf: bad modes\n" );
+
+   copyFileName ( outName, (Char*)"(none)" );
+   switch (srcMode) {
+      case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
+      case SM_F2F: copyFileName ( inName, name ); break;
+      case SM_F2O: copyFileName ( inName, name ); break;
+   }
+
+   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+      if (noisy)
+      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+                progName, inName );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+      fprintf ( stderr, "%s: Can't open input %s: %s.\n",
+                progName, inName, strerror(errno) );
+      setExit(1);
+      return;
+   }
+   if ( srcMode != SM_I2O ) {
+      MY_STAT(inName, &statBuf);
+      if ( MY_S_ISDIR(statBuf.st_mode) ) {
+         fprintf( stderr,
+                  "%s: Input file %s is a directory.\n",
+                  progName,inName);
+         setExit(1);
+         return;
+      }
+   }
+
+   switch ( srcMode ) {
+
+      case SM_I2O:
+         if ( isatty ( fileno ( stdin ) ) ) {
+            fprintf ( stderr,
+                      "%s: I won't read compressed data from a terminal.\n",
+                      progName );
+            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+                              progName, progName );
+            setExit(1);
+            return;
+         };
+         inStr = stdin;
+         break;
+
+      case SM_F2O: case SM_F2F:
+         inStr = fopen ( inName, "rb" );
+         if ( inStr == NULL ) {
+            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+                      progName, inName, strerror(errno) );
+            setExit(1);
+            return;
+         };
+         break;
+
+      default:
+         panic ( "testf: bad srcMode" );
+         break;
+   }
+
+   if (verbosity >= 1) {
+      fprintf ( stderr, "  %s: ", inName );
+      pad ( inName );
+      fflush ( stderr );
+   }
+
+   /*--- Now the input handle is sane.  Do the Biz. ---*/
+   outputHandleJustInCase = NULL;
+   allOK = testStream ( inStr );
+
+   if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
+   if (!allOK) testFailsExist = True;
+}
+
+
+/*---------------------------------------------*/
+static 
+void license ( void )
+{
+   fprintf ( stderr,
+
+    "bzip2, a block-sorting file compressor.  "
+    "Version %s.\n"
+    "   \n"
+    "   Copyright (C) 1996-2010 by Julian Seward.\n"
+    "   \n"
+    "   This program is free software; you can redistribute it and/or modify\n"
+    "   it under the terms set out in the LICENSE file, which is included\n"
+    "   in the bzip2-1.0.6 source distribution.\n"
+    "   \n"
+    "   This program is distributed in the hope that it will be useful,\n"
+    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "   LICENSE file for more details.\n"
+    "   \n",
+    BZ2_bzlibVersion()
+   );
+}
+
+
+/*---------------------------------------------*/
+static 
+void usage ( Char *fullProgName )
+{
+   fprintf (
+      stderr,
+      "bzip2, a block-sorting file compressor.  "
+      "Version %s.\n"
+      "\n   usage: %s [flags and input files in any order]\n"
+      "\n"
+      "   -h --help           print this message\n"
+      "   -d --decompress     force decompression\n"
+      "   -z --compress       force compression\n"
+      "   -k --keep           keep (don't delete) input files\n"
+      "   -f --force          overwrite existing output files\n"
+      "   -t --test           test compressed file integrity\n"
+      "   -c --stdout         output to standard out\n"
+      "   -q --quiet          suppress noncritical error messages\n"
+      "   -v --verbose        be verbose (a 2nd -v gives more)\n"
+      "   -L --license        display software version & license\n"
+      "   -V --version        display software version & license\n"
+      "   -s --small          use less memory (at most 2500k)\n"
+      "   -1 .. -9            set block size to 100k .. 900k\n"
+      "   --fast              alias for -1\n"
+      "   --best              alias for -9\n"
+      "\n"
+      "   If invoked as `bzip2', default action is to compress.\n"
+      "              as `bunzip2',  default action is to decompress.\n"
+      "              as `bzcat', default action is to decompress to stdout.\n"
+      "\n"
+      "   If no file names are given, bzip2 compresses or decompresses\n"
+      "   from standard input to standard output.  You can combine\n"
+      "   short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
+#     if BZ_UNIX
+      "\n"
+#     endif
+      ,
+
+      BZ2_bzlibVersion(),
+      fullProgName
+   );
+}
+
+
+/*---------------------------------------------*/
+static 
+void redundant ( Char* flag )
+{
+   fprintf ( 
+      stderr, 
+      "%s: %s is redundant in versions 0.9.5 and above\n",
+      progName, flag );
+}
+
+
+/*---------------------------------------------*/
+/*--
+  All the garbage from here to main() is purely to
+  implement a linked list of command-line arguments,
+  into which main() copies argv[1 .. argc-1].
+
+  The purpose of this exercise is to facilitate 
+  the expansion of wildcard characters * and ? in 
+  filenames for OSs which don't know how to do it
+  themselves, like MSDOS, Windows 95 and NT.
+
+  The actual Dirty Work is done by the platform-
+  specific macro APPEND_FILESPEC.
+--*/
+
+typedef
+   struct zzzz {
+      Char        *name;
+      struct zzzz *link;
+   }
+   Cell;
+
+
+/*---------------------------------------------*/
+static 
+void *myMalloc ( Int32 n )
+{
+   void* p;
+
+   p = malloc ( (size_t)n );
+   if (p == NULL) outOfMemory ();
+   return p;
+}
+
+
+/*---------------------------------------------*/
+static 
+Cell *mkCell ( void )
+{
+   Cell *c;
+
+   c = (Cell*) myMalloc ( sizeof ( Cell ) );
+   c->name = NULL;
+   c->link = NULL;
+   return c;
+}
+
+
+/*---------------------------------------------*/
+static 
+Cell *snocString ( Cell *root, Char *name )
+{
+   if (root == NULL) {
+      Cell *tmp = mkCell();
+      tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
+      strcpy ( tmp->name, name );
+      return tmp;
+   } else {
+      Cell *tmp = root;
+      while (tmp->link != NULL) tmp = tmp->link;
+      tmp->link = snocString ( tmp->link, name );
+      return root;
+   }
+}
+
+
+/*---------------------------------------------*/
+static 
+void addFlagsFromEnvVar ( Cell** argList, Char* varName ) 
+{
+   Int32 i, j, k;
+   Char *envbase, *p;
+
+   envbase = getenv(varName);
+   if (envbase != NULL) {
+      p = envbase;
+      i = 0;
+      while (True) {
+         if (p[i] == 0) break;
+         p += i;
+         i = 0;
+         while (isspace((Int32)(p[0]))) p++;
+         while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
+         if (i > 0) {
+            k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
+            for (j = 0; j < k; j++) tmpName[j] = p[j];
+            tmpName[k] = 0;
+            APPEND_FLAG(*argList, tmpName);
+         }
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+#define ISFLAG(s) (strcmp(aa->name, (s))==0)
+
+IntNative main ( IntNative argc, Char *argv[] )
+{
+   Int32  i, j;
+   Char   *tmp;
+   Cell   *argList;
+   Cell   *aa;
+   Bool   decode;
+
+   /*-- Be really really really paranoid :-) --*/
+   if (sizeof(Int32) != 4 || sizeof(UInt32) != 4  ||
+       sizeof(Int16) != 2 || sizeof(UInt16) != 2  ||
+       sizeof(Char)  != 1 || sizeof(UChar)  != 1)
+      configError();
+
+   /*-- Initialise --*/
+   outputHandleJustInCase  = NULL;
+   smallMode               = False;
+   keepInputFiles          = False;
+   forceOverwrite          = False;
+   noisy                   = True;
+   verbosity               = 0;
+   blockSize100k           = 9;
+   testFailsExist          = False;
+   unzFailsExist           = False;
+   numFileNames            = 0;
+   numFilesProcessed       = 0;
+   workFactor              = 30;
+   deleteOutputOnInterrupt = False;
+   exitValue               = 0;
+   i = j = 0; /* avoid bogus warning from egcs-1.1.X */
+
+   /*-- Set up signal handlers for mem access errors --*/
+   signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
+#  if BZ_UNIX
+#  ifndef __DJGPP__
+   signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
+#  endif
+#  endif
+
+   copyFileName ( inName,  (Char*)"(none)" );
+   copyFileName ( outName, (Char*)"(none)" );
+
+   copyFileName ( progNameReally, argv[0] );
+   progName = &progNameReally[0];
+   for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
+      if (*tmp == PATH_SEP) progName = tmp + 1;
+
+
+   /*-- Copy flags from env var BZIP2, and 
+        expand filename wildcards in arg list.
+   --*/
+   argList = NULL;
+   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP2" );
+   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP" );
+   for (i = 1; i <= argc-1; i++)
+      APPEND_FILESPEC(argList, argv[i]);
+
+
+   /*-- Find the length of the longest filename --*/
+   longestFileName = 7;
+   numFileNames    = 0;
+   decode          = True;
+   for (aa = argList; aa != NULL; aa = aa->link) {
+      if (ISFLAG("--")) { decode = False; continue; }
+      if (aa->name[0] == '-' && decode) continue;
+      numFileNames++;
+      if (longestFileName < (Int32)strlen(aa->name) )
+         longestFileName = (Int32)strlen(aa->name);
+   }
+
+
+   /*-- Determine source modes; flag handling may change this too. --*/
+   if (numFileNames == 0)
+      srcMode = SM_I2O; else srcMode = SM_F2F;
+
+
+   /*-- Determine what to do (compress/uncompress/test/cat). --*/
+   /*-- Note that subsequent flag handling may change this. --*/
+   opMode = OM_Z;
+
+   if ( (strstr ( progName, "unzip" ) != 0) ||
+        (strstr ( progName, "UNZIP" ) != 0) )
+      opMode = OM_UNZ;
+
+   if ( (strstr ( progName, "z2cat" ) != 0) ||
+        (strstr ( progName, "Z2CAT" ) != 0) ||
+        (strstr ( progName, "zcat" ) != 0)  ||
+        (strstr ( progName, "ZCAT" ) != 0) )  {
+      opMode = OM_UNZ;
+      srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
+   }
+
+
+   /*-- Look at the flags. --*/
+   for (aa = argList; aa != NULL; aa = aa->link) {
+      if (ISFLAG("--")) break;
+      if (aa->name[0] == '-' && aa->name[1] != '-') {
+         for (j = 1; aa->name[j] != '\0'; j++) {
+            switch (aa->name[j]) {
+               case 'c': srcMode          = SM_F2O; break;
+               case 'd': opMode           = OM_UNZ; break;
+               case 'z': opMode           = OM_Z; break;
+               case 'f': forceOverwrite   = True; break;
+               case 't': opMode           = OM_TEST; break;
+               case 'k': keepInputFiles   = True; break;
+               case 's': smallMode        = True; break;
+               case 'q': noisy            = False; break;
+               case '1': blockSize100k    = 1; break;
+               case '2': blockSize100k    = 2; break;
+               case '3': blockSize100k    = 3; break;
+               case '4': blockSize100k    = 4; break;
+               case '5': blockSize100k    = 5; break;
+               case '6': blockSize100k    = 6; break;
+               case '7': blockSize100k    = 7; break;
+               case '8': blockSize100k    = 8; break;
+               case '9': blockSize100k    = 9; break;
+               case 'V':
+               case 'L': license();            break;
+               case 'v': verbosity++; break;
+               case 'h': usage ( progName );
+                         exit ( 0 );
+                         break;
+               default:  fprintf ( stderr, "%s: Bad flag `%s'\n",
+                                   progName, aa->name );
+                         usage ( progName );
+                         exit ( 1 );
+                         break;
+            }
+         }
+      }
+   }
+   
+   /*-- And again ... --*/
+   for (aa = argList; aa != NULL; aa = aa->link) {
+      if (ISFLAG("--")) break;
+      if (ISFLAG("--stdout"))            srcMode          = SM_F2O;  else
+      if (ISFLAG("--decompress"))        opMode           = OM_UNZ;  else
+      if (ISFLAG("--compress"))          opMode           = OM_Z;    else
+      if (ISFLAG("--force"))             forceOverwrite   = True;    else
+      if (ISFLAG("--test"))              opMode           = OM_TEST; else
+      if (ISFLAG("--keep"))              keepInputFiles   = True;    else
+      if (ISFLAG("--small"))             smallMode        = True;    else
+      if (ISFLAG("--quiet"))             noisy            = False;   else
+      if (ISFLAG("--version"))           license();                  else
+      if (ISFLAG("--license"))           license();                  else
+      if (ISFLAG("--exponential"))       workFactor = 1;             else 
+      if (ISFLAG("--repetitive-best"))   redundant(aa->name);        else
+      if (ISFLAG("--repetitive-fast"))   redundant(aa->name);        else
+      if (ISFLAG("--fast"))              blockSize100k = 1;          else
+      if (ISFLAG("--best"))              blockSize100k = 9;          else
+      if (ISFLAG("--verbose"))           verbosity++;                else
+      if (ISFLAG("--help"))              { usage ( progName ); exit ( 0 ); }
+         else
+         if (strncmp ( aa->name, "--", 2) == 0) {
+            fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
+            usage ( progName );
+            exit ( 1 );
+         }
+   }
+
+   if (verbosity > 4) verbosity = 4;
+   if (opMode == OM_Z && smallMode && blockSize100k > 2) 
+      blockSize100k = 2;
+
+   if (opMode == OM_TEST && srcMode == SM_F2O) {
+      fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
+                progName );
+      exit ( 1 );
+   }
+
+   if (srcMode == SM_F2O && numFileNames == 0)
+      srcMode = SM_I2O;
+
+   if (opMode != OM_Z) blockSize100k = 0;
+
+   if (srcMode == SM_F2F) {
+      signal (SIGINT,  mySignalCatcher);
+      signal (SIGTERM, mySignalCatcher);
+#     if BZ_UNIX
+      signal (SIGHUP,  mySignalCatcher);
+#     endif
+   }
+
+   if (opMode == OM_Z) {
+     if (srcMode == SM_I2O) {
+        compress ( NULL );
+     } else {
+        decode = True;
+        for (aa = argList; aa != NULL; aa = aa->link) {
+           if (ISFLAG("--")) { decode = False; continue; }
+           if (aa->name[0] == '-' && decode) continue;
+           numFilesProcessed++;
+           compress ( aa->name );
+        }
+     }
+   } 
+   else
+
+   if (opMode == OM_UNZ) {
+      unzFailsExist = False;
+      if (srcMode == SM_I2O) {
+         uncompress ( NULL );
+      } else {
+         decode = True;
+         for (aa = argList; aa != NULL; aa = aa->link) {
+            if (ISFLAG("--")) { decode = False; continue; }
+            if (aa->name[0] == '-' && decode) continue;
+            numFilesProcessed++;
+            uncompress ( aa->name );
+         }      
+      }
+      if (unzFailsExist) { 
+         setExit(2); 
+         exit(exitValue);
+      }
+   } 
+
+   else {
+      testFailsExist = False;
+      if (srcMode == SM_I2O) {
+         testf ( NULL );
+      } else {
+         decode = True;
+         for (aa = argList; aa != NULL; aa = aa->link) {
+	    if (ISFLAG("--")) { decode = False; continue; }
+            if (aa->name[0] == '-' && decode) continue;
+            numFilesProcessed++;
+            testf ( aa->name );
+	 }
+      }
+      if (testFailsExist && noisy) {
+         fprintf ( stderr,
+           "\n"
+           "You can use the `bzip2recover' program to attempt to recover\n"
+           "data from undamaged sections of corrupted files.\n\n"
+         );
+         setExit(2);
+         exit(exitValue);
+      }
+   }
+
+   /* Free the argument list memory to mollify leak detectors 
+      (eg) Purify, Checker.  Serves no other useful purpose.
+   */
+   aa = argList;
+   while (aa != NULL) {
+      Cell* aa2 = aa->link;
+      if (aa->name != NULL) free(aa->name);
+      free(aa);
+      aa = aa2;
+   }
+
+   return exitValue;
+}
+
+
+/*-----------------------------------------------------------*/
+/*--- end                                         bzip2.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.txt b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.txt
new file mode 100644
index 0000000..d2deb39
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2.txt
@@ -0,0 +1,391 @@
+
+NAME
+       bzip2, bunzip2 - a block-sorting file compressor, v1.0.6
+       bzcat - decompresses files to stdout
+       bzip2recover - recovers data from damaged bzip2 files
+
+
+SYNOPSIS
+       bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
+       bunzip2 [ -fkvsVL ] [ filenames ...  ]
+       bzcat [ -s ] [ filenames ...  ]
+       bzip2recover filename
+
+
+DESCRIPTION
+       bzip2  compresses  files  using  the Burrows-Wheeler block
+       sorting text compression algorithm,  and  Huffman  coding.
+       Compression  is  generally  considerably  better than that
+       achieved by more conventional LZ77/LZ78-based compressors,
+       and  approaches  the performance of the PPM family of sta-
+       tistical compressors.
+
+       The command-line options are deliberately very similar  to
+       those of GNU gzip, but they are not identical.
+
+       bzip2  expects  a list of file names to accompany the com-
+       mand-line flags.  Each file is replaced  by  a  compressed
+       version  of  itself,  with  the  name "original_name.bz2".
+       Each compressed file has the same modification date,  per-
+       missions, and, when possible, ownership as the correspond-
+       ing original, so that these properties  can  be  correctly
+       restored  at  decompression  time.   File name handling is
+       naive in the sense that there is no mechanism for preserv-
+       ing  original file names, permissions, ownerships or dates
+       in filesystems which lack these concepts, or have  serious
+       file name length restrictions, such as MS-DOS.
+
+       bzip2  and  bunzip2 will by default not overwrite existing
+       files.  If you want this to happen, specify the -f flag.
+
+       If no file names  are  specified,  bzip2  compresses  from
+       standard  input  to  standard output.  In this case, bzip2
+       will decline to write compressed output to a terminal,  as
+       this  would  be  entirely  incomprehensible  and therefore
+       pointless.
+
+       bunzip2 (or bzip2 -d) decompresses  all  specified  files.
+       Files which were not created by bzip2 will be detected and
+       ignored, and a warning issued.  bzip2  attempts  to  guess
+       the  filename  for  the decompressed file from that of the
+       compressed file as follows:
+
+              filename.bz2    becomes   filename
+              filename.bz     becomes   filename
+              filename.tbz2   becomes   filename.tar
+              filename.tbz    becomes   filename.tar
+              anyothername    becomes   anyothername.out
+
+       If the file does not end in one of the recognised endings,
+       .bz2,  .bz,  .tbz2 or .tbz, bzip2 complains that it cannot
+       guess the name of the original file, and uses the original
+       name with .out appended.
+
+       As  with compression, supplying no filenames causes decom-
+       pression from standard input to standard output.
+
+       bunzip2 will correctly decompress a file which is the con-
+       catenation of two or more compressed files.  The result is
+       the concatenation of the corresponding uncompressed files.
+       Integrity testing (-t) of concatenated compressed files is
+       also supported.
+
+       You can also compress or decompress files to the  standard
+       output  by giving the -c flag.  Multiple files may be com-
+       pressed and decompressed like this.  The resulting outputs
+       are  fed  sequentially to stdout.  Compression of multiple
+       files in this manner generates a stream containing  multi-
+       ple compressed file representations.  Such a stream can be
+       decompressed correctly only  by  bzip2  version  0.9.0  or
+       later.   Earlier  versions of bzip2 will stop after decom-
+       pressing the first file in the stream.
+
+       bzcat (or bzip2 -dc) decompresses all specified  files  to
+       the standard output.
+
+       bzip2  will  read arguments from the environment variables
+       BZIP2 and BZIP, in  that  order,  and  will  process  them
+       before  any  arguments  read  from the command line.  This
+       gives a convenient way to supply default arguments.
+
+       Compression is always performed, even  if  the  compressed
+       file  is slightly larger than the original.  Files of less
+       than about one hundred bytes tend to get larger, since the
+       compression  mechanism  has  a  constant  overhead  in the
+       region of 50 bytes.  Random data (including the output  of
+       most  file  compressors)  is  coded at about 8.05 bits per
+       byte, giving an expansion of around 0.5%.
+
+       As a self-check for your  protection,  bzip2  uses  32-bit
+       CRCs  to make sure that the decompressed version of a file
+       is identical to the original.  This guards against corrup-
+       tion  of  the compressed data, and against undetected bugs
+       in bzip2 (hopefully very unlikely).  The chances  of  data
+       corruption  going  undetected  is  microscopic,  about one
+       chance in four billion for each file processed.  Be aware,
+       though,  that  the  check occurs upon decompression, so it
+       can only tell you that something is wrong.  It can't  help
+       you  recover  the original uncompressed data.  You can use
+       bzip2recover to try to recover data from damaged files.
+
+       Return values: 0 for a normal exit,  1  for  environmental
+       problems  (file not found, invalid flags, I/O errors, &c),
+       2 to indicate a corrupt compressed file, 3 for an internal
+       consistency error (eg, bug) which caused bzip2 to panic.
+
+
+OPTIONS
+       -c --stdout
+              Compress or decompress to standard output.
+
+       -d --decompress
+              Force  decompression.  bzip2, bunzip2 and bzcat are
+              really the same program,  and  the  decision  about
+              what  actions to take is done on the basis of which
+              name is used.  This flag overrides that  mechanism,
+              and forces bzip2 to decompress.
+
+       -z --compress
+              The   complement   to   -d:   forces   compression,
+              regardless of the invocation name.
+
+       -t --test
+              Check integrity of the specified file(s), but don't
+              decompress  them.   This  really  performs  a trial
+              decompression and throws away the result.
+
+       -f --force
+              Force overwrite of output files.   Normally,  bzip2
+              will  not  overwrite  existing  output files.  Also
+              forces bzip2 to break hard links to files, which it
+              otherwise wouldn't do.
+
+              bzip2  normally  declines to decompress files which
+              don't have the  correct  magic  header  bytes.   If
+              forced  (-f),  however,  it  will  pass  such files
+              through unmodified.  This is how GNU gzip  behaves.
+
+       -k --keep
+              Keep  (don't delete) input files during compression
+              or decompression.
+
+       -s --small
+              Reduce memory usage, for compression, decompression
+              and  testing.   Files  are  decompressed and tested
+              using a modified algorithm which only requires  2.5
+              bytes  per  block byte.  This means any file can be
+              decompressed in 2300k of memory,  albeit  at  about
+              half the normal speed.
+
+              During  compression,  -s  selects  a  block size of
+              200k, which limits memory use to  around  the  same
+              figure,  at  the expense of your compression ratio.
+              In short, if your  machine  is  low  on  memory  (8
+              megabytes  or  less),  use  -s for everything.  See
+              MEMORY MANAGEMENT below.
+
+       -q --quiet
+              Suppress non-essential warning messages.   Messages
+              pertaining  to I/O errors and other critical events
+              will not be suppressed.
+
+       -v --verbose
+              Verbose mode -- show the compression ratio for each
+              file  processed.   Further  -v's  increase the ver-
+              bosity level, spewing out lots of information which
+              is primarily of interest for diagnostic purposes.
+
+       -L --license -V --version
+              Display  the  software  version,  license terms and
+              conditions.
+
+       -1 (or --fast) to -9 (or --best)
+              Set the block size to 100 k, 200 k ..  900  k  when
+              compressing.   Has  no  effect  when decompressing.
+              See MEMORY MANAGEMENT below.  The --fast and --best
+              aliases  are  primarily for GNU gzip compatibility.
+              In particular, --fast doesn't make things  signifi-
+              cantly  faster.   And  --best  merely  selects  the
+              default behaviour.
+
+       --     Treats all subsequent arguments as file names, even
+              if they start with a dash.  This is so you can han-
+              dle files with names beginning  with  a  dash,  for
+              example: bzip2 -- -myfilename.
+
+       --repetitive-fast --repetitive-best
+              These  flags  are  redundant  in versions 0.9.5 and
+              above.  They provided some coarse control over  the
+              behaviour  of the sorting algorithm in earlier ver-
+              sions, which was sometimes useful.  0.9.5 and above
+              have  an  improved  algorithm  which  renders these
+              flags irrelevant.
+
+
+MEMORY MANAGEMENT
+       bzip2 compresses large files in blocks.   The  block  size
+       affects  both  the  compression  ratio  achieved,  and the
+       amount of memory needed for compression and decompression.
+       The  flags  -1  through  -9  specify  the block size to be
+       100,000 bytes through 900,000 bytes (the default)  respec-
+       tively.   At  decompression  time, the block size used for
+       compression is read from  the  header  of  the  compressed
+       file, and bunzip2 then allocates itself just enough memory
+       to decompress the file.  Since block sizes are  stored  in
+       compressed  files,  it follows that the flags -1 to -9 are
+       irrelevant to and so ignored during decompression.
+
+       Compression and decompression requirements, in bytes,  can
+       be estimated as:
+
+              Compression:   400k + ( 8 x block size )
+
+              Decompression: 100k + ( 4 x block size ), or
+                             100k + ( 2.5 x block size )
+
+       Larger  block  sizes  give  rapidly  diminishing  marginal
+       returns.  Most of the compression comes from the first two
+       or  three hundred k of block size, a fact worth bearing in
+       mind when using bzip2  on  small  machines.   It  is  also
+       important  to  appreciate  that  the  decompression memory
+       requirement is set at compression time by  the  choice  of
+       block size.
+
+       For  files  compressed  with  the default 900k block size,
+       bunzip2 will require about 3700 kbytes to decompress.   To
+       support decompression of any file on a 4 megabyte machine,
+       bunzip2 has an option to  decompress  using  approximately
+       half this amount of memory, about 2300 kbytes.  Decompres-
+       sion speed is also halved, so you should use  this  option
+       only where necessary.  The relevant flag is -s.
+
+       In general, try and use the largest block size memory con-
+       straints  allow,  since  that  maximises  the  compression
+       achieved.   Compression and decompression speed are virtu-
+       ally unaffected by block size.
+
+       Another significant point applies to files which fit in  a
+       single  block  --  that  means  most files you'd encounter
+       using a large block  size.   The  amount  of  real  memory
+       touched is proportional to the size of the file, since the
+       file is smaller than a block.  For example, compressing  a
+       file  20,000  bytes  long  with the flag -9 will cause the
+       compressor to allocate around 7600k of  memory,  but  only
+       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
+       decompressor will allocate 3700k but  only  touch  100k  +
+       20000 * 4 = 180 kbytes.
+
+       Here  is a table which summarises the maximum memory usage
+       for different block sizes.  Also  recorded  is  the  total
+       compressed  size for 14 files of the Calgary Text Compres-
+       sion Corpus totalling 3,141,622 bytes.  This column  gives
+       some  feel  for  how  compression  varies with block size.
+       These figures tend to understate the advantage  of  larger
+       block  sizes  for  larger files, since the Corpus is domi-
+       nated by smaller files.
+
+                  Compress   Decompress   Decompress   Corpus
+           Flag     usage      usage       -s usage     Size
+
+            -1      1200k       500k         350k      914704
+            -2      2000k       900k         600k      877703
+            -3      2800k      1300k         850k      860338
+            -4      3600k      1700k        1100k      846899
+            -5      4400k      2100k        1350k      845160
+            -6      5200k      2500k        1600k      838626
+            -7      6100k      2900k        1850k      834096
+            -8      6800k      3300k        2100k      828642
+            -9      7600k      3700k        2350k      828642
+
+
+RECOVERING DATA FROM DAMAGED FILES
+       bzip2 compresses files in blocks, usually 900kbytes  long.
+       Each block is handled independently.  If a media or trans-
+       mission error causes a multi-block  .bz2  file  to  become
+       damaged,  it  may  be  possible  to  recover data from the
+       undamaged blocks in the file.
+
+       The compressed representation of each block  is  delimited
+       by  a  48-bit pattern, which makes it possible to find the
+       block boundaries with reasonable  certainty.   Each  block
+       also  carries its own 32-bit CRC, so damaged blocks can be
+       distinguished from undamaged ones.
+
+       bzip2recover is a  simple  program  whose  purpose  is  to
+       search  for blocks in .bz2 files, and write each block out
+       into its own .bz2 file.  You can then use bzip2 -t to test
+       the integrity of the resulting files, and decompress those
+       which are undamaged.
+
+       bzip2recover takes a single argument, the name of the dam-
+       aged    file,    and    writes    a    number   of   files
+       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
+       the   extracted   blocks.   The   output   filenames   are
+       designed  so  that the use of wildcards in subsequent pro-
+       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
+       ered_data" -- processes the files in the correct order.
+
+       bzip2recover should be of most use dealing with large .bz2
+       files,  as  these will contain many blocks.  It is clearly
+       futile to use it on damaged single-block  files,  since  a
+       damaged  block  cannot  be recovered.  If you wish to min-
+       imise any potential data loss through media  or  transmis-
+       sion errors, you might consider compressing with a smaller
+       block size.
+
+
+PERFORMANCE NOTES
+       The sorting phase of compression gathers together  similar
+       strings  in  the  file.  Because of this, files containing
+       very long runs of  repeated  symbols,  like  "aabaabaabaab
+       ..."   (repeated  several hundred times) may compress more
+       slowly than normal.  Versions 0.9.5 and  above  fare  much
+       better  than previous versions in this respect.  The ratio
+       between worst-case and average-case compression time is in
+       the  region  of  10:1.  For previous versions, this figure
+       was more like 100:1.  You can use the -vvvv option to mon-
+       itor progress in great detail, if you want.
+
+       Decompression speed is unaffected by these phenomena.
+
+       bzip2  usually  allocates  several  megabytes of memory to
+       operate in, and then charges all over it in a fairly  ran-
+       dom  fashion.   This means that performance, both for com-
+       pressing and decompressing, is largely determined  by  the
+       speed  at  which  your  machine  can service cache misses.
+       Because of this, small changes to the code to  reduce  the
+       miss  rate  have  been observed to give disproportionately
+       large performance improvements.  I imagine bzip2 will per-
+       form best on machines with very large caches.
+
+
+CAVEATS
+       I/O  error  messages  are not as helpful as they could be.
+       bzip2 tries hard to detect I/O errors  and  exit  cleanly,
+       but  the  details  of  what  the problem is sometimes seem
+       rather misleading.
+
+       This manual page pertains to version 1.0.6 of bzip2.  Com-
+       pressed  data created by this version is entirely forwards
+       and  backwards  compatible  with   the   previous   public
+       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1,
+       1.0.2 and above, but with the  following  exception: 0.9.0
+       and above can  correctly decompress  multiple concatenated
+       compressed files.  0.1pl2  cannot do this;  it  will  stop
+       after  decompressing just the first file in the stream.
+
+       bzip2recover  versions prior to 1.0.2 used 32-bit integers
+       to represent bit positions in compressed  files,  so  they
+       could  not handle compressed files more than 512 megabytes
+       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
+       platforms  which  support them (GNU supported targets, and
+       Windows).  To establish whether or  not  bzip2recover  was
+       built  with  such  a limitation, run it without arguments.
+       In any event you can build yourself an  unlimited  version
+       if  you  can  recompile  it  with MaybeUInt64 set to be an
+       unsigned 64-bit integer.
+
+
+AUTHOR
+       Julian Seward, jsewardbzip.org.
+
+       http://www.bzip.org
+
+       The ideas embodied in bzip2 are due to (at least) the fol-
+       lowing  people: Michael Burrows and David Wheeler (for the
+       block sorting transformation), David Wheeler  (again,  for
+       the Huffman coder), Peter Fenwick (for the structured cod-
+       ing model in the original bzip, and many refinements), and
+       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
+       arithmetic  coder  in  the  original  bzip).   I  am  much
+       indebted for their help, support and advice.  See the man-
+       ual in the source distribution for pointers to sources  of
+       documentation.  Christian von Roques encouraged me to look
+       for faster sorting algorithms, so as to speed up  compres-
+       sion.  Bela Lubkin encouraged me to improve the worst-case
+       compression performance.  Donna Robinson XMLised the docu-
+       mentation.   The bz* scripts are derived from those of GNU
+       gzip.  Many people sent patches, helped  with  portability
+       problems,  lent  machines,  gave advice and were generally
+       helpful.
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2recover.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2recover.c
new file mode 100644
index 0000000..f9de049
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzip2recover.c
@@ -0,0 +1,514 @@
+/*-----------------------------------------------------------*/
+/*--- Block recoverer program for bzip2                   ---*/
+/*---                                      bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* This program is a complete hack and should be rewritten properly.
+	 It isn't very complicated. */
+
+#include 
+#include 
+#include 
+#include 
+
+
+/* This program records bit locations in the file to be recovered.
+   That means that if 64-bit ints are not supported, we will not
+   be able to recover .bz2 files over 512MB (2^32 bits) long.
+   On GNU supported platforms, we take advantage of the 64-bit
+   int support to circumvent this problem.  Ditto MSVC.
+
+   This change occurred in version 1.0.2; all prior versions have
+   the 512MB limitation.
+*/
+#ifdef __GNUC__
+   typedef  unsigned long long int  MaybeUInt64;
+#  define MaybeUInt64_FMT "%Lu"
+#else
+#ifdef _MSC_VER
+   typedef  unsigned __int64  MaybeUInt64;
+#  define MaybeUInt64_FMT "%I64u"
+#else
+   typedef  unsigned int   MaybeUInt64;
+#  define MaybeUInt64_FMT "%u"
+#endif
+#endif
+
+typedef  unsigned int   UInt32;
+typedef  int            Int32;
+typedef  unsigned char  UChar;
+typedef  char           Char;
+typedef  unsigned char  Bool;
+#define True    ((Bool)1)
+#define False   ((Bool)0)
+
+
+#define BZ_MAX_FILENAME 2000
+
+Char inFileName[BZ_MAX_FILENAME];
+Char outFileName[BZ_MAX_FILENAME];
+Char progName[BZ_MAX_FILENAME];
+
+MaybeUInt64 bytesOut = 0;
+MaybeUInt64 bytesIn  = 0;
+
+
+/*---------------------------------------------------*/
+/*--- Header bytes                                ---*/
+/*---------------------------------------------------*/
+
+#define BZ_HDR_B 0x42                         /* 'B' */
+#define BZ_HDR_Z 0x5a                         /* 'Z' */
+#define BZ_HDR_h 0x68                         /* 'h' */
+#define BZ_HDR_0 0x30                         /* '0' */
+ 
+
+/*---------------------------------------------------*/
+/*--- I/O errors                                  ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static void readError ( void )
+{
+   fprintf ( stderr,
+             "%s: I/O error reading `%s', possible reason follows.\n",
+            progName, inFileName );
+   perror ( progName );
+   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void writeError ( void )
+{
+   fprintf ( stderr,
+             "%s: I/O error reading `%s', possible reason follows.\n",
+            progName, inFileName );
+   perror ( progName );
+   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void mallocFail ( Int32 n )
+{
+   fprintf ( stderr,
+             "%s: malloc failed on request for %d bytes.\n",
+            progName, n );
+   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void tooManyBlocks ( Int32 max_handled_blocks )
+{
+   fprintf ( stderr,
+             "%s: `%s' appears to contain more than %d blocks\n",
+            progName, inFileName, max_handled_blocks );
+   fprintf ( stderr,
+             "%s: and cannot be handled.  To fix, increase\n",
+             progName );
+   fprintf ( stderr, 
+             "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
+             progName );
+   exit ( 1 );
+}
+
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+typedef
+   struct {
+      FILE*  handle;
+      Int32  buffer;
+      Int32  buffLive;
+      Char   mode;
+   }
+   BitStream;
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenReadStream ( FILE* stream )
+{
+   BitStream *bs = malloc ( sizeof(BitStream) );
+   if (bs == NULL) mallocFail ( sizeof(BitStream) );
+   bs->handle = stream;
+   bs->buffer = 0;
+   bs->buffLive = 0;
+   bs->mode = 'r';
+   return bs;
+}
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenWriteStream ( FILE* stream )
+{
+   BitStream *bs = malloc ( sizeof(BitStream) );
+   if (bs == NULL) mallocFail ( sizeof(BitStream) );
+   bs->handle = stream;
+   bs->buffer = 0;
+   bs->buffLive = 0;
+   bs->mode = 'w';
+   return bs;
+}
+
+
+/*---------------------------------------------*/
+static void bsPutBit ( BitStream* bs, Int32 bit )
+{
+   if (bs->buffLive == 8) {
+      Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
+      if (retVal == EOF) writeError();
+      bytesOut++;
+      bs->buffLive = 1;
+      bs->buffer = bit & 0x1;
+   } else {
+      bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
+      bs->buffLive++;
+   };
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Returns 0 or 1, or 2 to indicate EOF.
+--*/
+static Int32 bsGetBit ( BitStream* bs )
+{
+   if (bs->buffLive > 0) {
+      bs->buffLive --;
+      return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
+   } else {
+      Int32 retVal = getc ( bs->handle );
+      if ( retVal == EOF ) {
+         if (errno != 0) readError();
+         return 2;
+      }
+      bs->buffLive = 7;
+      bs->buffer = retVal;
+      return ( ((bs->buffer) >> 7) & 0x1 );
+   }
+}
+
+
+/*---------------------------------------------*/
+static void bsClose ( BitStream* bs )
+{
+   Int32 retVal;
+
+   if ( bs->mode == 'w' ) {
+      while ( bs->buffLive < 8 ) {
+         bs->buffLive++;
+         bs->buffer <<= 1;
+      };
+      retVal = putc ( (UChar) (bs->buffer), bs->handle );
+      if (retVal == EOF) writeError();
+      bytesOut++;
+      retVal = fflush ( bs->handle );
+      if (retVal == EOF) writeError();
+   }
+   retVal = fclose ( bs->handle );
+   if (retVal == EOF) {
+      if (bs->mode == 'w') writeError(); else readError();
+   }
+   free ( bs );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUChar ( BitStream* bs, UChar c )
+{
+   Int32 i;
+   for (i = 7; i >= 0; i--)
+      bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUInt32 ( BitStream* bs, UInt32 c )
+{
+   Int32 i;
+
+   for (i = 31; i >= 0; i--)
+      bsPutBit ( bs, (c >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static Bool endsInBz2 ( Char* name )
+{
+   Int32 n = strlen ( name );
+   if (n <= 4) return False;
+   return
+      (name[n-4] == '.' &&
+       name[n-3] == 'b' &&
+       name[n-2] == 'z' &&
+       name[n-1] == '2');
+}
+
+
+/*---------------------------------------------------*/
+/*---                                             ---*/
+/*---------------------------------------------------*/
+
+/* This logic isn't really right when it comes to Cygwin. */
+#ifdef _WIN32
+#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
+#else
+#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
+#endif
+
+#define BLOCK_HEADER_HI  0x00003141UL
+#define BLOCK_HEADER_LO  0x59265359UL
+
+#define BLOCK_ENDMARK_HI 0x00001772UL
+#define BLOCK_ENDMARK_LO 0x45385090UL
+
+/* Increase if necessary.  However, a .bz2 file with > 50000 blocks
+   would have an uncompressed size of at least 40GB, so the chances
+   are low you'll need to up this.
+*/
+#define BZ_MAX_HANDLED_BLOCKS 50000
+
+MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];
+
+Int32 main ( Int32 argc, Char** argv )
+{
+   FILE*       inFile;
+   FILE*       outFile;
+   BitStream*  bsIn, *bsWr;
+   Int32       b, wrBlock, currBlock, rbCtr;
+   MaybeUInt64 bitsRead;
+
+   UInt32      buffHi, buffLo, blockCRC;
+   Char*       p;
+
+   strcpy ( progName, argv[0] );
+   inFileName[0] = outFileName[0] = 0;
+
+   fprintf ( stderr, 
+             "bzip2recover 1.0.6: extracts blocks from damaged .bz2 files.\n" );
+
+   if (argc != 2) {
+      fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
+                        progName, progName );
+      switch (sizeof(MaybeUInt64)) {
+         case 8:
+            fprintf(stderr, 
+                    "\trestrictions on size of recovered file: None\n");
+            break;
+         case 4:
+            fprintf(stderr, 
+                    "\trestrictions on size of recovered file: 512 MB\n");
+            fprintf(stderr, 
+                    "\tto circumvent, recompile with MaybeUInt64 as an\n"
+                    "\tunsigned 64-bit int.\n");
+            break;
+         default:
+            fprintf(stderr, 
+                    "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
+                    "configuration error.\n");
+            break;
+      }
+      exit(1);
+   }
+
+   if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
+      fprintf ( stderr, 
+                "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
+                progName, (int)strlen(argv[1]) );
+      exit(1);
+   }
+
+   strcpy ( inFileName, argv[1] );
+
+   inFile = fopen ( inFileName, "rb" );
+   if (inFile == NULL) {
+      fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
+      exit(1);
+   }
+
+   bsIn = bsOpenReadStream ( inFile );
+   fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
+
+   bitsRead = 0;
+   buffHi = buffLo = 0;
+   currBlock = 0;
+   bStart[currBlock] = 0;
+
+   rbCtr = 0;
+
+   while (True) {
+      b = bsGetBit ( bsIn );
+      bitsRead++;
+      if (b == 2) {
+         if (bitsRead >= bStart[currBlock] &&
+            (bitsRead - bStart[currBlock]) >= 40) {
+            bEnd[currBlock] = bitsRead-1;
+            if (currBlock > 0)
+               fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
+                                 " to " MaybeUInt64_FMT " (incomplete)\n",
+                         currBlock,  bStart[currBlock], bEnd[currBlock] );
+         } else
+            currBlock--;
+         break;
+      }
+      buffHi = (buffHi << 1) | (buffLo >> 31);
+      buffLo = (buffLo << 1) | (b & 1);
+      if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI 
+             && buffLo == BLOCK_HEADER_LO)
+           || 
+           ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI 
+             && buffLo == BLOCK_ENDMARK_LO)
+         ) {
+         if (bitsRead > 49) {
+            bEnd[currBlock] = bitsRead-49;
+         } else {
+            bEnd[currBlock] = 0;
+         }
+         if (currBlock > 0 &&
+	     (bEnd[currBlock] - bStart[currBlock]) >= 130) {
+            fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
+                              " to " MaybeUInt64_FMT "\n",
+                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
+            rbStart[rbCtr] = bStart[currBlock];
+            rbEnd[rbCtr] = bEnd[currBlock];
+            rbCtr++;
+         }
+         if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
+            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
+         currBlock++;
+
+         bStart[currBlock] = bitsRead;
+      }
+   }
+
+   bsClose ( bsIn );
+
+   /*-- identified blocks run from 1 to rbCtr inclusive. --*/
+
+   if (rbCtr < 1) {
+      fprintf ( stderr,
+                "%s: sorry, I couldn't find any block boundaries.\n",
+                progName );
+      exit(1);
+   };
+
+   fprintf ( stderr, "%s: splitting into blocks\n", progName );
+
+   inFile = fopen ( inFileName, "rb" );
+   if (inFile == NULL) {
+      fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
+      exit(1);
+   }
+   bsIn = bsOpenReadStream ( inFile );
+
+   /*-- placate gcc's dataflow analyser --*/
+   blockCRC = 0; bsWr = 0;
+
+   bitsRead = 0;
+   outFile = NULL;
+   wrBlock = 0;
+   while (True) {
+      b = bsGetBit(bsIn);
+      if (b == 2) break;
+      buffHi = (buffHi << 1) | (buffLo >> 31);
+      buffLo = (buffLo << 1) | (b & 1);
+      if (bitsRead == 47+rbStart[wrBlock]) 
+         blockCRC = (buffHi << 16) | (buffLo >> 16);
+
+      if (outFile != NULL && bitsRead >= rbStart[wrBlock]
+                          && bitsRead <= rbEnd[wrBlock]) {
+         bsPutBit ( bsWr, b );
+      }
+
+      bitsRead++;
+
+      if (bitsRead == rbEnd[wrBlock]+1) {
+         if (outFile != NULL) {
+            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
+            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
+            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
+            bsPutUInt32 ( bsWr, blockCRC );
+            bsClose ( bsWr );
+         }
+         if (wrBlock >= rbCtr) break;
+         wrBlock++;
+      } else
+      if (bitsRead == rbStart[wrBlock]) {
+         /* Create the output file name, correctly handling leading paths. 
+            (31.10.2001 by Sergey E. Kusikov) */
+         Char* split;
+         Int32 ofs, k;
+         for (k = 0; k < BZ_MAX_FILENAME; k++) 
+            outFileName[k] = 0;
+         strcpy (outFileName, inFileName);
+         split = strrchr (outFileName, BZ_SPLIT_SYM);
+         if (split == NULL) {
+            split = outFileName;
+         } else {
+            ++split;
+	 }
+	 /* Now split points to the start of the basename. */
+         ofs  = split - outFileName;
+         sprintf (split, "rec%5d", wrBlock+1);
+         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
+         strcat (outFileName, inFileName + ofs);
+
+         if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
+
+         fprintf ( stderr, "   writing block %d to `%s' ...\n",
+                           wrBlock+1, outFileName );
+
+         outFile = fopen ( outFileName, "wb" );
+         if (outFile == NULL) {
+            fprintf ( stderr, "%s: can't write `%s'\n",
+                      progName, outFileName );
+            exit(1);
+         }
+         bsWr = bsOpenWriteStream ( outFile );
+         bsPutUChar ( bsWr, BZ_HDR_B );    
+         bsPutUChar ( bsWr, BZ_HDR_Z );    
+         bsPutUChar ( bsWr, BZ_HDR_h );    
+         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
+         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
+         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
+         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
+      }
+   }
+
+   fprintf ( stderr, "%s: finished\n", progName );
+   return 0;
+}
+
+
+
+/*-----------------------------------------------------------*/
+/*--- end                                  bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.c
new file mode 100644
index 0000000..d85e734
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.c
@@ -0,0 +1,1580 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* CHANGES
+   0.9.0    -- original version.
+   0.9.0a/b -- no changes in this file.
+   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+     fixed bzWrite/bzRead to ignore zero-length requests.
+     fixed bzread to correctly handle read requests after EOF.
+     wrong parameter order in call to bzDecompressInit in
+     bzBuffToBuffDecompress.  Fixed.
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+   fprintf(stderr, 
+      "\n\nbzip2/libbzip2: internal error number %d.\n"
+      "This is a bug in bzip2/libbzip2, %s.\n"
+      "Please report it to me at: jseward@bzip.org.  If this happened\n"
+      "when you were using some program which uses libbzip2 as a\n"
+      "component, you should also report this bug to the author(s)\n"
+      "of that program.  Please make an effort to report this bug;\n"
+      "timely and accurate bug reports eventually lead to higher\n"
+      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
+      errcode,
+      BZ2_bzlibVersion()
+   );
+
+   if (errcode == 1007) {
+   fprintf(stderr,
+      "\n*** A special note about internal error number 1007 ***\n"
+      "\n"
+      "Experience suggests that a common cause of i.e. 1007\n"
+      "is unreliable memory or other hardware.  The 1007 assertion\n"
+      "just happens to cross-check the results of huge numbers of\n"
+      "memory reads/writes, and so acts (unintendedly) as a stress\n"
+      "test of your memory system.\n"
+      "\n"
+      "I suggest the following: try compressing the file again,\n"
+      "possibly monitoring progress in detail with the -vv flag.\n"
+      "\n"
+      "* If the error cannot be reproduced, and/or happens at different\n"
+      "  points in compression, you may have a flaky memory system.\n"
+      "  Try a memory-test program.  I have used Memtest86\n"
+      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
+      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
+      "  power-on test, and may find failures that the BIOS doesn't.\n"
+      "\n"
+      "* If the error can be repeatably reproduced, this is a bug in\n"
+      "  bzip2, and I would very much like to hear about it.  Please\n"
+      "  let me know, and, ideally, save a copy of the file causing the\n"
+      "  problem -- without which I will be unable to investigate it.\n"
+      "\n"
+   );
+   }
+
+   exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+   if (sizeof(int)   != 4) return 0;
+   if (sizeof(short) != 2) return 0;
+   if (sizeof(char)  != 1) return 0;
+   return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+   void* v = malloc ( items * size );
+   return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+   if (addr != NULL) free ( addr );
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+   Int32 i;
+   s->nblock = 0;
+   s->numZ = 0;
+   s->state_out_pos = 0;
+   BZ_INITIALISE_CRC ( s->blockCRC );
+   for (i = 0; i < 256; i++) s->inUse[i] = False;
+   s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+   s->state_in_ch  = 256;
+   s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+   if (s->state_in_ch < 256 && s->state_in_len > 0)
+      return False; else
+      return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit) 
+                    ( bz_stream* strm, 
+                     int        blockSize100k,
+                     int        verbosity,
+                     int        workFactor )
+{
+   Int32   n;
+   EState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL || 
+       blockSize100k < 1 || blockSize100k > 9 ||
+       workFactor < 0 || workFactor > 250)
+     return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(EState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm = strm;
+
+   s->arr1 = NULL;
+   s->arr2 = NULL;
+   s->ftab = NULL;
+
+   n       = 100000 * blockSize100k;
+   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
+   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
+
+   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+      if (s->arr1 != NULL) BZFREE(s->arr1);
+      if (s->arr2 != NULL) BZFREE(s->arr2);
+      if (s->ftab != NULL) BZFREE(s->ftab);
+      if (s       != NULL) BZFREE(s);
+      return BZ_MEM_ERROR;
+   }
+
+   s->blockNo           = 0;
+   s->state             = BZ_S_INPUT;
+   s->mode              = BZ_M_RUNNING;
+   s->combinedCRC       = 0;
+   s->blockSize100k     = blockSize100k;
+   s->nblockMAX         = 100000 * blockSize100k - 19;
+   s->verbosity         = verbosity;
+   s->workFactor        = workFactor;
+
+   s->block             = (UChar*)s->arr2;
+   s->mtfv              = (UInt16*)s->arr1;
+   s->zbits             = NULL;
+   s->ptr               = (UInt32*)s->arr1;
+
+   strm->state          = s;
+   strm->total_in_lo32  = 0;
+   strm->total_in_hi32  = 0;
+   strm->total_out_lo32 = 0;
+   strm->total_out_hi32 = 0;
+   init_RL ( s );
+   prepare_new_block ( s );
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+   Int32 i;
+   UChar ch = (UChar)(s->state_in_ch);
+   for (i = 0; i < s->state_in_len; i++) {
+      BZ_UPDATE_CRC( s->blockCRC, ch );
+   }
+   s->inUse[s->state_in_ch] = True;
+   switch (s->state_in_len) {
+      case 1:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 2:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      case 3:
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         break;
+      default:
+         s->inUse[s->state_in_len-4] = True;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = (UChar)ch; s->nblock++;
+         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+         s->nblock++;
+         break;
+   }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+   if (s->state_in_ch < 256) add_pair_to_block ( s );
+   init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
+{                                                 \
+   UInt32 zchh = (UInt32)(zchh0);                 \
+   /*-- fast track the common case --*/           \
+   if (zchh != zs->state_in_ch &&                 \
+       zs->state_in_len == 1) {                   \
+      UChar ch = (UChar)(zs->state_in_ch);        \
+      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
+      zs->inUse[zs->state_in_ch] = True;          \
+      zs->block[zs->nblock] = (UChar)ch;          \
+      zs->nblock++;                               \
+      zs->state_in_ch = zchh;                     \
+   }                                              \
+   else                                           \
+   /*-- general, uncommon cases --*/              \
+   if (zchh != zs->state_in_ch ||                 \
+      zs->state_in_len == 255) {                  \
+      if (zs->state_in_ch < 256)                  \
+         add_pair_to_block ( zs );                \
+      zs->state_in_ch = zchh;                     \
+      zs->state_in_len = 1;                       \
+   } else {                                       \
+      zs->state_in_len++;                         \
+   }                                              \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+   Bool progress_in = False;
+
+   if (s->mode == BZ_M_RUNNING) {
+
+      /*-- fast track the common case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+      }
+
+   } else {
+
+      /*-- general, uncommon case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s->nblock >= s->nblockMAX) break;
+         /*-- no input? --*/
+         if (s->strm->avail_in == 0) break;
+         /*-- flush/finish end? --*/
+         if (s->avail_in_expect == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
+         s->strm->next_in++;
+         s->strm->avail_in--;
+         s->strm->total_in_lo32++;
+         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+         s->avail_in_expect--;
+      }
+   }
+   return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+   Bool progress_out = False;
+
+   while (True) {
+
+      /*-- no output space? --*/
+      if (s->strm->avail_out == 0) break;
+
+      /*-- block done? --*/
+      if (s->state_out_pos >= s->numZ) break;
+
+      progress_out = True;
+      *(s->strm->next_out) = s->zbits[s->state_out_pos];
+      s->state_out_pos++;
+      s->strm->avail_out--;
+      s->strm->next_out++;
+      s->strm->total_out_lo32++;
+      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+   }
+
+   return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+   Bool progress_in  = False;
+   Bool progress_out = False;
+   EState* s = strm->state;
+   
+   while (True) {
+
+      if (s->state == BZ_S_OUTPUT) {
+         progress_out |= copy_output_until_stop ( s );
+         if (s->state_out_pos < s->numZ) break;
+         if (s->mode == BZ_M_FINISHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+         prepare_new_block ( s );
+         s->state = BZ_S_INPUT;
+         if (s->mode == BZ_M_FLUSHING && 
+             s->avail_in_expect == 0 &&
+             isempty_RL(s)) break;
+      }
+
+      if (s->state == BZ_S_INPUT) {
+         progress_in |= copy_input_until_stop ( s );
+         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+            flush_RL ( s );
+            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->nblock >= s->nblockMAX) {
+            BZ2_compressBlock ( s, False );
+            s->state = BZ_S_OUTPUT;
+         }
+         else
+         if (s->strm->avail_in == 0) {
+            break;
+         }
+      }
+
+   }
+
+   return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+   Bool progress;
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   preswitch:
+   switch (s->mode) {
+
+      case BZ_M_IDLE:
+         return BZ_SEQUENCE_ERROR;
+
+      case BZ_M_RUNNING:
+         if (action == BZ_RUN) {
+            progress = handle_compress ( strm );
+            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+         } 
+         else
+	 if (action == BZ_FLUSH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FLUSHING;
+            goto preswitch;
+         }
+         else
+         if (action == BZ_FINISH) {
+            s->avail_in_expect = strm->avail_in;
+            s->mode = BZ_M_FINISHING;
+            goto preswitch;
+         }
+         else 
+            return BZ_PARAM_ERROR;
+
+      case BZ_M_FLUSHING:
+         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+         s->mode = BZ_M_RUNNING;
+         return BZ_RUN_OK;
+
+      case BZ_M_FINISHING:
+         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect != s->strm->avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (!progress) return BZ_SEQUENCE_ERROR;
+         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+         s->mode = BZ_M_IDLE;
+         return BZ_STREAM_END;
+   }
+   return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+{
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->arr1 != NULL) BZFREE(s->arr1);
+   if (s->arr2 != NULL) BZFREE(s->arr2);
+   if (s->ftab != NULL) BZFREE(s->ftab);
+   BZFREE(strm->state);
+
+   strm->state = NULL;   
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit) 
+                     ( bz_stream* strm, 
+                       int        verbosity,
+                       int        small )
+{
+   DState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(DState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s->strm                  = strm;
+   strm->state              = s;
+   s->state                 = BZ_X_MAGIC_1;
+   s->bsLive                = 0;
+   s->bsBuff                = 0;
+   s->calculatedCombinedCRC = 0;
+   strm->total_in_lo32      = 0;
+   strm->total_in_hi32      = 0;
+   strm->total_out_lo32     = 0;
+   strm->total_out_hi32     = 0;
+   s->smallDecompress       = (Bool)small;
+   s->ll4                   = NULL;
+   s->ll16                  = NULL;
+   s->tt                    = NULL;
+   s->currBlockNo           = 0;
+   s->verbosity             = verbosity;
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+               
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      /* restore */
+      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
+      UChar         c_state_out_ch       = s->state_out_ch;
+      Int32         c_state_out_len      = s->state_out_len;
+      Int32         c_nblock_used        = s->nblock_used;
+      Int32         c_k0                 = s->k0;
+      UInt32*       c_tt                 = s->tt;
+      UInt32        c_tPos               = s->tPos;
+      char*         cs_next_out          = s->strm->next_out;
+      unsigned int  cs_avail_out         = s->strm->avail_out;
+      Int32         ro_blockSize100k     = s->blockSize100k;
+      /* end restore */
+
+      UInt32       avail_out_INIT = cs_avail_out;
+      Int32        s_save_nblockPP = s->save_nblock+1;
+      unsigned int total_out_lo32_old;
+
+      while (True) {
+
+         /* try to finish existing run */
+         if (c_state_out_len > 0) {
+            while (True) {
+               if (cs_avail_out == 0) goto return_notr;
+               if (c_state_out_len == 1) break;
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               c_state_out_len--;
+               cs_next_out++;
+               cs_avail_out--;
+            }
+            s_state_out_len_eq_one:
+            {
+               if (cs_avail_out == 0) { 
+                  c_state_out_len = 1; goto return_notr;
+               };
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               cs_next_out++;
+               cs_avail_out--;
+            }
+         }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used > s_save_nblockPP)
+            return True;
+
+         /* can a new run be started? */
+         if (c_nblock_used == s_save_nblockPP) {
+            c_state_out_len = 0; goto return_notr;
+         };   
+         c_state_out_ch = c_k0;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (k1 != c_k0) { 
+            c_k0 = k1; goto s_state_out_len_eq_one; 
+         };
+         if (c_nblock_used == s_save_nblockPP) 
+            goto s_state_out_len_eq_one;
+   
+         c_state_out_len = 2;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         c_state_out_len = 3;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         c_state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST_C(c_k0); c_nblock_used++;
+      }
+
+      return_notr:
+      total_out_lo32_old = s->strm->total_out_lo32;
+      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+      if (s->strm->total_out_lo32 < total_out_lo32_old)
+         s->strm->total_out_hi32++;
+
+      /* save */
+      s->calculatedBlockCRC = c_calculatedBlockCRC;
+      s->state_out_ch       = c_state_out_ch;
+      s->state_out_len      = c_state_out_len;
+      s->nblock_used        = c_nblock_used;
+      s->k0                 = c_k0;
+      s->tt                 = c_tt;
+      s->tPos               = c_tPos;
+      s->strm->next_out     = cs_next_out;
+      s->strm->avail_out    = cs_avail_out;
+      /* end save */
+   }
+   return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+   Int32 nb, na, mid;
+   nb = 0;
+   na = 256;
+   do {
+      mid = (nb + na) >> 1;
+      if (indx >= cftab[mid]) nb = mid; else na = mid;
+   }
+   while (na - nb != 1);
+   return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+   UChar k1;
+
+   if (s->blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
+         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+      }
+
+   } else {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s->strm->avail_out == 0) return False;
+            if (s->state_out_len == 0) break;
+            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+            s->state_out_len--;
+            s->strm->next_out++;
+            s->strm->avail_out--;
+            s->strm->total_out_lo32++;
+            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s->nblock_used == s->save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s->nblock_used > s->save_nblock+1)
+            return True;
+   
+         s->state_out_len = 1;
+         s->state_out_ch = s->k0;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 2;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         s->state_out_len = 3;
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         if (s->nblock_used == s->save_nblock+1) continue;
+         if (k1 != s->k0) { s->k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); s->nblock_used++;
+         s->state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s->k0); s->nblock_used++;
+      }
+
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+   Bool    corrupt;
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   while (True) {
+      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+      if (s->state == BZ_X_OUTPUT) {
+         if (s->smallDecompress)
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
+         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+            if (s->verbosity >= 3) 
+               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
+                          s->calculatedBlockCRC );
+            if (s->verbosity >= 2) VPrintf0 ( "]" );
+            if (s->calculatedBlockCRC != s->storedBlockCRC)
+               return BZ_DATA_ERROR;
+            s->calculatedCombinedCRC 
+               = (s->calculatedCombinedCRC << 1) | 
+                    (s->calculatedCombinedCRC >> 31);
+            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+            s->state = BZ_X_BLKHDR_1;
+         } else {
+            return BZ_OK;
+         }
+      }
+      if (s->state >= BZ_X_MAGIC_1) {
+         Int32 r = BZ2_decompress ( s );
+         if (r == BZ_STREAM_END) {
+            if (s->verbosity >= 3)
+               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
+                          s->storedCombinedCRC, s->calculatedCombinedCRC );
+            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+               return BZ_DATA_ERROR;
+            return r;
+         }
+         if (s->state != BZ_X_OUTPUT) return r;
+      }
+   }
+
+   AssertH ( 0, 6001 );
+
+   return 0;  /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+{
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm->state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s->strm != strm) return BZ_PARAM_ERROR;
+
+   if (s->tt   != NULL) BZFREE(s->tt);
+   if (s->ll16 != NULL) BZFREE(s->ll16);
+   if (s->ll4  != NULL) BZFREE(s->ll4);
+
+   BZFREE(strm->state);
+   strm->state = NULL;
+
+   return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff                              ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee)                    \
+{                                         \
+   if (bzerror != NULL) *bzerror = eee;   \
+   if (bzf != NULL) bzf->lastErr = eee;   \
+}
+
+typedef 
+   struct {
+      FILE*     handle;
+      Char      buf[BZ_MAX_UNUSED];
+      Int32     bufN;
+      Bool      writing;
+      bz_stream strm;
+      Int32     lastErr;
+      Bool      initialisedOk;
+   }
+   bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen) 
+                    ( int*  bzerror,      
+                      FILE* f, 
+                      int   blockSize100k, 
+                      int   verbosity,
+                      int   workFactor )
+{
+   Int32   ret;
+   bzFile* bzf = NULL;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL ||
+       (blockSize100k < 1 || blockSize100k > 9) ||
+       (workFactor < 0 || workFactor > 250) ||
+       (verbosity < 0 || verbosity > 4))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+   bzf->initialisedOk = False;
+   bzf->bufN          = 0;
+   bzf->handle        = f;
+   bzf->writing       = True;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+
+   if (workFactor == 0) workFactor = 30;
+   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = 0;
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+             ( int*    bzerror, 
+               BZFILE* b, 
+               void*   buf, 
+               int     len )
+{
+   Int32 n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return; };
+
+   bzf->strm.avail_in = len;
+   bzf->strm.next_in  = buf;
+
+   while (True) {
+      bzf->strm.avail_out = BZ_MAX_UNUSED;
+      bzf->strm.next_out = bzf->buf;
+      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+      if (ret != BZ_RUN_OK)
+         { BZ_SETERR(ret); return; };
+
+      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                       n, bzf->handle );
+         if (n != n2 || ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return; };
+      }
+
+      if (bzf->strm.avail_in == 0)
+         { BZ_SETERR(BZ_OK); return; };
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in,
+                    unsigned int* nbytes_out )
+{
+   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
+                        nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in_lo32,
+                    unsigned int* nbytes_in_hi32,
+                    unsigned int* nbytes_out_lo32,
+                    unsigned int* nbytes_out_hi32 )
+{
+   Int32   n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+   if (!(bzf->writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf->handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+   if ((!abandon) && bzf->lastErr == BZ_OK) {
+      while (True) {
+         bzf->strm.avail_out = BZ_MAX_UNUSED;
+         bzf->strm.next_out = bzf->buf;
+         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+            { BZ_SETERR(ret); return; };
+
+         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
+                          n, bzf->handle );
+            if (n != n2 || ferror(bzf->handle))
+               { BZ_SETERR(BZ_IO_ERROR); return; };
+         }
+
+         if (ret == BZ_STREAM_END) break;
+      }
+   }
+
+   if ( !abandon && !ferror ( bzf->handle ) ) {
+      fflush ( bzf->handle );
+      if (ferror(bzf->handle))
+         { BZ_SETERR(BZ_IO_ERROR); return; };
+   }
+
+   if (nbytes_in_lo32 != NULL)
+      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+   if (nbytes_in_hi32 != NULL)
+      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+   if (nbytes_out_lo32 != NULL)
+      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+   if (nbytes_out_hi32 != NULL)
+      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+   BZ_SETERR(BZ_OK);
+   BZ2_bzCompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen) 
+                   ( int*  bzerror, 
+                     FILE* f, 
+                     int   verbosity,
+                     int   small,
+                     void* unused,
+                     int   nUnused )
+{
+   bzFile* bzf = NULL;
+   int     ret;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL || 
+       (small != 0 && small != 1) ||
+       (verbosity < 0 || verbosity > 4) ||
+       (unused == NULL && nUnused != 0) ||
+       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL) 
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+
+   bzf->initialisedOk = False;
+   bzf->handle        = f;
+   bzf->bufN          = 0;
+   bzf->writing       = False;
+   bzf->strm.bzalloc  = NULL;
+   bzf->strm.bzfree   = NULL;
+   bzf->strm.opaque   = NULL;
+   
+   while (nUnused > 0) {
+      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+      unused = ((void*)( 1 + ((UChar*)(unused))  ));
+      nUnused--;
+   }
+
+   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf->strm.avail_in = bzf->bufN;
+   bzf->strm.next_in  = bzf->buf;
+
+   bzf->initialisedOk = True;
+   return bzf;   
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+   if (bzf->initialisedOk)
+      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead) 
+           ( int*    bzerror, 
+             BZFILE* b, 
+             void*   buf, 
+             int     len )
+{
+   Int32   n, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+
+   if (bzf == NULL || buf == NULL || len < 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+   if (bzf->writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return 0; };
+
+   bzf->strm.avail_out = len;
+   bzf->strm.next_out = buf;
+
+   while (True) {
+
+      if (ferror(bzf->handle)) 
+         { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+         n = fread ( bzf->buf, sizeof(UChar), 
+                     BZ_MAX_UNUSED, bzf->handle );
+         if (ferror(bzf->handle))
+            { BZ_SETERR(BZ_IO_ERROR); return 0; };
+         bzf->bufN = n;
+         bzf->strm.avail_in = bzf->bufN;
+         bzf->strm.next_in = bzf->buf;
+      }
+
+      ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+      if (ret != BZ_OK && ret != BZ_STREAM_END)
+         { BZ_SETERR(ret); return 0; };
+
+      if (ret == BZ_OK && myfeof(bzf->handle) && 
+          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+      if (ret == BZ_STREAM_END)
+         { BZ_SETERR(BZ_STREAM_END);
+           return len - bzf->strm.avail_out; };
+      if (bzf->strm.avail_out == 0)
+         { BZ_SETERR(BZ_OK); return len; };
+      
+   }
+
+   return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused) 
+                     ( int*    bzerror, 
+                       BZFILE* b, 
+                       void**  unused, 
+                       int*    nUnused )
+{
+   bzFile* bzf = (bzFile*)b;
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (bzf->lastErr != BZ_STREAM_END)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (unused == NULL || nUnused == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+   BZ_SETERR(BZ_OK);
+   *nUnused = bzf->strm.avail_in;
+   *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress) 
+                         ( char*         dest, 
+                           unsigned int* destLen,
+                           char*         source, 
+                           unsigned int  sourceLen,
+                           int           blockSize100k, 
+                           int           verbosity, 
+                           int           workFactor )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       blockSize100k < 1 || blockSize100k > 9 ||
+       verbosity < 0 || verbosity > 4 ||
+       workFactor < 0 || workFactor > 250) 
+      return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+   if (ret == BZ_FINISH_OK) goto output_overflow;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;   
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow:
+   BZ2_bzCompressEnd ( &strm );
+   return BZ_OUTBUFF_FULL;
+
+   errhandler:
+   BZ2_bzCompressEnd ( &strm );
+   return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress) 
+                           ( char*         dest, 
+                             unsigned int* destLen,
+                             char*         source, 
+                             unsigned int  sourceLen,
+                             int           small,
+                             int           verbosity )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       (small != 0 && small != 1) ||
+       verbosity < 0 || verbosity > 4) 
+          return BZ_PARAM_ERROR;
+
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzDecompress ( &strm );
+   if (ret == BZ_OK) goto output_overflow_or_eof;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;
+   BZ2_bzDecompressEnd ( &strm );
+   return BZ_OK;
+
+   output_overflow_or_eof:
+   if (strm.avail_out > 0) {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_UNEXPECTED_EOF;
+   } else {
+      BZ2_bzDecompressEnd ( &strm );
+      return BZ_OUTBUFF_FULL;
+   };      
+
+   errhandler:
+   BZ2_bzDecompressEnd ( &strm );
+   return ret; 
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+   return version like "0.9.5d, 4-Sept-1999".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+   return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#   include 
+#   include 
+#if _MSC_VER > 1410
+#   define SET_BINARY_MODE(file) _setmode(_fileno(file),O_BINARY)
+#else
+#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#endif
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+               ( const char *path,   /* no use when bzdopen */
+                 int fd,             /* no use when bzdopen */
+                 const char *mode,
+                 int open_mode)      /* bzopen: 0, bzdopen:1 */
+{
+   int    bzerr;
+   char   unused[BZ_MAX_UNUSED];
+   int    blockSize100k = 9;
+   int    writing       = 0;
+   char   mode2[10]     = "";
+   FILE   *fp           = NULL;
+   BZFILE *bzfp         = NULL;
+   int    verbosity     = 0;
+   int    workFactor    = 30;
+   int    smallMode     = 0;
+   int    nUnused       = 0; 
+
+   if (mode == NULL) return NULL;
+   while (*mode) {
+      switch (*mode) {
+      case 'r':
+         writing = 0; break;
+      case 'w':
+         writing = 1; break;
+      case 's':
+         smallMode = 1; break;
+      default:
+         if (isdigit((int)(*mode))) {
+            blockSize100k = *mode-BZ_HDR_0;
+         }
+      }
+      mode++;
+   }
+   strcat(mode2, writing ? "w" : "r" );
+   strcat(mode2,"b");   /* binary mode */
+
+   if (open_mode==0) {
+      if (path==NULL || strcmp(path,"")==0) {
+        fp = (writing ? stdout : stdin);
+        SET_BINARY_MODE(fp);
+      } else {
+        fp = fopen(path,mode2);
+      }
+   } else {
+#ifdef BZ_STRICT_ANSI
+      fp = NULL;
+#else
+#if _MSC_VER > 1410
+      fp = _fdopen(fd,mode2);
+#else
+	   fp = fdopen(fd,mode2);
+#endif
+#endif
+   }
+   if (fp == NULL) return NULL;
+
+   if (writing) {
+      /* Guard against total chaos and anarchy -- JRS */
+      if (blockSize100k < 1) blockSize100k = 1;
+      if (blockSize100k > 9) blockSize100k = 9; 
+      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+                             verbosity,workFactor);
+   } else {
+      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+                            unused,nUnused);
+   }
+   if (bzfp == NULL) {
+      if (fp != stdin && fp != stdout) fclose(fp);
+      return NULL;
+   }
+   return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   open file for read or write.
+      ex) bzopen("file","w9")
+      case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+               ( const char *path,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+               ( int fd,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+   int bzerr, nread;
+   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+   nread = BZ2_bzRead(&bzerr,b,buf,len);
+   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+      return nread;
+   } else {
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+   int bzerr;
+
+   BZ2_bzWrite(&bzerr,b,buf,len);
+   if(bzerr == BZ_OK){
+      return len;
+   }else{
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+   /* do nothing now... */
+   return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+   int bzerr;
+   FILE *fp;
+   
+   if (b==NULL) {return;}
+   fp = ((bzFile *)b)->handle;
+   if(((bzFile*)b)->writing){
+      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+      if(bzerr != BZ_OK){
+         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+      }
+   }else{
+      BZ2_bzReadClose(&bzerr,b);
+   }
+   if(fp!=stdin && fp!=stdout){
+      fclose(fp);
+   }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   return last error code 
+--*/
+static const char *bzerrorstrings[] = {
+       "OK"
+      ,"SEQUENCE_ERROR"
+      ,"PARAM_ERROR"
+      ,"MEM_ERROR"
+      ,"DATA_ERROR"
+      ,"DATA_ERROR_MAGIC"
+      ,"IO_ERROR"
+      ,"UNEXPECTED_EOF"
+      ,"OUTBUFF_FULL"
+      ,"CONFIG_ERROR"
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+   int err = ((bzFile *)b)->lastErr;
+
+   if(err>0) err = 0;
+   *errnum = err;
+   return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.h b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.h
new file mode 100644
index 0000000..acb1935
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib.h
@@ -0,0 +1,285 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// we don't need the FILE* interface
+#define BZ_NO_STDIO
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef 
+   struct {
+      char *next_in;
+      unsigned int avail_in;
+      unsigned int total_in_lo32;
+      unsigned int total_in_hi32;
+
+      char *next_out;
+      unsigned int avail_out;
+      unsigned int total_out_lo32;
+      unsigned int total_out_hi32;
+
+      void *state;
+
+      void *(*bzalloc)(void *,int,int);
+      void (*bzfree)(void *,void *);
+      void *opaque;
+   } 
+   bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include 
+#endif
+
+#ifdef _WIN32
+#   include 
+#   ifdef small
+      /* windows.h define small to char */
+#      undef small
+#   endif
+#   ifdef BZ_EXPORT
+#   define BZ_API(func) WINAPI func
+#   define BZ_EXTERN extern
+#   else
+   /* import windows dll dynamically */
+#   define BZ_API(func) (WINAPI * func)
+#   define BZ_EXTERN
+#   endif
+#else
+#   define BZ_API(func) func
+#   define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
+      bz_stream* strm, 
+      int        blockSize100k, 
+      int        verbosity, 
+      int        workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
+      bz_stream* strm, 
+      int action 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
+      bz_stream *strm, 
+      int       verbosity, 
+      int       small
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
+      bz_stream *strm 
+   );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
+      int*  bzerror,   
+      FILE* f, 
+      int   verbosity, 
+      int   small,
+      void* unused,    
+      int   nUnused 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
+      int*    bzerror, 
+      BZFILE* b 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void**  unused,  
+      int*    nUnused 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
+      int*  bzerror,      
+      FILE* f, 
+      int   blockSize100k, 
+      int   verbosity, 
+      int   workFactor 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in, 
+      unsigned int* nbytes_out 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in_lo32, 
+      unsigned int* nbytes_in_hi32, 
+      unsigned int* nbytes_out_lo32, 
+      unsigned int* nbytes_out_hi32
+   );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           blockSize100k, 
+      int           verbosity, 
+      int           workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           small, 
+      int           verbosity 
+   );
+
+
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+      void
+   );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+      const char *path,
+      const char *mode
+   );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+      int        fd,
+      const char *mode
+   );
+         
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+      BZFILE* b, 
+      void* buf, 
+      int len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+      BZFILE* b
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+      BZFILE* b
+   );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+      BZFILE *b, 
+      int    *errnum
+   );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib_private.h b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib_private.h
new file mode 100644
index 0000000..5d0217f
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzlib_private.h
@@ -0,0 +1,509 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include 
+
+#ifndef BZ_NO_STDIO
+#include 
+#include 
+#include 
+#endif
+
+#include "bzlib.h"
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION  "1.0.6, 6-Sept-2010"
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__  /* */
+#endif 
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+   { if (!(cond)) {       \
+      fprintf ( stderr,   \
+        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+      exit(1); \
+   }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+   fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+   fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+   fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+   fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+   fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+   fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg)                do { } while (0)
+#define VPrintf0(zf)                     do { } while (0)
+#define VPrintf1(zf,za1)                 do { } while (0)
+#define VPrintf2(zf,za1,za2)             do { } while (0)
+#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+  
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS                          \
+   Int32 rNToGo;                               \
+   Int32 rTPos                                 \
+
+#define BZ_RAND_INIT_MASK                      \
+   s->rNToGo = 0;                              \
+   s->rTPos  = 0                               \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK                       \
+   if (s->rNToGo == 0) {                       \
+      s->rNToGo = BZ2_rNums[s->rTPos];         \
+      s->rTPos++;                              \
+      if (s->rTPos == 512) s->rTPos = 0;       \
+   }                                           \
+   s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar)              \
+{                                              \
+   crcVar = 0xffffffffL;                       \
+}
+
+#define BZ_FINALISE_CRC(crcVar)                \
+{                                              \
+   crcVar = ~(crcVar);                         \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha)              \
+{                                              \
+   crcVar = (crcVar << 8) ^                    \
+            BZ2_crc32Table[(crcVar >> 24) ^    \
+                           ((UChar)cha)];      \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* mode this stream is in, and whether inputting */
+      /* or outputting data */
+      Int32    mode;
+      Int32    state;
+
+      /* remembers avail_in when flush/finish requested */
+      UInt32   avail_in_expect;
+
+      /* for doing the block sorting */
+      UInt32*  arr1;
+      UInt32*  arr2;
+      UInt32*  ftab;
+      Int32    origPtr;
+
+      /* aliases for arr1 and arr2 */
+      UInt32*  ptr;
+      UChar*   block;
+      UInt16*  mtfv;
+      UChar*   zbits;
+
+      /* for deciding when to use the fallback sorting algorithm */
+      Int32    workFactor;
+
+      /* run-length-encoding of the input */
+      UInt32   state_in_ch;
+      Int32    state_in_len;
+      BZ_RAND_DECLS;
+
+      /* input and output limits and current posns */
+      Int32    nblock;
+      Int32    nblockMAX;
+      Int32    numZ;
+      Int32    state_out_pos;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      UChar    unseqToSeq[256];
+
+      /* the buffer for bit stream creation */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* block and combined CRCs */
+      UInt32   blockCRC;
+      UInt32   combinedCRC;
+
+      /* misc administratium */
+      Int32    verbosity;
+      Int32    blockNo;
+      Int32    blockSize100k;
+
+      /* stuff for coding the MTF values */
+      Int32    nMTF;
+      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+
+      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      /* second dimension: only 3 needed; 4 makes index calculations faster */
+      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+   }
+   EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void 
+BZ2_blockSort ( EState* );
+
+extern void 
+BZ2_compressBlock ( EState*, Bool );
+
+extern void 
+BZ2_bsInitWrite ( EState* );
+
+extern void 
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void 
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE        1
+#define BZ_X_OUTPUT      2
+
+#define BZ_X_MAGIC_1     10
+#define BZ_X_MAGIC_2     11
+#define BZ_X_MAGIC_3     12
+#define BZ_X_MAGIC_4     13
+#define BZ_X_BLKHDR_1    14
+#define BZ_X_BLKHDR_2    15
+#define BZ_X_BLKHDR_3    16
+#define BZ_X_BLKHDR_4    17
+#define BZ_X_BLKHDR_5    18
+#define BZ_X_BLKHDR_6    19
+#define BZ_X_BCRC_1      20
+#define BZ_X_BCRC_2      21
+#define BZ_X_BCRC_3      22
+#define BZ_X_BCRC_4      23
+#define BZ_X_RANDBIT     24
+#define BZ_X_ORIGPTR_1   25
+#define BZ_X_ORIGPTR_2   26
+#define BZ_X_ORIGPTR_3   27
+#define BZ_X_MAPPING_1   28
+#define BZ_X_MAPPING_2   29
+#define BZ_X_SELECTOR_1  30
+#define BZ_X_SELECTOR_2  31
+#define BZ_X_SELECTOR_3  32
+#define BZ_X_CODING_1    33
+#define BZ_X_CODING_2    34
+#define BZ_X_CODING_3    35
+#define BZ_X_MTF_1       36
+#define BZ_X_MTF_2       37
+#define BZ_X_MTF_3       38
+#define BZ_X_MTF_4       39
+#define BZ_X_MTF_5       40
+#define BZ_X_MTF_6       41
+#define BZ_X_ENDHDR_2    42
+#define BZ_X_ENDHDR_3    43
+#define BZ_X_ENDHDR_4    44
+#define BZ_X_ENDHDR_5    45
+#define BZ_X_ENDHDR_6    46
+#define BZ_X_CCRC_1      47
+#define BZ_X_CCRC_2      48
+#define BZ_X_CCRC_3      49
+#define BZ_X_CCRC_4      50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* state indicator for this stream */
+      Int32    state;
+
+      /* for doing the final run-length decoding */
+      UChar    state_out_ch;
+      Int32    state_out_len;
+      Bool     blockRandomised;
+      BZ_RAND_DECLS;
+
+      /* the buffer for bit stream reading */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* misc administratium */
+      Int32    blockSize100k;
+      Bool     smallDecompress;
+      Int32    currBlockNo;
+      Int32    verbosity;
+
+      /* for undoing the Burrows-Wheeler transform */
+      Int32    origPtr;
+      UInt32   tPos;
+      Int32    k0;
+      Int32    unzftab[256];
+      Int32    nblock_used;
+      Int32    cftab[257];
+      Int32    cftabCopy[257];
+
+      /* for undoing the Burrows-Wheeler transform (FAST) */
+      UInt32   *tt;
+
+      /* for undoing the Burrows-Wheeler transform (SMALL) */
+      UInt16   *ll16;
+      UChar    *ll4;
+
+      /* stored and calculated CRCs */
+      UInt32   storedBlockCRC;
+      UInt32   storedCombinedCRC;
+      UInt32   calculatedBlockCRC;
+      UInt32   calculatedCombinedCRC;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      Bool     inUse16[16];
+      UChar    seqToUnseq[256];
+
+      /* for decoding the MTF values */
+      UChar    mtfa   [MTFA_SIZE];
+      Int32    mtfbase[256 / MTFL_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    minLens[BZ_N_GROUPS];
+
+      /* save area for scalars in the main decompress code */
+      Int32    save_i;
+      Int32    save_j;
+      Int32    save_t;
+      Int32    save_alphaSize;
+      Int32    save_nGroups;
+      Int32    save_nSelectors;
+      Int32    save_EOB;
+      Int32    save_groupNo;
+      Int32    save_groupPos;
+      Int32    save_nextSym;
+      Int32    save_nblockMAX;
+      Int32    save_nblock;
+      Int32    save_es;
+      Int32    save_N;
+      Int32    save_curr;
+      Int32    save_zt;
+      Int32    save_zn; 
+      Int32    save_zvec;
+      Int32    save_zj;
+      Int32    save_gSel;
+      Int32    save_gMinlen;
+      Int32*   save_gLimit;
+      Int32*   save_gBase;
+      Int32*   save_gPerm;
+
+   }
+   DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc)                     \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    s->tPos = s->tt[s->tPos];                 \
+    cccc = (UChar)(s->tPos & 0xff);           \
+    s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc)                   \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+    c_tPos = c_tt[c_tPos];                    \
+    cccc = (UChar)(c_tPos & 0xff);            \
+    c_tPos >>= 8;
+
+#define SET_LL4(i,n)                                          \
+   { if (((i) & 0x1) == 0)                                    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
+        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
+   }
+
+#define GET_LL4(i)                             \
+   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n)                          \
+   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
+     SET_LL4(i, n >> 16);                    \
+   }
+
+#define GET_LL(i) \
+   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc)                            \
+    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+    cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
+    s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32 
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32 
+BZ2_decompress ( DState* );
+
+extern void 
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+                           Int32,  Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore
new file mode 100644
index 0000000..d314043
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# Bzmore wrapped for bzip2, 
+# adapted from zmore by Philippe Troin  for Debian GNU/Linux.
+
+PATH="/usr/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+	*less)	more=less	;;
+	*)	more=more       ;;
+esac
+
+if test "`echo -n a`" = "-n a"; then
+  # looks like a SysV system:
+  n1=''; n2='\c'
+else
+  n1='-n'; n2=''
+fi
+oldtty=`stty -g 2>/dev/null`
+if stty -cbreak 2>/dev/null; then
+  cb='cbreak'; ncb='-cbreak'
+else
+  # 'stty min 1' resets eof to ^a on both SunOS and SysV!
+  cb='min 1 -icanon'; ncb='icanon eof ^d'
+fi
+if test $? -eq 0 -a -n "$oldtty"; then
+   trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
+else
+   trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
+fi
+
+if test $# = 0; then
+    if test -t 0; then
+	echo usage: $prog files...
+    else
+	bzip2 -cdfq | eval $more
+    fi
+else
+    FIRST=1
+    for FILE
+    do
+	if test $FIRST -eq 0; then
+		echo $n1 "--More--(Next file: $FILE)$n2"
+		stty $cb -echo 2>/dev/null
+		ANS=`dd bs=1 count=1 2>/dev/null` 
+		stty $ncb echo 2>/dev/null
+		echo " "
+		if test "$ANS" = 'e' -o "$ANS" = 'q'; then
+			exit
+		fi
+	fi
+	if test "$ANS" != 's'; then
+		echo "------> $FILE <------"
+		bzip2 -cdfq "$FILE" | eval $more
+	fi
+	if test -t; then
+		FIRST=0
+	fi
+    done
+fi
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore.1 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore.1
new file mode 100644
index 0000000..b437d3b
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/bzmore.1
@@ -0,0 +1,152 @@
+.\"Shamelessly copied from zmore.1 by Philippe Troin 
+.\"for Debian GNU/Linux
+.TH BZMORE 1
+.SH NAME
+bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text
+.SH SYNOPSIS
+.B bzmore
+[ name ...  ]
+.br
+.B bzless
+[ name ...  ]
+.SH NOTE
+In the following description,
+.I bzless
+and
+.I less
+can be used interchangeably with
+.I bzmore
+and
+.I more.
+.SH DESCRIPTION
+.I  Bzmore
+is a filter which allows examination of compressed or plain text files
+one screenful at a time on a soft-copy terminal.
+.I bzmore
+works on files compressed with
+.I bzip2
+and also on uncompressed files.
+If a file does not exist,
+.I bzmore
+looks for a file of the same name with the addition of a .bz2 suffix.
+.PP
+.I Bzmore
+normally pauses after each screenful, printing --More--
+at the bottom of the screen.
+If the user then types a carriage return, one more line is displayed.
+If the user hits a space,
+another screenful is displayed.  Other possibilities are enumerated later.
+.PP
+.I Bzmore
+looks in the file
+.I /etc/termcap
+to determine terminal characteristics,
+and to determine the default window size.
+On a terminal capable of displaying 24 lines,
+the default window size is 22 lines.
+Other sequences which may be typed when
+.I bzmore
+pauses, and their effects, are as follows (\fIi\fP is an optional integer
+argument, defaulting to 1) :
+.PP
+.IP \fIi\|\fP
+display
+.I i
+more lines, (or another screenful if no argument is given)
+.PP
+.IP ^D
+display 11 more lines (a ``scroll'').
+If
+.I i
+is given, then the scroll size is set to \fIi\|\fP.
+.PP
+.IP d
+same as ^D (control-D)
+.PP
+.IP \fIi\|\fPz
+same as typing a space except that \fIi\|\fP, if present, becomes the new
+window size.  Note that the window size reverts back to the default at the
+end of the current file.
+.PP
+.IP \fIi\|\fPs
+skip \fIi\|\fP lines and print a screenful of lines
+.PP
+.IP \fIi\|\fPf
+skip \fIi\fP screenfuls and print a screenful of lines
+.PP
+.IP "q or Q"
+quit reading the current file; go on to the next (if any)
+.PP
+.IP "e or q"
+When the prompt --More--(Next file: 
+.IR file )
+is printed, this command causes bzmore to exit.
+.PP
+.IP s
+When the prompt --More--(Next file: 
+.IR file )
+is printed, this command causes bzmore to skip the next file and continue.
+.PP 
+.IP =
+Display the current line number.
+.PP
+.IP \fIi\|\fP/expr
+search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
+If the pattern is not found,
+.I bzmore
+goes on to the next file (if any).
+Otherwise, a screenful is displayed, starting two lines before the place
+where the expression was found.
+The user's erase and kill characters may be used to edit the regular
+expression.
+Erasing back past the first column cancels the search command.
+.PP
+.IP \fIi\|\fPn
+search for the \fIi\|\fP-th occurrence of the last regular expression entered.
+.PP
+.IP !command
+invoke a shell with \fIcommand\|\fP. 
+The character `!' in "command" are replaced with the
+previous shell command.  The sequence "\\!" is replaced by "!".
+.PP
+.IP ":q or :Q"
+quit reading the current file; go on to the next (if any)
+(same as q or Q).
+.PP
+.IP .
+(dot) repeat the previous command.
+.PP
+The commands take effect immediately, i.e., it is not necessary to
+type a carriage return.
+Up to the time when the command character itself is given,
+the user may hit the line kill character to cancel the numerical
+argument being formed.
+In addition, the user may hit the erase character to redisplay the
+--More-- message.
+.PP
+At any time when output is being sent to the terminal, the user can
+hit the quit key (normally control\-\\).
+.I Bzmore
+will stop sending output, and will display the usual --More--
+prompt.
+The user may then enter one of the above commands in the normal manner.
+Unfortunately, some output is lost when this is done, due to the
+fact that any characters waiting in the terminal's output queue
+are flushed when the quit signal occurs.
+.PP
+The terminal is set to
+.I noecho
+mode by this program so that the output can be continuous.
+What you type will thus not show on your terminal, except for the / and !
+commands.
+.PP
+If the standard output is not a teletype, then
+.I bzmore
+acts just like
+.I bzcat,
+except that a header is printed before each file.
+.SH FILES
+.DT
+/etc/termcap		Terminal data base
+.SH "SEE ALSO"
+more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1)
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/crctable.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/crctable.c
new file mode 100644
index 0000000..1fea7e9
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/crctable.c
@@ -0,0 +1,104 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs                                  ---*/
+/*---                                            crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*--
+  I think this is an implementation of the AUTODIN-II,
+  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
+  from code by Rob Warnock, in Section 51 of the
+  comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+   /*-- Ugly, innit? --*/
+
+   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/decompress.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/decompress.c
new file mode 100644
index 0000000..311f566
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/decompress.c
@@ -0,0 +1,646 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery                               ---*/
+/*---                                          decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+   Int32 i;
+   s->nInUse = 0;
+   for (i = 0; i < 256; i++)
+      if (s->inUse[i]) {
+         s->seqToUnseq[s->nInUse] = i;
+         s->nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr)                               \
+   { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn)                     \
+   case lll: s->state = lll;                      \
+   while (True) {                                 \
+      if (s->bsLive >= nnn) {                     \
+         UInt32 v;                                \
+         v = (s->bsBuff >>                        \
+             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
+         s->bsLive -= nnn;                        \
+         vvv = v;                                 \
+         break;                                   \
+      }                                           \
+      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
+      s->bsBuff                                   \
+         = (s->bsBuff << 8) |                     \
+           ((UInt32)                              \
+              (*((UChar*)(s->strm->next_in))));   \
+      s->bsLive += 8;                             \
+      s->strm->next_in++;                         \
+      s->strm->avail_in--;                        \
+      s->strm->total_in_lo32++;                   \
+      if (s->strm->total_in_lo32 == 0)            \
+         s->strm->total_in_hi32++;                \
+   }
+
+#define GET_UCHAR(lll,uuu)                        \
+   GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu)                          \
+   GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval)           \
+{                                                 \
+   if (groupPos == 0) {                           \
+      groupNo++;                                  \
+      if (groupNo >= nSelectors)                  \
+         RETURN(BZ_DATA_ERROR);                   \
+      groupPos = BZ_G_SIZE;                       \
+      gSel = s->selector[groupNo];                \
+      gMinlen = s->minLens[gSel];                 \
+      gLimit = &(s->limit[gSel][0]);              \
+      gPerm = &(s->perm[gSel][0]);                \
+      gBase = &(s->base[gSel][0]);                \
+   }                                              \
+   groupPos--;                                    \
+   zn = gMinlen;                                  \
+   GET_BITS(label1, zvec, zn);                    \
+   while (1) {                                    \
+      if (zn > 20 /* the longest code */)         \
+         RETURN(BZ_DATA_ERROR);                   \
+      if (zvec <= gLimit[zn]) break;              \
+      zn++;                                       \
+      GET_BIT(label2, zj);                        \
+      zvec = (zvec << 1) | zj;                    \
+   };                                             \
+   if (zvec - gBase[zn] < 0                       \
+       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
+      RETURN(BZ_DATA_ERROR);                      \
+   lval = gPerm[zvec - gBase[zn]];                \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+   UChar      uc;
+   Int32      retVal;
+   Int32      minLen, maxLen;
+   bz_stream* strm = s->strm;
+
+   /* stuff that needs to be saved/restored */
+   Int32  i;
+   Int32  j;
+   Int32  t;
+   Int32  alphaSize;
+   Int32  nGroups;
+   Int32  nSelectors;
+   Int32  EOB;
+   Int32  groupNo;
+   Int32  groupPos;
+   Int32  nextSym;
+   Int32  nblockMAX;
+   Int32  nblock;
+   Int32  es;
+   Int32  N;
+   Int32  curr;
+   Int32  zt;
+   Int32  zn; 
+   Int32  zvec;
+   Int32  zj;
+   Int32  gSel;
+   Int32  gMinlen;
+   Int32* gLimit;
+   Int32* gBase;
+   Int32* gPerm;
+
+   if (s->state == BZ_X_MAGIC_1) {
+      /*initialise the save area*/
+      s->save_i           = 0;
+      s->save_j           = 0;
+      s->save_t           = 0;
+      s->save_alphaSize   = 0;
+      s->save_nGroups     = 0;
+      s->save_nSelectors  = 0;
+      s->save_EOB         = 0;
+      s->save_groupNo     = 0;
+      s->save_groupPos    = 0;
+      s->save_nextSym     = 0;
+      s->save_nblockMAX   = 0;
+      s->save_nblock      = 0;
+      s->save_es          = 0;
+      s->save_N           = 0;
+      s->save_curr        = 0;
+      s->save_zt          = 0;
+      s->save_zn          = 0;
+      s->save_zvec        = 0;
+      s->save_zj          = 0;
+      s->save_gSel        = 0;
+      s->save_gMinlen     = 0;
+      s->save_gLimit      = NULL;
+      s->save_gBase       = NULL;
+      s->save_gPerm       = NULL;
+   }
+
+   /*restore from the save area*/
+   i           = s->save_i;
+   j           = s->save_j;
+   t           = s->save_t;
+   alphaSize   = s->save_alphaSize;
+   nGroups     = s->save_nGroups;
+   nSelectors  = s->save_nSelectors;
+   EOB         = s->save_EOB;
+   groupNo     = s->save_groupNo;
+   groupPos    = s->save_groupPos;
+   nextSym     = s->save_nextSym;
+   nblockMAX   = s->save_nblockMAX;
+   nblock      = s->save_nblock;
+   es          = s->save_es;
+   N           = s->save_N;
+   curr        = s->save_curr;
+   zt          = s->save_zt;
+   zn          = s->save_zn; 
+   zvec        = s->save_zvec;
+   zj          = s->save_zj;
+   gSel        = s->save_gSel;
+   gMinlen     = s->save_gMinlen;
+   gLimit      = s->save_gLimit;
+   gBase       = s->save_gBase;
+   gPerm       = s->save_gPerm;
+
+   retVal = BZ_OK;
+
+   switch (s->state) {
+
+      GET_UCHAR(BZ_X_MAGIC_1, uc);
+      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_2, uc);
+      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_3, uc)
+      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
+          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+      s->blockSize100k -= BZ_HDR_0;
+
+      if (s->smallDecompress) {
+         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+         s->ll4  = BZALLOC( 
+                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
+                   );
+         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+      } else {
+         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+      }
+
+      GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+      if (uc == 0x17) goto endhdr_2;
+      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_2, uc);
+      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_3, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_4, uc);
+      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_5, uc);
+      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_6, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+      s->currBlockNo++;
+      if (s->verbosity >= 2)
+         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
+ 
+      s->storedBlockCRC = 0;
+      GET_UCHAR(BZ_X_BCRC_1, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_2, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_3, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_4, uc);
+      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+      s->origPtr = 0;
+      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+      if (s->origPtr < 0)
+         RETURN(BZ_DATA_ERROR);
+      if (s->origPtr > 10 + 100000*s->blockSize100k) 
+         RETURN(BZ_DATA_ERROR);
+
+      /*--- Receive the mapping table ---*/
+      for (i = 0; i < 16; i++) {
+         GET_BIT(BZ_X_MAPPING_1, uc);
+         if (uc == 1) 
+            s->inUse16[i] = True; else 
+            s->inUse16[i] = False;
+      }
+
+      for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+      for (i = 0; i < 16; i++)
+         if (s->inUse16[i])
+            for (j = 0; j < 16; j++) {
+               GET_BIT(BZ_X_MAPPING_2, uc);
+               if (uc == 1) s->inUse[i * 16 + j] = True;
+            }
+      makeMaps_d ( s );
+      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+      alphaSize = s->nInUse+2;
+
+      /*--- Now the selectors ---*/
+      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+      for (i = 0; i < nSelectors; i++) {
+         j = 0;
+         while (True) {
+            GET_BIT(BZ_X_SELECTOR_3, uc);
+            if (uc == 0) break;
+            j++;
+            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+         }
+         s->selectorMtf[i] = j;
+      }
+
+      /*--- Undo the MTF values for the selectors. ---*/
+      {
+         UChar pos[BZ_N_GROUPS], tmp, v;
+         for (v = 0; v < nGroups; v++) pos[v] = v;
+   
+         for (i = 0; i < nSelectors; i++) {
+            v = s->selectorMtf[i];
+            tmp = pos[v];
+            while (v > 0) { pos[v] = pos[v-1]; v--; }
+            pos[0] = tmp;
+            s->selector[i] = tmp;
+         }
+      }
+
+      /*--- Now the coding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         GET_BITS(BZ_X_CODING_1, curr, 5);
+         for (i = 0; i < alphaSize; i++) {
+            while (True) {
+               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+               GET_BIT(BZ_X_CODING_2, uc);
+               if (uc == 0) break;
+               GET_BIT(BZ_X_CODING_3, uc);
+               if (uc == 0) curr++; else curr--;
+            }
+            s->len[t][i] = curr;
+         }
+      }
+
+      /*--- Create the Huffman decoding tables ---*/
+      for (t = 0; t < nGroups; t++) {
+         minLen = 32;
+         maxLen = 0;
+         for (i = 0; i < alphaSize; i++) {
+            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+            if (s->len[t][i] < minLen) minLen = s->len[t][i];
+         }
+         BZ2_hbCreateDecodeTables ( 
+            &(s->limit[t][0]), 
+            &(s->base[t][0]), 
+            &(s->perm[t][0]), 
+            &(s->len[t][0]),
+            minLen, maxLen, alphaSize
+         );
+         s->minLens[t] = minLen;
+      }
+
+      /*--- Now the MTF values ---*/
+
+      EOB      = s->nInUse+1;
+      nblockMAX = 100000 * s->blockSize100k;
+      groupNo  = -1;
+      groupPos = 0;
+
+      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+      /*-- MTF init --*/
+      {
+         Int32 ii, jj, kk;
+         kk = MTFA_SIZE-1;
+         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+               kk--;
+            }
+            s->mtfbase[ii] = kk + 1;
+         }
+      }
+      /*-- end MTF init --*/
+
+      nblock = 0;
+      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+      while (True) {
+
+         if (nextSym == EOB) break;
+
+         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+            es = -1;
+            N = 1;
+            do {
+               /* Check that N doesn't get too big, so that es doesn't
+                  go negative.  The maximum value that can be
+                  RUNA/RUNB encoded is equal to the block size (post
+                  the initial RLE), viz, 900k, so bounding N at 2
+                  million should guard against overflow without
+                  rejecting any legitimate inputs. */
+               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
+               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+               N = N * 2;
+               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+            }
+               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+            es++;
+            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+            s->unzftab[uc] += es;
+
+            if (s->smallDecompress)
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->ll16[nblock] = (UInt16)uc;
+                  nblock++;
+                  es--;
+               }
+            else
+               while (es > 0) {
+                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s->tt[nblock] = (UInt32)uc;
+                  nblock++;
+                  es--;
+               };
+
+            continue;
+
+         } else {
+
+            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+            /*-- uc = MTF ( nextSym-1 ) --*/
+            {
+               Int32 ii, jj, kk, pp, lno, off;
+               UInt32 nn;
+               nn = (UInt32)(nextSym - 1);
+
+               if (nn < MTFL_SIZE) {
+                  /* avoid general-case expense */
+                  pp = s->mtfbase[0];
+                  uc = s->mtfa[pp+nn];
+                  while (nn > 3) {
+                     Int32 z = pp+nn;
+                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
+                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
+                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
+                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
+                     nn -= 4;
+                  }
+                  while (nn > 0) { 
+                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
+                  };
+                  s->mtfa[pp] = uc;
+               } else { 
+                  /* general case */
+                  lno = nn / MTFL_SIZE;
+                  off = nn % MTFL_SIZE;
+                  pp = s->mtfbase[lno] + off;
+                  uc = s->mtfa[pp];
+                  while (pp > s->mtfbase[lno]) { 
+                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
+                  };
+                  s->mtfbase[lno]++;
+                  while (lno > 0) {
+                     s->mtfbase[lno]--;
+                     s->mtfa[s->mtfbase[lno]] 
+                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s->mtfbase[0]--;
+                  s->mtfa[s->mtfbase[0]] = uc;
+                  if (s->mtfbase[0] == 0) {
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s->mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+            }
+            /*-- end uc = MTF ( nextSym-1 ) --*/
+
+            s->unzftab[s->seqToUnseq[uc]]++;
+            if (s->smallDecompress)
+               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
+            nblock++;
+
+            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+            continue;
+         }
+      }
+
+      /* Now we know what nblock is, we can do a better sanity
+         check on s->origPtr.
+      */
+      if (s->origPtr < 0 || s->origPtr >= nblock)
+         RETURN(BZ_DATA_ERROR);
+
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      /* Check: unzftab entries in range. */
+      for (i = 0; i <= 255; i++) {
+         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
+            RETURN(BZ_DATA_ERROR);
+      }
+      /* Actually generate cftab. */
+      s->cftab[0] = 0;
+      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+      /* Check: cftab entries in range. */
+      for (i = 0; i <= 256; i++) {
+         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+            /* s->cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+      /* Check: cftab entries non-descending. */
+      for (i = 1; i <= 256; i++) {
+         if (s->cftab[i-1] > s->cftab[i]) {
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
+      s->state_out_len = 0;
+      s->state_out_ch  = 0;
+      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+      s->state = BZ_X_OUTPUT;
+      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+      if (s->smallDecompress) {
+
+         /*-- Make a copy of cftab, used in generation of T --*/
+         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+         /*-- compute the T vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->ll16[i]);
+            SET_LL(i, s->cftabCopy[uc]);
+            s->cftabCopy[uc]++;
+         }
+
+         /*-- Compute T^(-1) by pointer reversal on T --*/
+         i = s->origPtr;
+         j = GET_LL(i);
+         do {
+            Int32 tmp = GET_LL(j);
+            SET_LL(j, i);
+            i = j;
+            j = tmp;
+         }
+            while (i != s->origPtr);
+
+         s->tPos = s->origPtr;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_SMALL(s->k0); s->nblock_used++;
+         }
+
+      } else {
+
+         /*-- compute the T^(-1) vector --*/
+         for (i = 0; i < nblock; i++) {
+            uc = (UChar)(s->tt[i] & 0xff);
+            s->tt[s->cftab[uc]] |= (i << 8);
+            s->cftab[uc]++;
+         }
+
+         s->tPos = s->tt[s->origPtr] >> 8;
+         s->nblock_used = 0;
+         if (s->blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_FAST(s->k0); s->nblock_used++;
+         }
+
+      }
+
+      RETURN(BZ_OK);
+
+
+
+    endhdr_2:
+
+      GET_UCHAR(BZ_X_ENDHDR_2, uc);
+      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_3, uc);
+      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_4, uc);
+      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_5, uc);
+      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_6, uc);
+      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+      s->storedCombinedCRC = 0;
+      GET_UCHAR(BZ_X_CCRC_1, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_2, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_3, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_4, uc);
+      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+      s->state = BZ_X_IDLE;
+      RETURN(BZ_STREAM_END);
+
+      default: AssertH ( False, 4001 );
+   }
+
+   AssertH ( False, 4002 );
+
+   save_state_and_return:
+
+   s->save_i           = i;
+   s->save_j           = j;
+   s->save_t           = t;
+   s->save_alphaSize   = alphaSize;
+   s->save_nGroups     = nGroups;
+   s->save_nSelectors  = nSelectors;
+   s->save_EOB         = EOB;
+   s->save_groupNo     = groupNo;
+   s->save_groupPos    = groupPos;
+   s->save_nextSym     = nextSym;
+   s->save_nblockMAX   = nblockMAX;
+   s->save_nblock      = nblock;
+   s->save_es          = es;
+   s->save_N           = N;
+   s->save_curr        = curr;
+   s->save_zt          = zt;
+   s->save_zn          = zn;
+   s->save_zvec        = zvec;
+   s->save_zj          = zj;
+   s->save_gSel        = gSel;
+   s->save_gMinlen     = gMinlen;
+   s->save_gLimit      = gLimit;
+   s->save_gBase       = gBase;
+   s->save_gPerm       = gPerm;
+
+   return retVal;   
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                      decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.c
new file mode 100644
index 0000000..03fa146
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.c
@@ -0,0 +1,175 @@
+/*
+   minibz2
+      libbz2.dll test program.
+      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+      This file is Public Domain.  Welcome any email to me.
+
+   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
+*/
+
+#define BZ_IMPORT
+#include 
+#include 
+#include "bzlib.h"
+#ifdef _WIN32
+#include 
+#endif
+
+
+#ifdef _WIN32
+
+#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 
+
+#include 
+static int BZ2DLLLoaded = 0;
+static HINSTANCE BZ2DLLhLib;
+int BZ2DLLLoadLibrary(void)
+{
+   HINSTANCE hLib;
+
+   if(BZ2DLLLoaded==1){return 0;}
+   hLib=LoadLibrary(BZ2_LIBNAME);
+   if(hLib == NULL){
+      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
+      return -1;
+   }
+   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
+   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
+   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
+   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
+   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
+   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
+   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
+   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
+
+   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
+       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
+       || !BZ2_bzclose || !BZ2_bzerror) {
+      fprintf(stderr,"GetProcAddress failed.\n");
+      return -1;
+   }
+   BZ2DLLLoaded=1;
+   BZ2DLLhLib=hLib;
+   return 0;
+
+}
+int BZ2DLLFreeLibrary(void)
+{
+   if(BZ2DLLLoaded==0){return 0;}
+   FreeLibrary(BZ2DLLhLib);
+   BZ2DLLLoaded=0;
+}
+#endif /* WIN32 */
+
+void usage(void)
+{
+   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
+}
+
+int main(int argc,char *argv[])
+{
+   int decompress = 0;
+   int level = 9;
+   char *fn_r = NULL;
+   char *fn_w = NULL;
+
+#ifdef _WIN32
+   if(BZ2DLLLoadLibrary()<0){
+      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
+      exit(1);
+   }
+   printf("Loading of %s succeeded.  Library version is %s.\n",
+          BZ2_LIBNAME, BZ2_bzlibVersion() );
+#endif
+   while(++argv,--argc){
+      if(**argv =='-' || **argv=='/'){
+         char *p;
+
+         for(p=*argv+1;*p;p++){
+            if(*p=='d'){
+               decompress = 1;
+            }else if('1'<=*p && *p<='9'){
+               level = *p - '0';
+            }else{
+               usage();
+               exit(1);
+            }
+         }
+      }else{
+         break;
+      }
+   }
+   if(argc>=1){
+      fn_r = *argv;
+      argc--;argv++;
+   }else{
+      fn_r = NULL;
+   }
+   if(argc>=1){
+      fn_w = *argv;
+      argc--;argv++;
+   }else{
+      fn_w = NULL;
+   }
+   {
+      int len;
+      char buff[0x1000];
+      char mode[10];
+
+      if(decompress){
+         BZFILE *BZ2fp_r = NULL;
+         FILE *fp_w = NULL;
+
+         if(fn_w){
+            if((fp_w = fopen(fn_w,"wb"))==NULL){
+               printf("can't open [%s]\n",fn_w);
+               perror("reason:");
+               exit(1);
+            }
+         }else{
+            fp_w = stdout;
+         }
+         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
+            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
+            printf("can't bz2openstream\n");
+            exit(1);
+         }
+         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
+            fwrite(buff,1,len,fp_w);
+         }
+         BZ2_bzclose(BZ2fp_r);
+         if(fp_w != stdout) fclose(fp_w);
+      }else{
+         BZFILE *BZ2fp_w = NULL;
+         FILE *fp_r = NULL;
+
+         if(fn_r){
+            if((fp_r = fopen(fn_r,"rb"))==NULL){
+               printf("can't open [%s]\n",fn_r);
+               perror("reason:");
+               exit(1);
+            }
+         }else{
+            fp_r = stdin;
+         }
+         mode[0]='w';
+         mode[1] = '0' + level;
+         mode[2] = '\0';
+
+         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
+            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
+            printf("can't bz2openstream\n");
+            exit(1);
+         }
+         while((len=fread(buff,1,0x1000,fp_r))>0){
+            BZ2_bzwrite(BZ2fp_w,buff,len);
+         }
+         BZ2_bzclose(BZ2fp_w);
+         if(fp_r!=stdin)fclose(fp_r);
+      }
+   }
+#ifdef _WIN32
+   BZ2DLLFreeLibrary();
+#endif
+   return 0;
+}
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.dsp b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.dsp
new file mode 100644
index 0000000..4b1615e
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/dlltest.dsp
@@ -0,0 +1,93 @@
+# Microsoft Developer Studio Project File - Name="dlltest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=dlltest - Win32 Debug
+!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚Å‚Í‚ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
+!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
+!MESSAGE 
+!MESSAGE NMAKE /f "dlltest.mak".
+!MESSAGE 
+!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
+!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
+!MESSAGE 
+!MESSAGE NMAKE /f "dlltest.mak" CFG="dlltest - Win32 Debug"
+!MESSAGE 
+!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
+!MESSAGE 
+!MESSAGE "dlltest - Win32 Release" ("Win32 (x86) Console Application" —p)
+!MESSAGE "dlltest - Win32 Debug" ("Win32 (x86) Console Application" —p)
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "dlltest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"minibz2.exe"
+
+!ELSEIF  "$(CFG)" == "dlltest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "dlltest_"
+# PROP BASE Intermediate_Dir "dlltest_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "dlltest_"
+# PROP Intermediate_Dir "dlltest_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"minibz2.exe" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "dlltest - Win32 Release"
+# Name "dlltest - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dlltest.c
+# End Source File
+# End Target
+# End Project
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/entities.xml b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/entities.xml
new file mode 100644
index 0000000..4b28f34
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/entities.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/format.pl b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/format.pl
new file mode 100644
index 0000000..f169fd9
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/format.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -w
+#
+# ------------------------------------------------------------------
+# This file is part of bzip2/libbzip2, a program and library for
+# lossless, block-sorting data compression.
+#
+# bzip2/libbzip2 version 1.0.6 of 6 September 2010
+# Copyright (C) 1996-2010 Julian Seward 
+#
+# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+# README file.
+#
+# This program is released under the terms of the license contained
+# in the file LICENSE.
+# ------------------------------------------------------------------
+#
+use strict;
+
+# get command line values:
+if ( $#ARGV !=1 ) {
+    die "Usage:  $0 xml_infile xml_outfile\n";
+}
+
+my $infile = shift;
+# check infile exists
+die "Can't find file \"$infile\""
+  unless -f $infile;
+# check we can read infile
+if (! -r $infile) {
+    die "Can't read input $infile\n";
+}
+# check we can open infile
+open( INFILE,"<$infile" ) or 
+    die "Can't input $infile $!";
+
+#my $outfile = 'fmt-manual.xml';
+my $outfile = shift;
+#print "Infile: $infile, Outfile: $outfile\n";
+# check we can write to outfile
+open( OUTFILE,">$outfile" ) or 
+    die "Can't output $outfile $! for writing";
+
+my ($prev, $curr, $str);
+$prev = ''; $curr = '';
+while (  ) {
+
+		print OUTFILE $prev;
+    $prev = $curr;
+    $curr = $_;
+    $str = '';
+
+    if ( $prev =~ /$|$/ ) {
+        chomp $prev;
+        $curr = join( '', $prev, "|<\/screen>/ ) {
+        chomp $prev;
+        $curr = join( '', $prev, "]]>", $curr );
+				$prev = '';
+        next;
+    }
+}
+print OUTFILE $curr;
+close INFILE;
+close OUTFILE;
+exit;
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/huffman.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/huffman.c
new file mode 100644
index 0000000..2283fdb
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/huffman.c
@@ -0,0 +1,205 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2)                           \
+   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
+   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z)                                     \
+{                                                     \
+   Int32 zz, tmp;                                     \
+   zz = z; tmp = heap[zz];                            \
+   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
+      heap[zz] = heap[zz >> 1];                       \
+      zz >>= 1;                                       \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+#define DOWNHEAP(z)                                   \
+{                                                     \
+   Int32 zz, yy, tmp;                                 \
+   zz = z; tmp = heap[zz];                            \
+   while (True) {                                     \
+      yy = zz << 1;                                   \
+      if (yy > nHeap) break;                          \
+      if (yy < nHeap &&                               \
+          weight[heap[yy+1]] < weight[heap[yy]])      \
+         yy++;                                        \
+      if (weight[tmp] < weight[heap[yy]]) break;      \
+      heap[zz] = heap[yy];                            \
+      zz = yy;                                        \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len, 
+                             Int32 *freq,
+                             Int32 alphaSize,
+                             Int32 maxLen )
+{
+   /*--
+      Nodes and heap entries run from 1.  Entry 0
+      for both the heap and nodes is a sentinel.
+   --*/
+   Int32 nNodes, nHeap, n1, n2, i, j, k;
+   Bool  tooLong;
+
+   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
+   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+
+   for (i = 0; i < alphaSize; i++)
+      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+   while (True) {
+
+      nNodes = alphaSize;
+      nHeap = 0;
+
+      heap[0] = 0;
+      weight[0] = 0;
+      parent[0] = -2;
+
+      for (i = 1; i <= alphaSize; i++) {
+         parent[i] = -1;
+         nHeap++;
+         heap[nHeap] = i;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+   
+      while (nHeap > 1) {
+         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         nNodes++;
+         parent[n1] = parent[n2] = nNodes;
+         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+         parent[nNodes] = -1;
+         nHeap++;
+         heap[nHeap] = nNodes;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+      tooLong = False;
+      for (i = 1; i <= alphaSize; i++) {
+         j = 0;
+         k = i;
+         while (parent[k] >= 0) { k = parent[k]; j++; }
+         len[i-1] = j;
+         if (j > maxLen) tooLong = True;
+      }
+      
+      if (! tooLong) break;
+
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i < alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i <= alphaSize; i++) {
+         j = weight[i] >> 8;
+         j = 1 + (j / 2);
+         weight[i] = j << 8;
+      }
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+                         UChar *length,
+                         Int32 minLen,
+                         Int32 maxLen,
+                         Int32 alphaSize )
+{
+   Int32 n, vec, i;
+
+   vec = 0;
+   for (n = minLen; n <= maxLen; n++) {
+      for (i = 0; i < alphaSize; i++)
+         if (length[i] == n) { code[i] = vec; vec++; };
+      vec <<= 1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+                                Int32 *base,
+                                Int32 *perm,
+                                UChar *length,
+                                Int32 minLen,
+                                Int32 maxLen,
+                                Int32 alphaSize )
+{
+   Int32 pp, i, j, vec;
+
+   pp = 0;
+   for (i = minLen; i <= maxLen; i++)
+      for (j = 0; j < alphaSize; j++)
+         if (length[j] == i) { perm[pp] = j; pp++; };
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   vec = 0;
+
+   for (i = minLen; i <= maxLen; i++) {
+      vec += (base[i+1] - base[i]);
+      limit[i] = vec-1;
+      vec <<= 1;
+   }
+   for (i = minLen + 1; i <= maxLen; i++)
+      base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.def b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.def
new file mode 100644
index 0000000..2dc0dd8
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.def
@@ -0,0 +1,27 @@
+LIBRARY			LIBBZ2
+DESCRIPTION		"libbzip2: library for data compression"
+EXPORTS
+	BZ2_bzCompressInit
+	BZ2_bzCompress
+	BZ2_bzCompressEnd
+	BZ2_bzDecompressInit
+	BZ2_bzDecompress
+	BZ2_bzDecompressEnd
+	BZ2_bzReadOpen
+	BZ2_bzReadClose
+	BZ2_bzReadGetUnused
+	BZ2_bzRead
+	BZ2_bzWriteOpen
+	BZ2_bzWrite
+	BZ2_bzWriteClose
+	BZ2_bzWriteClose64
+	BZ2_bzBuffToBuffCompress
+	BZ2_bzBuffToBuffDecompress
+	BZ2_bzlibVersion
+	BZ2_bzopen
+	BZ2_bzdopen
+	BZ2_bzread
+	BZ2_bzwrite
+	BZ2_bzflush
+	BZ2_bzclose
+	BZ2_bzerror
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.dsp b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.dsp
new file mode 100644
index 0000000..a21a20f
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/libbz2.dsp
@@ -0,0 +1,130 @@
+# Microsoft Developer Studio Project File - Name="libbz2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libbz2 - Win32 Debug
+!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚Å‚Í‚ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
+!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
+!MESSAGE 
+!MESSAGE NMAKE /f "libbz2.mak".
+!MESSAGE 
+!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
+!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
+!MESSAGE 
+!MESSAGE NMAKE /f "libbz2.mak" CFG="libbz2 - Win32 Debug"
+!MESSAGE 
+!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
+!MESSAGE 
+!MESSAGE "libbz2 - Win32 Release" ("Win32 (x86) Dynamic-Link Library" —p)
+!MESSAGE "libbz2 - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" —p)
+!MESSAGE 
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "libbz2 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"libbz2.dll"
+
+!ELSEIF  "$(CFG)" == "libbz2 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"libbz2.dll" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "libbz2 - Win32 Release"
+# Name "libbz2 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\blocksort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib_private.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\crctable.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\decompress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\huffman.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libbz2.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\randtable.c
+# End Source File
+# End Target
+# End Project
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/makefile.msc b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/makefile.msc
new file mode 100644
index 0000000..799a18a
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/makefile.msc
@@ -0,0 +1,63 @@
+# Makefile for Microsoft Visual C++ 6.0
+# usage: nmake -f makefile.msc
+# K.M. Syring (syring@gsf.de)
+# Fixed up by JRS for bzip2-0.9.5d release.
+
+CC=cl
+CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64 -nologo
+
+OBJS= blocksort.obj  \
+      huffman.obj    \
+      crctable.obj   \
+      randtable.obj  \
+      compress.obj   \
+      decompress.obj \
+      bzlib.obj
+
+all: lib bzip2 test
+
+bzip2: lib
+	$(CC) $(CFLAGS) -o bzip2 bzip2.c libbz2.lib setargv.obj
+	$(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
+
+lib: $(OBJS)
+	lib /out:libbz2.lib $(OBJS)
+
+test: bzip2
+	type words1
+	.\\bzip2 -1  < sample1.ref > sample1.rb2
+	.\\bzip2 -2  < sample2.ref > sample2.rb2
+	.\\bzip2 -3  < sample3.ref > sample3.rb2
+	.\\bzip2 -d  < sample1.bz2 > sample1.tst
+	.\\bzip2 -d  < sample2.bz2 > sample2.tst
+	.\\bzip2 -ds < sample3.bz2 > sample3.tst
+	@echo All six of the fc's should find no differences.
+	@echo If fc finds an error on sample3.bz2, this could be
+	@echo because WinZip's 'TAR file smart CR/LF conversion'
+	@echo is too clever for its own good.  Disable this option.
+	@echo The correct size for sample3.ref is 120,244.  If it
+	@echo is 150,251, WinZip has messed it up.
+	fc sample1.bz2 sample1.rb2 
+	fc sample2.bz2 sample2.rb2
+	fc sample3.bz2 sample3.rb2
+	fc sample1.tst sample1.ref
+	fc sample2.tst sample2.ref
+	fc sample3.tst sample3.ref
+
+
+
+clean: 
+	del *.obj
+	del libbz2.lib 
+	del bzip2.exe
+	del bzip2recover.exe
+	del sample1.rb2 
+	del sample2.rb2 
+	del sample3.rb2
+	del sample1.tst 
+	del sample2.tst
+	del sample3.tst
+
+.c.obj: 
+	$(CC) $(CFLAGS) -c $*.c -o $*.obj
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/mk251.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/mk251.c
new file mode 100644
index 0000000..c9c36f6
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/mk251.c
@@ -0,0 +1,31 @@
+
+/* Spew out a long sequence of the byte 251.  When fed to bzip2
+   versions 1.0.0 or 1.0.1, causes it to die with internal error
+   1007 in blocksort.c.  This assertion misses an extremely rare
+   case, which is fixed in this version (1.0.2) and above.
+*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include 
+
+int main ()
+{
+   int i;
+   for (i = 0; i < 48500000 ; i++)
+     putchar(251);
+   return 0;
+}
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/randtable.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/randtable.c
new file mode 100644
index 0000000..6d62459
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/randtable.c
@@ -0,0 +1,84 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks               ---*/
+/*---                                           randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = { 
+   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
+   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
+   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
+   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
+   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
+   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
+   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
+   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
+   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
+   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
+   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
+   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
+   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
+   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
+   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
+   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
+   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
+   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
+   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
+   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
+   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
+   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
+   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
+   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
+   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
+   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
+   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
+   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
+   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
+   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
+   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
+   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
+   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
+   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
+   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
+   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
+   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
+   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
+   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
+   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
+   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
+   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
+   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
+   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
+   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
+   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
+   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
+   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
+   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
+   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
+   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
+   936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       randtable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/spewG.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/spewG.c
new file mode 100644
index 0000000..14a3649
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/spewG.c
@@ -0,0 +1,54 @@
+
+/* spew out a thoroughly gigantic file designed so that bzip2
+   can compress it reasonably rapidly.  This is to help test
+   support for large files (> 2GB) in a reasonable amount of time.
+   I suggest you use the undocumented --exponential option to
+   bzip2 when compressing the resulting file; this saves a bit of
+   time.  Note: *don't* bother with --exponential when compressing 
+   Real Files; it'll just waste a lot of CPU time :-)
+   (but is otherwise harmless).
+*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+	 ------------------------------------------------------------------ */
+
+
+#define _FILE_OFFSET_BITS 64
+
+#include 
+#include 
+
+/* The number of megabytes of junk to spew out (roughly) */
+#define MEGABYTES 5000
+
+#define N_BUF 1000000
+char buf[N_BUF];
+
+int main ( int argc, char** argv )
+{
+   int ii, kk, p;
+   srandom(1);
+   setbuffer ( stdout, buf, N_BUF );
+   for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
+      p = 25+random()%50;
+      for (ii = 0; ii < p; ii++)
+         printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
+      for (ii = 0; ii < p-1; ii++)
+         printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
+      for (ii = 0; ii < p+1; ii++)
+         printf ( "ccccccccccccccccccccccccccccccccccccc" );
+   }
+   fflush(stdout);
+   return 0;
+}
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/unzcrash.c b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/unzcrash.c
new file mode 100644
index 0000000..7041da5
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/unzcrash.c
@@ -0,0 +1,141 @@
+
+/* A test program written to test robustness to decompression of
+   corrupted data.  Usage is 
+       unzcrash filename
+   and the program will read the specified file, compress it (in memory),
+   and then repeatedly decompress it, each time with a different bit of
+   the compressed data inverted, so as to test all possible one-bit errors.
+   This should not cause any invalid memory accesses.  If it does, 
+   I want to know about it!
+
+   PS.  As you can see from the above description, the process is
+   incredibly slow.  A file of size eg 5KB will cause it to run for
+   many hours.
+*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.6 of 6 September 2010
+   Copyright (C) 1996-2010 Julian Seward 
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include 
+#include 
+#include "bzlib.h"
+
+#define M_BLOCK 1000000
+
+typedef unsigned char uchar;
+
+#define M_BLOCK_OUT (M_BLOCK + 1000000)
+uchar inbuf[M_BLOCK];
+uchar outbuf[M_BLOCK_OUT];
+uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
+
+int nIn, nOut, nZ;
+
+static char *bzerrorstrings[] = {
+       "OK"
+      ,"SEQUENCE_ERROR"
+      ,"PARAM_ERROR"
+      ,"MEM_ERROR"
+      ,"DATA_ERROR"
+      ,"DATA_ERROR_MAGIC"
+      ,"IO_ERROR"
+      ,"UNEXPECTED_EOF"
+      ,"OUTBUFF_FULL"
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+      ,"???"   /* for future */
+};
+
+void flip_bit ( int bit )
+{
+   int byteno = bit / 8;
+   int bitno  = bit % 8;
+   uchar mask = 1 << bitno;
+   //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
+   //          byteno, bitno, (int)mask );
+   zbuf[byteno] ^= mask;
+}
+
+int main ( int argc, char** argv )
+{
+   FILE* f;
+   int   r;
+   int   bit;
+   int   i;
+
+   if (argc != 2) {
+      fprintf ( stderr, "usage: unzcrash filename\n" );
+      return 1;
+   }
+
+   f = fopen ( argv[1], "r" );
+   if (!f) {
+      fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
+      return 1;
+   }
+
+   nIn = fread ( inbuf, 1, M_BLOCK, f );
+   fprintf ( stderr, "%d bytes read\n", nIn );
+
+   nZ = M_BLOCK;
+   r = BZ2_bzBuffToBuffCompress (
+         zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
+
+   assert (r == BZ_OK);
+   fprintf ( stderr, "%d after compression\n", nZ );
+
+   for (bit = 0; bit < nZ*8; bit++) {
+      fprintf ( stderr, "bit %d  ", bit );
+      flip_bit ( bit );
+      nOut = M_BLOCK_OUT;
+      r = BZ2_bzBuffToBuffDecompress (
+            outbuf, &nOut, zbuf, nZ, 0, 0 );
+      fprintf ( stderr, " %d  %s ", r, bzerrorstrings[-r] );
+
+      if (r != BZ_OK) {
+         fprintf ( stderr, "\n" );
+      } else {
+         if (nOut != nIn) {
+           fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
+           return 1;
+         } else {
+           for (i = 0; i < nOut; i++)
+             if (inbuf[i] != outbuf[i]) { 
+                fprintf(stderr, "mismatch at %d\n", i ); 
+                return 1; 
+           }
+           if (i == nOut) fprintf(stderr, "really ok!\n" );
+         }
+      }
+
+      flip_bit ( bit );
+   }
+
+#if 0
+   assert (nOut == nIn);
+   for (i = 0; i < nOut; i++) {
+     if (inbuf[i] != outbuf[i]) {
+        fprintf ( stderr, "difference at %d !\n", i );
+        return 1;
+     }
+   }
+#endif
+
+   fprintf ( stderr, "all ok\n" );
+   return 0;
+}
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words0 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words0
new file mode 100644
index 0000000..fbf442a
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words0
@@ -0,0 +1,9 @@
+
+If compilation produces errors, or a large number of warnings,
+please read README.COMPILATION.PROBLEMS -- you might be able to
+adjust the flags in this Makefile to improve matters.
+
+Also in README.COMPILATION.PROBLEMS are some hints that may help
+if your build produces an executable which is unable to correctly
+handle so-called 'large files' -- files of size 2GB or more.
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words1 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words1
new file mode 100644
index 0000000..2e83de9
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words1
@@ -0,0 +1,4 @@
+
+Doing 6 tests (3 compress, 3 uncompress) ...
+If there's a problem, things might stop at this point.
+ 
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words2 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words2
new file mode 100644
index 0000000..caddcf4
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words2
@@ -0,0 +1,5 @@
+
+Checking test results.  If any of the four "cmp"s which follow
+report any differences, something is wrong.  If you can't easily
+figure out what, please let me know (jseward@bzip.org).
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words3 b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words3
new file mode 100644
index 0000000..6972669
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/words3
@@ -0,0 +1,30 @@
+
+If you got this far and the 'cmp's didn't complain, it looks
+like you're in business.  
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and 
+/usr/local/include, type
+
+   make install
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type 
+
+   make install PREFIX=/xxx/yyy
+
+If you are (justifiably) paranoid and want to see what 'make install'
+is going to do, you can first do
+
+   make -n install                      or
+   make -n install PREFIX=/xxx/yyy      respectively.
+
+The -n instructs make to show the commands it would execute, but
+not actually execute them.
+
+Instructions for use are in the preformatted manual page, in the file
+bzip2.txt.  For more detailed documentation, read the full manual.  
+It is available in Postscript form (manual.ps), PDF form (manual.pdf),
+and HTML form (manual.html).
+
+You can also do "bzip2 --help" to see some helpful information. 
+"bzip2 -L" displays the software license.
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/xmlproc.sh b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/xmlproc.sh
new file mode 100755
index 0000000..ca284ea
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/bzip2/xmlproc.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+# see the README file for usage etc.
+#
+# ------------------------------------------------------------------
+#  This file is part of bzip2/libbzip2, a program and library for
+#  lossless, block-sorting data compression.
+#
+#  bzip2/libbzip2 version 1.0.6 of 6 September 2010
+#  Copyright (C) 1996-2010 Julian Seward 
+#
+#  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+#  README file.
+#
+#  This program is released under the terms of the license contained
+#  in the file LICENSE.
+# ----------------------------------------------------------------
+
+
+usage() {
+  echo '';
+  echo 'Usage: xmlproc.sh -[option] ';
+  echo 'Specify a target from:';
+  echo '-v      verify xml file conforms to dtd';
+  echo '-html   output in html format (single file)';
+  echo '-ps     output in postscript format';
+  echo '-pdf    output in pdf format';
+  exit;
+}
+
+if test $# -ne 2; then
+  usage
+fi
+# assign the variable for the output type
+action=$1; shift
+# assign the output filename
+xmlfile=$1; shift
+# and check user input it correct
+if !(test -f $xmlfile); then
+  echo "No such file: $xmlfile";
+  exit;
+fi
+# some other stuff we will use
+OUT=output
+xsl_fo=bz-fo.xsl
+xsl_html=bz-html.xsl
+
+basename=$xmlfile
+basename=${basename//'.xml'/''}
+
+fofile="${basename}.fo"
+htmlfile="${basename}.html"
+pdffile="${basename}.pdf"
+psfile="${basename}.ps"
+xmlfmtfile="${basename}.fmt"
+
+# first process the xmlfile with CDATA tags
+./format.pl $xmlfile $xmlfmtfile
+# so the shell knows where the catalogs live
+export XML_CATALOG_FILES=/etc/xml/catalog
+
+# post-processing tidy up
+cleanup() {
+  echo "Cleaning up: $@" 
+  while [ $# != 0 ]
+  do
+    arg=$1; shift;
+    echo "  deleting $arg";
+    rm $arg
+  done
+}
+
+case $action in
+  -v)
+   flags='--noout --xinclude --noblanks --postvalid'
+   dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd'
+   xmllint $flags $dtd $xmlfmtfile 2> $OUT 
+   egrep 'error' $OUT 
+   rm $OUT
+  ;;
+
+  -html)
+   echo "Creating $htmlfile ..."
+   xsltproc --nonet --xinclude  -o $htmlfile $xsl_html $xmlfmtfile
+   cleanup $xmlfmtfile
+  ;;
+
+  -pdf)
+   echo "Creating $pdffile ..."
+   xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
+   pdfxmltex $fofile >$OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT  tileNum;//! StringList;
+
+//Loads a stringlist from a file
+//note that each String added to StringList
+//is separated by a \\n character and it's present
+//at the end of line.
+/** Loads a StringList from a file.
+This function loads a StringList from a file where each string is divided by a \\n char.*/
+void LoadFromFile(io::IReadFile* file, StringList& strlist)
+{
+	const long sz = file->getSize();
+	char* buf = new char[sz+1];
+	file->read(buf, sz);
+	buf[sz] = 0;
+	char* p = buf;
+	char* start = p;
+
+	while(*p)
+	{
+		if (*p == '\n')
+		{
+			core::stringc str(start, (u32)(p - start - 1));
+			str.trim();
+			strlist.push_back(str);
+			start = p+1;
+		}
+
+		++p;
+	}
+
+	if (p - start > 1)
+	{
+		core::stringc str(start, (u32)(p - start - 1));
+		str.trim();
+		strlist.push_back(str);
+	}
+
+	delete [] buf;
+};
+
+//This function subdivides a string in a list of strings
+/** This function subdivides strings divided by divider in a list of strings.
+\return A StringList made of all strings divided by divider.*/
+StringList SubdivideString(const core::stringc& str, const core::stringc& divider)
+{
+	StringList strings; //returned StringList
+	strings.clear();    //clear returned stringlist
+
+	int c=0;
+	int l=str.size();
+
+	//process entire string
+	while(c& materials,
+			int num_material)
+{
+	// offset for already handled lines
+	const int offs=4;
+
+	StringList temp;
+	StringList temp1;
+
+	// The number of materials is predetermined
+	materials.reallocate(num_material);
+	for(int i=0; i=9)
+		{
+			temp1=SubdivideString(temp[temp.size() - 1],",");
+			materials[i].lightmapFlag=atoi(temp1[0].c_str());
+			materials[i].lightmapName=temp1[1];
+			materials[i].lightmapName.replace('\\','/');
+			materials[i].lightmapBlend = atoi(temp1[2].c_str());
+		}
+		else
+		{
+			materials[i].lightmapFlag=1;
+			materials[i].lightmapName="";
+		}
+	}
+	return true;
+}
+
+
+/**This function extract an array of dmfMaterial from a DMF file considering 1st an 2nd layer for water plains.
+You must give in input a StringList representing a DMF file loaded with LoadFromFile.
+\return true if function succeed or false on fail.*/
+bool GetDMFWaterMaterials(const StringList& RawFile /**& materials/**= 0.91
+	temp=SubdivideString(RawFile[0],";");//file info
+
+	if ( temp[0] != "DeleD Map File" )
+		return false;//not a deled file
+
+	temp.clear();
+	temp=SubdivideString(RawFile[1]," ");//get version
+	temp1=SubdivideString(temp[1],";");
+
+	if (atof(temp1[0].c_str()) < 0.91)
+		return false;//not correct version
+
+	//end checking
+	temp.clear();
+	temp1.clear();
+
+	for(int i=0;i pos;
+		const u32 posCount = core::strtoul10(RawFile[offs].c_str());
+		++offs;
+		pos.reallocate(posCount);
+		for (u32 i=0; i= 0.91
+	temp=SubdivideString(RawFile[0],";");//file info
+
+	if ( temp[0] != "DeleD Map File" )
+		return false;//not a deled file
+
+	temp.clear();
+	temp=SubdivideString(RawFile[1]," ");//get version
+	temp1=SubdivideString(temp[1],";");
+
+	if (atof(temp1[0].c_str()) < 0.91)
+		return false;//not correct version
+
+	//end checking
+
+	temp.clear();
+	temp1.clear();
+	offs=offs + atoi(RawFile[offs].c_str());
+	offs++;
+	s32 objs = atoi(RawFile[offs].c_str());
+	s32 lit=0;
+	s32 d_lit=0;
+	offs++;
+
+	//let's get position of lights in file
+	int i;
+	for(i=0;i= 0.91
+	temp=SubdivideString(RawFile[0],";");//file info
+
+	if ( temp[0] != "DeleD Map File" )
+		return false;//not a deled file
+
+	temp.clear();
+	temp=SubdivideString(RawFile[1]," ");//get version
+	temp1=SubdivideString(temp[1],";");
+
+	if (atof(temp1[0].c_str()) < 0.91)
+		return false;//not correct version
+
+	//end checking
+
+	temp.clear();
+	temp1.clear();
+	offs=offs+atoi(RawFile[offs].c_str());
+	offs++;
+	s32 objs=atoi(RawFile[offs].c_str());
+	s32 fac=0,vert=0,tmp_sz=0,vert_cnt=0,face_cnt=0,wat_id=0;
+	core::dimension2d tilenum(40,40);
+	f32 waveheight=3.0f;
+	f32 wavespeed=300.0f;
+	f32 wavelength=80.0f;
+	offs++;
+
+	for(int i=0;i
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+#ifndef GL_VERSION_1_2
+#define GL_UNSIGNED_BYTE_3_3_2            0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034
+#define GL_UNSIGNED_INT_8_8_8_8           0x8035
+#define GL_UNSIGNED_INT_10_10_10_2        0x8036
+#define GL_TEXTURE_BINDING_3D             0x806A
+#define GL_PACK_SKIP_IMAGES               0x806B
+#define GL_PACK_IMAGE_HEIGHT              0x806C
+#define GL_UNPACK_SKIP_IMAGES             0x806D
+#define GL_UNPACK_IMAGE_HEIGHT            0x806E
+#define GL_TEXTURE_3D                     0x806F
+#define GL_PROXY_TEXTURE_3D               0x8070
+#define GL_TEXTURE_DEPTH                  0x8071
+#define GL_TEXTURE_WRAP_R                 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE            0x8073
+#define GL_UNSIGNED_BYTE_2_3_3_REV        0x8362
+#define GL_UNSIGNED_SHORT_5_6_5           0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV       0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV     0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV     0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV       0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV    0x8368
+#define GL_BGR                            0x80E0
+#define GL_BGRA                           0x80E1
+#define GL_MAX_ELEMENTS_VERTICES          0x80E8
+#define GL_MAX_ELEMENTS_INDICES           0x80E9
+#define GL_CLAMP_TO_EDGE                  0x812F
+#define GL_TEXTURE_MIN_LOD                0x813A
+#define GL_TEXTURE_MAX_LOD                0x813B
+#define GL_TEXTURE_BASE_LEVEL             0x813C
+#define GL_TEXTURE_MAX_LEVEL              0x813D
+#define GL_SMOOTH_POINT_SIZE_RANGE        0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY  0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE        0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY  0x0B23
+#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_RESCALE_NORMAL                 0x803A
+#define GL_LIGHT_MODEL_COLOR_CONTROL      0x81F8
+#define GL_SINGLE_COLOR                   0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR        0x81FA
+#define GL_ALIASED_POINT_SIZE_RANGE       0x846D
+#endif
+
+#ifndef GL_ARB_imaging
+#define GL_CONSTANT_COLOR                 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR       0x8002
+#define GL_CONSTANT_ALPHA                 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA       0x8004
+#define GL_BLEND_COLOR                    0x8005
+#define GL_FUNC_ADD                       0x8006
+#define GL_MIN                            0x8007
+#define GL_MAX                            0x8008
+#define GL_BLEND_EQUATION                 0x8009
+#define GL_FUNC_SUBTRACT                  0x800A
+#define GL_FUNC_REVERSE_SUBTRACT          0x800B
+#endif
+
+#ifndef GL_ARB_imaging_DEPRECATED
+#define GL_CONVOLUTION_1D                 0x8010
+#define GL_CONVOLUTION_2D                 0x8011
+#define GL_SEPARABLE_2D                   0x8012
+#define GL_CONVOLUTION_BORDER_MODE        0x8013
+#define GL_CONVOLUTION_FILTER_SCALE       0x8014
+#define GL_CONVOLUTION_FILTER_BIAS        0x8015
+#define GL_REDUCE                         0x8016
+#define GL_CONVOLUTION_FORMAT             0x8017
+#define GL_CONVOLUTION_WIDTH              0x8018
+#define GL_CONVOLUTION_HEIGHT             0x8019
+#define GL_MAX_CONVOLUTION_WIDTH          0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT         0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE     0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE   0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE    0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE   0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS      0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS    0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS     0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS    0x8023
+#define GL_HISTOGRAM                      0x8024
+#define GL_PROXY_HISTOGRAM                0x8025
+#define GL_HISTOGRAM_WIDTH                0x8026
+#define GL_HISTOGRAM_FORMAT               0x8027
+#define GL_HISTOGRAM_RED_SIZE             0x8028
+#define GL_HISTOGRAM_GREEN_SIZE           0x8029
+#define GL_HISTOGRAM_BLUE_SIZE            0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE           0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE       0x802C
+#define GL_HISTOGRAM_SINK                 0x802D
+#define GL_MINMAX                         0x802E
+#define GL_MINMAX_FORMAT                  0x802F
+#define GL_MINMAX_SINK                    0x8030
+#define GL_TABLE_TOO_LARGE                0x8031
+#define GL_COLOR_MATRIX                   0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH       0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH   0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE    0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE  0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE   0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE  0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS     0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS   0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS    0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS   0x80BB
+#define GL_COLOR_TABLE                    0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE   0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE  0x80D2
+#define GL_PROXY_COLOR_TABLE              0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE              0x80D6
+#define GL_COLOR_TABLE_BIAS               0x80D7
+#define GL_COLOR_TABLE_FORMAT             0x80D8
+#define GL_COLOR_TABLE_WIDTH              0x80D9
+#define GL_COLOR_TABLE_RED_SIZE           0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE         0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE          0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE         0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE     0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE     0x80DF
+#define GL_CONSTANT_BORDER                0x8151
+#define GL_REPLICATE_BORDER               0x8153
+#define GL_CONVOLUTION_BORDER_COLOR       0x8154
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_TEXTURE0                       0x84C0
+#define GL_TEXTURE1                       0x84C1
+#define GL_TEXTURE2                       0x84C2
+#define GL_TEXTURE3                       0x84C3
+#define GL_TEXTURE4                       0x84C4
+#define GL_TEXTURE5                       0x84C5
+#define GL_TEXTURE6                       0x84C6
+#define GL_TEXTURE7                       0x84C7
+#define GL_TEXTURE8                       0x84C8
+#define GL_TEXTURE9                       0x84C9
+#define GL_TEXTURE10                      0x84CA
+#define GL_TEXTURE11                      0x84CB
+#define GL_TEXTURE12                      0x84CC
+#define GL_TEXTURE13                      0x84CD
+#define GL_TEXTURE14                      0x84CE
+#define GL_TEXTURE15                      0x84CF
+#define GL_TEXTURE16                      0x84D0
+#define GL_TEXTURE17                      0x84D1
+#define GL_TEXTURE18                      0x84D2
+#define GL_TEXTURE19                      0x84D3
+#define GL_TEXTURE20                      0x84D4
+#define GL_TEXTURE21                      0x84D5
+#define GL_TEXTURE22                      0x84D6
+#define GL_TEXTURE23                      0x84D7
+#define GL_TEXTURE24                      0x84D8
+#define GL_TEXTURE25                      0x84D9
+#define GL_TEXTURE26                      0x84DA
+#define GL_TEXTURE27                      0x84DB
+#define GL_TEXTURE28                      0x84DC
+#define GL_TEXTURE29                      0x84DD
+#define GL_TEXTURE30                      0x84DE
+#define GL_TEXTURE31                      0x84DF
+#define GL_ACTIVE_TEXTURE                 0x84E0
+#define GL_MULTISAMPLE                    0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE            0x809F
+#define GL_SAMPLE_COVERAGE                0x80A0
+#define GL_SAMPLE_BUFFERS                 0x80A8
+#define GL_SAMPLES                        0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE          0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT         0x80AB
+#define GL_TEXTURE_CUBE_MAP               0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP       0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y    0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z    0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP         0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE      0x851C
+#define GL_COMPRESSED_RGB                 0x84ED
+#define GL_COMPRESSED_RGBA                0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT       0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE  0x86A0
+#define GL_TEXTURE_COMPRESSED             0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3
+#define GL_CLAMP_TO_BORDER                0x812D
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_CLIENT_ACTIVE_TEXTURE          0x84E1
+#define GL_MAX_TEXTURE_UNITS              0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX     0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX    0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX       0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX         0x84E6
+#define GL_MULTISAMPLE_BIT                0x20000000
+#define GL_NORMAL_MAP                     0x8511
+#define GL_REFLECTION_MAP                 0x8512
+#define GL_COMPRESSED_ALPHA               0x84E9
+#define GL_COMPRESSED_LUMINANCE           0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA     0x84EB
+#define GL_COMPRESSED_INTENSITY           0x84EC
+#define GL_COMBINE                        0x8570
+#define GL_COMBINE_RGB                    0x8571
+#define GL_COMBINE_ALPHA                  0x8572
+#define GL_SOURCE0_RGB                    0x8580
+#define GL_SOURCE1_RGB                    0x8581
+#define GL_SOURCE2_RGB                    0x8582
+#define GL_SOURCE0_ALPHA                  0x8588
+#define GL_SOURCE1_ALPHA                  0x8589
+#define GL_SOURCE2_ALPHA                  0x858A
+#define GL_OPERAND0_RGB                   0x8590
+#define GL_OPERAND1_RGB                   0x8591
+#define GL_OPERAND2_RGB                   0x8592
+#define GL_OPERAND0_ALPHA                 0x8598
+#define GL_OPERAND1_ALPHA                 0x8599
+#define GL_OPERAND2_ALPHA                 0x859A
+#define GL_RGB_SCALE                      0x8573
+#define GL_ADD_SIGNED                     0x8574
+#define GL_INTERPOLATE                    0x8575
+#define GL_SUBTRACT                       0x84E7
+#define GL_CONSTANT                       0x8576
+#define GL_PRIMARY_COLOR                  0x8577
+#define GL_PREVIOUS                       0x8578
+#define GL_DOT3_RGB                       0x86AE
+#define GL_DOT3_RGBA                      0x86AF
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_BLEND_DST_RGB                  0x80C8
+#define GL_BLEND_SRC_RGB                  0x80C9
+#define GL_BLEND_DST_ALPHA                0x80CA
+#define GL_BLEND_SRC_ALPHA                0x80CB
+#define GL_POINT_FADE_THRESHOLD_SIZE      0x8128
+#define GL_DEPTH_COMPONENT16              0x81A5
+#define GL_DEPTH_COMPONENT24              0x81A6
+#define GL_DEPTH_COMPONENT32              0x81A7
+#define GL_MIRRORED_REPEAT                0x8370
+#define GL_MAX_TEXTURE_LOD_BIAS           0x84FD
+#define GL_TEXTURE_LOD_BIAS               0x8501
+#define GL_INCR_WRAP                      0x8507
+#define GL_DECR_WRAP                      0x8508
+#define GL_TEXTURE_DEPTH_SIZE             0x884A
+#define GL_TEXTURE_COMPARE_MODE           0x884C
+#define GL_TEXTURE_COMPARE_FUNC           0x884D
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_POINT_SIZE_MIN                 0x8126
+#define GL_POINT_SIZE_MAX                 0x8127
+#define GL_POINT_DISTANCE_ATTENUATION     0x8129
+#define GL_GENERATE_MIPMAP                0x8191
+#define GL_GENERATE_MIPMAP_HINT           0x8192
+#define GL_FOG_COORDINATE_SOURCE          0x8450
+#define GL_FOG_COORDINATE                 0x8451
+#define GL_FRAGMENT_DEPTH                 0x8452
+#define GL_CURRENT_FOG_COORDINATE         0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE      0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE    0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER   0x8456
+#define GL_FOG_COORDINATE_ARRAY           0x8457
+#define GL_COLOR_SUM                      0x8458
+#define GL_CURRENT_SECONDARY_COLOR        0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE     0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE     0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE   0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER  0x845D
+#define GL_SECONDARY_COLOR_ARRAY          0x845E
+#define GL_TEXTURE_FILTER_CONTROL         0x8500
+#define GL_DEPTH_TEXTURE_MODE             0x884B
+#define GL_COMPARE_R_TO_TEXTURE           0x884E
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_BUFFER_SIZE                    0x8764
+#define GL_BUFFER_USAGE                   0x8765
+#define GL_QUERY_COUNTER_BITS             0x8864
+#define GL_CURRENT_QUERY                  0x8865
+#define GL_QUERY_RESULT                   0x8866
+#define GL_QUERY_RESULT_AVAILABLE         0x8867
+#define GL_ARRAY_BUFFER                   0x8892
+#define GL_ELEMENT_ARRAY_BUFFER           0x8893
+#define GL_ARRAY_BUFFER_BINDING           0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING   0x8895
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY                      0x88B8
+#define GL_WRITE_ONLY                     0x88B9
+#define GL_READ_WRITE                     0x88BA
+#define GL_BUFFER_ACCESS                  0x88BB
+#define GL_BUFFER_MAPPED                  0x88BC
+#define GL_BUFFER_MAP_POINTER             0x88BD
+#define GL_STREAM_DRAW                    0x88E0
+#define GL_STREAM_READ                    0x88E1
+#define GL_STREAM_COPY                    0x88E2
+#define GL_STATIC_DRAW                    0x88E4
+#define GL_STATIC_READ                    0x88E5
+#define GL_STATIC_COPY                    0x88E6
+#define GL_DYNAMIC_DRAW                   0x88E8
+#define GL_DYNAMIC_READ                   0x88E9
+#define GL_DYNAMIC_COPY                   0x88EA
+#define GL_SAMPLES_PASSED                 0x8914
+#endif
+
+#ifndef GL_VERSION_1_5_DEPRECATED
+#define GL_VERTEX_ARRAY_BUFFER_BINDING    0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING    0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING     0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING     0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING    0x889E
+#define GL_FOG_COORD_SRC                  0x8450
+#define GL_FOG_COORD                      0x8451
+#define GL_CURRENT_FOG_COORD              0x8453
+#define GL_FOG_COORD_ARRAY_TYPE           0x8454
+#define GL_FOG_COORD_ARRAY_STRIDE         0x8455
+#define GL_FOG_COORD_ARRAY_POINTER        0x8456
+#define GL_FOG_COORD_ARRAY                0x8457
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
+#define GL_SRC0_RGB                       0x8580
+#define GL_SRC1_RGB                       0x8581
+#define GL_SRC2_RGB                       0x8582
+#define GL_SRC0_ALPHA                     0x8588
+#define GL_SRC1_ALPHA                     0x8589
+#define GL_SRC2_ALPHA                     0x858A
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_BLEND_EQUATION_RGB             0x8009
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED    0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE       0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE     0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE       0x8625
+#define GL_CURRENT_VERTEX_ATTRIB          0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE      0x8642
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER    0x8645
+#define GL_STENCIL_BACK_FUNC              0x8800
+#define GL_STENCIL_BACK_FAIL              0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL   0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS   0x8803
+#define GL_MAX_DRAW_BUFFERS               0x8824
+#define GL_DRAW_BUFFER0                   0x8825
+#define GL_DRAW_BUFFER1                   0x8826
+#define GL_DRAW_BUFFER2                   0x8827
+#define GL_DRAW_BUFFER3                   0x8828
+#define GL_DRAW_BUFFER4                   0x8829
+#define GL_DRAW_BUFFER5                   0x882A
+#define GL_DRAW_BUFFER6                   0x882B
+#define GL_DRAW_BUFFER7                   0x882C
+#define GL_DRAW_BUFFER8                   0x882D
+#define GL_DRAW_BUFFER9                   0x882E
+#define GL_DRAW_BUFFER10                  0x882F
+#define GL_DRAW_BUFFER11                  0x8830
+#define GL_DRAW_BUFFER12                  0x8831
+#define GL_DRAW_BUFFER13                  0x8832
+#define GL_DRAW_BUFFER14                  0x8833
+#define GL_DRAW_BUFFER15                  0x8834
+#define GL_BLEND_EQUATION_ALPHA           0x883D
+#define GL_MAX_VERTEX_ATTRIBS             0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_IMAGE_UNITS        0x8872
+#define GL_FRAGMENT_SHADER                0x8B30
+#define GL_VERTEX_SHADER                  0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS  0x8B4A
+#define GL_MAX_VARYING_FLOATS             0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE                    0x8B4F
+#define GL_FLOAT_VEC2                     0x8B50
+#define GL_FLOAT_VEC3                     0x8B51
+#define GL_FLOAT_VEC4                     0x8B52
+#define GL_INT_VEC2                       0x8B53
+#define GL_INT_VEC3                       0x8B54
+#define GL_INT_VEC4                       0x8B55
+#define GL_BOOL                           0x8B56
+#define GL_BOOL_VEC2                      0x8B57
+#define GL_BOOL_VEC3                      0x8B58
+#define GL_BOOL_VEC4                      0x8B59
+#define GL_FLOAT_MAT2                     0x8B5A
+#define GL_FLOAT_MAT3                     0x8B5B
+#define GL_FLOAT_MAT4                     0x8B5C
+#define GL_SAMPLER_1D                     0x8B5D
+#define GL_SAMPLER_2D                     0x8B5E
+#define GL_SAMPLER_3D                     0x8B5F
+#define GL_SAMPLER_CUBE                   0x8B60
+#define GL_SAMPLER_1D_SHADOW              0x8B61
+#define GL_SAMPLER_2D_SHADOW              0x8B62
+#define GL_DELETE_STATUS                  0x8B80
+#define GL_COMPILE_STATUS                 0x8B81
+#define GL_LINK_STATUS                    0x8B82
+#define GL_VALIDATE_STATUS                0x8B83
+#define GL_INFO_LOG_LENGTH                0x8B84
+#define GL_ATTACHED_SHADERS               0x8B85
+#define GL_ACTIVE_UNIFORMS                0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH      0x8B87
+#define GL_SHADER_SOURCE_LENGTH           0x8B88
+#define GL_ACTIVE_ATTRIBUTES              0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH    0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION       0x8B8C
+#define GL_CURRENT_PROGRAM                0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN      0x8CA0
+#define GL_LOWER_LEFT                     0x8CA1
+#define GL_UPPER_LEFT                     0x8CA2
+#define GL_STENCIL_BACK_REF               0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK        0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK         0x8CA5
+#endif
+
+#ifndef GL_VERSION_2_0_DEPRECATED
+#define GL_VERTEX_PROGRAM_TWO_SIDE        0x8643
+#define GL_POINT_SPRITE                   0x8861
+#define GL_COORD_REPLACE                  0x8862
+#define GL_MAX_TEXTURE_COORDS             0x8871
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_PIXEL_PACK_BUFFER              0x88EB
+#define GL_PIXEL_UNPACK_BUFFER            0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING      0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING    0x88EF
+#define GL_FLOAT_MAT2x3                   0x8B65
+#define GL_FLOAT_MAT2x4                   0x8B66
+#define GL_FLOAT_MAT3x2                   0x8B67
+#define GL_FLOAT_MAT3x4                   0x8B68
+#define GL_FLOAT_MAT4x2                   0x8B69
+#define GL_FLOAT_MAT4x3                   0x8B6A
+#define GL_SRGB                           0x8C40
+#define GL_SRGB8                          0x8C41
+#define GL_SRGB_ALPHA                     0x8C42
+#define GL_SRGB8_ALPHA8                   0x8C43
+#define GL_COMPRESSED_SRGB                0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA          0x8C49
+#endif
+
+#ifndef GL_VERSION_2_1_DEPRECATED
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_SLUMINANCE_ALPHA               0x8C44
+#define GL_SLUMINANCE8_ALPHA8             0x8C45
+#define GL_SLUMINANCE                     0x8C46
+#define GL_SLUMINANCE8                    0x8C47
+#define GL_COMPRESSED_SLUMINANCE          0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA    0x8C4B
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_COMPARE_REF_TO_TEXTURE         0x884E
+#define GL_CLIP_DISTANCE0                 0x3000
+#define GL_CLIP_DISTANCE1                 0x3001
+#define GL_CLIP_DISTANCE2                 0x3002
+#define GL_CLIP_DISTANCE3                 0x3003
+#define GL_CLIP_DISTANCE4                 0x3004
+#define GL_CLIP_DISTANCE5                 0x3005
+#define GL_CLIP_DISTANCE6                 0x3006
+#define GL_CLIP_DISTANCE7                 0x3007
+#define GL_MAX_CLIP_DISTANCES             0x0D32
+#define GL_MAJOR_VERSION                  0x821B
+#define GL_MINOR_VERSION                  0x821C
+#define GL_NUM_EXTENSIONS                 0x821D
+#define GL_CONTEXT_FLAGS                  0x821E
+#define GL_DEPTH_BUFFER                   0x8223
+#define GL_STENCIL_BUFFER                 0x8224
+#define GL_COMPRESSED_RED                 0x8225
+#define GL_COMPRESSED_RG                  0x8226
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_RGBA32F                        0x8814
+#define GL_RGB32F                         0x8815
+#define GL_RGBA16F                        0x881A
+#define GL_RGB16F                         0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER    0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS       0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET       0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET       0x8905
+#define GL_CLAMP_READ_COLOR               0x891C
+#define GL_FIXED_ONLY                     0x891D
+#define GL_MAX_VARYING_COMPONENTS         0x8B4B
+#define GL_TEXTURE_1D_ARRAY               0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY         0x8C19
+#define GL_TEXTURE_2D_ARRAY               0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY         0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY       0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY       0x8C1D
+#define GL_R11F_G11F_B10F                 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV   0x8C3B
+#define GL_RGB9_E5                        0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV       0x8C3E
+#define GL_TEXTURE_SHARED_SIZE            0x8C3F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS    0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_PRIMITIVES_GENERATED           0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD             0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS            0x8C8C
+#define GL_SEPARATE_ATTRIBS               0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER      0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI                       0x8D70
+#define GL_RGB32UI                        0x8D71
+#define GL_RGBA16UI                       0x8D76
+#define GL_RGB16UI                        0x8D77
+#define GL_RGBA8UI                        0x8D7C
+#define GL_RGB8UI                         0x8D7D
+#define GL_RGBA32I                        0x8D82
+#define GL_RGB32I                         0x8D83
+#define GL_RGBA16I                        0x8D88
+#define GL_RGB16I                         0x8D89
+#define GL_RGBA8I                         0x8D8E
+#define GL_RGB8I                          0x8D8F
+#define GL_RED_INTEGER                    0x8D94
+#define GL_GREEN_INTEGER                  0x8D95
+#define GL_BLUE_INTEGER                   0x8D96
+#define GL_RGB_INTEGER                    0x8D98
+#define GL_RGBA_INTEGER                   0x8D99
+#define GL_BGR_INTEGER                    0x8D9A
+#define GL_BGRA_INTEGER                   0x8D9B
+#define GL_SAMPLER_1D_ARRAY               0x8DC0
+#define GL_SAMPLER_2D_ARRAY               0x8DC1
+#define GL_SAMPLER_1D_ARRAY_SHADOW        0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW        0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW            0x8DC5
+#define GL_UNSIGNED_INT_VEC2              0x8DC6
+#define GL_UNSIGNED_INT_VEC3              0x8DC7
+#define GL_UNSIGNED_INT_VEC4              0x8DC8
+#define GL_INT_SAMPLER_1D                 0x8DC9
+#define GL_INT_SAMPLER_2D                 0x8DCA
+#define GL_INT_SAMPLER_3D                 0x8DCB
+#define GL_INT_SAMPLER_CUBE               0x8DCC
+#define GL_INT_SAMPLER_1D_ARRAY           0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY           0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_1D        0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D        0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D        0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE      0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY  0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY  0x8DD7
+#define GL_QUERY_WAIT                     0x8E13
+#define GL_QUERY_NO_WAIT                  0x8E14
+#define GL_QUERY_BY_REGION_WAIT           0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT        0x8E16
+#define GL_BUFFER_ACCESS_FLAGS            0x911F
+#define GL_BUFFER_MAP_LENGTH              0x9120
+#define GL_BUFFER_MAP_OFFSET              0x9121
+/* Reuse tokens from ARB_depth_buffer_float */
+/* reuse GL_DEPTH_COMPONENT32F */
+/* reuse GL_DEPTH32F_STENCIL8 */
+/* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */
+/* Reuse tokens from ARB_framebuffer_object */
+/* reuse GL_INVALID_FRAMEBUFFER_OPERATION */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+/* reuse GL_FRAMEBUFFER_DEFAULT */
+/* reuse GL_FRAMEBUFFER_UNDEFINED */
+/* reuse GL_DEPTH_STENCIL_ATTACHMENT */
+/* reuse GL_INDEX */
+/* reuse GL_MAX_RENDERBUFFER_SIZE */
+/* reuse GL_DEPTH_STENCIL */
+/* reuse GL_UNSIGNED_INT_24_8 */
+/* reuse GL_DEPTH24_STENCIL8 */
+/* reuse GL_TEXTURE_STENCIL_SIZE */
+/* reuse GL_TEXTURE_RED_TYPE */
+/* reuse GL_TEXTURE_GREEN_TYPE */
+/* reuse GL_TEXTURE_BLUE_TYPE */
+/* reuse GL_TEXTURE_ALPHA_TYPE */
+/* reuse GL_TEXTURE_DEPTH_TYPE */
+/* reuse GL_UNSIGNED_NORMALIZED */
+/* reuse GL_FRAMEBUFFER_BINDING */
+/* reuse GL_DRAW_FRAMEBUFFER_BINDING */
+/* reuse GL_RENDERBUFFER_BINDING */
+/* reuse GL_READ_FRAMEBUFFER */
+/* reuse GL_DRAW_FRAMEBUFFER */
+/* reuse GL_READ_FRAMEBUFFER_BINDING */
+/* reuse GL_RENDERBUFFER_SAMPLES */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* reuse GL_FRAMEBUFFER_COMPLETE */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+/* reuse GL_FRAMEBUFFER_UNSUPPORTED */
+/* reuse GL_MAX_COLOR_ATTACHMENTS */
+/* reuse GL_COLOR_ATTACHMENT0 */
+/* reuse GL_COLOR_ATTACHMENT1 */
+/* reuse GL_COLOR_ATTACHMENT2 */
+/* reuse GL_COLOR_ATTACHMENT3 */
+/* reuse GL_COLOR_ATTACHMENT4 */
+/* reuse GL_COLOR_ATTACHMENT5 */
+/* reuse GL_COLOR_ATTACHMENT6 */
+/* reuse GL_COLOR_ATTACHMENT7 */
+/* reuse GL_COLOR_ATTACHMENT8 */
+/* reuse GL_COLOR_ATTACHMENT9 */
+/* reuse GL_COLOR_ATTACHMENT10 */
+/* reuse GL_COLOR_ATTACHMENT11 */
+/* reuse GL_COLOR_ATTACHMENT12 */
+/* reuse GL_COLOR_ATTACHMENT13 */
+/* reuse GL_COLOR_ATTACHMENT14 */
+/* reuse GL_COLOR_ATTACHMENT15 */
+/* reuse GL_DEPTH_ATTACHMENT */
+/* reuse GL_STENCIL_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER */
+/* reuse GL_RENDERBUFFER */
+/* reuse GL_RENDERBUFFER_WIDTH */
+/* reuse GL_RENDERBUFFER_HEIGHT */
+/* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */
+/* reuse GL_STENCIL_INDEX1 */
+/* reuse GL_STENCIL_INDEX4 */
+/* reuse GL_STENCIL_INDEX8 */
+/* reuse GL_STENCIL_INDEX16 */
+/* reuse GL_RENDERBUFFER_RED_SIZE */
+/* reuse GL_RENDERBUFFER_GREEN_SIZE */
+/* reuse GL_RENDERBUFFER_BLUE_SIZE */
+/* reuse GL_RENDERBUFFER_ALPHA_SIZE */
+/* reuse GL_RENDERBUFFER_DEPTH_SIZE */
+/* reuse GL_RENDERBUFFER_STENCIL_SIZE */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+/* reuse GL_MAX_SAMPLES */
+/* Reuse tokens from ARB_framebuffer_sRGB */
+/* reuse GL_FRAMEBUFFER_SRGB */
+/* Reuse tokens from ARB_half_float_vertex */
+/* reuse GL_HALF_FLOAT */
+/* Reuse tokens from ARB_map_buffer_range */
+/* reuse GL_MAP_READ_BIT */
+/* reuse GL_MAP_WRITE_BIT */
+/* reuse GL_MAP_INVALIDATE_RANGE_BIT */
+/* reuse GL_MAP_INVALIDATE_BUFFER_BIT */
+/* reuse GL_MAP_FLUSH_EXPLICIT_BIT */
+/* reuse GL_MAP_UNSYNCHRONIZED_BIT */
+/* Reuse tokens from ARB_texture_compression_rgtc */
+/* reuse GL_COMPRESSED_RED_RGTC1 */
+/* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */
+/* reuse GL_COMPRESSED_RG_RGTC2 */
+/* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */
+/* Reuse tokens from ARB_texture_rg */
+/* reuse GL_RG */
+/* reuse GL_RG_INTEGER */
+/* reuse GL_R8 */
+/* reuse GL_R16 */
+/* reuse GL_RG8 */
+/* reuse GL_RG16 */
+/* reuse GL_R16F */
+/* reuse GL_R32F */
+/* reuse GL_RG16F */
+/* reuse GL_RG32F */
+/* reuse GL_R8I */
+/* reuse GL_R8UI */
+/* reuse GL_R16I */
+/* reuse GL_R16UI */
+/* reuse GL_R32I */
+/* reuse GL_R32UI */
+/* reuse GL_RG8I */
+/* reuse GL_RG8UI */
+/* reuse GL_RG16I */
+/* reuse GL_RG16UI */
+/* reuse GL_RG32I */
+/* reuse GL_RG32UI */
+/* Reuse tokens from ARB_vertex_array_object */
+/* reuse GL_VERTEX_ARRAY_BINDING */
+#endif
+
+#ifndef GL_VERSION_3_0_DEPRECATED
+#define GL_CLAMP_VERTEX_COLOR             0x891A
+#define GL_CLAMP_FRAGMENT_COLOR           0x891B
+#define GL_ALPHA_INTEGER                  0x8D97
+/* Reuse tokens from ARB_framebuffer_object */
+/* reuse GL_TEXTURE_LUMINANCE_TYPE */
+/* reuse GL_TEXTURE_INTENSITY_TYPE */
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_SAMPLER_2D_RECT                0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW         0x8B64
+#define GL_SAMPLER_BUFFER                 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT            0x8DCD
+#define GL_INT_SAMPLER_BUFFER             0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT   0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER    0x8DD8
+#define GL_TEXTURE_BUFFER                 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE        0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER         0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT          0x8C2E
+#define GL_TEXTURE_RECTANGLE              0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE      0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE        0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE     0x84F8
+#define GL_RED_SNORM                      0x8F90
+#define GL_RG_SNORM                       0x8F91
+#define GL_RGB_SNORM                      0x8F92
+#define GL_RGBA_SNORM                     0x8F93
+#define GL_R8_SNORM                       0x8F94
+#define GL_RG8_SNORM                      0x8F95
+#define GL_RGB8_SNORM                     0x8F96
+#define GL_RGBA8_SNORM                    0x8F97
+#define GL_R16_SNORM                      0x8F98
+#define GL_RG16_SNORM                     0x8F99
+#define GL_RGB16_SNORM                    0x8F9A
+#define GL_RGBA16_SNORM                   0x8F9B
+#define GL_SIGNED_NORMALIZED              0x8F9C
+#define GL_PRIMITIVE_RESTART              0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX        0x8F9E
+/* Reuse tokens from ARB_copy_buffer */
+/* reuse GL_COPY_READ_BUFFER */
+/* reuse GL_COPY_WRITE_BUFFER */
+/* Reuse tokens from ARB_draw_instanced (none) */
+/* Reuse tokens from ARB_uniform_buffer_object */
+/* reuse GL_UNIFORM_BUFFER */
+/* reuse GL_UNIFORM_BUFFER_BINDING */
+/* reuse GL_UNIFORM_BUFFER_START */
+/* reuse GL_UNIFORM_BUFFER_SIZE */
+/* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */
+/* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */
+/* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */
+/* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */
+/* reuse GL_MAX_UNIFORM_BLOCK_SIZE */
+/* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */
+/* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */
+/* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */
+/* reuse GL_ACTIVE_UNIFORM_BLOCKS */
+/* reuse GL_UNIFORM_TYPE */
+/* reuse GL_UNIFORM_SIZE */
+/* reuse GL_UNIFORM_NAME_LENGTH */
+/* reuse GL_UNIFORM_BLOCK_INDEX */
+/* reuse GL_UNIFORM_OFFSET */
+/* reuse GL_UNIFORM_ARRAY_STRIDE */
+/* reuse GL_UNIFORM_MATRIX_STRIDE */
+/* reuse GL_UNIFORM_IS_ROW_MAJOR */
+/* reuse GL_UNIFORM_BLOCK_BINDING */
+/* reuse GL_UNIFORM_BLOCK_DATA_SIZE */
+/* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */
+/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */
+/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */
+/* reuse GL_INVALID_INDEX */
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_CORE_PROFILE_BIT       0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY                0x000A
+#define GL_LINE_STRIP_ADJACENCY           0x000B
+#define GL_TRIANGLES_ADJACENCY            0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY       0x000D
+#define GL_PROGRAM_POINT_SIZE             0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER                0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT          0x8916
+#define GL_GEOMETRY_INPUT_TYPE            0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE           0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES   0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS   0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS  0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS  0x9125
+#define GL_CONTEXT_PROFILE_MASK           0x9126
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* Reuse tokens from ARB_depth_clamp */
+/* reuse GL_DEPTH_CLAMP */
+/* Reuse tokens from ARB_draw_elements_base_vertex (none) */
+/* Reuse tokens from ARB_fragment_coord_conventions (none) */
+/* Reuse tokens from ARB_provoking_vertex */
+/* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+/* Reuse tokens from ARB_seamless_cube_map */
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+/* Reuse tokens from ARB_sync */
+/* reuse GL_MAX_SERVER_WAIT_TIMEOUT */
+/* reuse GL_OBJECT_TYPE */
+/* reuse GL_SYNC_CONDITION */
+/* reuse GL_SYNC_STATUS */
+/* reuse GL_SYNC_FLAGS */
+/* reuse GL_SYNC_FENCE */
+/* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */
+/* reuse GL_UNSIGNALED */
+/* reuse GL_SIGNALED */
+/* reuse GL_ALREADY_SIGNALED */
+/* reuse GL_TIMEOUT_EXPIRED */
+/* reuse GL_CONDITION_SATISFIED */
+/* reuse GL_WAIT_FAILED */
+/* reuse GL_TIMEOUT_IGNORED */
+/* reuse GL_SYNC_FLUSH_COMMANDS_BIT */
+/* reuse GL_TIMEOUT_IGNORED */
+/* Reuse tokens from ARB_texture_multisample */
+/* reuse GL_SAMPLE_POSITION */
+/* reuse GL_SAMPLE_MASK */
+/* reuse GL_SAMPLE_MASK_VALUE */
+/* reuse GL_MAX_SAMPLE_MASK_WORDS */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_SAMPLES */
+/* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */
+/* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */
+/* reuse GL_MAX_INTEGER_SAMPLES */
+/* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR    0x88FE
+/* Reuse tokens from ARB_blend_func_extended */
+/* reuse GL_SRC1_COLOR */
+/* reuse GL_ONE_MINUS_SRC1_COLOR */
+/* reuse GL_ONE_MINUS_SRC1_ALPHA */
+/* reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */
+/* Reuse tokens from ARB_explicit_attrib_location (none) */
+/* Reuse tokens from ARB_occlusion_query2 */
+/* reuse GL_ANY_SAMPLES_PASSED */
+/* Reuse tokens from ARB_sampler_objects */
+/* reuse GL_SAMPLER_BINDING */
+/* Reuse tokens from ARB_shader_bit_encoding (none) */
+/* Reuse tokens from ARB_texture_rgb10_a2ui */
+/* reuse GL_RGB10_A2UI */
+/* Reuse tokens from ARB_texture_swizzle */
+/* reuse GL_TEXTURE_SWIZZLE_R */
+/* reuse GL_TEXTURE_SWIZZLE_G */
+/* reuse GL_TEXTURE_SWIZZLE_B */
+/* reuse GL_TEXTURE_SWIZZLE_A */
+/* reuse GL_TEXTURE_SWIZZLE_RGBA */
+/* Reuse tokens from ARB_timer_query */
+/* reuse GL_TIME_ELAPSED */
+/* reuse GL_TIMESTAMP */
+/* Reuse tokens from ARB_vertex_type_2_10_10_10_rev */
+/* reuse GL_INT_2_10_10_10_REV */
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_SAMPLE_SHADING                 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE       0x8C37
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_TEXTURE_CUBE_MAP_ARRAY         0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY   0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY         0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW  0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY     0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+/* Reuse tokens from ARB_texture_query_lod (none) */
+/* Reuse tokens from ARB_draw_buffers_blend (none) */
+/* Reuse tokens from ARB_draw_indirect */
+/* reuse GL_DRAW_INDIRECT_BUFFER */
+/* reuse GL_DRAW_INDIRECT_BUFFER_BINDING */
+/* Reuse tokens from ARB_gpu_shader5 */
+/* reuse GL_GEOMETRY_SHADER_INVOCATIONS */
+/* reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS */
+/* reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */
+/* reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */
+/* reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */
+/* reuse GL_MAX_VERTEX_STREAMS */
+/* Reuse tokens from ARB_gpu_shader_fp64 */
+/* reuse GL_DOUBLE_VEC2 */
+/* reuse GL_DOUBLE_VEC3 */
+/* reuse GL_DOUBLE_VEC4 */
+/* reuse GL_DOUBLE_MAT2 */
+/* reuse GL_DOUBLE_MAT3 */
+/* reuse GL_DOUBLE_MAT4 */
+/* reuse GL_DOUBLE_MAT2x3 */
+/* reuse GL_DOUBLE_MAT2x4 */
+/* reuse GL_DOUBLE_MAT3x2 */
+/* reuse GL_DOUBLE_MAT3x4 */
+/* reuse GL_DOUBLE_MAT4x2 */
+/* reuse GL_DOUBLE_MAT4x3 */
+/* Reuse tokens from ARB_shader_subroutine */
+/* reuse GL_ACTIVE_SUBROUTINES */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORMS */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS */
+/* reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH */
+/* reuse GL_MAX_SUBROUTINES */
+/* reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS */
+/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */
+/* reuse GL_COMPATIBLE_SUBROUTINES */
+/* Reuse tokens from ARB_tessellation_shader */
+/* reuse GL_PATCHES */
+/* reuse GL_PATCH_VERTICES */
+/* reuse GL_PATCH_DEFAULT_INNER_LEVEL */
+/* reuse GL_PATCH_DEFAULT_OUTER_LEVEL */
+/* reuse GL_TESS_CONTROL_OUTPUT_VERTICES */
+/* reuse GL_TESS_GEN_MODE */
+/* reuse GL_TESS_GEN_SPACING */
+/* reuse GL_TESS_GEN_VERTEX_ORDER */
+/* reuse GL_TESS_GEN_POINT_MODE */
+/* reuse GL_ISOLINES */
+/* reuse GL_FRACTIONAL_ODD */
+/* reuse GL_FRACTIONAL_EVEN */
+/* reuse GL_MAX_PATCH_VERTICES */
+/* reuse GL_MAX_TESS_GEN_LEVEL */
+/* reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_PATCH_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS */
+/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS */
+/* reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS */
+/* reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER */
+/* reuse GL_TESS_EVALUATION_SHADER */
+/* reuse GL_TESS_CONTROL_SHADER */
+/* Reuse tokens from ARB_texture_buffer_object_rgb32 (none) */
+/* Reuse tokens from ARB_transform_feedback2 */
+/* reuse GL_TRANSFORM_FEEDBACK */
+/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */
+/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */
+/* reuse GL_TRANSFORM_FEEDBACK_BINDING */
+/* Reuse tokens from ARB_transform_feedback3 */
+/* reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */
+/* reuse GL_MAX_VERTEX_STREAMS */
+#endif
+
+#ifndef GL_VERSION_4_1
+/* Reuse tokens from ARB_ES2_compatibility */
+/* reuse GL_FIXED */
+/* reuse GL_IMPLEMENTATION_COLOR_READ_TYPE */
+/* reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT */
+/* reuse GL_LOW_FLOAT */
+/* reuse GL_MEDIUM_FLOAT */
+/* reuse GL_HIGH_FLOAT */
+/* reuse GL_LOW_INT */
+/* reuse GL_MEDIUM_INT */
+/* reuse GL_HIGH_INT */
+/* reuse GL_SHADER_COMPILER */
+/* reuse GL_NUM_SHADER_BINARY_FORMATS */
+/* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */
+/* reuse GL_MAX_VARYING_VECTORS */
+/* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+/* Reuse tokens from ARB_get_program_binary */
+/* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */
+/* reuse GL_PROGRAM_BINARY_LENGTH */
+/* reuse GL_NUM_PROGRAM_BINARY_FORMATS */
+/* reuse GL_PROGRAM_BINARY_FORMATS */
+/* Reuse tokens from ARB_separate_shader_objects */
+/* reuse GL_VERTEX_SHADER_BIT */
+/* reuse GL_FRAGMENT_SHADER_BIT */
+/* reuse GL_GEOMETRY_SHADER_BIT */
+/* reuse GL_TESS_CONTROL_SHADER_BIT */
+/* reuse GL_TESS_EVALUATION_SHADER_BIT */
+/* reuse GL_ALL_SHADER_BITS */
+/* reuse GL_PROGRAM_SEPARABLE */
+/* reuse GL_ACTIVE_PROGRAM */
+/* reuse GL_PROGRAM_PIPELINE_BINDING */
+/* Reuse tokens from ARB_shader_precision (none) */
+/* Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already */
+/* Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already */
+/* reuse GL_MAX_VIEWPORTS */
+/* reuse GL_VIEWPORT_SUBPIXEL_BITS */
+/* reuse GL_VIEWPORT_BOUNDS_RANGE */
+/* reuse GL_LAYER_PROVOKING_VERTEX */
+/* reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX */
+/* reuse GL_UNDEFINED_VERTEX */
+#endif
+
+#ifndef GL_VERSION_4_2
+/* Reuse tokens from ARB_base_instance (none) */
+/* Reuse tokens from ARB_shading_language_420pack (none) */
+/* Reuse tokens from ARB_transform_feedback_instanced (none) */
+/* Reuse tokens from ARB_compressed_texture_pixel_storage */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_WIDTH */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_HEIGHT */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_DEPTH */
+/* reuse GL_UNPACK_COMPRESSED_BLOCK_SIZE */
+/* reuse GL_PACK_COMPRESSED_BLOCK_WIDTH */
+/* reuse GL_PACK_COMPRESSED_BLOCK_HEIGHT */
+/* reuse GL_PACK_COMPRESSED_BLOCK_DEPTH */
+/* reuse GL_PACK_COMPRESSED_BLOCK_SIZE */
+/* Reuse tokens from ARB_conservative_depth (none) */
+/* Reuse tokens from ARB_internalformat_query */
+/* reuse GL_NUM_SAMPLE_COUNTS */
+/* Reuse tokens from ARB_map_buffer_alignment */
+/* reuse GL_MIN_MAP_BUFFER_ALIGNMENT */
+/* Reuse tokens from ARB_shader_atomic_counters */
+/* reuse GL_ATOMIC_COUNTER_BUFFER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_BINDING */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_START */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_SIZE */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER */
+/* reuse GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_VERTEX_ATOMIC_COUNTERS */
+/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS */
+/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS */
+/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTERS */
+/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTERS */
+/* reuse GL_MAX_COMBINED_ATOMIC_COUNTERS */
+/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE */
+/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS */
+/* reuse GL_ACTIVE_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX */
+/* reuse GL_UNSIGNED_INT_ATOMIC_COUNTER */
+/* Reuse tokens from ARB_shader_image_load_store */
+/* reuse GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT */
+/* reuse GL_ELEMENT_ARRAY_BARRIER_BIT */
+/* reuse GL_UNIFORM_BARRIER_BIT */
+/* reuse GL_TEXTURE_FETCH_BARRIER_BIT */
+/* reuse GL_SHADER_IMAGE_ACCESS_BARRIER_BIT */
+/* reuse GL_COMMAND_BARRIER_BIT */
+/* reuse GL_PIXEL_BUFFER_BARRIER_BIT */
+/* reuse GL_TEXTURE_UPDATE_BARRIER_BIT */
+/* reuse GL_BUFFER_UPDATE_BARRIER_BIT */
+/* reuse GL_FRAMEBUFFER_BARRIER_BIT */
+/* reuse GL_TRANSFORM_FEEDBACK_BARRIER_BIT */
+/* reuse GL_ATOMIC_COUNTER_BARRIER_BIT */
+/* reuse GL_ALL_BARRIER_BITS */
+/* reuse GL_MAX_IMAGE_UNITS */
+/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */
+/* reuse GL_IMAGE_BINDING_NAME */
+/* reuse GL_IMAGE_BINDING_LEVEL */
+/* reuse GL_IMAGE_BINDING_LAYERED */
+/* reuse GL_IMAGE_BINDING_LAYER */
+/* reuse GL_IMAGE_BINDING_ACCESS */
+/* reuse GL_IMAGE_1D */
+/* reuse GL_IMAGE_2D */
+/* reuse GL_IMAGE_3D */
+/* reuse GL_IMAGE_2D_RECT */
+/* reuse GL_IMAGE_CUBE */
+/* reuse GL_IMAGE_BUFFER */
+/* reuse GL_IMAGE_1D_ARRAY */
+/* reuse GL_IMAGE_2D_ARRAY */
+/* reuse GL_IMAGE_CUBE_MAP_ARRAY */
+/* reuse GL_IMAGE_2D_MULTISAMPLE */
+/* reuse GL_IMAGE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_INT_IMAGE_1D */
+/* reuse GL_INT_IMAGE_2D */
+/* reuse GL_INT_IMAGE_3D */
+/* reuse GL_INT_IMAGE_2D_RECT */
+/* reuse GL_INT_IMAGE_CUBE */
+/* reuse GL_INT_IMAGE_BUFFER */
+/* reuse GL_INT_IMAGE_1D_ARRAY */
+/* reuse GL_INT_IMAGE_2D_ARRAY */
+/* reuse GL_INT_IMAGE_CUBE_MAP_ARRAY */
+/* reuse GL_INT_IMAGE_2D_MULTISAMPLE */
+/* reuse GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_1D */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D */
+/* reuse GL_UNSIGNED_INT_IMAGE_3D */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_RECT */
+/* reuse GL_UNSIGNED_INT_IMAGE_CUBE */
+/* reuse GL_UNSIGNED_INT_IMAGE_BUFFER */
+/* reuse GL_UNSIGNED_INT_IMAGE_1D_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE */
+/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_MAX_IMAGE_SAMPLES */
+/* reuse GL_IMAGE_BINDING_FORMAT */
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE */
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS */
+/* reuse GL_MAX_VERTEX_IMAGE_UNIFORMS */
+/* reuse GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS */
+/* reuse GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS */
+/* reuse GL_MAX_GEOMETRY_IMAGE_UNIFORMS */
+/* reuse GL_MAX_FRAGMENT_IMAGE_UNIFORMS */
+/* reuse GL_MAX_COMBINED_IMAGE_UNIFORMS */
+/* Reuse tokens from ARB_shading_language_packing (none) */
+/* Reuse tokens from ARB_texture_storage */
+/* reuse GL_TEXTURE_IMMUTABLE_FORMAT */
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_TEXTURE0_ARB                   0x84C0
+#define GL_TEXTURE1_ARB                   0x84C1
+#define GL_TEXTURE2_ARB                   0x84C2
+#define GL_TEXTURE3_ARB                   0x84C3
+#define GL_TEXTURE4_ARB                   0x84C4
+#define GL_TEXTURE5_ARB                   0x84C5
+#define GL_TEXTURE6_ARB                   0x84C6
+#define GL_TEXTURE7_ARB                   0x84C7
+#define GL_TEXTURE8_ARB                   0x84C8
+#define GL_TEXTURE9_ARB                   0x84C9
+#define GL_TEXTURE10_ARB                  0x84CA
+#define GL_TEXTURE11_ARB                  0x84CB
+#define GL_TEXTURE12_ARB                  0x84CC
+#define GL_TEXTURE13_ARB                  0x84CD
+#define GL_TEXTURE14_ARB                  0x84CE
+#define GL_TEXTURE15_ARB                  0x84CF
+#define GL_TEXTURE16_ARB                  0x84D0
+#define GL_TEXTURE17_ARB                  0x84D1
+#define GL_TEXTURE18_ARB                  0x84D2
+#define GL_TEXTURE19_ARB                  0x84D3
+#define GL_TEXTURE20_ARB                  0x84D4
+#define GL_TEXTURE21_ARB                  0x84D5
+#define GL_TEXTURE22_ARB                  0x84D6
+#define GL_TEXTURE23_ARB                  0x84D7
+#define GL_TEXTURE24_ARB                  0x84D8
+#define GL_TEXTURE25_ARB                  0x84D9
+#define GL_TEXTURE26_ARB                  0x84DA
+#define GL_TEXTURE27_ARB                  0x84DB
+#define GL_TEXTURE28_ARB                  0x84DC
+#define GL_TEXTURE29_ARB                  0x84DD
+#define GL_TEXTURE30_ARB                  0x84DE
+#define GL_TEXTURE31_ARB                  0x84DF
+#define GL_ACTIVE_TEXTURE_ARB             0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB      0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB          0x84E2
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB   0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB     0x84E6
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_MULTISAMPLE_ARB                0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB   0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB        0x809F
+#define GL_SAMPLE_COVERAGE_ARB            0x80A0
+#define GL_SAMPLE_BUFFERS_ARB             0x80A8
+#define GL_SAMPLES_ARB                    0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB      0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB     0x80AB
+#define GL_MULTISAMPLE_BIT_ARB            0x20000000
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_NORMAL_MAP_ARB                 0x8511
+#define GL_REFLECTION_MAP_ARB             0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB           0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB   0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB     0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB  0x851C
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_COMPRESSED_ALPHA_ARB           0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB       0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB       0x84EC
+#define GL_COMPRESSED_RGB_ARB             0x84ED
+#define GL_COMPRESSED_RGBA_ARB            0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB   0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB         0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_ARB            0x812D
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_POINT_SIZE_MIN_ARB             0x8126
+#define GL_POINT_SIZE_MAX_ARB             0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB  0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_MAX_VERTEX_UNITS_ARB           0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB        0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB           0x86A6
+#define GL_VERTEX_BLEND_ARB               0x86A7
+#define GL_CURRENT_WEIGHT_ARB             0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB          0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB        0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB          0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB       0x86AC
+#define GL_WEIGHT_ARRAY_ARB               0x86AD
+#define GL_MODELVIEW0_ARB                 0x1700
+#define GL_MODELVIEW1_ARB                 0x850A
+#define GL_MODELVIEW2_ARB                 0x8722
+#define GL_MODELVIEW3_ARB                 0x8723
+#define GL_MODELVIEW4_ARB                 0x8724
+#define GL_MODELVIEW5_ARB                 0x8725
+#define GL_MODELVIEW6_ARB                 0x8726
+#define GL_MODELVIEW7_ARB                 0x8727
+#define GL_MODELVIEW8_ARB                 0x8728
+#define GL_MODELVIEW9_ARB                 0x8729
+#define GL_MODELVIEW10_ARB                0x872A
+#define GL_MODELVIEW11_ARB                0x872B
+#define GL_MODELVIEW12_ARB                0x872C
+#define GL_MODELVIEW13_ARB                0x872D
+#define GL_MODELVIEW14_ARB                0x872E
+#define GL_MODELVIEW15_ARB                0x872F
+#define GL_MODELVIEW16_ARB                0x8730
+#define GL_MODELVIEW17_ARB                0x8731
+#define GL_MODELVIEW18_ARB                0x8732
+#define GL_MODELVIEW19_ARB                0x8733
+#define GL_MODELVIEW20_ARB                0x8734
+#define GL_MODELVIEW21_ARB                0x8735
+#define GL_MODELVIEW22_ARB                0x8736
+#define GL_MODELVIEW23_ARB                0x8737
+#define GL_MODELVIEW24_ARB                0x8738
+#define GL_MODELVIEW25_ARB                0x8739
+#define GL_MODELVIEW26_ARB                0x873A
+#define GL_MODELVIEW27_ARB                0x873B
+#define GL_MODELVIEW28_ARB                0x873C
+#define GL_MODELVIEW29_ARB                0x873D
+#define GL_MODELVIEW30_ARB                0x873E
+#define GL_MODELVIEW31_ARB                0x873F
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_MATRIX_PALETTE_ARB             0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB       0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB     0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB         0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB       0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB    0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB    0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB  0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB                    0x8570
+#define GL_COMBINE_RGB_ARB                0x8571
+#define GL_COMBINE_ALPHA_ARB              0x8572
+#define GL_SOURCE0_RGB_ARB                0x8580
+#define GL_SOURCE1_RGB_ARB                0x8581
+#define GL_SOURCE2_RGB_ARB                0x8582
+#define GL_SOURCE0_ALPHA_ARB              0x8588
+#define GL_SOURCE1_ALPHA_ARB              0x8589
+#define GL_SOURCE2_ALPHA_ARB              0x858A
+#define GL_OPERAND0_RGB_ARB               0x8590
+#define GL_OPERAND1_RGB_ARB               0x8591
+#define GL_OPERAND2_RGB_ARB               0x8592
+#define GL_OPERAND0_ALPHA_ARB             0x8598
+#define GL_OPERAND1_ALPHA_ARB             0x8599
+#define GL_OPERAND2_ALPHA_ARB             0x859A
+#define GL_RGB_SCALE_ARB                  0x8573
+#define GL_ADD_SIGNED_ARB                 0x8574
+#define GL_INTERPOLATE_ARB                0x8575
+#define GL_SUBTRACT_ARB                   0x84E7
+#define GL_CONSTANT_ARB                   0x8576
+#define GL_PRIMARY_COLOR_ARB              0x8577
+#define GL_PREVIOUS_ARB                   0x8578
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_DOT3_RGB_ARB                   0x86AE
+#define GL_DOT3_RGBA_ARB                  0x86AF
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_ARB            0x8370
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_DEPTH_COMPONENT16_ARB          0x81A5
+#define GL_DEPTH_COMPONENT24_ARB          0x81A6
+#define GL_DEPTH_COMPONENT32_ARB          0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB         0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB         0x884B
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_TEXTURE_COMPARE_MODE_ARB       0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB       0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB       0x884E
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#endif
+
+#ifndef GL_ARB_window_pos
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_COLOR_SUM_ARB                  0x8458
+#define GL_VERTEX_PROGRAM_ARB             0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB   0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB   0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB      0x8626
+#define GL_PROGRAM_LENGTH_ARB             0x8627
+#define GL_PROGRAM_STRING_ARB             0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB       0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB             0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB  0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB    0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB     0x864B
+#define GL_PROGRAM_BINDING_ARB            0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB         0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB       0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB       0x8875
+#define GL_PROGRAM_FORMAT_ARB             0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB       0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB   0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB        0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB    0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB         0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB     0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB  0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB            0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB        0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB     0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB  0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB   0x88B7
+#define GL_MATRIX0_ARB                    0x88C0
+#define GL_MATRIX1_ARB                    0x88C1
+#define GL_MATRIX2_ARB                    0x88C2
+#define GL_MATRIX3_ARB                    0x88C3
+#define GL_MATRIX4_ARB                    0x88C4
+#define GL_MATRIX5_ARB                    0x88C5
+#define GL_MATRIX6_ARB                    0x88C6
+#define GL_MATRIX7_ARB                    0x88C7
+#define GL_MATRIX8_ARB                    0x88C8
+#define GL_MATRIX9_ARB                    0x88C9
+#define GL_MATRIX10_ARB                   0x88CA
+#define GL_MATRIX11_ARB                   0x88CB
+#define GL_MATRIX12_ARB                   0x88CC
+#define GL_MATRIX13_ARB                   0x88CD
+#define GL_MATRIX14_ARB                   0x88CE
+#define GL_MATRIX15_ARB                   0x88CF
+#define GL_MATRIX16_ARB                   0x88D0
+#define GL_MATRIX17_ARB                   0x88D1
+#define GL_MATRIX18_ARB                   0x88D2
+#define GL_MATRIX19_ARB                   0x88D3
+#define GL_MATRIX20_ARB                   0x88D4
+#define GL_MATRIX21_ARB                   0x88D5
+#define GL_MATRIX22_ARB                   0x88D6
+#define GL_MATRIX23_ARB                   0x88D7
+#define GL_MATRIX24_ARB                   0x88D8
+#define GL_MATRIX25_ARB                   0x88D9
+#define GL_MATRIX26_ARB                   0x88DA
+#define GL_MATRIX27_ARB                   0x88DB
+#define GL_MATRIX28_ARB                   0x88DC
+#define GL_MATRIX29_ARB                   0x88DD
+#define GL_MATRIX30_ARB                   0x88DE
+#define GL_MATRIX31_ARB                   0x88DF
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_FRAGMENT_PROGRAM_ARB           0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB   0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB   0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB   0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB         0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB    0x8872
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_BUFFER_SIZE_ARB                0x8764
+#define GL_BUFFER_USAGE_ARB               0x8765
+#define GL_ARRAY_BUFFER_ARB               0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB       0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB       0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB                  0x88B8
+#define GL_WRITE_ONLY_ARB                 0x88B9
+#define GL_READ_WRITE_ARB                 0x88BA
+#define GL_BUFFER_ACCESS_ARB              0x88BB
+#define GL_BUFFER_MAPPED_ARB              0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB         0x88BD
+#define GL_STREAM_DRAW_ARB                0x88E0
+#define GL_STREAM_READ_ARB                0x88E1
+#define GL_STREAM_COPY_ARB                0x88E2
+#define GL_STATIC_DRAW_ARB                0x88E4
+#define GL_STATIC_READ_ARB                0x88E5
+#define GL_STATIC_COPY_ARB                0x88E6
+#define GL_DYNAMIC_DRAW_ARB               0x88E8
+#define GL_DYNAMIC_READ_ARB               0x88E9
+#define GL_DYNAMIC_COPY_ARB               0x88EA
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_QUERY_COUNTER_BITS_ARB         0x8864
+#define GL_CURRENT_QUERY_ARB              0x8865
+#define GL_QUERY_RESULT_ARB               0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB     0x8867
+#define GL_SAMPLES_PASSED_ARB             0x8914
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_PROGRAM_OBJECT_ARB             0x8B40
+#define GL_SHADER_OBJECT_ARB              0x8B48
+#define GL_OBJECT_TYPE_ARB                0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB             0x8B4F
+#define GL_FLOAT_VEC2_ARB                 0x8B50
+#define GL_FLOAT_VEC3_ARB                 0x8B51
+#define GL_FLOAT_VEC4_ARB                 0x8B52
+#define GL_INT_VEC2_ARB                   0x8B53
+#define GL_INT_VEC3_ARB                   0x8B54
+#define GL_INT_VEC4_ARB                   0x8B55
+#define GL_BOOL_ARB                       0x8B56
+#define GL_BOOL_VEC2_ARB                  0x8B57
+#define GL_BOOL_VEC3_ARB                  0x8B58
+#define GL_BOOL_VEC4_ARB                  0x8B59
+#define GL_FLOAT_MAT2_ARB                 0x8B5A
+#define GL_FLOAT_MAT3_ARB                 0x8B5B
+#define GL_FLOAT_MAT4_ARB                 0x8B5C
+#define GL_SAMPLER_1D_ARB                 0x8B5D
+#define GL_SAMPLER_2D_ARB                 0x8B5E
+#define GL_SAMPLER_3D_ARB                 0x8B5F
+#define GL_SAMPLER_CUBE_ARB               0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB          0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB          0x8B62
+#define GL_SAMPLER_2D_RECT_ARB            0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB     0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB       0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB      0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB         0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB     0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB     0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB    0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB     0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_VERTEX_SHADER_ARB              0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB         0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB   0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_FRAGMENT_SHADER_ARB            0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_SHADING_LANGUAGE_VERSION_ARB   0x8B8C
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_POINT_SPRITE_ARB               0x8861
+#define GL_COORD_REPLACE_ARB              0x8862
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ARB           0x8824
+#define GL_DRAW_BUFFER0_ARB               0x8825
+#define GL_DRAW_BUFFER1_ARB               0x8826
+#define GL_DRAW_BUFFER2_ARB               0x8827
+#define GL_DRAW_BUFFER3_ARB               0x8828
+#define GL_DRAW_BUFFER4_ARB               0x8829
+#define GL_DRAW_BUFFER5_ARB               0x882A
+#define GL_DRAW_BUFFER6_ARB               0x882B
+#define GL_DRAW_BUFFER7_ARB               0x882C
+#define GL_DRAW_BUFFER8_ARB               0x882D
+#define GL_DRAW_BUFFER9_ARB               0x882E
+#define GL_DRAW_BUFFER10_ARB              0x882F
+#define GL_DRAW_BUFFER11_ARB              0x8830
+#define GL_DRAW_BUFFER12_ARB              0x8831
+#define GL_DRAW_BUFFER13_ARB              0x8832
+#define GL_DRAW_BUFFER14_ARB              0x8833
+#define GL_DRAW_BUFFER15_ARB              0x8834
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_ARB          0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB  0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB    0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_RGBA_FLOAT_MODE_ARB            0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB         0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB       0x891B
+#define GL_CLAMP_READ_COLOR_ARB           0x891C
+#define GL_FIXED_ONLY_ARB                 0x891D
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_HALF_FLOAT_ARB                 0x140B
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_TEXTURE_RED_TYPE_ARB           0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB         0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB          0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB         0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB     0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB     0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB         0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB        0x8C17
+#define GL_RGBA32F_ARB                    0x8814
+#define GL_RGB32F_ARB                     0x8815
+#define GL_ALPHA32F_ARB                   0x8816
+#define GL_INTENSITY32F_ARB               0x8817
+#define GL_LUMINANCE32F_ARB               0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB         0x8819
+#define GL_RGBA16F_ARB                    0x881A
+#define GL_RGB16F_ARB                     0x881B
+#define GL_ALPHA16F_ARB                   0x881C
+#define GL_INTENSITY16F_ARB               0x881D
+#define GL_LUMINANCE16F_ARB               0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB         0x881F
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_ARB          0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB        0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB  0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F             0x8CAC
+#define GL_DEPTH32F_STENCIL8              0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION  0x0506
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT            0x8218
+#define GL_FRAMEBUFFER_UNDEFINED          0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT       0x821A
+#define GL_MAX_RENDERBUFFER_SIZE          0x84E8
+#define GL_DEPTH_STENCIL                  0x84F9
+#define GL_UNSIGNED_INT_24_8              0x84FA
+#define GL_DEPTH24_STENCIL8               0x88F0
+#define GL_TEXTURE_STENCIL_SIZE           0x88F1
+#define GL_TEXTURE_RED_TYPE               0x8C10
+#define GL_TEXTURE_GREEN_TYPE             0x8C11
+#define GL_TEXTURE_BLUE_TYPE              0x8C12
+#define GL_TEXTURE_ALPHA_TYPE             0x8C13
+#define GL_TEXTURE_DEPTH_TYPE             0x8C16
+#define GL_UNSIGNED_NORMALIZED            0x8C17
+#define GL_FRAMEBUFFER_BINDING            0x8CA6
+#define GL_DRAW_FRAMEBUFFER_BINDING       GL_FRAMEBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING           0x8CA7
+#define GL_READ_FRAMEBUFFER               0x8CA8
+#define GL_DRAW_FRAMEBUFFER               0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING       0x8CAA
+#define GL_RENDERBUFFER_SAMPLES           0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE           0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED        0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS          0x8CDF
+#define GL_COLOR_ATTACHMENT0              0x8CE0
+#define GL_COLOR_ATTACHMENT1              0x8CE1
+#define GL_COLOR_ATTACHMENT2              0x8CE2
+#define GL_COLOR_ATTACHMENT3              0x8CE3
+#define GL_COLOR_ATTACHMENT4              0x8CE4
+#define GL_COLOR_ATTACHMENT5              0x8CE5
+#define GL_COLOR_ATTACHMENT6              0x8CE6
+#define GL_COLOR_ATTACHMENT7              0x8CE7
+#define GL_COLOR_ATTACHMENT8              0x8CE8
+#define GL_COLOR_ATTACHMENT9              0x8CE9
+#define GL_COLOR_ATTACHMENT10             0x8CEA
+#define GL_COLOR_ATTACHMENT11             0x8CEB
+#define GL_COLOR_ATTACHMENT12             0x8CEC
+#define GL_COLOR_ATTACHMENT13             0x8CED
+#define GL_COLOR_ATTACHMENT14             0x8CEE
+#define GL_COLOR_ATTACHMENT15             0x8CEF
+#define GL_DEPTH_ATTACHMENT               0x8D00
+#define GL_STENCIL_ATTACHMENT             0x8D20
+#define GL_FRAMEBUFFER                    0x8D40
+#define GL_RENDERBUFFER                   0x8D41
+#define GL_RENDERBUFFER_WIDTH             0x8D42
+#define GL_RENDERBUFFER_HEIGHT            0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT   0x8D44
+#define GL_STENCIL_INDEX1                 0x8D46
+#define GL_STENCIL_INDEX4                 0x8D47
+#define GL_STENCIL_INDEX8                 0x8D48
+#define GL_STENCIL_INDEX16                0x8D49
+#define GL_RENDERBUFFER_RED_SIZE          0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE        0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE         0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE        0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE        0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE      0x8D55
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES                    0x8D57
+#endif
+
+#ifndef GL_ARB_framebuffer_object_DEPRECATED
+#define GL_INDEX                          0x8222
+#define GL_TEXTURE_LUMINANCE_TYPE         0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE         0x8C15
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB               0x8DB9
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_LINES_ADJACENCY_ARB            0x000A
+#define GL_LINE_STRIP_ADJACENCY_ARB       0x000B
+#define GL_TRIANGLES_ADJACENCY_ARB        0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB   0x000D
+#define GL_PROGRAM_POINT_SIZE_ARB         0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_GEOMETRY_SHADER_ARB            0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_ARB      0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_ARB        0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB       0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_HALF_FLOAT                     0x140B
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_MAP_READ_BIT                   0x0001
+#define GL_MAP_WRITE_BIT                  0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT       0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT      0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT         0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT         0x0020
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_TEXTURE_BUFFER_ARB             0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB    0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_ARB     0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_ARB      0x8C2E
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1           0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1    0x8DBC
+#define GL_COMPRESSED_RG_RGTC2            0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2     0x8DBE
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_RG                             0x8227
+#define GL_RG_INTEGER                     0x8228
+#define GL_R8                             0x8229
+#define GL_R16                            0x822A
+#define GL_RG8                            0x822B
+#define GL_RG16                           0x822C
+#define GL_R16F                           0x822D
+#define GL_R32F                           0x822E
+#define GL_RG16F                          0x822F
+#define GL_RG32F                          0x8230
+#define GL_R8I                            0x8231
+#define GL_R8UI                           0x8232
+#define GL_R16I                           0x8233
+#define GL_R16UI                          0x8234
+#define GL_R32I                           0x8235
+#define GL_R32UI                          0x8236
+#define GL_RG8I                           0x8237
+#define GL_RG8UI                          0x8238
+#define GL_RG16I                          0x8239
+#define GL_RG16UI                         0x823A
+#define GL_RG32I                          0x823B
+#define GL_RG32UI                         0x823C
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING           0x85B5
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_UNIFORM_BUFFER                 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING         0x8A28
+#define GL_UNIFORM_BUFFER_START           0x8A29
+#define GL_UNIFORM_BUFFER_SIZE            0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS      0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS    0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS    0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS    0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS    0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE         0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS          0x8A36
+#define GL_UNIFORM_TYPE                   0x8A37
+#define GL_UNIFORM_SIZE                   0x8A38
+#define GL_UNIFORM_NAME_LENGTH            0x8A39
+#define GL_UNIFORM_BLOCK_INDEX            0x8A3A
+#define GL_UNIFORM_OFFSET                 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE           0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE          0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR           0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING          0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE        0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH      0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS  0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX                  0xFFFFFFFFu
+#endif
+
+#ifndef GL_ARB_compatibility
+/* ARB_compatibility just defines tokens from core 3.0 */
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_COPY_READ_BUFFER               0x8F36
+#define GL_COPY_WRITE_BUFFER              0x8F37
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_DEPTH_CLAMP                    0x864F
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION        0x8E4D
+#define GL_LAST_VERTEX_CONVENTION         0x8E4E
+#define GL_PROVOKING_VERTEX               0x8E4F
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS      0x884F
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_MAX_SERVER_WAIT_TIMEOUT        0x9111
+#define GL_OBJECT_TYPE                    0x9112
+#define GL_SYNC_CONDITION                 0x9113
+#define GL_SYNC_STATUS                    0x9114
+#define GL_SYNC_FLAGS                     0x9115
+#define GL_SYNC_FENCE                     0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE     0x9117
+#define GL_UNSIGNALED                     0x9118
+#define GL_SIGNALED                       0x9119
+#define GL_ALREADY_SIGNALED               0x911A
+#define GL_TIMEOUT_EXPIRED                0x911B
+#define GL_CONDITION_SATISFIED            0x911C
+#define GL_WAIT_FAILED                    0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT        0x00000001
+#define GL_TIMEOUT_IGNORED                0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_SAMPLE_POSITION                0x8E50
+#define GL_SAMPLE_MASK                    0x8E51
+#define GL_SAMPLE_MASK_VALUE              0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS          0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE         0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE   0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY   0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES                0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE         0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE     0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY   0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES      0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES      0x910F
+#define GL_MAX_INTEGER_SAMPLES            0x9110
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_SAMPLE_SHADING_ARB             0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB   0x8C37
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB     0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB     0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_SHADER_INCLUDE_ARB             0x8DAE
+#define GL_NAMED_STRING_LENGTH_ARB        0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB          0x8DEA
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_SRC1_COLOR                     0x88F9
+/* reuse GL_SRC1_ALPHA */
+#define GL_ONE_MINUS_SRC1_COLOR           0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA           0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS   0x88FC
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ANY_SAMPLES_PASSED             0x8C2F
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_SAMPLER_BINDING                0x8919
+#endif
+
+#ifndef GL_ARB_shader_bit_encoding
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_RGB10_A2UI                     0x906F
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R              0x8E42
+#define GL_TEXTURE_SWIZZLE_G              0x8E43
+#define GL_TEXTURE_SWIZZLE_B              0x8E44
+#define GL_TEXTURE_SWIZZLE_A              0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA           0x8E46
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_TIME_ELAPSED                   0x88BF
+#define GL_TIMESTAMP                      0x8E28
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */
+#define GL_INT_2_10_10_10_REV             0x8D9F
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_DRAW_INDIRECT_BUFFER           0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING   0x8F43
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_GEOMETRY_SHADER_INVOCATIONS    0x887F
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+/* reuse GL_MAX_VERTEX_STREAMS */
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+/* reuse GL_DOUBLE */
+#define GL_DOUBLE_VEC2                    0x8FFC
+#define GL_DOUBLE_VEC3                    0x8FFD
+#define GL_DOUBLE_VEC4                    0x8FFE
+#define GL_DOUBLE_MAT2                    0x8F46
+#define GL_DOUBLE_MAT3                    0x8F47
+#define GL_DOUBLE_MAT4                    0x8F48
+#define GL_DOUBLE_MAT2x3                  0x8F49
+#define GL_DOUBLE_MAT2x4                  0x8F4A
+#define GL_DOUBLE_MAT3x2                  0x8F4B
+#define GL_DOUBLE_MAT3x4                  0x8F4C
+#define GL_DOUBLE_MAT4x2                  0x8F4D
+#define GL_DOUBLE_MAT4x3                  0x8F4E
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ACTIVE_SUBROUTINES             0x8DE5
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS     0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH   0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_MAX_SUBROUTINES                0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_NUM_COMPATIBLE_SUBROUTINES     0x8E4A
+#define GL_COMPATIBLE_SUBROUTINES         0x8E4B
+/* reuse GL_UNIFORM_SIZE */
+/* reuse GL_UNIFORM_NAME_LENGTH */
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_PATCHES                        0x000E
+#define GL_PATCH_VERTICES                 0x8E72
+#define GL_PATCH_DEFAULT_INNER_LEVEL      0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL      0x8E74
+#define GL_TESS_CONTROL_OUTPUT_VERTICES   0x8E75
+#define GL_TESS_GEN_MODE                  0x8E76
+#define GL_TESS_GEN_SPACING               0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER          0x8E78
+#define GL_TESS_GEN_POINT_MODE            0x8E79
+/* reuse GL_TRIANGLES */
+/* reuse GL_QUADS */
+#define GL_ISOLINES                       0x8E7A
+/* reuse GL_EQUAL */
+#define GL_FRACTIONAL_ODD                 0x8E7B
+#define GL_FRACTIONAL_EVEN                0x8E7C
+/* reuse GL_CCW */
+/* reuse GL_CW */
+#define GL_MAX_PATCH_VERTICES             0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL             0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS      0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_TESS_EVALUATION_SHADER         0x8E87
+#define GL_TESS_CONTROL_SHADER            0x8E88
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+/* reuse GL_RGB32F */
+/* reuse GL_RGB32UI */
+/* reuse GL_RGB32I */
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK             0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING     0x8E25
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS             0x8E71
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_FIXED                          0x140C
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_LOW_FLOAT                      0x8DF0
+#define GL_MEDIUM_FLOAT                   0x8DF1
+#define GL_HIGH_FLOAT                     0x8DF2
+#define GL_LOW_INT                        0x8DF3
+#define GL_MEDIUM_INT                     0x8DF4
+#define GL_HIGH_INT                       0x8DF5
+#define GL_SHADER_COMPILER                0x8DFA
+#define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9
+#define GL_MAX_VERTEX_UNIFORM_VECTORS     0x8DFB
+#define GL_MAX_VARYING_VECTORS            0x8DFC
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS   0x8DFD
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH          0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS     0x87FE
+#define GL_PROGRAM_BINARY_FORMATS         0x87FF
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_VERTEX_SHADER_BIT              0x00000001
+#define GL_FRAGMENT_SHADER_BIT            0x00000002
+#define GL_GEOMETRY_SHADER_BIT            0x00000004
+#define GL_TESS_CONTROL_SHADER_BIT        0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT     0x00000010
+#define GL_ALL_SHADER_BITS                0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE              0x8258
+#define GL_ACTIVE_PROGRAM                 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING       0x825A
+#endif
+
+#ifndef GL_ARB_shader_precision
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+/* reuse GL_RGB32I */
+/* reuse GL_DOUBLE_VEC2 */
+/* reuse GL_DOUBLE_VEC3 */
+/* reuse GL_DOUBLE_VEC4 */
+/* reuse GL_DOUBLE_MAT2 */
+/* reuse GL_DOUBLE_MAT3 */
+/* reuse GL_DOUBLE_MAT4 */
+/* reuse GL_DOUBLE_MAT2x3 */
+/* reuse GL_DOUBLE_MAT2x4 */
+/* reuse GL_DOUBLE_MAT3x2 */
+/* reuse GL_DOUBLE_MAT3x4 */
+/* reuse GL_DOUBLE_MAT4x2 */
+/* reuse GL_DOUBLE_MAT4x3 */
+#endif
+
+#ifndef GL_ARB_viewport_array
+/* reuse GL_SCISSOR_BOX */
+/* reuse GL_VIEWPORT */
+/* reuse GL_DEPTH_RANGE */
+/* reuse GL_SCISSOR_TEST */
+#define GL_MAX_VIEWPORTS                  0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS         0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE          0x825D
+#define GL_LAYER_PROVOKING_VERTEX         0x825E
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_UNDEFINED_VERTEX               0x8260
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_SYNC_CL_EVENT_ARB              0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB     0x8241
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB   0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB    0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB  0x8245
+#define GL_DEBUG_SOURCE_API_ARB           0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB   0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_ARB   0x824A
+#define GL_DEBUG_SOURCE_OTHER_ARB         0x824B
+#define GL_DEBUG_TYPE_ERROR_ARB           0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_ARB     0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB     0x8250
+#define GL_DEBUG_TYPE_OTHER_ARB           0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB   0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB  0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_ARB      0x9145
+#define GL_DEBUG_SEVERITY_HIGH_ARB        0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB      0x9147
+#define GL_DEBUG_SEVERITY_LOW_ARB         0x9148
+#endif
+
+#ifndef GL_ARB_robustness
+/* reuse GL_NO_ERROR */
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_LOSE_CONTEXT_ON_RESET_ARB      0x8252
+#define GL_GUILTY_CONTEXT_RESET_ARB       0x8253
+#define GL_INNOCENT_CONTEXT_RESET_ARB     0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_ARB      0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_NO_RESET_NOTIFICATION_ARB      0x8261
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#endif
+
+#ifndef GL_ARB_base_instance
+#endif
+
+#ifndef GL_ARB_shading_language_420pack
+#endif
+
+#ifndef GL_ARB_transform_feedback_instanced
+#endif
+
+#ifndef GL_ARB_compressed_texture_pixel_storage
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH  0x9127
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH  0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE   0x912A
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH    0x912B
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT   0x912C
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH    0x912D
+#define GL_PACK_COMPRESSED_BLOCK_SIZE     0x912E
+#endif
+
+#ifndef GL_ARB_conservative_depth
+#endif
+
+#ifndef GL_ARB_internalformat_query
+#define GL_NUM_SAMPLE_COUNTS              0x9380
+#endif
+
+#ifndef GL_ARB_map_buffer_alignment
+#define GL_MIN_MAP_BUFFER_ALIGNMENT       0x90BC
+#endif
+
+#ifndef GL_ARB_shader_atomic_counters
+#define GL_ATOMIC_COUNTER_BUFFER          0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING  0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_START    0x92C2
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE     0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS     0x92D2
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS   0x92D5
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS   0x92D6
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS   0x92D7
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS  0x92D9
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER    0x92DB
+#endif
+
+#ifndef GL_ARB_shader_image_load_store
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT      0x00000002
+#define GL_UNIFORM_BARRIER_BIT            0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT      0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_COMMAND_BARRIER_BIT            0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT       0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT     0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT      0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT        0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT     0x00001000
+#define GL_ALL_BARRIER_BITS               0xFFFFFFFF
+#define GL_MAX_IMAGE_UNITS                0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_IMAGE_BINDING_NAME             0x8F3A
+#define GL_IMAGE_BINDING_LEVEL            0x8F3B
+#define GL_IMAGE_BINDING_LAYERED          0x8F3C
+#define GL_IMAGE_BINDING_LAYER            0x8F3D
+#define GL_IMAGE_BINDING_ACCESS           0x8F3E
+#define GL_IMAGE_1D                       0x904C
+#define GL_IMAGE_2D                       0x904D
+#define GL_IMAGE_3D                       0x904E
+#define GL_IMAGE_2D_RECT                  0x904F
+#define GL_IMAGE_CUBE                     0x9050
+#define GL_IMAGE_BUFFER                   0x9051
+#define GL_IMAGE_1D_ARRAY                 0x9052
+#define GL_IMAGE_2D_ARRAY                 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY           0x9054
+#define GL_IMAGE_2D_MULTISAMPLE           0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY     0x9056
+#define GL_INT_IMAGE_1D                   0x9057
+#define GL_INT_IMAGE_2D                   0x9058
+#define GL_INT_IMAGE_3D                   0x9059
+#define GL_INT_IMAGE_2D_RECT              0x905A
+#define GL_INT_IMAGE_CUBE                 0x905B
+#define GL_INT_IMAGE_BUFFER               0x905C
+#define GL_INT_IMAGE_1D_ARRAY             0x905D
+#define GL_INT_IMAGE_2D_ARRAY             0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY       0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE       0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D          0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D          0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D          0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT     0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE        0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER      0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY    0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY    0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_MAX_IMAGE_SAMPLES              0x906D
+#define GL_IMAGE_BINDING_FORMAT           0x906E
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS      0x90CA
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS    0x90CD
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS    0x90CE
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS    0x90CF
+#endif
+
+#ifndef GL_ARB_shading_language_packing
+#endif
+
+#ifndef GL_ARB_texture_storage
+#define GL_TEXTURE_IMMUTABLE_FORMAT       0x912F
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_ABGR_EXT                       0x8000
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_CONSTANT_COLOR_EXT             0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT   0x8002
+#define GL_CONSTANT_ALPHA_EXT             0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT   0x8004
+#define GL_BLEND_COLOR_EXT                0x8005
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_POLYGON_OFFSET_EXT             0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT      0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT        0x8039
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_ALPHA4_EXT                     0x803B
+#define GL_ALPHA8_EXT                     0x803C
+#define GL_ALPHA12_EXT                    0x803D
+#define GL_ALPHA16_EXT                    0x803E
+#define GL_LUMINANCE4_EXT                 0x803F
+#define GL_LUMINANCE8_EXT                 0x8040
+#define GL_LUMINANCE12_EXT                0x8041
+#define GL_LUMINANCE16_EXT                0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT          0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT          0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT          0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT         0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT        0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT        0x8048
+#define GL_INTENSITY_EXT                  0x8049
+#define GL_INTENSITY4_EXT                 0x804A
+#define GL_INTENSITY8_EXT                 0x804B
+#define GL_INTENSITY12_EXT                0x804C
+#define GL_INTENSITY16_EXT                0x804D
+#define GL_RGB2_EXT                       0x804E
+#define GL_RGB4_EXT                       0x804F
+#define GL_RGB5_EXT                       0x8050
+#define GL_RGB8_EXT                       0x8051
+#define GL_RGB10_EXT                      0x8052
+#define GL_RGB12_EXT                      0x8053
+#define GL_RGB16_EXT                      0x8054
+#define GL_RGBA2_EXT                      0x8055
+#define GL_RGBA4_EXT                      0x8056
+#define GL_RGB5_A1_EXT                    0x8057
+#define GL_RGBA8_EXT                      0x8058
+#define GL_RGB10_A2_EXT                   0x8059
+#define GL_RGBA12_EXT                     0x805A
+#define GL_RGBA16_EXT                     0x805B
+#define GL_TEXTURE_RED_SIZE_EXT           0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT         0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT          0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT         0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT     0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT     0x8061
+#define GL_REPLACE_EXT                    0x8062
+#define GL_PROXY_TEXTURE_1D_EXT           0x8063
+#define GL_PROXY_TEXTURE_2D_EXT           0x8064
+#define GL_TEXTURE_TOO_LARGE_EXT          0x8065
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_PACK_SKIP_IMAGES_EXT           0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT          0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT         0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT        0x806E
+#define GL_TEXTURE_3D_EXT                 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT           0x8070
+#define GL_TEXTURE_DEPTH_EXT              0x8071
+#define GL_TEXTURE_WRAP_R_EXT             0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT        0x8073
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_FILTER4_SGIS                   0x8146
+#define GL_TEXTURE_FILTER4_SIZE_SGIS      0x8147
+#endif
+
+#ifndef GL_EXT_subtexture
+#endif
+
+#ifndef GL_EXT_copy_texture
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_HISTOGRAM_EXT                  0x8024
+#define GL_PROXY_HISTOGRAM_EXT            0x8025
+#define GL_HISTOGRAM_WIDTH_EXT            0x8026
+#define GL_HISTOGRAM_FORMAT_EXT           0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT         0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT       0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT        0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT       0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT   0x802C
+#define GL_HISTOGRAM_SINK_EXT             0x802D
+#define GL_MINMAX_EXT                     0x802E
+#define GL_MINMAX_FORMAT_EXT              0x802F
+#define GL_MINMAX_SINK_EXT                0x8030
+#define GL_TABLE_TOO_LARGE_EXT            0x8031
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_CONVOLUTION_1D_EXT             0x8010
+#define GL_CONVOLUTION_2D_EXT             0x8011
+#define GL_SEPARABLE_2D_EXT               0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT    0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT   0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT    0x8015
+#define GL_REDUCE_EXT                     0x8016
+#define GL_CONVOLUTION_FORMAT_EXT         0x8017
+#define GL_CONVOLUTION_WIDTH_EXT          0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT         0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT      0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT     0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT  0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_COLOR_MATRIX_SGI               0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI   0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_COLOR_TABLE_SGI                0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI          0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI          0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI           0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI         0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI          0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI       0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI     0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI      0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI     0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_PIXEL_TEXTURE_SGIS             0x8353
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_GROUP_COLOR_SGIS         0x8356
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_PIXEL_TEX_GEN_SGIX             0x8139
+#define GL_PIXEL_TEX_GEN_MODE_SGIX        0x832B
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_PACK_SKIP_VOLUMES_SGIS         0x8130
+#define GL_PACK_IMAGE_DEPTH_SGIS          0x8131
+#define GL_UNPACK_SKIP_VOLUMES_SGIS       0x8132
+#define GL_UNPACK_IMAGE_DEPTH_SGIS        0x8133
+#define GL_TEXTURE_4D_SGIS                0x8134
+#define GL_PROXY_TEXTURE_4D_SGIS          0x8135
+#define GL_TEXTURE_4DSIZE_SGIS            0x8136
+#define GL_TEXTURE_WRAP_Q_SGIS            0x8137
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS       0x8138
+#define GL_TEXTURE_4D_BINDING_SGIS        0x814F
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_TEXTURE_COLOR_TABLE_SGI        0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI  0x80BD
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_CMYK_EXT                       0x800C
+#define GL_CMYKA_EXT                      0x800D
+#define GL_PACK_CMYK_HINT_EXT             0x800E
+#define GL_UNPACK_CMYK_HINT_EXT           0x800F
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_TEXTURE_PRIORITY_EXT           0x8066
+#define GL_TEXTURE_RESIDENT_EXT           0x8067
+#define GL_TEXTURE_1D_BINDING_EXT         0x8068
+#define GL_TEXTURE_2D_BINDING_EXT         0x8069
+#define GL_TEXTURE_3D_BINDING_EXT         0x806A
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_DETAIL_TEXTURE_2D_SGIS         0x8095
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_LINEAR_DETAIL_SGIS             0x8097
+#define GL_LINEAR_DETAIL_ALPHA_SGIS       0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS       0x8099
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS      0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS       0x809B
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_LINEAR_SHARPEN_SGIS            0x80AD
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS      0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS      0x80AF
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_UNSIGNED_BYTE_3_3_2_EXT        0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT     0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT     0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT       0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT    0x8036
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_TEXTURE_MIN_LOD_SGIS           0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS           0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS        0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS         0x813D
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_MULTISAMPLE_SGIS               0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS      0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS       0x809F
+#define GL_SAMPLE_MASK_SGIS               0x80A0
+#define GL_1PASS_SGIS                     0x80A1
+#define GL_2PASS_0_SGIS                   0x80A2
+#define GL_2PASS_1_SGIS                   0x80A3
+#define GL_4PASS_0_SGIS                   0x80A4
+#define GL_4PASS_1_SGIS                   0x80A5
+#define GL_4PASS_2_SGIS                   0x80A6
+#define GL_4PASS_3_SGIS                   0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS            0x80A8
+#define GL_SAMPLES_SGIS                   0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS         0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS        0x80AB
+#define GL_SAMPLE_PATTERN_SGIS            0x80AC
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_RESCALE_NORMAL_EXT             0x803A
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_VERTEX_ARRAY_EXT               0x8074
+#define GL_NORMAL_ARRAY_EXT               0x8075
+#define GL_COLOR_ARRAY_EXT                0x8076
+#define GL_INDEX_ARRAY_EXT                0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT        0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT            0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT          0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT          0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT        0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT         0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT          0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT        0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT         0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT           0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT           0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT         0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT          0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT           0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT         0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT          0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT   0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT   0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT  0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT     0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT      0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT       0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT       0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT        0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT        0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT    0x8093
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_GENERATE_MIPMAP_SGIS           0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS      0x8192
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX     0x8170
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX    0x8171
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX     0x8172
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX    0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX     0x8176
+#define GL_MAX_CLIPMAP_DEPTH_SGIX         0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX   0x844D
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX    0x844E
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX    0x844F
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_TEXTURE_COMPARE_SGIX           0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX  0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX          0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX          0x819D
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_SGIS             0x812F
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_SGIS           0x812D
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_FUNC_ADD_EXT                   0x8006
+#define GL_MIN_EXT                        0x8007
+#define GL_MAX_EXT                        0x8008
+#define GL_BLEND_EQUATION_EXT             0x8009
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_FUNC_SUBTRACT_EXT              0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT      0x800B
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_INTERLACE_SGIX                 0x8094
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_WIDTH_SGIX          0x8140
+#define GL_PIXEL_TILE_HEIGHT_SGIX         0x8141
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX     0x8142
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX    0x8143
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX     0x8144
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX     0x8145
+#endif
+
+#ifndef GL_SGIS_texture_select
+#define GL_DUAL_ALPHA4_SGIS               0x8110
+#define GL_DUAL_ALPHA8_SGIS               0x8111
+#define GL_DUAL_ALPHA12_SGIS              0x8112
+#define GL_DUAL_ALPHA16_SGIS              0x8113
+#define GL_DUAL_LUMINANCE4_SGIS           0x8114
+#define GL_DUAL_LUMINANCE8_SGIS           0x8115
+#define GL_DUAL_LUMINANCE12_SGIS          0x8116
+#define GL_DUAL_LUMINANCE16_SGIS          0x8117
+#define GL_DUAL_INTENSITY4_SGIS           0x8118
+#define GL_DUAL_INTENSITY8_SGIS           0x8119
+#define GL_DUAL_INTENSITY12_SGIS          0x811A
+#define GL_DUAL_INTENSITY16_SGIS          0x811B
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS     0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS     0x811D
+#define GL_QUAD_ALPHA4_SGIS               0x811E
+#define GL_QUAD_ALPHA8_SGIS               0x811F
+#define GL_QUAD_LUMINANCE4_SGIS           0x8120
+#define GL_QUAD_LUMINANCE8_SGIS           0x8121
+#define GL_QUAD_INTENSITY4_SGIS           0x8122
+#define GL_QUAD_INTENSITY8_SGIS           0x8123
+#define GL_DUAL_TEXTURE_SELECT_SGIS       0x8124
+#define GL_QUAD_TEXTURE_SELECT_SGIS       0x8125
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SPRITE_SGIX                    0x8148
+#define GL_SPRITE_MODE_SGIX               0x8149
+#define GL_SPRITE_AXIS_SGIX               0x814A
+#define GL_SPRITE_TRANSLATION_SGIX        0x814B
+#define GL_SPRITE_AXIAL_SGIX              0x814C
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX     0x814D
+#define GL_SPRITE_EYE_ALIGNED_SGIX        0x814E
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_POINT_SIZE_MIN_EXT             0x8126
+#define GL_POINT_SIZE_MAX_EXT             0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT  0x8128
+#define GL_DISTANCE_ATTENUATION_EXT       0x8129
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_POINT_SIZE_MIN_SGIS            0x8126
+#define GL_POINT_SIZE_MAX_SGIS            0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_DISTANCE_ATTENUATION_SGIS      0x8129
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX   0x8181
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX  0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_FRAMEZOOM_SGIX                 0x818B
+#define GL_FRAMEZOOM_FACTOR_SGIX          0x818C
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX      0x818D
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#endif
+
+#ifndef GL_FfdMaskSGIX
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX   0x00000001
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX  0x00000002
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_GEOMETRY_DEFORMATION_SGIX      0x8194
+#define GL_TEXTURE_DEFORMATION_SGIX       0x8195
+#define GL_DEFORMATIONS_MASK_SGIX         0x8196
+#define GL_MAX_DEFORMATION_ORDER_SGIX     0x8197
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_REFERENCE_PLANE_SGIX           0x817D
+#define GL_REFERENCE_PLANE_EQUATION_SGIX  0x817E
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_DEPTH_COMPONENT16_SGIX         0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX         0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX         0x81A7
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_FOG_FUNC_SGIS                  0x812A
+#define GL_FOG_FUNC_POINTS_SGIS           0x812B
+#define GL_MAX_FOG_FUNC_POINTS_SGIS       0x812C
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_FOG_OFFSET_SGIX                0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX          0x8199
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_IMAGE_SCALE_X_HP               0x8155
+#define GL_IMAGE_SCALE_Y_HP               0x8156
+#define GL_IMAGE_TRANSLATE_X_HP           0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP           0x8158
+#define GL_IMAGE_ROTATE_ANGLE_HP          0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP       0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP       0x815B
+#define GL_IMAGE_MAG_FILTER_HP            0x815C
+#define GL_IMAGE_MIN_FILTER_HP            0x815D
+#define GL_IMAGE_CUBIC_WEIGHT_HP          0x815E
+#define GL_CUBIC_HP                       0x815F
+#define GL_AVERAGE_HP                     0x8160
+#define GL_IMAGE_TRANSFORM_2D_HP          0x8161
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_IGNORE_BORDER_HP               0x8150
+#define GL_CONSTANT_BORDER_HP             0x8151
+#define GL_REPLICATE_BORDER_HP            0x8153
+#define GL_CONVOLUTION_BORDER_COLOR_HP    0x8154
+#endif
+
+#ifndef GL_INGR_palette_buffer
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_TEXTURE_ENV_BIAS_SGIX          0x80BE
+#endif
+
+#ifndef GL_EXT_color_subtable
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_VERTEX_DATA_HINT_PGI           0x1A22A
+#define GL_VERTEX_CONSISTENT_HINT_PGI     0x1A22B
+#define GL_MATERIAL_SIDE_HINT_PGI         0x1A22C
+#define GL_MAX_VERTEX_HINT_PGI            0x1A22D
+#define GL_COLOR3_BIT_PGI                 0x00010000
+#define GL_COLOR4_BIT_PGI                 0x00020000
+#define GL_EDGEFLAG_BIT_PGI               0x00040000
+#define GL_INDEX_BIT_PGI                  0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI            0x00100000
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI            0x00400000
+#define GL_MAT_EMISSION_BIT_PGI           0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI      0x01000000
+#define GL_MAT_SHININESS_BIT_PGI          0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI           0x04000000
+#define GL_NORMAL_BIT_PGI                 0x08000000
+#define GL_TEXCOORD1_BIT_PGI              0x10000000
+#define GL_TEXCOORD2_BIT_PGI              0x20000000
+#define GL_TEXCOORD3_BIT_PGI              0x40000000
+#define GL_TEXCOORD4_BIT_PGI              0x80000000
+#define GL_VERTEX23_BIT_PGI               0x00000004
+#define GL_VERTEX4_BIT_PGI                0x00000008
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI   0x1A1F8
+#define GL_CONSERVE_MEMORY_HINT_PGI       0x1A1FD
+#define GL_RECLAIM_MEMORY_HINT_PGI        0x1A1FE
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI     0x1A202
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI   0x1A204
+#define GL_ALWAYS_FAST_HINT_PGI           0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI           0x1A20D
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI        0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI        0x1A20F
+#define GL_ALLOW_DRAW_FRG_HINT_PGI        0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI        0x1A211
+#define GL_STRICT_DEPTHFUNC_HINT_PGI      0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI       0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI        0x1A218
+#define GL_FULL_STIPPLE_HINT_PGI          0x1A219
+#define GL_CLIP_NEAR_HINT_PGI             0x1A220
+#define GL_CLIP_FAR_HINT_PGI              0x1A221
+#define GL_WIDE_LINE_HINT_PGI             0x1A222
+#define GL_BACK_NORMALS_HINT_PGI          0x1A223
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_COLOR_INDEX1_EXT               0x80E2
+#define GL_COLOR_INDEX2_EXT               0x80E3
+#define GL_COLOR_INDEX4_EXT               0x80E4
+#define GL_COLOR_INDEX8_EXT               0x80E5
+#define GL_COLOR_INDEX12_EXT              0x80E6
+#define GL_COLOR_INDEX16_EXT              0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT         0x80ED
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT  0x80F0
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_LIST_PRIORITY_SGIX             0x8182
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_IR_INSTRUMENT1_SGIX            0x817F
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX     0x8183
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_TEXTURE_LOD_BIAS_S_SGIX        0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX        0x818F
+#define GL_TEXTURE_LOD_BIAS_R_SGIX        0x8190
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SHADOW_AMBIENT_SGIX            0x80BF
+#endif
+
+#ifndef GL_EXT_index_texture
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_INDEX_MATERIAL_EXT             0x81B8
+#define GL_INDEX_MATERIAL_PARAMETER_EXT   0x81B9
+#define GL_INDEX_MATERIAL_FACE_EXT        0x81BA
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_INDEX_TEST_EXT                 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT            0x81B6
+#define GL_INDEX_TEST_REF_EXT             0x81B7
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_IUI_V2F_EXT                    0x81AD
+#define GL_IUI_V3F_EXT                    0x81AE
+#define GL_IUI_N3F_V2F_EXT                0x81AF
+#define GL_IUI_N3F_V3F_EXT                0x81B0
+#define GL_T2F_IUI_V2F_EXT                0x81B1
+#define GL_T2F_IUI_V3F_EXT                0x81B2
+#define GL_T2F_IUI_N3F_V2F_EXT            0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT            0x81B4
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT   0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT   0x81A9
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_CULL_VERTEX_EXT                0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT   0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_YCRCB_422_SGIX                 0x81BB
+#define GL_YCRCB_444_SGIX                 0x81BC
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_FRAGMENT_LIGHTING_SGIX         0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX   0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX       0x8404
+#define GL_MAX_ACTIVE_LIGHTS_SGIX         0x8405
+#define GL_CURRENT_RASTER_NORMAL_SGIX     0x8406
+#define GL_LIGHT_ENV_MODE_SGIX            0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT0_SGIX           0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX           0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX           0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX           0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX           0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX           0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX           0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX           0x8413
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_RASTER_POSITION_UNCLIPPED_IBM  0x19262
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_TEXTURE_LIGHTING_MODE_HP       0x8167
+#define GL_TEXTURE_POST_SPECULAR_HP       0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP        0x8169
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_MAX_ELEMENTS_VERTICES_EXT      0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT       0x80E9
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_PHONG_WIN                      0x80EA
+#define GL_PHONG_HINT_WIN                 0x80EB
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_FOG_SPECULAR_TEXTURE_WIN       0x80EC
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_FRAGMENT_MATERIAL_EXT          0x8349
+#define GL_FRAGMENT_NORMAL_EXT            0x834A
+#define GL_FRAGMENT_COLOR_EXT             0x834C
+#define GL_ATTENUATION_EXT                0x834D
+#define GL_SHADOW_ATTENUATION_EXT         0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT   0x834F
+#define GL_TEXTURE_LIGHT_EXT              0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT      0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+/* reuse GL_FRAGMENT_DEPTH_EXT */
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_ALPHA_MIN_SGIX                 0x8320
+#define GL_ALPHA_MAX_SGIX                 0x8321
+#endif
+
+#ifndef GL_SGIX_impact_pixel_texture
+#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX   0x8184
+#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX     0x8185
+#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX     0x8186
+#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX    0x8189
+#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX    0x818A
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_BGR_EXT                        0x80E0
+#define GL_BGRA_EXT                       0x80E1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_ASYNC_MARKER_SGIX              0x8329
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_ASYNC_TEX_IMAGE_SGIX           0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX         0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX         0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX       0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX     0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX     0x8361
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_ASYNC_HISTOGRAM_SGIX           0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX       0x832D
+#endif
+
+#ifndef GL_INTEL_texture_scissor
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_PARALLEL_ARRAYS_INTEL          0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_OCCLUSION_TEST_HP              0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP       0x8166
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_PIXEL_TRANSFORM_2D_EXT         0x8330
+#define GL_PIXEL_MAG_FILTER_EXT           0x8331
+#define GL_PIXEL_MIN_FILTER_EXT           0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT         0x8333
+#define GL_CUBIC_EXT                      0x8334
+#define GL_AVERAGE_EXT                    0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT  0x8338
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_SHARED_TEXTURE_PALETTE_EXT     0x81FB
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT  0x81F8
+#define GL_SINGLE_COLOR_EXT               0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT    0x81FA
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_COLOR_SUM_EXT                  0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT    0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT      0x845E
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_PERTURB_EXT                    0x85AE
+#define GL_TEXTURE_NORMAL_EXT             0x85AF
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_FOG_COORDINATE_SOURCE_EXT      0x8450
+#define GL_FOG_COORDINATE_EXT             0x8451
+#define GL_FRAGMENT_DEPTH_EXT             0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT     0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT  0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT       0x8457
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_SCREEN_COORDINATES_REND        0x8490
+#define GL_INVERTED_SCREEN_W_REND         0x8491
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_TANGENT_ARRAY_EXT              0x8439
+#define GL_BINORMAL_ARRAY_EXT             0x843A
+#define GL_CURRENT_TANGENT_EXT            0x843B
+#define GL_CURRENT_BINORMAL_EXT           0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT         0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT       0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT        0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT      0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT      0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT     0x8443
+#define GL_MAP1_TANGENT_EXT               0x8444
+#define GL_MAP2_TANGENT_EXT               0x8445
+#define GL_MAP1_BINORMAL_EXT              0x8446
+#define GL_MAP2_BINORMAL_EXT              0x8447
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_COMBINE_EXT                    0x8570
+#define GL_COMBINE_RGB_EXT                0x8571
+#define GL_COMBINE_ALPHA_EXT              0x8572
+#define GL_RGB_SCALE_EXT                  0x8573
+#define GL_ADD_SIGNED_EXT                 0x8574
+#define GL_INTERPOLATE_EXT                0x8575
+#define GL_CONSTANT_EXT                   0x8576
+#define GL_PRIMARY_COLOR_EXT              0x8577
+#define GL_PREVIOUS_EXT                   0x8578
+#define GL_SOURCE0_RGB_EXT                0x8580
+#define GL_SOURCE1_RGB_EXT                0x8581
+#define GL_SOURCE2_RGB_EXT                0x8582
+#define GL_SOURCE0_ALPHA_EXT              0x8588
+#define GL_SOURCE1_ALPHA_EXT              0x8589
+#define GL_SOURCE2_ALPHA_EXT              0x858A
+#define GL_OPERAND0_RGB_EXT               0x8590
+#define GL_OPERAND1_RGB_EXT               0x8591
+#define GL_OPERAND2_RGB_EXT               0x8592
+#define GL_OPERAND0_ALPHA_EXT             0x8598
+#define GL_OPERAND1_ALPHA_EXT             0x8599
+#define GL_OPERAND2_ALPHA_EXT             0x859A
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_TRANSFORM_HINT_APPLE           0x85B1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_FOG_SCALE_SGIX                 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX           0x81FD
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_UNPACK_CONSTANT_DATA_SUNX      0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX     0x81D6
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_GLOBAL_ALPHA_SUN               0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN        0x81DA
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_RESTART_SUN                    0x0001
+#define GL_REPLACE_MIDDLE_SUN             0x0002
+#define GL_REPLACE_OLDEST_SUN             0x0003
+#define GL_TRIANGLE_LIST_SUN              0x81D7
+#define GL_REPLACEMENT_CODE_SUN           0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN     0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN                   0x85C4
+#define GL_R1UI_C4UB_V3F_SUN              0x85C5
+#define GL_R1UI_C3F_V3F_SUN               0x85C6
+#define GL_R1UI_N3F_V3F_SUN               0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN           0x85C8
+#define GL_R1UI_T2F_V3F_SUN               0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN           0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN       0x85CB
+#endif
+
+#ifndef GL_SUN_vertex
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_BLEND_DST_RGB_EXT              0x80C8
+#define GL_BLEND_SRC_RGB_EXT              0x80C9
+#define GL_BLEND_DST_ALPHA_EXT            0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT            0x80CB
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_RED_MIN_CLAMP_INGR             0x8560
+#define GL_GREEN_MIN_CLAMP_INGR           0x8561
+#define GL_BLUE_MIN_CLAMP_INGR            0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR           0x8563
+#define GL_RED_MAX_CLAMP_INGR             0x8564
+#define GL_GREEN_MAX_CLAMP_INGR           0x8565
+#define GL_BLUE_MAX_CLAMP_INGR            0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR           0x8567
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INTERLACE_READ_INGR            0x8568
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_INCR_WRAP_EXT                  0x8507
+#define GL_DECR_WRAP_EXT                  0x8508
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_422_EXT                        0x80CC
+#define GL_422_REV_EXT                    0x80CD
+#define GL_422_AVERAGE_EXT                0x80CE
+#define GL_422_REV_AVERAGE_EXT            0x80CF
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NORMAL_MAP_NV                  0x8511
+#define GL_REFLECTION_MAP_NV              0x8512
+#endif
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_NORMAL_MAP_EXT                 0x8511
+#define GL_REFLECTION_MAP_EXT             0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT           0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT   0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT     0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT  0x851C
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_WRAP_BORDER_SUN                0x81D4
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT       0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT     0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT           0x8501
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT     0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_MODELVIEW0_STACK_DEPTH_EXT     GL_MODELVIEW_STACK_DEPTH
+#define GL_MODELVIEW1_STACK_DEPTH_EXT     0x8502
+#define GL_MODELVIEW0_MATRIX_EXT          GL_MODELVIEW_MATRIX
+#define GL_MODELVIEW1_MATRIX_EXT          0x8506
+#define GL_VERTEX_WEIGHTING_EXT           0x8509
+#define GL_MODELVIEW0_EXT                 GL_MODELVIEW
+#define GL_MODELVIEW1_EXT                 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT      0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT        0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT   0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT   0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_MAX_SHININESS_NV               0x8504
+#define GL_MAX_SPOT_EXPONENT_NV           0x8505
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_NV          0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV   0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV    0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV  0x8521
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_REGISTER_COMBINERS_NV          0x8522
+#define GL_VARIABLE_A_NV                  0x8523
+#define GL_VARIABLE_B_NV                  0x8524
+#define GL_VARIABLE_C_NV                  0x8525
+#define GL_VARIABLE_D_NV                  0x8526
+#define GL_VARIABLE_E_NV                  0x8527
+#define GL_VARIABLE_F_NV                  0x8528
+#define GL_VARIABLE_G_NV                  0x8529
+#define GL_CONSTANT_COLOR0_NV             0x852A
+#define GL_CONSTANT_COLOR1_NV             0x852B
+#define GL_PRIMARY_COLOR_NV               0x852C
+#define GL_SECONDARY_COLOR_NV             0x852D
+#define GL_SPARE0_NV                      0x852E
+#define GL_SPARE1_NV                      0x852F
+#define GL_DISCARD_NV                     0x8530
+#define GL_E_TIMES_F_NV                   0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV           0x8536
+#define GL_UNSIGNED_INVERT_NV             0x8537
+#define GL_EXPAND_NORMAL_NV               0x8538
+#define GL_EXPAND_NEGATE_NV               0x8539
+#define GL_HALF_BIAS_NORMAL_NV            0x853A
+#define GL_HALF_BIAS_NEGATE_NV            0x853B
+#define GL_SIGNED_IDENTITY_NV             0x853C
+#define GL_SIGNED_NEGATE_NV               0x853D
+#define GL_SCALE_BY_TWO_NV                0x853E
+#define GL_SCALE_BY_FOUR_NV               0x853F
+#define GL_SCALE_BY_ONE_HALF_NV           0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV   0x8541
+#define GL_COMBINER_INPUT_NV              0x8542
+#define GL_COMBINER_MAPPING_NV            0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV    0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV     0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV     0x8546
+#define GL_COMBINER_MUX_SUM_NV            0x8547
+#define GL_COMBINER_SCALE_NV              0x8548
+#define GL_COMBINER_BIAS_NV               0x8549
+#define GL_COMBINER_AB_OUTPUT_NV          0x854A
+#define GL_COMBINER_CD_OUTPUT_NV          0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV         0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV       0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV       0x854E
+#define GL_COLOR_SUM_CLAMP_NV             0x854F
+#define GL_COMBINER0_NV                   0x8550
+#define GL_COMBINER1_NV                   0x8551
+#define GL_COMBINER2_NV                   0x8552
+#define GL_COMBINER3_NV                   0x8553
+#define GL_COMBINER4_NV                   0x8554
+#define GL_COMBINER5_NV                   0x8555
+#define GL_COMBINER6_NV                   0x8556
+#define GL_COMBINER7_NV                   0x8557
+/* reuse GL_TEXTURE0_ARB */
+/* reuse GL_TEXTURE1_ARB */
+/* reuse GL_ZERO */
+/* reuse GL_NONE */
+/* reuse GL_FOG */
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_FOG_DISTANCE_MODE_NV           0x855A
+#define GL_EYE_RADIAL_NV                  0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV          0x855C
+/* reuse GL_EYE_PLANE */
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_EMBOSS_LIGHT_NV                0x855D
+#define GL_EMBOSS_CONSTANT_NV             0x855E
+#define GL_EMBOSS_MAP_NV                  0x855F
+#endif
+
+#ifndef GL_NV_blend_square
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_COMBINE4_NV                    0x8503
+#define GL_SOURCE3_RGB_NV                 0x8583
+#define GL_SOURCE3_ALPHA_NV               0x858B
+#define GL_OPERAND3_RGB_NV                0x8593
+#define GL_OPERAND3_ALPHA_NV              0x859B
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#endif
+
+#ifndef GL_MESA_window_pos
+#endif
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_CULL_VERTEX_IBM                103050
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_VERTEX_ARRAY_LIST_IBM          103070
+#define GL_NORMAL_ARRAY_LIST_IBM          103071
+#define GL_COLOR_ARRAY_LIST_IBM           103072
+#define GL_INDEX_ARRAY_LIST_IBM           103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM   103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM       103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM  103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM   103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM   103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM    103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM    103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_PACK_SUBSAMPLE_RATE_SGIX       0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX     0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX      0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX      0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX      0x85A4
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_YCRCB_SGIX                     0x8318
+#define GL_YCRCBA_SGIX                    0x8319
+#endif
+
+#ifndef GL_SGI_depth_pass_instrument
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX     0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_COMPRESSED_RGB_FXT1_3DFX       0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX      0x86B1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_MULTISAMPLE_3DFX               0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX            0x86B3
+#define GL_SAMPLES_3DFX                   0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX           0x20000000
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_MULTISAMPLE_EXT                0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT       0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT        0x809F
+#define GL_SAMPLE_MASK_EXT                0x80A0
+#define GL_1PASS_EXT                      0x80A1
+#define GL_2PASS_0_EXT                    0x80A2
+#define GL_2PASS_1_EXT                    0x80A3
+#define GL_4PASS_0_EXT                    0x80A4
+#define GL_4PASS_1_EXT                    0x80A5
+#define GL_4PASS_2_EXT                    0x80A6
+#define GL_4PASS_3_EXT                    0x80A7
+#define GL_SAMPLE_BUFFERS_EXT             0x80A8
+#define GL_SAMPLES_EXT                    0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT          0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT         0x80AB
+#define GL_SAMPLE_PATTERN_EXT             0x80AC
+#define GL_MULTISAMPLE_BIT_EXT            0x20000000
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_VERTEX_PRECLIP_SGIX            0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX       0x83EF
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_CONVOLUTION_HINT_SGIX          0x8316
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_PACK_RESAMPLE_SGIX             0x842C
+#define GL_UNPACK_RESAMPLE_SGIX           0x842D
+#define GL_RESAMPLE_REPLICATE_SGIX        0x842E
+#define GL_RESAMPLE_ZERO_FILL_SGIX        0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX         0x8430
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_EYE_DISTANCE_TO_POINT_SGIS     0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS  0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS      0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS   0x81F3
+#define GL_EYE_POINT_SGIS                 0x81F4
+#define GL_OBJECT_POINT_SGIS              0x81F5
+#define GL_EYE_LINE_SGIS                  0x81F6
+#define GL_OBJECT_LINE_SGIS               0x81F7
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS   0x81EF
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_DOT3_RGB_EXT                   0x8740
+#define GL_DOT3_RGBA_EXT                  0x8741
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_MIRROR_CLAMP_ATI               0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI       0x8743
+#endif
+
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV               0x84F2
+#define GL_FENCE_STATUS_NV                0x84F3
+#define GL_FENCE_CONDITION_NV             0x84F4
+#endif
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_IBM            0x8370
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_EVAL_2D_NV                     0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV          0x86C1
+#define GL_MAP_TESSELLATION_NV            0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV          0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV          0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV         0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV         0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV         0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV         0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV         0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV         0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV         0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV         0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV         0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV         0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV        0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV        0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV        0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV        0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV        0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV        0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV        0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV     0x86D7
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_DEPTH_STENCIL_NV               0x84F9
+#define GL_UNSIGNED_INT_24_8_NV           0x84FA
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_PER_STAGE_CONSTANTS_NV         0x8535
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_NV           0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV   0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV     0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV  0x84F8
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV    0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV      0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV  0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV          0x86DC
+#define GL_SHADER_CONSISTENT_NV           0x86DD
+#define GL_TEXTURE_SHADER_NV              0x86DE
+#define GL_SHADER_OPERATION_NV            0x86DF
+#define GL_CULL_MODES_NV                  0x86E0
+#define GL_OFFSET_TEXTURE_MATRIX_NV       0x86E1
+#define GL_OFFSET_TEXTURE_SCALE_NV        0x86E2
+#define GL_OFFSET_TEXTURE_BIAS_NV         0x86E3
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV    GL_OFFSET_TEXTURE_MATRIX_NV
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV     GL_OFFSET_TEXTURE_SCALE_NV
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV      GL_OFFSET_TEXTURE_BIAS_NV
+#define GL_PREVIOUS_TEXTURE_INPUT_NV      0x86E4
+#define GL_CONST_EYE_NV                   0x86E5
+#define GL_PASS_THROUGH_NV                0x86E6
+#define GL_CULL_FRAGMENT_NV               0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV           0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV     0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV     0x86EA
+#define GL_DOT_PRODUCT_NV                 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV   0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV      0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV                        0x86F4
+#define GL_DSDT_NV                        0x86F5
+#define GL_DSDT_MAG_NV                    0x86F6
+#define GL_DSDT_MAG_VIB_NV                0x86F7
+#define GL_HILO16_NV                      0x86F8
+#define GL_SIGNED_HILO_NV                 0x86F9
+#define GL_SIGNED_HILO16_NV               0x86FA
+#define GL_SIGNED_RGBA_NV                 0x86FB
+#define GL_SIGNED_RGBA8_NV                0x86FC
+#define GL_SIGNED_RGB_NV                  0x86FE
+#define GL_SIGNED_RGB8_NV                 0x86FF
+#define GL_SIGNED_LUMINANCE_NV            0x8701
+#define GL_SIGNED_LUMINANCE8_NV           0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV      0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV    0x8704
+#define GL_SIGNED_ALPHA_NV                0x8705
+#define GL_SIGNED_ALPHA8_NV               0x8706
+#define GL_SIGNED_INTENSITY_NV            0x8707
+#define GL_SIGNED_INTENSITY8_NV           0x8708
+#define GL_DSDT8_NV                       0x8709
+#define GL_DSDT8_MAG8_NV                  0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV       0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV   0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV                    0x870E
+#define GL_LO_SCALE_NV                    0x870F
+#define GL_DS_SCALE_NV                    0x8710
+#define GL_DT_SCALE_NV                    0x8711
+#define GL_MAGNITUDE_SCALE_NV             0x8712
+#define GL_VIBRANCE_SCALE_NV              0x8713
+#define GL_HI_BIAS_NV                     0x8714
+#define GL_LO_BIAS_NV                     0x8715
+#define GL_DS_BIAS_NV                     0x8716
+#define GL_DT_BIAS_NV                     0x8717
+#define GL_MAGNITUDE_BIAS_NV              0x8718
+#define GL_VIBRANCE_BIAS_NV               0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV       0x871A
+#define GL_TEXTURE_HI_SIZE_NV             0x871B
+#define GL_TEXTURE_LO_SIZE_NV             0x871C
+#define GL_TEXTURE_DS_SIZE_NV             0x871D
+#define GL_TEXTURE_DT_SIZE_NV             0x871E
+#define GL_TEXTURE_MAG_SIZE_NV            0x871F
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV      0x86EF
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_VERTEX_PROGRAM_NV              0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV        0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV           0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV         0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV           0x8625
+#define GL_CURRENT_ATTRIB_NV              0x8626
+#define GL_PROGRAM_LENGTH_NV              0x8627
+#define GL_PROGRAM_STRING_NV              0x8628
+#define GL_MODELVIEW_PROJECTION_NV        0x8629
+#define GL_IDENTITY_NV                    0x862A
+#define GL_INVERSE_NV                     0x862B
+#define GL_TRANSPOSE_NV                   0x862C
+#define GL_INVERSE_TRANSPOSE_NV           0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV          0x862F
+#define GL_MATRIX0_NV                     0x8630
+#define GL_MATRIX1_NV                     0x8631
+#define GL_MATRIX2_NV                     0x8632
+#define GL_MATRIX3_NV                     0x8633
+#define GL_MATRIX4_NV                     0x8634
+#define GL_MATRIX5_NV                     0x8635
+#define GL_MATRIX6_NV                     0x8636
+#define GL_MATRIX7_NV                     0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV  0x8640
+#define GL_CURRENT_MATRIX_NV              0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV   0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV     0x8643
+#define GL_PROGRAM_PARAMETER_NV           0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV        0x8645
+#define GL_PROGRAM_TARGET_NV              0x8646
+#define GL_PROGRAM_RESIDENT_NV            0x8647
+#define GL_TRACK_MATRIX_NV                0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV      0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV      0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV      0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV        0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV        0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV        0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV        0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV        0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV        0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV        0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV        0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV        0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV        0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV       0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV       0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV       0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV       0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV       0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV       0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV       0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV       0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV       0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV       0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV       0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV       0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV       0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV       0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV       0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV       0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV      0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV      0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV      0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV      0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV      0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV      0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV       0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV       0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV       0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV       0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV       0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV       0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV       0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV       0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV       0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV       0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV      0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV      0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV      0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV      0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV      0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV      0x867F
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX       0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX       0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX       0x836B
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SCALEBIAS_HINT_SGIX            0x8322
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_INTERLACE_OML                  0x8980
+#define GL_INTERLACE_READ_OML             0x8981
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_FORMAT_SUBSAMPLE_24_24_OML     0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML   0x8983
+#endif
+
+#ifndef GL_OML_resample
+#define GL_PACK_RESAMPLE_OML              0x8984
+#define GL_UNPACK_RESAMPLE_OML            0x8985
+#define GL_RESAMPLE_REPLICATE_OML         0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML         0x8987
+#define GL_RESAMPLE_AVERAGE_OML           0x8988
+#define GL_RESAMPLE_DECIMATE_OML          0x8989
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_DEPTH_STENCIL_TO_RGBA_NV       0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV       0x886F
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_BUMP_ROT_MATRIX_ATI            0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI       0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI         0x8777
+#define GL_BUMP_TEX_UNITS_ATI             0x8778
+#define GL_DUDV_ATI                       0x8779
+#define GL_DU8DV8_ATI                     0x877A
+#define GL_BUMP_ENVMAP_ATI                0x877B
+#define GL_BUMP_TARGET_ATI                0x877C
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_FRAGMENT_SHADER_ATI            0x8920
+#define GL_REG_0_ATI                      0x8921
+#define GL_REG_1_ATI                      0x8922
+#define GL_REG_2_ATI                      0x8923
+#define GL_REG_3_ATI                      0x8924
+#define GL_REG_4_ATI                      0x8925
+#define GL_REG_5_ATI                      0x8926
+#define GL_REG_6_ATI                      0x8927
+#define GL_REG_7_ATI                      0x8928
+#define GL_REG_8_ATI                      0x8929
+#define GL_REG_9_ATI                      0x892A
+#define GL_REG_10_ATI                     0x892B
+#define GL_REG_11_ATI                     0x892C
+#define GL_REG_12_ATI                     0x892D
+#define GL_REG_13_ATI                     0x892E
+#define GL_REG_14_ATI                     0x892F
+#define GL_REG_15_ATI                     0x8930
+#define GL_REG_16_ATI                     0x8931
+#define GL_REG_17_ATI                     0x8932
+#define GL_REG_18_ATI                     0x8933
+#define GL_REG_19_ATI                     0x8934
+#define GL_REG_20_ATI                     0x8935
+#define GL_REG_21_ATI                     0x8936
+#define GL_REG_22_ATI                     0x8937
+#define GL_REG_23_ATI                     0x8938
+#define GL_REG_24_ATI                     0x8939
+#define GL_REG_25_ATI                     0x893A
+#define GL_REG_26_ATI                     0x893B
+#define GL_REG_27_ATI                     0x893C
+#define GL_REG_28_ATI                     0x893D
+#define GL_REG_29_ATI                     0x893E
+#define GL_REG_30_ATI                     0x893F
+#define GL_REG_31_ATI                     0x8940
+#define GL_CON_0_ATI                      0x8941
+#define GL_CON_1_ATI                      0x8942
+#define GL_CON_2_ATI                      0x8943
+#define GL_CON_3_ATI                      0x8944
+#define GL_CON_4_ATI                      0x8945
+#define GL_CON_5_ATI                      0x8946
+#define GL_CON_6_ATI                      0x8947
+#define GL_CON_7_ATI                      0x8948
+#define GL_CON_8_ATI                      0x8949
+#define GL_CON_9_ATI                      0x894A
+#define GL_CON_10_ATI                     0x894B
+#define GL_CON_11_ATI                     0x894C
+#define GL_CON_12_ATI                     0x894D
+#define GL_CON_13_ATI                     0x894E
+#define GL_CON_14_ATI                     0x894F
+#define GL_CON_15_ATI                     0x8950
+#define GL_CON_16_ATI                     0x8951
+#define GL_CON_17_ATI                     0x8952
+#define GL_CON_18_ATI                     0x8953
+#define GL_CON_19_ATI                     0x8954
+#define GL_CON_20_ATI                     0x8955
+#define GL_CON_21_ATI                     0x8956
+#define GL_CON_22_ATI                     0x8957
+#define GL_CON_23_ATI                     0x8958
+#define GL_CON_24_ATI                     0x8959
+#define GL_CON_25_ATI                     0x895A
+#define GL_CON_26_ATI                     0x895B
+#define GL_CON_27_ATI                     0x895C
+#define GL_CON_28_ATI                     0x895D
+#define GL_CON_29_ATI                     0x895E
+#define GL_CON_30_ATI                     0x895F
+#define GL_CON_31_ATI                     0x8960
+#define GL_MOV_ATI                        0x8961
+#define GL_ADD_ATI                        0x8963
+#define GL_MUL_ATI                        0x8964
+#define GL_SUB_ATI                        0x8965
+#define GL_DOT3_ATI                       0x8966
+#define GL_DOT4_ATI                       0x8967
+#define GL_MAD_ATI                        0x8968
+#define GL_LERP_ATI                       0x8969
+#define GL_CND_ATI                        0x896A
+#define GL_CND0_ATI                       0x896B
+#define GL_DOT2_ADD_ATI                   0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI     0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI     0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI     0x896F
+#define GL_NUM_PASSES_ATI                 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI  0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI     0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI    0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI        0x8975
+#define GL_SWIZZLE_STR_ATI                0x8976
+#define GL_SWIZZLE_STQ_ATI                0x8977
+#define GL_SWIZZLE_STR_DR_ATI             0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI             0x8979
+#define GL_SWIZZLE_STRQ_ATI               0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI            0x897B
+#define GL_RED_BIT_ATI                    0x00000001
+#define GL_GREEN_BIT_ATI                  0x00000002
+#define GL_BLUE_BIT_ATI                   0x00000004
+#define GL_2X_BIT_ATI                     0x00000001
+#define GL_4X_BIT_ATI                     0x00000002
+#define GL_8X_BIT_ATI                     0x00000004
+#define GL_HALF_BIT_ATI                   0x00000008
+#define GL_QUARTER_BIT_ATI                0x00000010
+#define GL_EIGHTH_BIT_ATI                 0x00000020
+#define GL_SATURATE_BIT_ATI               0x00000040
+#define GL_COMP_BIT_ATI                   0x00000002
+#define GL_NEGATE_BIT_ATI                 0x00000004
+#define GL_BIAS_BIT_ATI                   0x00000008
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_PN_TRIANGLES_ATI               0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI    0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI   0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_STATIC_ATI                     0x8760
+#define GL_DYNAMIC_ATI                    0x8761
+#define GL_PRESERVE_ATI                   0x8762
+#define GL_DISCARD_ATI                    0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI         0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI        0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI        0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI        0x8767
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_VERTEX_SHADER_EXT              0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT      0x8781
+#define GL_OP_INDEX_EXT                   0x8782
+#define GL_OP_NEGATE_EXT                  0x8783
+#define GL_OP_DOT3_EXT                    0x8784
+#define GL_OP_DOT4_EXT                    0x8785
+#define GL_OP_MUL_EXT                     0x8786
+#define GL_OP_ADD_EXT                     0x8787
+#define GL_OP_MADD_EXT                    0x8788
+#define GL_OP_FRAC_EXT                    0x8789
+#define GL_OP_MAX_EXT                     0x878A
+#define GL_OP_MIN_EXT                     0x878B
+#define GL_OP_SET_GE_EXT                  0x878C
+#define GL_OP_SET_LT_EXT                  0x878D
+#define GL_OP_CLAMP_EXT                   0x878E
+#define GL_OP_FLOOR_EXT                   0x878F
+#define GL_OP_ROUND_EXT                   0x8790
+#define GL_OP_EXP_BASE_2_EXT              0x8791
+#define GL_OP_LOG_BASE_2_EXT              0x8792
+#define GL_OP_POWER_EXT                   0x8793
+#define GL_OP_RECIP_EXT                   0x8794
+#define GL_OP_RECIP_SQRT_EXT              0x8795
+#define GL_OP_SUB_EXT                     0x8796
+#define GL_OP_CROSS_PRODUCT_EXT           0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT         0x8798
+#define GL_OP_MOV_EXT                     0x8799
+#define GL_OUTPUT_VERTEX_EXT              0x879A
+#define GL_OUTPUT_COLOR0_EXT              0x879B
+#define GL_OUTPUT_COLOR1_EXT              0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT      0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT      0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT      0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT      0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT      0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT      0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT      0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT      0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT      0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT      0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT     0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT     0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT     0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT     0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT     0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT     0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT     0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT     0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT     0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT     0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT     0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT     0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT     0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT     0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT     0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT     0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT     0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT     0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT     0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT     0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT     0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT     0x87BC
+#define GL_OUTPUT_FOG_EXT                 0x87BD
+#define GL_SCALAR_EXT                     0x87BE
+#define GL_VECTOR_EXT                     0x87BF
+#define GL_MATRIX_EXT                     0x87C0
+#define GL_VARIANT_EXT                    0x87C1
+#define GL_INVARIANT_EXT                  0x87C2
+#define GL_LOCAL_CONSTANT_EXT             0x87C3
+#define GL_LOCAL_EXT                      0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT   0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT     0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT   0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT       0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT    0x87D4
+#define GL_X_EXT                          0x87D5
+#define GL_Y_EXT                          0x87D6
+#define GL_Z_EXT                          0x87D7
+#define GL_W_EXT                          0x87D8
+#define GL_NEGATIVE_X_EXT                 0x87D9
+#define GL_NEGATIVE_Y_EXT                 0x87DA
+#define GL_NEGATIVE_Z_EXT                 0x87DB
+#define GL_NEGATIVE_W_EXT                 0x87DC
+#define GL_ZERO_EXT                       0x87DD
+#define GL_ONE_EXT                        0x87DE
+#define GL_NEGATIVE_ONE_EXT               0x87DF
+#define GL_NORMALIZED_RANGE_EXT           0x87E0
+#define GL_FULL_RANGE_EXT                 0x87E1
+#define GL_CURRENT_VERTEX_EXT             0x87E2
+#define GL_MVP_MATRIX_EXT                 0x87E3
+#define GL_VARIANT_VALUE_EXT              0x87E4
+#define GL_VARIANT_DATATYPE_EXT           0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT       0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT         0x87E7
+#define GL_VARIANT_ARRAY_EXT              0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT      0x87E9
+#define GL_INVARIANT_VALUE_EXT            0x87EA
+#define GL_INVARIANT_DATATYPE_EXT         0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT       0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT    0x87ED
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_MAX_VERTEX_STREAMS_ATI         0x876B
+#define GL_VERTEX_STREAM0_ATI             0x876C
+#define GL_VERTEX_STREAM1_ATI             0x876D
+#define GL_VERTEX_STREAM2_ATI             0x876E
+#define GL_VERTEX_STREAM3_ATI             0x876F
+#define GL_VERTEX_STREAM4_ATI             0x8770
+#define GL_VERTEX_STREAM5_ATI             0x8771
+#define GL_VERTEX_STREAM6_ATI             0x8772
+#define GL_VERTEX_STREAM7_ATI             0x8773
+#define GL_VERTEX_SOURCE_ATI              0x8774
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ELEMENT_ARRAY_ATI              0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI         0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI      0x876A
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_QUAD_MESH_SUN                  0x8614
+#define GL_TRIANGLE_MESH_SUN              0x8615
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SLICE_ACCUM_SUN                0x85CC
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_MULTISAMPLE_FILTER_HINT_NV     0x8534
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_DEPTH_CLAMP_NV                 0x864F
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_PIXEL_COUNTER_BITS_NV          0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV  0x8865
+#define GL_PIXEL_COUNT_NV                 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV       0x8867
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_POINT_SPRITE_NV                0x8861
+#define GL_COORD_REPLACE_NV               0x8862
+#define GL_POINT_SPRITE_R_MODE_NV         0x8863
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV      0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV   0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV    0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV    0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV      0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV                       0x885E
+#define GL_SIGNED_HILO8_NV                0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV           0x8860
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_STENCIL_TEST_TWO_SIDE_EXT      0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT        0x8911
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_TEXT_FRAGMENT_SHADER_ATI       0x8200
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_UNPACK_CLIENT_STORAGE_APPLE    0x85B2
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_ELEMENT_ARRAY_APPLE            0x8A0C
+#define GL_ELEMENT_ARRAY_TYPE_APPLE       0x8A0D
+#define GL_ELEMENT_ARRAY_POINTER_APPLE    0x8A0E
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_DRAW_PIXELS_APPLE              0x8A0A
+#define GL_FENCE_APPLE                    0x8A0B
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_APPLE     0x85B5
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_APPLE       0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CLIENT_APPLE           0x85B4
+#define GL_STORAGE_CACHED_APPLE           0x85BE
+#define GL_STORAGE_SHARED_APPLE           0x85BF
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_YCBCR_422_APPLE                0x85B9
+#define GL_UNSIGNED_SHORT_8_8_APPLE       0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE   0x85BB
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_RGB_S3TC                       0x83A0
+#define GL_RGB4_S3TC                      0x83A1
+#define GL_RGBA_S3TC                      0x83A2
+#define GL_RGBA4_S3TC                     0x83A3
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ATI           0x8824
+#define GL_DRAW_BUFFER0_ATI               0x8825
+#define GL_DRAW_BUFFER1_ATI               0x8826
+#define GL_DRAW_BUFFER2_ATI               0x8827
+#define GL_DRAW_BUFFER3_ATI               0x8828
+#define GL_DRAW_BUFFER4_ATI               0x8829
+#define GL_DRAW_BUFFER5_ATI               0x882A
+#define GL_DRAW_BUFFER6_ATI               0x882B
+#define GL_DRAW_BUFFER7_ATI               0x882C
+#define GL_DRAW_BUFFER8_ATI               0x882D
+#define GL_DRAW_BUFFER9_ATI               0x882E
+#define GL_DRAW_BUFFER10_ATI              0x882F
+#define GL_DRAW_BUFFER11_ATI              0x8830
+#define GL_DRAW_BUFFER12_ATI              0x8831
+#define GL_DRAW_BUFFER13_ATI              0x8832
+#define GL_DRAW_BUFFER14_ATI              0x8833
+#define GL_DRAW_BUFFER15_ATI              0x8834
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_TYPE_RGBA_FLOAT_ATI            0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_MODULATE_ADD_ATI               0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI        0x8745
+#define GL_MODULATE_SUBTRACT_ATI          0x8746
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_RGBA_FLOAT32_ATI               0x8814
+#define GL_RGB_FLOAT32_ATI                0x8815
+#define GL_ALPHA_FLOAT32_ATI              0x8816
+#define GL_INTENSITY_FLOAT32_ATI          0x8817
+#define GL_LUMINANCE_FLOAT32_ATI          0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI    0x8819
+#define GL_RGBA_FLOAT16_ATI               0x881A
+#define GL_RGB_FLOAT16_ATI                0x881B
+#define GL_ALPHA_FLOAT16_ATI              0x881C
+#define GL_INTENSITY_FLOAT16_ATI          0x881D
+#define GL_LUMINANCE_FLOAT16_ATI          0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI    0x881F
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_FLOAT_R_NV                     0x8880
+#define GL_FLOAT_RG_NV                    0x8881
+#define GL_FLOAT_RGB_NV                   0x8882
+#define GL_FLOAT_RGBA_NV                  0x8883
+#define GL_FLOAT_R16_NV                   0x8884
+#define GL_FLOAT_R32_NV                   0x8885
+#define GL_FLOAT_RG16_NV                  0x8886
+#define GL_FLOAT_RG32_NV                  0x8887
+#define GL_FLOAT_RGB16_NV                 0x8888
+#define GL_FLOAT_RGB32_NV                 0x8889
+#define GL_FLOAT_RGBA16_NV                0x888A
+#define GL_FLOAT_RGBA32_NV                0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV    0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV     0x888D
+#define GL_FLOAT_RGBA_MODE_NV             0x888E
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV            0x8870
+#define GL_MAX_TEXTURE_COORDS_NV          0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV     0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV    0x8873
+#define GL_PROGRAM_ERROR_STRING_NV        0x8874
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_HALF_FLOAT_NV                  0x140B
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_WRITE_PIXEL_DATA_RANGE_NV      0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV       0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_PRIMITIVE_RESTART_NV           0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV     0x8559
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#endif
+
+#ifndef GL_NV_vertex_program2
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_STENCIL_BACK_FUNC_ATI          0x8800
+#define GL_STENCIL_BACK_FAIL_ATI          0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_DEPTH_BOUNDS_TEST_EXT          0x8890
+#define GL_DEPTH_BOUNDS_EXT               0x8891
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_MIRROR_CLAMP_EXT               0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT       0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT     0x8912
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_BLEND_EQUATION_RGB_EXT         0x8009
+#define GL_BLEND_EQUATION_ALPHA_EXT       0x883D
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_PACK_INVERT_MESA               0x8758
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_UNSIGNED_SHORT_8_8_MESA        0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA    0x85BB
+#define GL_YCBCR_MESA                     0x8757
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_EXT          0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT        0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT  0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV      0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV        0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV      0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV      0x88F8
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */
+#endif
+
+#ifndef GL_NV_vertex_program3
+/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT      0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT        0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT       0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT       0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT    0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT      0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT          0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT          0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT          0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT          0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT          0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT          0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT          0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT          0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT          0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT          0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT         0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT         0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT         0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT         0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT         0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT         0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT           0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT         0x8D20
+#define GL_FRAMEBUFFER_EXT                0x8D40
+#define GL_RENDERBUFFER_EXT               0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT         0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT        0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT             0x8D46
+#define GL_STENCIL_INDEX4_EXT             0x8D47
+#define GL_STENCIL_INDEX8_EXT             0x8D48
+#define GL_STENCIL_INDEX16_EXT            0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT      0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT    0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT     0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT    0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT    0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT  0x8D55
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_DEPTH_STENCIL_EXT              0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT          0x84FA
+#define GL_DEPTH24_STENCIL8_EXT           0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT       0x88F1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_STENCIL_TAG_BITS_EXT           0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT    0x88F3
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_SRGB_EXT                       0x8C40
+#define GL_SRGB8_EXT                      0x8C41
+#define GL_SRGB_ALPHA_EXT                 0x8C42
+#define GL_SRGB8_ALPHA8_EXT               0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT           0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT         0x8C45
+#define GL_SLUMINANCE_EXT                 0x8C46
+#define GL_SLUMINANCE8_EXT                0x8C47
+#define GL_COMPRESSED_SRGB_EXT            0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT      0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT      0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT  0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_EXT           0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT           0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT   GL_FRAMEBUFFER_BINDING_EXT
+#define GL_READ_FRAMEBUFFER_BINDING_EXT   0x8CAA
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_EXT       0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT                0x8D57
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_TEXTURE_1D_STACK_MESAX         0x8759
+#define GL_TEXTURE_2D_STACK_MESAX         0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX   0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX   0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_TIME_ELAPSED_EXT               0x88BF
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE    0x8A13
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV    0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV    0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV   0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV   0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_LINES_ADJACENCY_EXT            0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT       0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT        0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT   0x000D
+#define GL_GEOMETRY_PROGRAM_NV            0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define GL_GEOMETRY_VERTICES_OUT_EXT      0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT        0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT       0x8DDC
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_PROGRAM_POINT_SIZE_EXT         0x8642
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_GEOMETRY_SHADER_EXT            0x8DD9
+/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */
+/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */
+/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */
+/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_VARYING_COMPONENTS_EXT     0x8B4B
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+/* reuse GL_LINES_ADJACENCY_EXT */
+/* reuse GL_LINE_STRIP_ADJACENCY_EXT */
+/* reuse GL_TRIANGLES_ADJACENCY_EXT */
+/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+/* reuse GL_PROGRAM_POINT_SIZE_EXT */
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_SAMPLER_1D_ARRAY_EXT           0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT           0x8DC1
+#define GL_SAMPLER_BUFFER_EXT             0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT    0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT    0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT        0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT          0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT          0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT          0x8DC8
+#define GL_INT_SAMPLER_1D_EXT             0x8DC9
+#define GL_INT_SAMPLER_2D_EXT             0x8DCA
+#define GL_INT_SAMPLER_3D_EXT             0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT           0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT        0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT       0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT       0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT         0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT    0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT    0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT    0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT  0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_R11F_G11F_B10F_EXT             0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT     0x8C3C
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_TEXTURE_1D_ARRAY_EXT           0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT     0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT           0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT     0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT   0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT   0x8C1D
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT   0x88FF
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_TEXTURE_BUFFER_EXT             0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT    0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT     0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT      0x8C2E
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1_EXT       0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_RGB9_E5_EXT                    0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT   0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT        0x8C3F
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F_NV          0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV           0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV     0x8DAF
+#endif
+
+#ifndef GL_NV_fragment_program4
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV  0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV  0x8E12
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB_EXT           0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT   0x8DBA
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_BACK_PRIMARY_COLOR_NV          0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV        0x8C78
+#define GL_TEXTURE_COORD_NV               0x8C79
+#define GL_CLIP_DISTANCE_NV               0x8C7A
+#define GL_VERTEX_ID_NV                   0x8C7B
+#define GL_PRIMITIVE_ID_NV                0x8C7C
+#define GL_GENERIC_ATTRIB_NV              0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV  0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV             0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV   0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV   0x8C86
+#define GL_PRIMITIVES_GENERATED_NV        0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV          0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV         0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV            0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV   0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#define GL_LAYER_NV                       0x8DAA
+#define GL_NEXT_BUFFER_NV                 -2
+#define GL_SKIP_COMPONENTS4_NV            -3
+#define GL_SKIP_COMPONENTS3_NV            -4
+#define GL_SKIP_COMPONENTS2_NV            -5
+#define GL_SKIP_COMPONENTS1_NV            -6
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT  0x8DED
+#define GL_UNIFORM_BUFFER_EXT             0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT     0x8DEF
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_RGBA32UI_EXT                   0x8D70
+#define GL_RGB32UI_EXT                    0x8D71
+#define GL_ALPHA32UI_EXT                  0x8D72
+#define GL_INTENSITY32UI_EXT              0x8D73
+#define GL_LUMINANCE32UI_EXT              0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT        0x8D75
+#define GL_RGBA16UI_EXT                   0x8D76
+#define GL_RGB16UI_EXT                    0x8D77
+#define GL_ALPHA16UI_EXT                  0x8D78
+#define GL_INTENSITY16UI_EXT              0x8D79
+#define GL_LUMINANCE16UI_EXT              0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT        0x8D7B
+#define GL_RGBA8UI_EXT                    0x8D7C
+#define GL_RGB8UI_EXT                     0x8D7D
+#define GL_ALPHA8UI_EXT                   0x8D7E
+#define GL_INTENSITY8UI_EXT               0x8D7F
+#define GL_LUMINANCE8UI_EXT               0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT         0x8D81
+#define GL_RGBA32I_EXT                    0x8D82
+#define GL_RGB32I_EXT                     0x8D83
+#define GL_ALPHA32I_EXT                   0x8D84
+#define GL_INTENSITY32I_EXT               0x8D85
+#define GL_LUMINANCE32I_EXT               0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT         0x8D87
+#define GL_RGBA16I_EXT                    0x8D88
+#define GL_RGB16I_EXT                     0x8D89
+#define GL_ALPHA16I_EXT                   0x8D8A
+#define GL_INTENSITY16I_EXT               0x8D8B
+#define GL_LUMINANCE16I_EXT               0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT         0x8D8D
+#define GL_RGBA8I_EXT                     0x8D8E
+#define GL_RGB8I_EXT                      0x8D8F
+#define GL_ALPHA8I_EXT                    0x8D90
+#define GL_INTENSITY8I_EXT                0x8D91
+#define GL_LUMINANCE8I_EXT                0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT          0x8D93
+#define GL_RED_INTEGER_EXT                0x8D94
+#define GL_GREEN_INTEGER_EXT              0x8D95
+#define GL_BLUE_INTEGER_EXT               0x8D96
+#define GL_ALPHA_INTEGER_EXT              0x8D97
+#define GL_RGB_INTEGER_EXT                0x8D98
+#define GL_RGBA_INTEGER_EXT               0x8D99
+#define GL_BGR_INTEGER_EXT                0x8D9A
+#define GL_BGRA_INTEGER_EXT               0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT          0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT    0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT          0x8D9E
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_QUERY_WAIT_NV                  0x8E13
+#define GL_QUERY_NO_WAIT_NV               0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV        0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV     0x8E16
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_FRAME_NV                       0x8E26
+#define GL_FIELDS_NV                      0x8E27
+#define GL_CURRENT_TIME_NV                0x8E28
+#define GL_NUM_FILL_STREAMS_NV            0x8E29
+#define GL_PRESENT_TIME_NV                0x8E2A
+#define GL_PRESENT_DURATION_NV            0x8E2B
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT  0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+#define GL_INTERLEAVED_ATTRIBS_EXT        0x8C8C
+#define GL_SEPARATE_ATTRIBS_EXT           0x8C8D
+#define GL_PRIMITIVES_GENERATED_EXT       0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_RASTERIZER_DISCARD_EXT         0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_PROGRAM_MATRIX_EXT             0x8E2D
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT   0x8E2E
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R_EXT          0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT          0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT          0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT          0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT       0x8E46
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_SAMPLE_POSITION_NV             0x8E50
+#define GL_SAMPLE_MASK_NV                 0x8E51
+#define GL_SAMPLE_MASK_VALUE_NV           0x8E52
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV        0x8E55
+#define GL_SAMPLER_RENDERBUFFER_NV        0x8E56
+#define GL_INT_SAMPLER_RENDERBUFFER_NV    0x8E57
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV       0x8E59
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK_NV          0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV  0x8E25
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_VBO_FREE_MEMORY_ATI            0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI        0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI   0x87FD
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_COUNTER_TYPE_AMD               0x8BC0
+#define GL_COUNTER_RANGE_AMD              0x8BC1
+#define GL_UNSIGNED_INT64_AMD             0x8BC2
+#define GL_PERCENTAGE_AMD                 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD   0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD        0x8BC5
+#define GL_PERFMON_RESULT_AMD             0x8BC6
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_SAMPLER_BUFFER_AMD             0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD         0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD          0x9004
+#define GL_TESSELLATION_FACTOR_AMD        0x9005
+#define GL_DISCRETE_AMD                   0x9006
+#define GL_CONTINUOUS_AMD                 0x9007
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT    0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT     0x8E4E
+#define GL_PROVOKING_VERTEX_EXT           0x8E4F
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_ALPHA_SNORM                    0x9010
+#define GL_LUMINANCE_SNORM                0x9011
+#define GL_LUMINANCE_ALPHA_SNORM          0x9012
+#define GL_INTENSITY_SNORM                0x9013
+#define GL_ALPHA8_SNORM                   0x9014
+#define GL_LUMINANCE8_SNORM               0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM        0x9016
+#define GL_INTENSITY8_SNORM               0x9017
+#define GL_ALPHA16_SNORM                  0x9018
+#define GL_LUMINANCE16_SNORM              0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM      0x901A
+#define GL_INTENSITY16_SNORM              0x901B
+/* reuse GL_RED_SNORM */
+/* reuse GL_RG_SNORM */
+/* reuse GL_RGB_SNORM */
+/* reuse GL_RGBA_SNORM */
+/* reuse GL_R8_SNORM */
+/* reuse GL_RG8_SNORM */
+/* reuse GL_RGB8_SNORM */
+/* reuse GL_RGBA8_SNORM */
+/* reuse GL_R16_SNORM */
+/* reuse GL_RG16_SNORM */
+/* reuse GL_RGB16_SNORM */
+/* reuse GL_RGBA16_SNORM */
+/* reuse GL_SIGNED_NORMALIZED */
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_TEXTURE_RANGE_LENGTH_APPLE     0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE    0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE     0x85BC
+#define GL_STORAGE_PRIVATE_APPLE          0x85BD
+/* reuse GL_STORAGE_CACHED_APPLE */
+/* reuse GL_STORAGE_SHARED_APPLE */
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_HALF_APPLE                     0x140B
+#define GL_RGBA_FLOAT32_APPLE             0x8814
+#define GL_RGB_FLOAT32_APPLE              0x8815
+#define GL_ALPHA_FLOAT32_APPLE            0x8816
+#define GL_INTENSITY_FLOAT32_APPLE        0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE        0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE  0x8819
+#define GL_RGBA_FLOAT16_APPLE             0x881A
+#define GL_RGB_FLOAT16_APPLE              0x881B
+#define GL_ALPHA_FLOAT16_APPLE            0x881C
+#define GL_INTENSITY_FLOAT16_APPLE        0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE        0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE  0x881F
+#define GL_COLOR_FLOAT_APPLE              0x8A0F
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_VERTEX_ATTRIB_MAP1_APPLE       0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE       0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE  0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE  0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_AUX_DEPTH_STENCIL_APPLE        0x8A14
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_BUFFER_OBJECT_APPLE            0x85B3
+#define GL_RELEASED_APPLE                 0x8A19
+#define GL_VOLATILE_APPLE                 0x8A1A
+#define GL_RETAINED_APPLE                 0x8A1B
+#define GL_UNDEFINED_APPLE                0x8A1C
+#define GL_PURGEABLE_APPLE                0x8A1D
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_PACK_ROW_BYTES_APPLE           0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE         0x8A16
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE                  0x8A1F
+/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */
+/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_VIDEO_BUFFER_NV                0x9020
+#define GL_VIDEO_BUFFER_BINDING_NV        0x9021
+#define GL_FIELD_UPPER_NV                 0x9022
+#define GL_FIELD_LOWER_NV                 0x9023
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV   0x9024
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV   0x9027
+#define GL_VIDEO_BUFFER_PITCH_NV          0x9028
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV  0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV  0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_PARTIAL_SUCCESS_NV             0x902E
+#define GL_SUCCESS_NV                     0x902F
+#define GL_FAILURE_NV                     0x9030
+#define GL_YCBYCR8_422_NV                 0x9031
+#define GL_YCBAYCR8A_4224_NV              0x9032
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV  0x9033
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV  0x9035
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV       0x9037
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV   0x9038
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV  0x9039
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+#endif
+
+#ifndef GL_NV_copy_image
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_ACTIVE_PROGRAM_EXT             0x8B8D
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_BUFFER_GPU_ADDRESS_NV          0x8F1D
+#define GL_GPU_ADDRESS_NV                 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV   0x8F35
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV       0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV        0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV        0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV         0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV         0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV     0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV     0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV       0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV  0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV         0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV         0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV          0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV          0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV  0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV      0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV      0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV        0x8F33
+#define GL_DRAW_INDIRECT_UNIFIED_NV       0x8F40
+#define GL_DRAW_INDIRECT_ADDRESS_NV       0x8F41
+#define GL_DRAW_INDIRECT_LENGTH_NV        0x8F42
+#endif
+
+#ifndef GL_NV_texture_barrier
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_MAX_IMAGE_UNITS_EXT            0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_IMAGE_BINDING_NAME_EXT         0x8F3A
+#define GL_IMAGE_BINDING_LEVEL_EXT        0x8F3B
+#define GL_IMAGE_BINDING_LAYERED_EXT      0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT        0x8F3D
+#define GL_IMAGE_BINDING_ACCESS_EXT       0x8F3E
+#define GL_IMAGE_1D_EXT                   0x904C
+#define GL_IMAGE_2D_EXT                   0x904D
+#define GL_IMAGE_3D_EXT                   0x904E
+#define GL_IMAGE_2D_RECT_EXT              0x904F
+#define GL_IMAGE_CUBE_EXT                 0x9050
+#define GL_IMAGE_BUFFER_EXT               0x9051
+#define GL_IMAGE_1D_ARRAY_EXT             0x9052
+#define GL_IMAGE_2D_ARRAY_EXT             0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT       0x9054
+#define GL_IMAGE_2D_MULTISAMPLE_EXT       0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_INT_IMAGE_1D_EXT               0x9057
+#define GL_INT_IMAGE_2D_EXT               0x9058
+#define GL_INT_IMAGE_3D_EXT               0x9059
+#define GL_INT_IMAGE_2D_RECT_EXT          0x905A
+#define GL_INT_IMAGE_CUBE_EXT             0x905B
+#define GL_INT_IMAGE_BUFFER_EXT           0x905C
+#define GL_INT_IMAGE_1D_ARRAY_EXT         0x905D
+#define GL_INT_IMAGE_2D_ARRAY_EXT         0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT   0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT   0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT      0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT      0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT      0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT    0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT  0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_MAX_IMAGE_SAMPLES_EXT          0x906D
+#define GL_IMAGE_BINDING_FORMAT_EXT       0x906E
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT  0x00000002
+#define GL_UNIFORM_BARRIER_BIT_EXT        0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT  0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_COMMAND_BARRIER_BIT_EXT        0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT   0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT  0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT    0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_ALL_BARRIER_BITS_EXT           0xFFFFFFFF
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+/* reuse GL_DOUBLE */
+#define GL_DOUBLE_VEC2_EXT                0x8FFC
+#define GL_DOUBLE_VEC3_EXT                0x8FFD
+#define GL_DOUBLE_VEC4_EXT                0x8FFE
+#define GL_DOUBLE_MAT2_EXT                0x8F46
+#define GL_DOUBLE_MAT3_EXT                0x8F47
+#define GL_DOUBLE_MAT4_EXT                0x8F48
+#define GL_DOUBLE_MAT2x3_EXT              0x8F49
+#define GL_DOUBLE_MAT2x4_EXT              0x8F4A
+#define GL_DOUBLE_MAT3x2_EXT              0x8F4B
+#define GL_DOUBLE_MAT3x4_EXT              0x8F4C
+#define GL_DOUBLE_MAT4x2_EXT              0x8F4D
+#define GL_DOUBLE_MAT4x3_EXT              0x8F4E
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44
+#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV  0x8F45
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_INT64_NV                       0x140E
+#define GL_UNSIGNED_INT64_NV              0x140F
+#define GL_INT8_NV                        0x8FE0
+#define GL_INT8_VEC2_NV                   0x8FE1
+#define GL_INT8_VEC3_NV                   0x8FE2
+#define GL_INT8_VEC4_NV                   0x8FE3
+#define GL_INT16_NV                       0x8FE4
+#define GL_INT16_VEC2_NV                  0x8FE5
+#define GL_INT16_VEC3_NV                  0x8FE6
+#define GL_INT16_VEC4_NV                  0x8FE7
+#define GL_INT64_VEC2_NV                  0x8FE9
+#define GL_INT64_VEC3_NV                  0x8FEA
+#define GL_INT64_VEC4_NV                  0x8FEB
+#define GL_UNSIGNED_INT8_NV               0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV          0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV          0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV          0x8FEF
+#define GL_UNSIGNED_INT16_NV              0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV         0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV         0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV         0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV         0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV         0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV         0x8FF7
+#define GL_FLOAT16_NV                     0x8FF8
+#define GL_FLOAT16_VEC2_NV                0x8FF9
+#define GL_FLOAT16_VEC3_NV                0x8FFA
+#define GL_FLOAT16_VEC4_NV                0x8FFB
+/* reuse GL_PATCHES */
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010
+/* reuse GL_READ_WRITE */
+/* reuse GL_WRITE_ONLY */
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV   0x86D8
+#define GL_TESS_CONTROL_PROGRAM_NV        0x891E
+#define GL_TESS_EVALUATION_PROGRAM_NV     0x891F
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+/* reuse GL_INT64_NV */
+/* reuse GL_UNSIGNED_INT64_NV */
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_COVERAGE_SAMPLES_NV            0x80A9
+#define GL_COLOR_SAMPLES_NV               0x8E20
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_DATA_BUFFER_AMD                0x9151
+#define GL_PERFORMANCE_MONITOR_AMD        0x9152
+#define GL_QUERY_OBJECT_AMD               0x9153
+#define GL_VERTEX_ARRAY_OBJECT_AMD        0x9154
+#define GL_SAMPLER_OBJECT_AMD             0x9155
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD  0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_AMD      0x9145
+#define GL_DEBUG_SEVERITY_HIGH_AMD        0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD      0x9147
+#define GL_DEBUG_SEVERITY_LOW_AMD         0x9148
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD   0x9149
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_OTHER_AMD       0x9150
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_SURFACE_STATE_NV               0x86EB
+#define GL_SURFACE_REGISTERED_NV          0x86FD
+#define GL_SURFACE_MAPPED_NV              0x8700
+#define GL_WRITE_DISCARD_NV               0x88BE
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#endif
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_DEPTH_CLAMP_NEAR_AMD           0x901E
+#define GL_DEPTH_CLAMP_FAR_AMD            0x901F
+#endif
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_TEXTURE_SRGB_DECODE_EXT        0x8A48
+#define GL_DECODE_EXT                     0x8A49
+#define GL_SKIP_DECODE_EXT                0x8A4A
+#endif
+
+#ifndef GL_NV_texture_multisample
+#define GL_TEXTURE_COVERAGE_SAMPLES_NV    0x9045
+#define GL_TEXTURE_COLOR_SAMPLES_NV       0x9046
+#endif
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_FACTOR_MIN_AMD                 0x901C
+#define GL_FACTOR_MAX_AMD                 0x901D
+#endif
+
+#ifndef GL_AMD_sample_positions
+#define GL_SUBSAMPLE_DISTANCE_AMD         0x883F
+#endif
+
+#ifndef GL_EXT_x11_sync_object
+#define GL_SYNC_X11_FENCE_EXT             0x90E1
+#endif
+
+#ifndef GL_AMD_multi_draw_indirect
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample_blit_scaled
+#define GL_SCALED_RESOLVE_FASTEST_EXT     0x90BA
+#define GL_SCALED_RESOLVE_NICEST_EXT      0x90BB
+#endif
+
+
+/*************************************************************/
+
+#include 
+#ifndef GL_VERSION_2_0
+/* GL type for program/shader text */
+typedef char GLchar;
+#endif
+
+#ifndef GL_VERSION_1_5
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+
+#ifndef GL_ARB_shader_objects
+/* GL types for program/shader text and shader object handles */
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+#endif
+
+/* GL type for "half" precision (s10e5) float data in host memory */
+#ifndef GL_ARB_half_float_pixel
+typedef unsigned short GLhalfARB;
+#endif
+
+#ifndef GL_NV_half_float
+typedef unsigned short GLhalfNV;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glxext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GL_EXT_timer_query extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include 
+#elif defined(__sun__) || defined(__digital__)
+#include 
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include 
+#elif defined(__SCO__) || defined(__USLC__)
+#include 
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include 
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include 
+#endif
+#endif
+
+#ifndef GL_EXT_timer_query
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+
+#ifndef GL_ARB_sync
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+#ifndef GL_ARB_cl_event
+/* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */
+struct _cl_context;
+struct _cl_event;
+#endif
+
+#ifndef GL_ARB_debug_output
+typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_AMD_debug_output
+typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+typedef GLintptr GLvdpauSurfaceNV;
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void APIENTRY glBlendEquation (GLenum mode);
+GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_VERSION_1_2_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogram (GLenum target);
+GLAPI void APIENTRY glResetMinmax (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target);
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTexture (GLenum texture);
+GLAPI void APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_VERSION_1_3_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientActiveTexture (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_VERSION_1_4_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordf (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoordd (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2sv (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3sv (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQuery (GLuint id);
+GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQuery (GLenum target);
+GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer);
+GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target);
+GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GLAPI void APIENTRY glCompileShader (GLuint shader);
+GLAPI GLuint APIENTRY glCreateProgram (void);
+GLAPI GLuint APIENTRY glCreateShader (GLenum type);
+GLAPI void APIENTRY glDeleteProgram (GLuint program);
+GLAPI void APIENTRY glDeleteShader (GLuint shader);
+GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
+GLAPI GLboolean APIENTRY glIsShader (GLuint shader);
+GLAPI void APIENTRY glLinkProgram (GLuint program);
+GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+GLAPI void APIENTRY glUseProgram (GLuint program);
+GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glValidateProgram (GLuint program);
+GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_VERSION_3_0 1
+/* OpenGL 3.0 also reuses entry points from these extensions: */
+/* ARB_framebuffer_object */
+/* ARB_map_buffer_range */
+/* ARB_vertex_array_object */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnablei (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisablei (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index);
+GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedback (void);
+GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);
+GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRender (void);
+GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+/* OpenGL 3.1 also reuses entry points from these extensions: */
+/* ARB_copy_buffer */
+/* ARB_uniform_buffer_object */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+/* OpenGL 3.2 also reuses entry points from these extensions: */
+/* ARB_draw_elements_base_vertex */
+/* ARB_provoking_vertex */
+/* ARB_sync */
+/* ARB_texture_multisample */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERSION_3_3 1
+/* OpenGL 3.3 also reuses entry points from these extensions: */
+/* ARB_blend_func_extended */
+/* ARB_sampler_objects */
+/* ARB_explicit_attrib_location, but it has none */
+/* ARB_occlusion_query2 (no entry points) */
+/* ARB_shader_bit_encoding (no entry points) */
+/* ARB_texture_rgb10_a2ui (no entry points) */
+/* ARB_texture_swizzle (no entry points) */
+/* ARB_timer_query */
+/* ARB_vertex_type_2_10_10_10_rev */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_VERSION_4_0 1
+/* OpenGL 4.0 also reuses entry points from these extensions: */
+/* ARB_texture_query_lod (no entry points) */
+/* ARB_draw_indirect */
+/* ARB_gpu_shader5 (no entry points) */
+/* ARB_gpu_shader_fp64 */
+/* ARB_shader_subroutine */
+/* ARB_tessellation_shader */
+/* ARB_texture_buffer_object_rgb32 (no entry points) */
+/* ARB_texture_cube_map_array (no entry points) */
+/* ARB_texture_gather (no entry points) */
+/* ARB_transform_feedback2 */
+/* ARB_transform_feedback3 */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShading (GLclampf value);
+GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_VERSION_4_1
+#define GL_VERSION_4_1 1
+/* OpenGL 4.1 reuses entry points from these extensions: */
+/* ARB_ES2_compatibility */
+/* ARB_get_program_binary */
+/* ARB_separate_shader_objects */
+/* ARB_shader_precision (no entry points) */
+/* ARB_vertex_attrib_64bit */
+/* ARB_viewport_array */
+#endif
+
+#ifndef GL_VERSION_4_2
+#define GL_VERSION_4_2 1
+/* OpenGL 4.2 reuses entry points from these extensions: */
+/* ARB_base_instance */
+/* ARB_shading_language_420pack (no entry points) */
+/* ARB_transform_feedback_instanced */
+/* ARB_compressed_texture_pixel_storage (no entry points) */
+/* ARB_conservative_depth (no entry points) */
+/* ARB_internalformat_query */
+/* ARB_map_buffer_alignment (no entry points) */
+/* ARB_shader_atomic_counters */
+/* ARB_shader_image_load_store */
+/* ARB_shading_language_packing (no entry points) */
+/* ARB_texture_storage */
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleCoverageARB (GLclampf value, GLboolean invert);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights);
+GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights);
+GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights);
+GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights);
+GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights);
+GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights);
+GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights);
+GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights);
+GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexBlendARB (GLint count);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
+typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index);
+GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices);
+GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices);
+GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices);
+GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+#endif
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program);
+GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program);
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer);
+GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target);
+GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id);
+GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQueryARB (GLenum target);
+GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj);
+GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname);
+GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj);
+GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType);
+GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj);
+GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void);
+GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj);
+GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj);
+GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params);
+GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#define GL_ARB_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_ARB_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmap (GLenum target);
+GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_ARB_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value);
+GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex 1
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_ARB_instanced_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_ARB_map_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_ARB_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_ARB_texture_rg 1
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_ARB_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArray (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertex (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GLAPI GLboolean APIENTRY glIsSync (GLsync sync);
+GLAPI void APIENTRY glDeleteSync (GLsync sync);
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShadingARB (GLclampf value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_ARB_shading_language_include 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_ARB_texture_compression_bptc 1
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_ARB_blend_func_extended 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name);
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#define GL_ARB_explicit_attrib_location 1
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ARB_occlusion_query2 1
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_ARB_sampler_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler);
+GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);
+GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_bit_encoding
+#define GL_ARB_shader_bit_encoding 1
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_ARB_texture_rgb10_a2ui 1
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_ARB_texture_swizzle 1
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target);
+GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+#define GL_ARB_vertex_type_2_10_10_10_rev 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_ARB_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect);
+GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_ARB_gpu_shader5 1
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+#define GL_ARB_gpu_shader_fp64 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x);
+GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ARB_shader_subroutine 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);
+GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);
+GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);
+typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_ARB_tessellation_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value);
+GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+#define GL_ARB_texture_buffer_object_rgb32 1
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_ARB_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedback (void);
+GLAPI void APIENTRY glResumeTransformFeedback (void);
+GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_ARB_transform_feedback3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream);
+GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id);
+GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index);
+GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);
+typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_ARB_ES2_compatibility 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReleaseShaderCompiler (void);
+GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GLAPI void APIENTRY glDepthRangef (GLclampf n, GLclampf f);
+GLAPI void APIENTRY glClearDepthf (GLclampf d);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
+typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLclampf d);
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_ARB_get_program_binary 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_ARB_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
+GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* *strings);
+GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
+GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
+GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);
+GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0);
+GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* *strings);
+typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+#define GL_ARB_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_viewport_array
+#define GL_ARB_viewport_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);
+GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLclampd *v);
+GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLclampd n, GLclampd f);
+GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_ARB_cl_event 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_ARB_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif
+
+#ifndef GL_ARB_robustness
+#define GL_ARB_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void);
+GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values);
+GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values);
+GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values);
+GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern);
+GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);
+typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values);
+typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern);
+typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#define GL_ARB_shader_stencil_export 1
+#endif
+
+#ifndef GL_ARB_base_instance
+#define GL_ARB_base_instance 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
+GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+#endif
+
+#ifndef GL_ARB_shading_language_420pack
+#define GL_ARB_shading_language_420pack 1
+#endif
+
+#ifndef GL_ARB_transform_feedback_instanced
+#define GL_ARB_transform_feedback_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei primcount);
+GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+#endif
+
+#ifndef GL_ARB_compressed_texture_pixel_storage
+#define GL_ARB_compressed_texture_pixel_storage 1
+#endif
+
+#ifndef GL_ARB_conservative_depth
+#define GL_ARB_conservative_depth 1
+#endif
+
+#ifndef GL_ARB_internalformat_query
+#define GL_ARB_internalformat_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#endif
+
+#ifndef GL_ARB_map_buffer_alignment
+#define GL_ARB_map_buffer_alignment 1
+#endif
+
+#ifndef GL_ARB_shader_atomic_counters
+#define GL_ARB_shader_atomic_counters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_shader_image_load_store
+#define GL_ARB_shader_image_load_store 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
+#endif
+
+#ifndef GL_ARB_shading_language_packing
+#define GL_ARB_shading_language_packing 1
+#endif
+
+#ifndef GL_ARB_texture_storage
+#define GL_ARB_texture_storage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights);
+GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights);
+typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogramEXT (GLenum target);
+GLAPI void APIENTRY glResetMinmaxEXT (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences);
+GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture);
+GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures);
+GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures);
+GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture);
+GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures);
+typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glArrayElementEXT (GLint i);
+GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer);
+GLAPI void APIENTRY glGetPointervEXT (GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer);
+typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+#endif
+
+#ifndef GL_SGIX_texture_select
+#define GL_SGIX_texture_select 1
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_SGIS_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_SGIX_instruments 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetInstrumentsSGIX (void);
+GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer);
+GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p);
+GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker);
+GLAPI void APIENTRY glStartInstrumentsSGIX (void);
+GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer);
+typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p);
+typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker);
+typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker);
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameZoomSGIX (GLint factor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTagSampleBufferSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+GLAPI void APIENTRY glDeformSGIX (GLbitfield mask);
+GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushRasterSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points);
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+#endif
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode);
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data);
+GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params);
+GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param);
+GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+#endif
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref);
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+GLAPI void APIENTRY glUnlockArraysEXT (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void);
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_SGIX_fragment_lighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode);
+GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params);
+GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glApplyTextureEXT (GLenum mode);
+GLAPI void APIENTRY glTextureLightEXT (GLenum pname);
+GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker);
+GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp);
+GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp);
+GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range);
+GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range);
+GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp);
+typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp);
+typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz);
+GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz);
+GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz);
+GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz);
+GLAPI void APIENTRY glTangent3ivEXT (const GLint *v);
+GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz);
+GLAPI void APIENTRY glTangent3svEXT (const GLshort *v);
+GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz);
+GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz);
+GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz);
+GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz);
+GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v);
+GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz);
+GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v);
+GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz);
+typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz);
+typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz);
+typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz);
+typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz);
+typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz);
+typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz);
+typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz);
+typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz);
+typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz);
+typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFinishTextureSUNX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void);
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor);
+GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor);
+GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor);
+GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code);
+GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code);
+GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code);
+GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code);
+GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code);
+GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code);
+GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_blend_func_separate
+#define GL_INGR_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight);
+GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight);
+GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushVertexArrayRangeNV (void);
+GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+#endif
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glResizeBuffersMESA (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void);
+#endif
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+#endif
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_SGIS_texture_color_mask 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const GLvoid *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params);
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+#endif
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence);
+GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFinishFenceNV (GLuint fence);
+GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences);
+GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params);
+GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program);
+GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id);
+GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program);
+typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v);
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SGIX_scalebias_hint 1
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+#endif
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param);
+GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param);
+GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range);
+GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glBeginFragmentShaderATI (void);
+GLAPI void APIENTRY glEndFragmentShaderATI (void);
+GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle);
+GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle);
+GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value);
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage);
+GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params);
+GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage);
+typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVertexShaderEXT (void);
+GLAPI void APIENTRY glEndVertexShaderEXT (void);
+GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id);
+GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range);
+GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id);
+GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1);
+GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr);
+GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr);
+GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr);
+GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr);
+GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr);
+GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr);
+GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr);
+GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr);
+GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id);
+GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id);
+GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value);
+GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value);
+GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value);
+GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value);
+GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value);
+GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap);
+GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data);
+GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr);
+typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr);
+typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr);
+typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr);
+typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr);
+typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr);
+typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x);
+GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x);
+GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x);
+GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x);
+GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y);
+GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords);
+GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz);
+GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream);
+GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerATI (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glEndOcclusionQueryNV (void);
+GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences);
+GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence);
+GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name);
+GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences);
+typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_ATI_pixel_format_float 1
+/* This is really a WGL extension, but defines some associated GL enums.
+ * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string.
+ */
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s);
+GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s);
+GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog);
+GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog);
+GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight);
+GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight);
+GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x);
+GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s);
+typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog);
+typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPrimitiveRestartNV (void);
+GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+#endif
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+#endif
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const GLvoid *string);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string);
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit);
+GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glClearDepthdNV (GLdouble depth);
+GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+#endif
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackNV (void);
+GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode);
+GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name);
+GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location);
+GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer);
+GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location);
+GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha);
+GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#define GL_GREMEDY_frame_terminator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameTerminatorGREMEDY (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRenderNV (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_NV_present_video 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_EXT_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackEXT (void);
+GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixPopEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixPushEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data);
+GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, GLvoid* *data);
+GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer);
+GLAPI GLvoid* APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length);
+GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params);
+GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target);
+GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target);
+GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target);
+GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x);
+GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data);
+typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params);
+typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
+typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+#define GL_EXT_vertex_array_bgra 1
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_EXT_texture_swizzle 1
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_NV_explicit_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask);
+GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
+typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedbackNV (void);
+GLAPI void APIENTRY glResumeTransformFeedbackNV (void);
+GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_AMD_vertex_shader_tesselator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor);
+GLAPI void APIENTRY glTessellationModeAMD (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const GLvoid *pointer);
+GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_NV_video_capture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program);
+GLAPI void APIENTRY glActiveProgramEXT (GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string);
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access);
+GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target);
+GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target);
+GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access);
+GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer);
+GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer);
+GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result);
+GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params);
+GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result);
+typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride);
+GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
+#endif
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureBarrierNV (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void);
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#define GL_AMD_shader_stencil_export 1
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+#define GL_AMD_seamless_cubemap_per_texture 1
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#define GL_AMD_conservative_depth 1
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_EXT_shader_image_load_store 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers);
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+#define GL_EXT_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_NV_gpu_program5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param);
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);
+GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);
+GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);
+GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_NV_shader_buffer_store 1
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_NV_tessellation_program5 1
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+#define GL_NV_vertex_attrib_integer_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_NV_multisample_coverage 1
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_AMD_name_gen_delete 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names);
+GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names);
+GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names);
+typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names);
+typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name);
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_AMD_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_NV_vdpau_interop 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVDPAUInitNV (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+GLAPI void APIENTRY glVDPAUFiniNV (void);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI void APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access);
+GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef void (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
+typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#define GL_AMD_transform_feedback3_lines_triangles 1
+#endif
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_AMD_depth_clamp_separate 1
+#endif
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+#endif
+
+#ifndef GL_NV_texture_multisample
+#define GL_NV_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+#endif
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_AMD_blend_minmax_factor 1
+#endif
+
+#ifndef GL_AMD_sample_positions
+#define GL_AMD_sample_positions 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val);
+#endif
+
+#ifndef GL_EXT_x11_sync_object
+#define GL_EXT_x11_sync_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags);
+#endif
+
+#ifndef GL_AMD_multi_draw_indirect
+#define GL_AMD_multi_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample_blit_scaled
+#define GL_EXT_framebuffer_multisample_blit_scaled 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/glxext.h b/src/others/irrlicht-1.8.1/source/Irrlicht/glxext.h
new file mode 100644
index 0000000..07b0219
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/glxext.h
@@ -0,0 +1,993 @@
+#ifndef __glxext_h_
+#define __glxext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2011 The Khronos Group Inc.
+** 
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+** 
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include 
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number, required by OpenGL ABI for Linux */
+/* glxext.h last updated 2010/08/06 */
+/* Current version at http://www.opengl.org/registry/ */
+#define GLX_GLXEXT_VERSION 32
+
+#ifndef GLX_VERSION_1_3
+#define GLX_WINDOW_BIT                     0x00000001
+#define GLX_PIXMAP_BIT                     0x00000002
+#define GLX_PBUFFER_BIT                    0x00000004
+#define GLX_RGBA_BIT                       0x00000001
+#define GLX_COLOR_INDEX_BIT                0x00000002
+#define GLX_PBUFFER_CLOBBER_MASK           0x08000000
+#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_CONFIG_CAVEAT                  0x20
+#define GLX_X_VISUAL_TYPE                  0x22
+#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_DONT_CARE                      0xFFFFFFFF
+#define GLX_NONE                           0x8000
+#define GLX_SLOW_CONFIG                    0x8001
+#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_TRANSPARENT_RGB                0x8008
+#define GLX_TRANSPARENT_INDEX              0x8009
+#define GLX_VISUAL_ID                      0x800B
+#define GLX_SCREEN                         0x800C
+#define GLX_NON_CONFORMANT_CONFIG          0x800D
+#define GLX_DRAWABLE_TYPE                  0x8010
+#define GLX_RENDER_TYPE                    0x8011
+#define GLX_X_RENDERABLE                   0x8012
+#define GLX_FBCONFIG_ID                    0x8013
+#define GLX_RGBA_TYPE                      0x8014
+#define GLX_COLOR_INDEX_TYPE               0x8015
+#define GLX_MAX_PBUFFER_WIDTH              0x8016
+#define GLX_MAX_PBUFFER_HEIGHT             0x8017
+#define GLX_MAX_PBUFFER_PIXELS             0x8018
+#define GLX_PRESERVED_CONTENTS             0x801B
+#define GLX_LARGEST_PBUFFER                0x801C
+#define GLX_WIDTH                          0x801D
+#define GLX_HEIGHT                         0x801E
+#define GLX_EVENT_MASK                     0x801F
+#define GLX_DAMAGED                        0x8020
+#define GLX_SAVED                          0x8021
+#define GLX_WINDOW                         0x8022
+#define GLX_PBUFFER                        0x8023
+#define GLX_PBUFFER_HEIGHT                 0x8040
+#define GLX_PBUFFER_WIDTH                  0x8041
+#endif
+
+#ifndef GLX_VERSION_1_4
+#define GLX_SAMPLE_BUFFERS                 100000
+#define GLX_SAMPLES                        100001
+#endif
+
+#ifndef GLX_ARB_get_proc_address
+#endif
+
+#ifndef GLX_ARB_multisample
+#define GLX_SAMPLE_BUFFERS_ARB             100000
+#define GLX_SAMPLES_ARB                    100001
+#endif
+
+#ifndef GLX_ARB_vertex_buffer_object
+#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
+#endif
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_RGBA_FLOAT_TYPE_ARB            0x20B9
+#define GLX_RGBA_FLOAT_BIT_ARB             0x00000004
+#endif
+
+#ifndef GLX_ARB_framebuffer_sRGB
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB   0x20B2
+#endif
+
+#ifndef GLX_ARB_create_context
+#define GLX_CONTEXT_DEBUG_BIT_ARB          0x00000001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_MAJOR_VERSION_ARB      0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB      0x2092
+#define GLX_CONTEXT_FLAGS_ARB              0x2094
+#endif
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB   0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB       0x9126
+#endif
+
+#ifndef GLX_ARB_create_context_robustness
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB  0x00000004
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB      0x8252
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GLX_NO_RESET_NOTIFICATION_ARB      0x8261
+#endif
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SAMPLE_BUFFERS_SGIS            100000
+#define GLX_SAMPLES_SGIS                   100001
+#endif
+
+#ifndef GLX_EXT_visual_info
+#define GLX_X_VISUAL_TYPE_EXT              0x22
+#define GLX_TRANSPARENT_TYPE_EXT           0x23
+#define GLX_TRANSPARENT_INDEX_VALUE_EXT    0x24
+#define GLX_TRANSPARENT_RED_VALUE_EXT      0x25
+#define GLX_TRANSPARENT_GREEN_VALUE_EXT    0x26
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT     0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE_EXT    0x28
+#define GLX_NONE_EXT                       0x8000
+#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_TRANSPARENT_RGB_EXT            0x8008
+#define GLX_TRANSPARENT_INDEX_EXT          0x8009
+#endif
+
+#ifndef GLX_SGI_swap_control
+#endif
+
+#ifndef GLX_SGI_video_sync
+#endif
+
+#ifndef GLX_SGI_make_current_read
+#endif
+
+#ifndef GLX_SGIX_video_source
+#endif
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_VISUAL_CAVEAT_EXT              0x20
+#define GLX_SLOW_VISUAL_EXT                0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT      0x800D
+/* reuse GLX_NONE_EXT */
+#endif
+
+#ifndef GLX_EXT_import_context
+#define GLX_SHARE_CONTEXT_EXT              0x800A
+#define GLX_VISUAL_ID_EXT                  0x800B
+#define GLX_SCREEN_EXT                     0x800C
+#endif
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_WINDOW_BIT_SGIX                0x00000001
+#define GLX_PIXMAP_BIT_SGIX                0x00000002
+#define GLX_RGBA_BIT_SGIX                  0x00000001
+#define GLX_COLOR_INDEX_BIT_SGIX           0x00000002
+#define GLX_DRAWABLE_TYPE_SGIX             0x8010
+#define GLX_RENDER_TYPE_SGIX               0x8011
+#define GLX_X_RENDERABLE_SGIX              0x8012
+#define GLX_FBCONFIG_ID_SGIX               0x8013
+#define GLX_RGBA_TYPE_SGIX                 0x8014
+#define GLX_COLOR_INDEX_TYPE_SGIX          0x8015
+/* reuse GLX_SCREEN_EXT */
+#endif
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_PBUFFER_BIT_SGIX               0x00000004
+#define GLX_BUFFER_CLOBBER_MASK_SGIX       0x08000000
+#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX     0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX    0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT_SGIX      0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX     0x00000008
+#define GLX_AUX_BUFFERS_BIT_SGIX           0x00000010
+#define GLX_DEPTH_BUFFER_BIT_SGIX          0x00000020
+#define GLX_STENCIL_BUFFER_BIT_SGIX        0x00000040
+#define GLX_ACCUM_BUFFER_BIT_SGIX          0x00000080
+#define GLX_SAMPLE_BUFFERS_BIT_SGIX        0x00000100
+#define GLX_MAX_PBUFFER_WIDTH_SGIX         0x8016
+#define GLX_MAX_PBUFFER_HEIGHT_SGIX        0x8017
+#define GLX_MAX_PBUFFER_PIXELS_SGIX        0x8018
+#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX     0x8019
+#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX    0x801A
+#define GLX_PRESERVED_CONTENTS_SGIX        0x801B
+#define GLX_LARGEST_PBUFFER_SGIX           0x801C
+#define GLX_WIDTH_SGIX                     0x801D
+#define GLX_HEIGHT_SGIX                    0x801E
+#define GLX_EVENT_MASK_SGIX                0x801F
+#define GLX_DAMAGED_SGIX                   0x8020
+#define GLX_SAVED_SGIX                     0x8021
+#define GLX_WINDOW_SGIX                    0x8022
+#define GLX_PBUFFER_SGIX                   0x8023
+#endif
+
+#ifndef GLX_SGI_cushion
+#endif
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SYNC_FRAME_SGIX                0x00000000
+#define GLX_SYNC_SWAP_SGIX                 0x00000001
+#endif
+
+#ifndef GLX_SGIX_dmbuffer
+#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX     0x8024
+#endif
+
+#ifndef GLX_SGIX_swap_group
+#endif
+
+#ifndef GLX_SGIX_swap_barrier
+#endif
+
+#ifndef GLX_SGIS_blended_overlay
+#define GLX_BLENDED_RGBA_SGIS              0x8025
+#endif
+
+#ifndef GLX_SGIS_shared_multisample
+#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
+#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
+#endif
+
+#ifndef GLX_SUN_get_transparent_index
+#endif
+
+#ifndef GLX_3DFX_multisample
+#define GLX_SAMPLE_BUFFERS_3DFX            0x8050
+#define GLX_SAMPLES_3DFX                   0x8051
+#endif
+
+#ifndef GLX_MESA_copy_sub_buffer
+#endif
+
+#ifndef GLX_MESA_pixmap_colormap
+#endif
+
+#ifndef GLX_MESA_release_buffers
+#endif
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_3DFX_WINDOW_MODE_MESA          0x1
+#define GLX_3DFX_FULLSCREEN_MODE_MESA      0x2
+#endif
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_VISUAL_SELECT_GROUP_SGIX       0x8028
+#endif
+
+#ifndef GLX_OML_swap_method
+#define GLX_SWAP_METHOD_OML                0x8060
+#define GLX_SWAP_EXCHANGE_OML              0x8061
+#define GLX_SWAP_COPY_OML                  0x8062
+#define GLX_SWAP_UNDEFINED_OML             0x8063
+#endif
+
+#ifndef GLX_OML_sync_control
+#endif
+
+#ifndef GLX_NV_float_buffer
+#define GLX_FLOAT_COMPONENTS_NV            0x20B0
+#endif
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
+#define GLX_BAD_HYPERPIPE_CONFIG_SGIX      91
+#define GLX_BAD_HYPERPIPE_SGIX             92
+#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX    0x00000001
+#define GLX_HYPERPIPE_RENDER_PIPE_SGIX     0x00000002
+#define GLX_PIPE_RECT_SGIX                 0x00000001
+#define GLX_PIPE_RECT_LIMITS_SGIX          0x00000002
+#define GLX_HYPERPIPE_STEREO_SGIX          0x00000003
+#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX   0x00000004
+#define GLX_HYPERPIPE_ID_SGIX              0x8030
+#endif
+
+#ifndef GLX_MESA_agp_offset
+#endif
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT   0x20B1
+#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT    0x00000008
+#endif
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT   0x20B2
+#endif
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_TEXTURE_1D_BIT_EXT             0x00000001
+#define GLX_TEXTURE_2D_BIT_EXT             0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT      0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT        0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT       0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT     0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT    0x20D3
+#define GLX_Y_INVERTED_EXT                 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT             0x20D5
+#define GLX_TEXTURE_TARGET_EXT             0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT             0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT        0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT         0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT        0x20DA
+#define GLX_TEXTURE_1D_EXT                 0x20DB
+#define GLX_TEXTURE_2D_EXT                 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT          0x20DD
+#define GLX_FRONT_LEFT_EXT                 0x20DE
+#define GLX_FRONT_RIGHT_EXT                0x20DF
+#define GLX_BACK_LEFT_EXT                  0x20E0
+#define GLX_BACK_RIGHT_EXT                 0x20E1
+#define GLX_FRONT_EXT                      GLX_FRONT_LEFT_EXT
+#define GLX_BACK_EXT                       GLX_BACK_LEFT_EXT
+#define GLX_AUX0_EXT                       0x20E2
+#define GLX_AUX1_EXT                       0x20E3
+#define GLX_AUX2_EXT                       0x20E4
+#define GLX_AUX3_EXT                       0x20E5
+#define GLX_AUX4_EXT                       0x20E6
+#define GLX_AUX5_EXT                       0x20E7
+#define GLX_AUX6_EXT                       0x20E8
+#define GLX_AUX7_EXT                       0x20E9
+#define GLX_AUX8_EXT                       0x20EA
+#define GLX_AUX9_EXT                       0x20EB
+#endif
+
+#ifndef GLX_NV_present_video
+#define GLX_NUM_VIDEO_SLOTS_NV             0x20F0
+#endif
+
+#ifndef GLX_NV_video_out
+#define GLX_VIDEO_OUT_COLOR_NV             0x20C3
+#define GLX_VIDEO_OUT_ALPHA_NV             0x20C4
+#define GLX_VIDEO_OUT_DEPTH_NV             0x20C5
+#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV   0x20C6
+#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV   0x20C7
+#define GLX_VIDEO_OUT_FRAME_NV             0x20C8
+#define GLX_VIDEO_OUT_FIELD_1_NV           0x20C9
+#define GLX_VIDEO_OUT_FIELD_2_NV           0x20CA
+#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
+#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
+#endif
+
+#ifndef GLX_NV_swap_group
+#endif
+
+#ifndef GLX_NV_video_capture
+#define GLX_DEVICE_ID_NV                   0x20CD
+#define GLX_UNIQUE_ID_NV                   0x20CE
+#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV     0x20CF
+#endif
+
+#ifndef GLX_EXT_swap_control
+#define GLX_SWAP_INTERVAL_EXT              0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT          0x20F2
+#endif
+
+#ifndef GLX_NV_copy_image
+#endif
+
+#ifndef GLX_INTEL_swap_event
+#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
+#define GLX_EXCHANGE_COMPLETE_INTEL        0x8180
+#define GLX_COPY_COMPLETE_INTEL            0x8181
+#define GLX_FLIP_COMPLETE_INTEL            0x8182
+#endif
+
+#ifndef GLX_NV_multisample_coverage
+#define GLX_COVERAGE_SAMPLES_NV            100001
+#define GLX_COLOR_SAMPLES_NV               0x20B3
+#endif
+
+#ifndef GLX_AMD_gpu_association
+#define GLX_GPU_VENDOR_AMD                 0x1F00
+#define GLX_GPU_RENDERER_STRING_AMD        0x1F01
+#define GLX_GPU_OPENGL_VERSION_STRING_AMD  0x1F02
+#define GLX_GPU_FASTEST_TARGET_GPUS_AMD    0x21A2
+#define GLX_GPU_RAM_AMD                    0x21A3
+#define GLX_GPU_CLOCK_AMD                  0x21A4
+#define GLX_GPU_NUM_PIPES_AMD              0x21A5
+#define GLX_GPU_NUM_SIMD_AMD               0x21A6
+#define GLX_GPU_NUM_RB_AMD                 0x21A7
+#define GLX_GPU_NUM_SPI_AMD                0x21A8
+#endif
+
+#ifndef GLX_EXT_create_context_es2_profile
+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT    0x00000004
+#endif
+
+
+/*************************************************************/
+
+#ifndef GLX_ARB_get_proc_address
+typedef void (*__GLXextFuncPtr)(void);
+#endif
+
+#ifndef GLX_SGIX_video_source
+typedef XID GLXVideoSourceSGIX;
+#endif
+
+#ifndef GLX_SGIX_fbconfig
+typedef XID GLXFBConfigIDSGIX;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+#endif
+
+#ifndef GLX_SGIX_pbuffer
+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*/
+    int x, y;
+    int width, height;
+    int count;		  /* if nonzero, at least this many more */
+} GLXBufferClobberEventSGIX;
+#endif
+
+#ifndef GLX_NV_video_output
+typedef unsigned int GLXVideoDeviceNV;
+#endif
+
+#ifndef GLX_NV_video_capture
+typedef XID GLXVideoCaptureDeviceNV;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GLX_OML_sync_control extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include 
+#elif defined(__sun__) || defined(__digital__)
+#include 
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include 
+#elif defined(__SCO__) || defined(__USLC__)
+#include 
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include 
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include      /* Fallback option */
+#endif
+#endif
+
+#ifndef GLX_VERSION_1_3
+#define GLX_VERSION_1_3 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXFBConfig * glXGetFBConfigs (Display *dpy, int screen, int *nelements);
+extern GLXFBConfig * glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements);
+extern int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value);
+extern XVisualInfo * glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config);
+extern GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+extern void glXDestroyWindow (Display *dpy, GLXWindow win);
+extern GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+extern void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap);
+extern GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list);
+extern void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf);
+extern void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+extern GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+extern Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+extern GLXDrawable glXGetCurrentReadDrawable (void);
+extern Display * glXGetCurrentDisplay (void);
+extern int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value);
+extern void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+extern void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXFBConfig * ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
+typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
+typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
+typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
+typedef Display * ( * PFNGLXGETCURRENTDISPLAYPROC) (void);
+typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+#endif
+
+#ifndef GLX_VERSION_1_4
+#define GLX_VERSION_1_4 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern __GLXextFuncPtr glXGetProcAddress (const GLubyte *procName);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName);
+#endif
+
+#ifndef GLX_ARB_get_proc_address
+#define GLX_ARB_get_proc_address 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *procName);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName);
+#endif
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample 1
+#endif
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_ARB_fbconfig_float 1
+#endif
+
+#ifndef GLX_ARB_framebuffer_sRGB
+#define GLX_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef GLX_ARB_create_context
+#define GLX_ARB_create_context 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXContext glXCreateContextAttribsARB (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+#endif
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile 1
+#endif
+
+#ifndef GLX_ARB_create_context_robustness
+#define GLX_ARB_create_context_robustness 1
+#endif
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SGIS_multisample 1
+#endif
+
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info 1
+#endif
+
+#ifndef GLX_SGI_swap_control
+#define GLX_SGI_swap_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXSwapIntervalSGI (int interval);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
+#endif
+
+#ifndef GLX_SGI_video_sync
+#define GLX_SGI_video_sync 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXGetVideoSyncSGI (unsigned int *count);
+extern int glXWaitVideoSyncSGI (int divisor, int remainder, unsigned int *count);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count);
+typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count);
+#endif
+
+#ifndef GLX_SGI_make_current_read
+#define GLX_SGI_make_current_read 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXMakeCurrentReadSGI (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+extern GLXDrawable glXGetCurrentReadDrawableSGI (void);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
+#endif
+
+#ifndef GLX_SGIX_video_source
+#define GLX_SGIX_video_source 1
+#ifdef _VL_H
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
+extern void glXDestroyGLXVideoSourceSGIX (Display *dpy, GLXVideoSourceSGIX glxvideosource);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXVideoSourceSGIX ( * PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
+typedef void ( * PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource);
+#endif /* _VL_H */
+#endif
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating 1
+#endif
+
+#ifndef GLX_EXT_import_context
+#define GLX_EXT_import_context 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Display * glXGetCurrentDisplayEXT (void);
+extern int glXQueryContextInfoEXT (Display *dpy, GLXContext context, int attribute, int *value);
+extern GLXContextID glXGetContextIDEXT (const GLXContext context);
+extern GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID);
+extern void glXFreeContextEXT (Display *dpy, GLXContext context);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Display * ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void);
+typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value);
+typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
+typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID);
+typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context);
+#endif
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_SGIX_fbconfig 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXGetFBConfigAttribSGIX (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
+extern GLXFBConfigSGIX * glXChooseFBConfigSGIX (Display *dpy, int screen, int *attrib_list, int *nelements);
+extern GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
+extern GLXContext glXCreateContextWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+extern XVisualInfo * glXGetVisualFromFBConfigSGIX (Display *dpy, GLXFBConfigSGIX config);
+extern GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *dpy, XVisualInfo *vis);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
+typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements);
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
+typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config);
+typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis);
+#endif
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_SGIX_pbuffer 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+extern void glXDestroyGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf);
+extern int glXQueryGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
+extern void glXSelectEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long mask);
+extern void glXGetSelectedEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long *mask);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf);
+typedef int ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
+typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask);
+typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask);
+#endif
+
+#ifndef GLX_SGI_cushion
+#define GLX_SGI_cushion 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXCushionSGI (Display *dpy, Window window, float cushion);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion);
+#endif
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SGIX_video_resize 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXBindChannelToWindowSGIX (Display *display, int screen, int channel, Window window);
+extern int glXChannelRectSGIX (Display *display, int screen, int channel, int x, int y, int w, int h);
+extern int glXQueryChannelRectSGIX (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+extern int glXQueryChannelDeltasSGIX (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
+extern int glXChannelRectSyncSGIX (Display *display, int screen, int channel, GLenum synctype);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window);
+typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h);
+typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
+typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype);
+#endif
+
+#ifndef GLX_SGIX_dmbuffer
+#define GLX_SGIX_dmbuffer 1
+#ifdef _DM_BUFFER_H_
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXAssociateDMPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
+#endif /* _DM_BUFFER_H_ */
+#endif
+
+#ifndef GLX_SGIX_swap_group
+#define GLX_SGIX_swap_group 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXJoinSwapGroupSGIX (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+#endif
+
+#ifndef GLX_SGIX_swap_barrier
+#define GLX_SGIX_swap_barrier 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXBindSwapBarrierSGIX (Display *dpy, GLXDrawable drawable, int barrier);
+extern Bool glXQueryMaxSwapBarriersSGIX (Display *dpy, int screen, int *max);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
+typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
+#endif
+
+#ifndef GLX_SUN_get_transparent_index
+#define GLX_SUN_get_transparent_index 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Status glXGetTransparentIndexSUN (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
+#endif
+
+#ifndef GLX_MESA_copy_sub_buffer
+#define GLX_MESA_copy_sub_buffer 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXCopySubBufferMESA (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
+#endif
+
+#ifndef GLX_MESA_pixmap_colormap
+#define GLX_MESA_pixmap_colormap 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#endif
+
+#ifndef GLX_MESA_release_buffers
+#define GLX_MESA_release_buffers 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXReleaseBuffersMESA (Display *dpy, GLXDrawable drawable);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable);
+#endif
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_MESA_set_3dfx_mode 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXSet3DfxModeMESA (int mode);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXSET3DFXMODEMESAPROC) (int mode);
+#endif
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_SGIX_visual_select_group 1
+#endif
+
+#ifndef GLX_OML_swap_method
+#define GLX_OML_swap_method 1
+#endif
+
+#ifndef GLX_OML_sync_control
+#define GLX_OML_sync_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXGetSyncValuesOML (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
+extern Bool glXGetMscRateOML (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
+extern int64_t glXSwapBuffersMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+extern Bool glXWaitForMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+extern Bool glXWaitForSbcOML (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
+typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
+typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
+#endif
+
+#ifndef GLX_NV_float_buffer
+#define GLX_NV_float_buffer 1
+#endif
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_SGIX_hyperpipe 1
+
+typedef struct {
+    char    pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+    int     networkId;
+} GLXHyperpipeNetworkSGIX;
+
+typedef struct {
+    char    pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+    int     channel;
+    unsigned int
+      participationType;
+    int     timeSlice;
+} GLXHyperpipeConfigSGIX;
+
+typedef struct {
+    char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+    int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
+    int destXOrigin, destYOrigin, destWidth, destHeight;
+} GLXPipeRect;
+
+typedef struct {
+    char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+    int XOrigin, YOrigin, maxHeight, maxWidth;
+} GLXPipeRectLimits;
+
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXHyperpipeNetworkSGIX * glXQueryHyperpipeNetworkSGIX (Display *dpy, int *npipes);
+extern int glXHyperpipeConfigSGIX (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+extern GLXHyperpipeConfigSGIX * glXQueryHyperpipeConfigSGIX (Display *dpy, int hpId, int *npipes);
+extern int glXDestroyHyperpipeConfigSGIX (Display *dpy, int hpId);
+extern int glXBindHyperpipeSGIX (Display *dpy, int hpId);
+extern int glXQueryHyperpipeBestAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+extern int glXHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+extern int glXQueryHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
+typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
+typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+#endif
+
+#ifndef GLX_MESA_agp_offset
+#define GLX_MESA_agp_offset 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern unsigned int glXGetAGPOffsetMESA (const void *pointer);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer);
+#endif
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_EXT_fbconfig_packed_float 1
+#endif
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_EXT_texture_from_pixmap 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXBindTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
+extern void glXReleaseTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
+typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer);
+#endif
+
+#ifndef GLX_NV_present_video
+#define GLX_NV_present_video 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern unsigned int * glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements);
+extern int glXBindVideoDeviceNV (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef unsigned int * ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
+typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
+#endif
+
+#ifndef GLX_NV_video_output
+#define GLX_NV_video_output 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXGetVideoDeviceNV (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
+extern int glXReleaseVideoDeviceNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
+extern int glXBindVideoImageNV (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+extern int glXReleaseVideoImageNV (Display *dpy, GLXPbuffer pbuf);
+extern int glXSendPbufferToVideoNV (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
+extern int glXGetVideoInfoNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
+typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
+typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
+typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+
+#ifndef GLX_NV_swap_group
+#define GLX_NV_swap_group 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXJoinSwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint group);
+extern Bool glXBindSwapBarrierNV (Display *dpy, GLuint group, GLuint barrier);
+extern Bool glXQuerySwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
+extern Bool glXQueryMaxSwapGroupsNV (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
+extern Bool glXQueryFrameCountNV (Display *dpy, int screen, GLuint *count);
+extern Bool glXResetFrameCountNV (Display *dpy, int screen);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group);
+typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier);
+typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
+typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
+typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count);
+typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen);
+#endif
+
+#ifndef GLX_NV_video_capture
+#define GLX_NV_video_capture 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXBindVideoCaptureDeviceNV (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+extern GLXVideoCaptureDeviceNV * glXEnumerateVideoCaptureDevicesNV (Display *dpy, int screen, int *nelements);
+extern void glXLockVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
+extern int glXQueryVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
+extern void glXReleaseVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+typedef GLXVideoCaptureDeviceNV * ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements);
+typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
+typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
+typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
+#endif
+
+#ifndef GLX_EXT_swap_control
+#define GLX_EXT_swap_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXSwapIntervalEXT (Display *dpy, GLXDrawable drawable, int interval);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval);
+#endif
+
+#ifndef GLX_NV_copy_image
+#define GLX_NV_copy_image 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXCopyImageSubDataNV (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GLX_INTEL_swap_event
+#define GLX_INTEL_swap_event 1
+#endif
+
+#ifndef GLX_NV_multisample_coverage
+#define GLX_NV_multisample_coverage 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/irrXML.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/irrXML.cpp
new file mode 100644
index 0000000..9197348
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/irrXML.cpp
@@ -0,0 +1,180 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine" and the "irrXML" project.
+// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
+
+#include "irrXML.h"
+#include "irrString.h"
+#include "irrArray.h"
+#include "fast_atof.h"
+#include "CXMLReaderImpl.h"
+
+namespace irr
+{
+namespace io
+{
+
+//! Implementation of the file read callback for ordinary files
+class CFileReadCallBack : public IFileReadCallBack
+{
+public:
+
+	//! construct from filename
+	CFileReadCallBack(const char* filename)
+		: File(0), Size(-1), Close(true)
+	{
+		// open file
+		File = fopen(filename, "rb");
+
+		if (File)
+			getFileSize();
+	}
+
+	//! construct from FILE pointer
+	CFileReadCallBack(FILE* file)
+		: File(file), Size(-1), Close(false)
+	{
+		if (File)
+			getFileSize();
+	}
+
+	//! destructor
+	virtual ~CFileReadCallBack()
+	{
+		if (Close && File)
+			fclose(File);
+	}
+
+	//! Reads an amount of bytes from the file.
+	virtual int read(void* buffer, int sizeToRead)
+	{
+		if (!File)
+			return 0;
+
+		return (int)fread(buffer, 1, sizeToRead, File);
+	}
+
+	//! Returns size of file in bytes
+	virtual long getSize() const
+	{
+		return Size;
+	}
+
+private:
+
+	//! retrieves the file size of the open file
+	void getFileSize()
+	{
+		fseek(File, 0, SEEK_END);
+		Size = ftell(File);
+		fseek(File, 0, SEEK_SET);
+	}
+
+	FILE* File;
+	long Size;
+	bool Close;
+
+}; // end class CFileReadCallBack
+
+
+
+// FACTORY FUNCTIONS:
+
+
+//! Creates an instance of an UFT-8 or ASCII character xml parser. 
+IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(const char* filename)
+{
+	return createIrrXMLReader(new CFileReadCallBack(filename), true); 
+}
+
+
+//! Creates an instance of an UFT-8 or ASCII character xml parser. 
+IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(FILE* file)
+{
+	return createIrrXMLReader(new CFileReadCallBack(file), true); 
+}
+
+
+//! Creates an instance of an UFT-8 or ASCII character xml parser. 
+IRRLICHT_API IrrXMLReader* IRRCALLCONV createIrrXMLReader(IFileReadCallBack* callback,
+														  bool deleteCallback)
+{
+	if (callback && (callback->getSize() >= 0))
+	{
+		return new CXMLReaderImpl(callback, deleteCallback); 
+	}
+	else
+	{
+		if(callback && deleteCallback)
+			delete callback;
+
+		return 0;
+	}
+}
+
+
+//! Creates an instance of an UTF-16 xml parser. 
+IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(const char* filename)
+{
+	return createIrrXMLReaderUTF16(new CFileReadCallBack(filename), true); 
+}
+
+
+//! Creates an instance of an UTF-16 xml parser. 
+IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(FILE* file)
+{
+	return createIrrXMLReaderUTF16(new CFileReadCallBack(file), true); 
+}
+
+
+//! Creates an instance of an UTF-16 xml parser. 
+IRRLICHT_API IrrXMLReaderUTF16* IRRCALLCONV createIrrXMLReaderUTF16(IFileReadCallBack* callback,
+																	bool deleteCallback)
+{
+	if (callback && (callback->getSize() >= 0))
+	{
+		return new CXMLReaderImpl(callback, deleteCallback); 
+	}
+	else
+	{
+		if(callback && deleteCallback)
+			delete callback;
+
+		return 0;
+	}
+}
+
+
+//! Creates an instance of an UTF-32 xml parser. 
+IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(const char* filename)
+{
+	return createIrrXMLReaderUTF32(new CFileReadCallBack(filename), true); 
+}
+
+
+//! Creates an instance of an UTF-32 xml parser. 
+IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(FILE* file)
+{
+	return createIrrXMLReaderUTF32(new CFileReadCallBack(file), true); 
+}
+
+
+//! Creates an instance of an UTF-32 xml parser. 
+IRRLICHT_API IrrXMLReaderUTF32* IRRCALLCONV createIrrXMLReaderUTF32(
+		IFileReadCallBack* callback, bool deleteCallback)
+{
+	if (callback && (callback->getSize() >= 0))
+	{
+		return new CXMLReaderImpl(callback, deleteCallback); 
+	}
+	else
+	{
+		if(callback && deleteCallback)
+			delete callback;
+
+		return 0;
+	}
+}
+
+
+} // end namespace io
+} // end namespace irr
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.c b/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.c
new file mode 100644
index 0000000..4fdc11d
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.c
@@ -0,0 +1,999 @@
+/* LzmaDec.c -- LZMA Decoder
+2009-09-20 : Igor Pavlov : Public domain */
+
+#include "LzmaDec.h"
+
+#include 
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+  { UPDATE_0(p); i = (i + i); A0; } else \
+  { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+  { i = 1; \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+  { UPDATE_0_CHECK; i = (i + i); A0; } else \
+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+  Result:
+    SZ_OK - OK
+    SZ_ERROR_DATA - Error
+  p->remainLen:
+    < kMatchSpecLenStart : normal remain
+    = kMatchSpecLenStart : finished
+    = kMatchSpecLenStart + 1 : Flush marker
+    = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  CLzmaProb *probs = p->probs;
+
+  unsigned state = p->state;
+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+  unsigned lc = p->prop.lc;
+
+  Byte *dic = p->dic;
+  SizeT dicBufSize = p->dicBufSize;
+  SizeT dicPos = p->dicPos;
+  
+  UInt32 processedPos = p->processedPos;
+  UInt32 checkDicSize = p->checkDicSize;
+  unsigned len = 0;
+
+  const Byte *buf = p->buf;
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+
+  do
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = processedPos & pbMask;
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0(prob)
+    {
+      unsigned symbol;
+      UPDATE_0(prob);
+      prob = probs + Literal;
+      if (checkDicSize != 0 || processedPos != 0)
+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+      if (state < kNumLitStates)
+      {
+        state -= (state < 4) ? state : 3;
+        symbol = 1;
+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+        unsigned offs = 0x100;
+        state -= (state < 10) ? 3 : 6;
+        symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      dic[dicPos++] = (Byte)symbol;
+      processedPos++;
+      continue;
+    }
+    else
+    {
+      UPDATE_1(prob);
+      prob = probs + IsRep + state;
+      IF_BIT_0(prob)
+      {
+        UPDATE_0(prob);
+        state += kNumStates;
+        prob = probs + LenCoder;
+      }
+      else
+      {
+        UPDATE_1(prob);
+        if (checkDicSize == 0 && processedPos == 0)
+          return SZ_ERROR_DATA;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0(prob)
+        {
+          UPDATE_0(prob);
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+            dicPos++;
+            processedPos++;
+            state = state < kNumLitStates ? 9 : 11;
+            continue;
+          }
+          UPDATE_1(prob);
+        }
+        else
+        {
+          UInt32 distance;
+          UPDATE_1(prob);
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            distance = rep1;
+          }
+          else
+          {
+            UPDATE_1(prob);
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0(prob)
+            {
+              UPDATE_0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UPDATE_1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0(probLen)
+        {
+          UPDATE_0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = (1 << kLenNumLowBits);
+        }
+        else
+        {
+          UPDATE_1(probLen);
+          probLen = prob + LenChoice2;
+          IF_BIT_0(probLen)
+          {
+            UPDATE_0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = (1 << kLenNumMidBits);
+          }
+          else
+          {
+            UPDATE_1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = (1 << kLenNumHighBits);
+          }
+        }
+        TREE_DECODE(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state >= kNumStates)
+      {
+        UInt32 distance;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+        TREE_6_DECODE(prob, distance);
+        if (distance >= kStartPosModelIndex)
+        {
+          unsigned posSlot = (unsigned)distance;
+          int numDirectBits = (int)(((distance >> 1) - 1));
+          distance = (2 | (distance & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            distance <<= numDirectBits;
+            prob = probs + SpecPos + distance - posSlot - 1;
+            {
+              UInt32 mask = 1;
+              unsigned i = 1;
+              do
+              {
+                GET_BIT2(prob + i, i, ; , distance |= mask);
+                mask <<= 1;
+              }
+              while (--numDirectBits != 0);
+            }
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE
+              range >>= 1;
+              
+              {
+                UInt32 t;
+                code -= range;
+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+                distance = (distance << 1) + (t + 1);
+                code += range & t;
+              }
+              /*
+              distance <<= 1;
+              if (code >= range)
+              {
+                code -= range;
+                distance |= 1;
+              }
+              */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            distance <<= kNumAlignBits;
+            {
+              unsigned i = 1;
+              GET_BIT2(prob + i, i, ; , distance |= 1);
+              GET_BIT2(prob + i, i, ; , distance |= 2);
+              GET_BIT2(prob + i, i, ; , distance |= 4);
+              GET_BIT2(prob + i, i, ; , distance |= 8);
+            }
+            if (distance == (UInt32)0xFFFFFFFF)
+            {
+              len += kMatchSpecLenStart;
+              state -= kNumStates;
+              break;
+            }
+          }
+        }
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        rep0 = distance + 1;
+        if (checkDicSize == 0)
+        {
+          if (distance >= processedPos)
+            return SZ_ERROR_DATA;
+        }
+        else if (distance >= checkDicSize)
+          return SZ_ERROR_DATA;
+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+      }
+
+      len += kMatchMinLen;
+
+      if (limit == dicPos)
+        return SZ_ERROR_DATA;
+      {
+        SizeT rem = limit - dicPos;
+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+        processedPos += curLen;
+
+        len -= curLen;
+        if (pos + curLen <= dicBufSize)
+        {
+          Byte *dest = dic + dicPos;
+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+          const Byte *lim = dest + curLen;
+          dicPos += curLen;
+          do
+            *(dest) = (Byte)*(dest + src);
+          while (++dest != lim);
+        }
+        else
+        {
+          do
+          {
+            dic[dicPos++] = dic[pos];
+            if (++pos == dicBufSize)
+              pos = 0;
+          }
+          while (--curLen != 0);
+        }
+      }
+    }
+  }
+  while (dicPos < limit && buf < bufLimit);
+  NORMALIZE;
+  p->buf = buf;
+  p->range = range;
+  p->code = code;
+  p->remainLen = len;
+  p->dicPos = dicPos;
+  p->processedPos = processedPos;
+  p->reps[0] = rep0;
+  p->reps[1] = rep1;
+  p->reps[2] = rep2;
+  p->reps[3] = rep3;
+  p->state = state;
+
+  return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+  {
+    Byte *dic = p->dic;
+    SizeT dicPos = p->dicPos;
+    SizeT dicBufSize = p->dicBufSize;
+    unsigned len = p->remainLen;
+    UInt32 rep0 = p->reps[0];
+    if (limit - dicPos < len)
+      len = (unsigned)(limit - dicPos);
+
+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+      p->checkDicSize = p->prop.dicSize;
+
+    p->processedPos += len;
+    p->remainLen -= len;
+    while (len-- != 0)
+    {
+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+      dicPos++;
+    }
+    p->dicPos = dicPos;
+  }
+}
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  do
+  {
+    SizeT limit2 = limit;
+    if (p->checkDicSize == 0)
+    {
+      UInt32 rem = p->prop.dicSize - p->processedPos;
+      if (limit - p->dicPos > rem)
+        limit2 = p->dicPos + rem;
+    }
+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+    if (p->processedPos >= p->prop.dicSize)
+      p->checkDicSize = p->prop.dicSize;
+    LzmaDec_WriteRem(p, limit);
+  }
+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+  if (p->remainLen > kMatchSpecLenStart)
+  {
+    p->remainLen = kMatchSpecLenStart;
+  }
+  return 0;
+}
+
+typedef enum
+{
+  DUMMY_ERROR, /* unexpected end of input stream */
+  DUMMY_LIT,
+  DUMMY_MATCH,
+  DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+  const Byte *bufLimit = buf + inSize;
+  CLzmaProb *probs = p->probs;
+  unsigned state = p->state;
+  ELzmaDummy res;
+
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0_CHECK(prob)
+    {
+      UPDATE_0_CHECK
+
+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+      prob = probs + Literal;
+      if (p->checkDicSize != 0 || p->processedPos != 0)
+        prob += (LZMA_LIT_SIZE *
+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+      if (state < kNumLitStates)
+      {
+        unsigned symbol = 1;
+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+        unsigned offs = 0x100;
+        unsigned symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      res = DUMMY_LIT;
+    }
+    else
+    {
+      unsigned len;
+      UPDATE_1_CHECK;
+
+      prob = probs + IsRep + state;
+      IF_BIT_0_CHECK(prob)
+      {
+        UPDATE_0_CHECK;
+        state = 0;
+        prob = probs + LenCoder;
+        res = DUMMY_MATCH;
+      }
+      else
+      {
+        UPDATE_1_CHECK;
+        res = DUMMY_REP;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0_CHECK(prob)
+        {
+          UPDATE_0_CHECK;
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+            NORMALIZE_CHECK;
+            return DUMMY_REP;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+          }
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0_CHECK(prob)
+            {
+              UPDATE_0_CHECK;
+            }
+            else
+            {
+              UPDATE_1_CHECK;
+            }
+          }
+        }
+        state = kNumStates;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0_CHECK(probLen)
+        {
+          UPDATE_0_CHECK;
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = 1 << kLenNumLowBits;
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          probLen = prob + LenChoice2;
+          IF_BIT_0_CHECK(probLen)
+          {
+            UPDATE_0_CHECK;
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = 1 << kLenNumMidBits;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = 1 << kLenNumHighBits;
+          }
+        }
+        TREE_DECODE_CHECK(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        unsigned posSlot;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+            kNumPosSlotBits);
+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+
+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+          if (posSlot < kEndPosModelIndex)
+          {
+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE_CHECK
+              range >>= 1;
+              code -= range & (((code - range) >> 31) - 1);
+              /* if (code >= range) code -= range; */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            unsigned i = 1;
+            do
+            {
+              GET_BIT_CHECK(prob + i, i);
+            }
+            while (--numDirectBits != 0);
+          }
+        }
+      }
+    }
+  }
+  NORMALIZE_CHECK;
+  return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+  p->range = 0xFFFFFFFF;
+  p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+  p->needFlush = 1;
+  p->remainLen = 0;
+  p->tempBufSize = 0;
+
+  if (initDic)
+  {
+    p->processedPos = 0;
+    p->checkDicSize = 0;
+    p->needInitState = 1;
+  }
+  if (initState)
+    p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+  p->dicPos = 0;
+  LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+  UInt32 i;
+  CLzmaProb *probs = p->probs;
+  for (i = 0; i < numProbs; i++)
+    probs[i] = kBitModelTotal >> 1;
+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+  p->state = 0;
+  p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+    ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT inSize = *srcLen;
+  (*srcLen) = 0;
+  LzmaDec_WriteRem(p, dicLimit);
+  
+  *status = LZMA_STATUS_NOT_SPECIFIED;
+
+  while (p->remainLen != kMatchSpecLenStart)
+  {
+      int checkEndMarkNow;
+
+      if (p->needFlush != 0)
+      {
+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+          p->tempBuf[p->tempBufSize++] = *src++;
+        if (p->tempBufSize < RC_INIT_SIZE)
+        {
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+          return SZ_OK;
+        }
+        if (p->tempBuf[0] != 0)
+          return SZ_ERROR_DATA;
+
+        LzmaDec_InitRc(p, p->tempBuf);
+        p->tempBufSize = 0;
+      }
+
+      checkEndMarkNow = 0;
+      if (p->dicPos >= dicLimit)
+      {
+        if (p->remainLen == 0 && p->code == 0)
+        {
+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+          return SZ_OK;
+        }
+        if (finishMode == LZMA_FINISH_ANY)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_OK;
+        }
+        if (p->remainLen != 0)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_ERROR_DATA;
+        }
+        checkEndMarkNow = 1;
+      }
+
+      if (p->needInitState)
+        LzmaDec_InitStateReal(p);
+  
+      if (p->tempBufSize == 0)
+      {
+        SizeT processed;
+        const Byte *bufLimit;
+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            memcpy(p->tempBuf, src, inSize);
+            p->tempBufSize = (unsigned)inSize;
+            (*srcLen) += inSize;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+          bufLimit = src;
+        }
+        else
+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+        p->buf = src;
+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+          return SZ_ERROR_DATA;
+        processed = (SizeT)(p->buf - src);
+        (*srcLen) += processed;
+        src += processed;
+        inSize -= processed;
+      }
+      else
+      {
+        unsigned rem = p->tempBufSize, lookAhead = 0;
+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+          p->tempBuf[rem++] = src[lookAhead++];
+        p->tempBufSize = rem;
+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            (*srcLen) += lookAhead;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+        }
+        p->buf = p->tempBuf;
+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+          return SZ_ERROR_DATA;
+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+        (*srcLen) += lookAhead;
+        src += lookAhead;
+        inSize -= lookAhead;
+        p->tempBufSize = 0;
+      }
+  }
+  if (p->code == 0)
+    *status = LZMA_STATUS_FINISHED_WITH_MARK;
+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT outSize = *destLen;
+  SizeT inSize = *srcLen;
+  *srcLen = *destLen = 0;
+  for (;;)
+  {
+    SizeT inSizeCur = inSize, outSizeCur, dicPos;
+    ELzmaFinishMode curFinishMode;
+    SRes res;
+    if (p->dicPos == p->dicBufSize)
+      p->dicPos = 0;
+    dicPos = p->dicPos;
+    if (outSize > p->dicBufSize - dicPos)
+    {
+      outSizeCur = p->dicBufSize;
+      curFinishMode = LZMA_FINISH_ANY;
+    }
+    else
+    {
+      outSizeCur = dicPos + outSize;
+      curFinishMode = finishMode;
+    }
+
+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+    src += inSizeCur;
+    inSize -= inSizeCur;
+    *srcLen += inSizeCur;
+    outSizeCur = p->dicPos - dicPos;
+    memcpy(dest, p->dic + dicPos, outSizeCur);
+    dest += outSizeCur;
+    outSize -= outSizeCur;
+    *destLen += outSizeCur;
+    if (res != 0)
+      return res;
+    if (outSizeCur == 0 || outSize == 0)
+      return SZ_OK;
+  }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->probs);
+  p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->dic);
+  p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+  LzmaDec_FreeProbs(p, alloc);
+  LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+  UInt32 dicSize;
+  Byte d;
+  
+  if (size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_UNSUPPORTED;
+  else
+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+ 
+  if (dicSize < LZMA_DIC_MIN)
+    dicSize = LZMA_DIC_MIN;
+  p->dicSize = dicSize;
+
+  d = data[0];
+  if (d >= (9 * 5 * 5))
+    return SZ_ERROR_UNSUPPORTED;
+
+  p->lc = d % 9;
+  d /= 9;
+  p->pb = d / 5;
+  p->lp = d % 5;
+
+  return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+  if (p->probs == 0 || numProbs != p->numProbs)
+  {
+    LzmaDec_FreeProbs(p, alloc);
+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->numProbs = numProbs;
+    if (p->probs == 0)
+      return SZ_ERROR_MEM;
+  }
+  return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  SizeT dicBufSize;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  dicBufSize = propNew.dicSize;
+  if (p->dic == 0 || dicBufSize != p->dicBufSize)
+  {
+    LzmaDec_FreeDict(p, alloc);
+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+    if (p->dic == 0)
+    {
+      LzmaDec_FreeProbs(p, alloc);
+      return SZ_ERROR_MEM;
+    }
+  }
+  p->dicBufSize = dicBufSize;
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc)
+{
+  CLzmaDec p;
+  SRes res;
+  SizeT inSize = *srcLen;
+  SizeT outSize = *destLen;
+  *srcLen = *destLen = 0;
+  if (inSize < RC_INIT_SIZE)
+    return SZ_ERROR_INPUT_EOF;
+
+  LzmaDec_Construct(&p);
+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+  if (res != 0)
+    return res;
+  p.dic = dest;
+  p.dicBufSize = outSize;
+
+  LzmaDec_Init(&p);
+  
+  *srcLen = inSize;
+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+    res = SZ_ERROR_INPUT_EOF;
+
+  (*destLen) = p.dicPos;
+  LzmaDec_FreeProbs(&p, alloc);
+  return res;
+}
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.h b/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.h
new file mode 100644
index 0000000..6741a64
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/LzmaDec.h
@@ -0,0 +1,231 @@
+/* LzmaDec.h -- LZMA Decoder
+2009-02-07 : Igor Pavlov : Public domain */
+
+#ifndef __LZMA_DEC_H
+#define __LZMA_DEC_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+   but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+  unsigned lc, lp, pb;
+  UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+  SZ_OK
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+  CLzmaProps prop;
+  CLzmaProb *probs;
+  Byte *dic;
+  const Byte *buf;
+  UInt32 range, code;
+  SizeT dicPos;
+  SizeT dicBufSize;
+  UInt32 processedPos;
+  UInt32 checkDicSize;
+  unsigned state;
+  UInt32 reps[4];
+  unsigned remainLen;
+  int needFlush;
+  int needInitState;
+  UInt32 numProbs;
+  unsigned tempBufSize;
+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+  LZMA_FINISH_ANY,   /* finish at any point */
+  LZMA_FINISH_END    /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+   You must use LZMA_FINISH_END, when you know that current output buffer
+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+   and output value of destLen will be less than output buffer size limit.
+   You can check status result also.
+
+   You can use multiple checks to test data integrity after full decompression:
+     1) Check Result and "status" variable.
+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+        You must use correct finish mode in that case. */
+
+typedef enum
+{
+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+     1) Dictionary Interface
+     2) Buffer Interface
+     3) One Call Interface
+   You can select any of these interfaces, but don't mix functions from different
+   groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+     1) LzmaDec_Allocate / LzmaDec_Free
+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+   You can use variant 2, if you set dictionary buffer manually.
+   For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+  SZ_OK
+  SZ_ERROR_MEM         - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+   
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+   dictionary to some other external buffer.
+   You must work with CLzmaDec variables directly in this interface.
+
+   STEPS:
+     LzmaDec_Constr()
+     LzmaDec_Allocate()
+     for (each new stream)
+     {
+       LzmaDec_Init()
+       while (it needs more decompression)
+       {
+         LzmaDec_DecodeToDic()
+         use data from CLzmaDec::dic and update CLzmaDec::dicPos
+       }
+     }
+     LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+   
+   The decoding to internal dictionary buffer (CLzmaDec::dic).
+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (dicLimit).
+  LZMA_FINISH_ANY - Decode just dicLimit bytes.
+  LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_NEEDS_MORE_INPUT
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+   See LzmaDec_DecodeToDic description for information about STEPS and return results,
+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+   to work with CLzmaDec variables manually.
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+  SZ_ERROR_MEM  - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/Types.h b/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/Types.h
new file mode 100644
index 0000000..f193ce2
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/lzma/Types.h
@@ -0,0 +1,254 @@
+/* Types.h -- Basic types
+2010-10-09 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include 
+
+#ifdef _WIN32
+#include 
+#endif
+
+#ifndef EXTERN_C_BEGIN
+#ifdef __cplusplus
+#define EXTERN_C_BEGIN extern "C" {
+#define EXTERN_C_END }
+#else
+#define EXTERN_C_BEGIN
+#define EXTERN_C_END
+#endif
+#endif
+
+EXTERN_C_BEGIN
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifdef _WIN32
+typedef DWORD WRes;
+#else
+typedef int WRes;
+#endif
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+   NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#define UINT64_CONST(n) n
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#define UINT64_CONST(n) n ## ULL
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _WIN32
+#define MY_STD_CALL __stdcall
+#else
+#define MY_STD_CALL
+#endif
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_FAST_CALL __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+  Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
+} IByteIn;
+
+typedef struct
+{
+  void (*Write)(void *p, Byte b);
+} IByteOut;
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+
+typedef struct
+{
+  size_t (*Write)(void *p, const void *buf, size_t size);
+    /* Returns: result - the number of actually written bytes.
+       (result < size) means error */
+} ISeqOutStream;
+
+typedef enum
+{
+  SZ_SEEK_SET = 0,
+  SZ_SEEK_CUR = 1,
+  SZ_SEEK_END = 2
+} ESzSeek;
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ISeekInStream;
+
+typedef struct
+{
+  SRes (*Look)(void *p, const void **buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) > input(*size)) is not allowed
+       (output(*size) < input(*size)) is allowed */
+  SRes (*Skip)(void *p, size_t offset);
+    /* offset must be <= output(*size) of Look */
+
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* reads directly (without buffer). It's same as ISeqInStream::Read */
+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ILookInStream;
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+
+#define LookToRead_BUF_SIZE (1 << 14)
+
+typedef struct
+{
+  ILookInStream s;
+  ISeekInStream *realStream;
+  size_t pos;
+  size_t size;
+  Byte buf[LookToRead_BUF_SIZE];
+} CLookToRead;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+void LookToRead_Init(CLookToRead *p);
+
+typedef struct
+{
+  ISeqInStream s;
+  ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+typedef struct
+{
+  ISeqInStream s;
+  ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+typedef struct
+{
+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+    /* Returns: result. (result != SZ_OK) means break.
+       Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+  void *(*Alloc)(void *p, size_t size);
+  void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#ifdef _WIN32
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#endif
+
+EXTERN_C_END
+
+#endif
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/os.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/os.cpp
new file mode 100644
index 0000000..2371c08
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/os.cpp
@@ -0,0 +1,347 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "os.h"
+#include "irrString.h"
+#include "IrrCompileConfig.h"
+#include "irrMath.h"
+
+#if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
+	#include 
+	#define bswap_16(X) SDL_Swap16(X)
+	#define bswap_32(X) SDL_Swap32(X)
+#elif defined(_IRR_WINDOWS_API_) && defined(_MSC_VER) && (_MSC_VER > 1298)
+	#include 
+	#define bswap_16(X) _byteswap_ushort(X)
+	#define bswap_32(X) _byteswap_ulong(X)
+#if (_MSC_VER >= 1400)
+	#define localtime _localtime_s
+#endif
+#elif defined(_IRR_OSX_PLATFORM_)
+	#include 
+	#define bswap_16(X) OSReadSwapInt16(&X,0)
+	#define bswap_32(X) OSReadSwapInt32(&X,0)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
+	#include 
+	#define bswap_16(X) bswap16(X)
+	#define bswap_32(X) bswap32(X)
+#elif !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__PPC__) && !defined(_IRR_WINDOWS_API_)
+	#include 
+#else
+	#define bswap_16(X) ((((X)&0xFF) << 8) | (((X)&0xFF00) >> 8))
+	#define bswap_32(X) ( (((X)&0x000000FF)<<24) | (((X)&0xFF000000) >> 24) | (((X)&0x0000FF00) << 8) | (((X) &0x00FF0000) >> 8))
+#endif
+
+namespace irr
+{
+namespace os
+{
+	u16 Byteswap::byteswap(u16 num) {return bswap_16(num);}
+	s16 Byteswap::byteswap(s16 num) {return bswap_16(num);}
+	u32 Byteswap::byteswap(u32 num) {return bswap_32(num);}
+	s32 Byteswap::byteswap(s32 num) {return bswap_32(num);}
+	f32 Byteswap::byteswap(f32 num) {u32 tmp=IR(num); tmp=bswap_32(tmp); return (FR(tmp));}
+	// prevent accidental byte swapping of chars
+	u8  Byteswap::byteswap(u8 num)  {return num;}
+	c8  Byteswap::byteswap(c8 num)  {return num;}
+}
+}
+
+#if defined(_IRR_WINDOWS_API_)
+// ----------------------------------------------------------------
+// Windows specific functions
+// ----------------------------------------------------------------
+
+#ifdef _IRR_XBOX_PLATFORM_
+#include 
+#else
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#endif
+
+namespace irr
+{
+namespace os
+{
+	//! prints a debuginfo string
+	void Printer::print(const c8* message)
+	{
+#if defined (_WIN32_WCE )
+		core::stringw tmp(message);
+		tmp += L"\n";
+		OutputDebugStringW(tmp.c_str());
+#else
+		core::stringc tmp(message);
+		tmp += "\n";
+		OutputDebugStringA(tmp.c_str());
+		printf("%s", tmp.c_str());
+#endif
+	}
+
+	static LARGE_INTEGER HighPerformanceFreq;
+	static BOOL HighPerformanceTimerSupport = FALSE;
+	static BOOL MultiCore = FALSE;
+
+	void Timer::initTimer(bool usePerformanceTimer)
+	{
+#if !defined(_WIN32_WCE) && !defined (_IRR_XBOX_PLATFORM_)
+		// workaround for hires timer on multiple core systems, bios bugs result in bad hires timers.
+		SYSTEM_INFO sysinfo;
+		GetSystemInfo(&sysinfo);
+		MultiCore = (sysinfo.dwNumberOfProcessors > 1);
+#endif
+		if (usePerformanceTimer)
+			HighPerformanceTimerSupport = QueryPerformanceFrequency(&HighPerformanceFreq);
+		else
+			HighPerformanceTimerSupport = FALSE;
+		initVirtualTimer();
+	}
+
+	u32 Timer::getRealTime()
+	{
+		if (HighPerformanceTimerSupport)
+		{
+#if !defined(_WIN32_WCE) && !defined (_IRR_XBOX_PLATFORM_)
+			// Avoid potential timing inaccuracies across multiple cores by
+			// temporarily setting the affinity of this process to one core.
+			DWORD_PTR affinityMask=0;
+			if(MultiCore)
+				affinityMask = SetThreadAffinityMask(GetCurrentThread(), 1);
+#endif
+			LARGE_INTEGER nTime;
+			BOOL queriedOK = QueryPerformanceCounter(&nTime);
+
+#if !defined(_WIN32_WCE)  && !defined (_IRR_XBOX_PLATFORM_)
+			// Restore the true affinity.
+			if(MultiCore)
+				(void)SetThreadAffinityMask(GetCurrentThread(), affinityMask);
+#endif
+			if(queriedOK)
+				return u32((nTime.QuadPart) * 1000 / HighPerformanceFreq.QuadPart);
+
+		}
+
+		return GetTickCount();
+	}
+
+} // end namespace os
+
+
+#else
+
+// ----------------------------------------------------------------
+// linux/ansi version
+// ----------------------------------------------------------------
+
+#include 
+#include 
+#include 
+
+namespace irr
+{
+namespace os
+{
+
+	//! prints a debuginfo string
+	void Printer::print(const c8* message)
+	{
+		printf("%s\n", message);
+	}
+
+	void Timer::initTimer(bool usePerformanceTimer)
+	{
+		initVirtualTimer();
+	}
+
+	u32 Timer::getRealTime()
+	{
+		timeval tv;
+		gettimeofday(&tv, 0);
+		return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+	}
+} // end namespace os
+
+#endif // end linux / windows
+
+namespace os
+{
+	// The platform independent implementation of the printer
+	ILogger* Printer::Logger = 0;
+
+	void Printer::log(const c8* message, ELOG_LEVEL ll)
+	{
+		if (Logger)
+			Logger->log(message, ll);
+	}
+
+	void Printer::log(const wchar_t* message, ELOG_LEVEL ll)
+	{
+		if (Logger)
+			Logger->log(message, ll);
+	}
+
+	void Printer::log(const c8* message, const c8* hint, ELOG_LEVEL ll)
+	{
+		if (Logger)
+			Logger->log(message, hint, ll);
+	}
+
+	void Printer::log(const c8* message, const io::path& hint, ELOG_LEVEL ll)
+	{
+		if (Logger)
+			Logger->log(message, hint.c_str(), ll);
+	}
+
+	// our Randomizer is not really os specific, so we
+	// code one for all, which should work on every platform the same,
+	// which is desireable.
+
+	s32 Randomizer::seed = 0x0f0f0f0f;
+
+	//! generates a pseudo random number
+	s32 Randomizer::rand()
+	{
+		// (a*seed)%m with Schrage's method
+		seed = a * (seed%q) - r* (seed/q);
+		if (seed<0)
+			seed += m;
+
+		return seed;
+	}
+
+	//! generates a pseudo random number
+	f32 Randomizer::frand()
+	{
+		return rand()*(1.f/rMax);
+	}
+
+	s32 Randomizer::randMax()
+	{
+		return rMax;
+	}
+
+	//! resets the randomizer
+	void Randomizer::reset(s32 value)
+	{
+		seed = value;
+	}
+
+
+	// ------------------------------------------------------
+	// virtual timer implementation
+
+	f32 Timer::VirtualTimerSpeed = 1.0f;
+	s32 Timer::VirtualTimerStopCounter = 0;
+	u32 Timer::LastVirtualTime = 0;
+	u32 Timer::StartRealTime = 0;
+	u32 Timer::StaticTime = 0;
+
+	//! Get real time and date in calendar form
+	ITimer::RealTimeDate Timer::getRealTimeAndDate()
+	{
+		time_t rawtime;
+		time(&rawtime);
+
+		struct tm * timeinfo;
+		timeinfo = localtime(&rawtime);
+
+		// init with all 0 to indicate error
+		ITimer::RealTimeDate date={0};
+		// at least Windows returns NULL on some illegal dates
+		if (timeinfo)
+		{
+			// set useful values if succeeded
+			date.Hour=(u32)timeinfo->tm_hour;
+			date.Minute=(u32)timeinfo->tm_min;
+			date.Second=(u32)timeinfo->tm_sec;
+			date.Day=(u32)timeinfo->tm_mday;
+			date.Month=(u32)timeinfo->tm_mon+1;
+			date.Year=(u32)timeinfo->tm_year+1900;
+			date.Weekday=(ITimer::EWeekday)timeinfo->tm_wday;
+			date.Yearday=(u32)timeinfo->tm_yday+1;
+			date.IsDST=timeinfo->tm_isdst != 0;
+		}
+		return date;
+	}
+
+	//! returns current virtual time
+	u32 Timer::getTime()
+	{
+		if (isStopped())
+			return LastVirtualTime;
+
+		return LastVirtualTime + (u32)((StaticTime - StartRealTime) * VirtualTimerSpeed);
+	}
+
+	//! ticks, advances the virtual timer
+	void Timer::tick()
+	{
+		StaticTime = getRealTime();
+	}
+
+	//! sets the current virtual time
+	void Timer::setTime(u32 time)
+	{
+		StaticTime = getRealTime();
+		LastVirtualTime = time;
+		StartRealTime = StaticTime;
+	}
+
+	//! stops the virtual timer
+	void Timer::stopTimer()
+	{
+		if (!isStopped())
+		{
+			// stop the virtual timer
+			LastVirtualTime = getTime();
+		}
+
+		--VirtualTimerStopCounter;
+	}
+
+	//! starts the virtual timer
+	void Timer::startTimer()
+	{
+		++VirtualTimerStopCounter;
+
+		if (!isStopped())
+		{
+			// restart virtual timer
+			setTime(LastVirtualTime);
+		}
+	}
+
+	//! sets the speed of the virtual timer
+	void Timer::setSpeed(f32 speed)
+	{
+		setTime(getTime());
+
+		VirtualTimerSpeed = speed;
+		if (VirtualTimerSpeed < 0.0f)
+			VirtualTimerSpeed = 0.0f;
+	}
+
+	//! gets the speed of the virtual timer
+	f32 Timer::getSpeed()
+	{
+		return VirtualTimerSpeed;
+	}
+
+	//! returns if the timer currently is stopped
+	bool Timer::isStopped()
+	{
+		return VirtualTimerStopCounter < 0;
+	}
+
+	void Timer::initVirtualTimer()
+	{
+		StaticTime = getRealTime();
+		StartRealTime = StaticTime;
+	}
+
+} // end namespace os
+} // end namespace irr
+
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/os.h b/src/others/irrlicht-1.8.1/source/Irrlicht/os.h
new file mode 100644
index 0000000..07059ca
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/os.h
@@ -0,0 +1,131 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#ifndef __IRR_OS_H_INCLUDED__
+#define __IRR_OS_H_INCLUDED__
+
+#include "IrrCompileConfig.h" // for endian check
+#include "irrTypes.h"
+#include "irrString.h"
+#include "path.h"
+#include "ILogger.h"
+#include "ITimer.h"
+
+namespace irr
+{
+
+namespace os
+{
+	class Byteswap
+	{
+	public:
+		static u16 byteswap(u16 num);
+		static s16 byteswap(s16 num);
+		static u32 byteswap(u32 num);
+		static s32 byteswap(s32 num);
+		static f32 byteswap(f32 num);
+		// prevent accidental swapping of chars
+		static u8  byteswap(u8  num);
+		static c8  byteswap(c8  num);
+	};
+
+	class Printer
+	{
+	public:
+		// prints out a string to the console out stdout or debug log or whatever
+		static void print(const c8* message);
+		static void log(const c8* message, ELOG_LEVEL ll = ELL_INFORMATION);
+		static void log(const wchar_t* message, ELOG_LEVEL ll = ELL_INFORMATION);
+		static void log(const c8* message, const c8* hint, ELOG_LEVEL ll = ELL_INFORMATION);
+		static void log(const c8* message, const io::path& hint, ELOG_LEVEL ll = ELL_INFORMATION);
+		static ILogger* Logger;
+	};
+
+
+	// mixed linear congruential generator (MLCG)
+	// numbers chosen according to L'Ecuyer, Commun. ACM 31 (1988) 742
+	// period is somewhere around m-1
+	class Randomizer
+	{
+	public:
+
+		//! resets the randomizer
+		static void reset(s32 value=0x0f0f0f0f);
+
+		//! generates a pseudo random number in the range 0..randMax()
+		static s32 rand();
+
+		//! generates a pseudo random number in the range 0..1
+		static f32 frand();
+
+		//! get maxmimum number generated by rand()
+		static s32 randMax();
+
+	private:
+
+		static s32 seed;
+		static const s32 m = 2147483399;	// a non-Mersenne prime
+		static const s32 a = 40692;			// another spectral success story
+		static const s32 q = m/a;
+		static const s32 r = m%a;			// again less than q
+		static const s32 rMax = m-1;
+	};
+
+
+
+
+	class Timer
+	{
+	public:
+
+		//! returns the current time in milliseconds
+		static u32 getTime();
+
+		//! get current time and date in calendar form
+		static ITimer::RealTimeDate getRealTimeAndDate();
+
+		//! initializes the real timer
+		static void initTimer(bool usePerformanceTimer=true);
+
+		//! sets the current virtual (game) time
+		static void setTime(u32 time);
+
+		//! stops the virtual (game) timer
+		static void stopTimer();
+
+		//! starts the game timer
+		static void startTimer();
+
+		//! sets the speed of the virtual timer
+		static void setSpeed(f32 speed);
+
+		//! gets the speed of the virtual timer
+		static f32 getSpeed();
+
+		//! returns if the timer currently is stopped
+		static bool isStopped();
+
+		//! makes the virtual timer update the time value based on the real time
+		static void tick();
+
+		//! returns the current real time in milliseconds
+		static u32 getRealTime();
+
+	private:
+
+		static void initVirtualTimer();
+
+		static f32 VirtualTimerSpeed;
+		static s32 VirtualTimerStopCounter;
+		static u32 StartRealTime;
+		static u32 LastVirtualTime;
+		static u32 StaticTime;
+	};
+
+} // end namespace os
+} // end namespace irr
+
+
+#endif
+
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/resource.h b/src/others/irrlicht-1.8.1/source/Irrlicht/resource.h
new file mode 100644
index 0000000..c734d2a
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Irrlicht.rc
+
+// Nächste Standardwerte für neue Objekte
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1001
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/source.txt b/src/others/irrlicht-1.8.1/source/Irrlicht/source.txt
new file mode 100644
index 0000000..f90ea06
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/source.txt
@@ -0,0 +1,40 @@
+Source code of the Irrlicht Engine
+
+The complete source of the Irrlicht Engine can be found when decompressing
+the .zip file included in this directory. 
+Please note that YOU DO NOT NEED THIS SOURCE to develop 3d applications with
+the Irrlicht Engine. Instead, please use the .dll in the \bin directory, the 
+.lib in the \lib directory and the header files in the \include directory.
+
+You will find a good tutorial how to set up your development environment and to
+use the engine in the \examples directory. (Try 1.helloworld)
+
+The source of the engine is only included because of the following reasons:
+
+	- To let developers be able to debug the engine.
+	- To let developers be able to make changes to the engine.
+	- To let developers be able to compile their own versions of the engine.
+	
+	
+	
+HOW TO COMPILE THE ENGINE WITH LINUX
+
+If you wish to compile the engine in linux yourself, unzip the source source.zip
+file in the \source directory. Run a 'make' in the now existing new subfolder 'Irrlicht'.
+After this, you should be able to make all example applications in \examples.
+Then just start an X Server and run them, from the directory where they are.
+
+If you get a compiling/linking problem like 
+
+ undefined reference to `glXGetProcAddress'
+ 
+Then there are several solutions: 
+A) This disables the use of OpenGL extensions:
+  Open the file IrrCompileConfig.h, comment out _IRR_OPENGL_USE_EXTPOINTER_,
+  and recompile Irrlicht using 
+  make clean
+  make
+B) Replace all occurrences of 'glXGetProcAddress' with 'glXGetProcAddressARB' and run a
+   make
+   This will solve the issue but keep the OpenGL extension enabled.
+   
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/wglext.h b/src/others/irrlicht-1.8.1/source/Irrlicht/wglext.h
new file mode 100644
index 0000000..a9ddc52
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/wglext.h
@@ -0,0 +1,929 @@
+#ifndef __wglext_h_
+#define __wglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2011 The Khronos Group Inc.
+** 
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+** 
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include 
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number */
+/* wglext.h last updated 2011/04/13 */
+/* Current version at http://www.opengl.org/registry/ */
+#define WGL_WGLEXT_VERSION 23
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB  0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB       0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB     0x00000008
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB         0x2041
+#define WGL_SAMPLES_ARB                0x2042
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB   0x2000
+#define WGL_DRAW_TO_WINDOW_ARB         0x2001
+#define WGL_DRAW_TO_BITMAP_ARB         0x2002
+#define WGL_ACCELERATION_ARB           0x2003
+#define WGL_NEED_PALETTE_ARB           0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB    0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB     0x2006
+#define WGL_SWAP_METHOD_ARB            0x2007
+#define WGL_NUMBER_OVERLAYS_ARB        0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB       0x2009
+#define WGL_TRANSPARENT_ARB            0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB  0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB            0x200C
+#define WGL_SHARE_STENCIL_ARB          0x200D
+#define WGL_SHARE_ACCUM_ARB            0x200E
+#define WGL_SUPPORT_GDI_ARB            0x200F
+#define WGL_SUPPORT_OPENGL_ARB         0x2010
+#define WGL_DOUBLE_BUFFER_ARB          0x2011
+#define WGL_STEREO_ARB                 0x2012
+#define WGL_PIXEL_TYPE_ARB             0x2013
+#define WGL_COLOR_BITS_ARB             0x2014
+#define WGL_RED_BITS_ARB               0x2015
+#define WGL_RED_SHIFT_ARB              0x2016
+#define WGL_GREEN_BITS_ARB             0x2017
+#define WGL_GREEN_SHIFT_ARB            0x2018
+#define WGL_BLUE_BITS_ARB              0x2019
+#define WGL_BLUE_SHIFT_ARB             0x201A
+#define WGL_ALPHA_BITS_ARB             0x201B
+#define WGL_ALPHA_SHIFT_ARB            0x201C
+#define WGL_ACCUM_BITS_ARB             0x201D
+#define WGL_ACCUM_RED_BITS_ARB         0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB       0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB        0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB       0x2021
+#define WGL_DEPTH_BITS_ARB             0x2022
+#define WGL_STENCIL_BITS_ARB           0x2023
+#define WGL_AUX_BUFFERS_ARB            0x2024
+#define WGL_NO_ACCELERATION_ARB        0x2025
+#define WGL_GENERIC_ACCELERATION_ARB   0x2026
+#define WGL_FULL_ACCELERATION_ARB      0x2027
+#define WGL_SWAP_EXCHANGE_ARB          0x2028
+#define WGL_SWAP_COPY_ARB              0x2029
+#define WGL_SWAP_UNDEFINED_ARB         0x202A
+#define WGL_TYPE_RGBA_ARB              0x202B
+#define WGL_TYPE_COLORINDEX_ARB        0x202C
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_ARB   0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_DRAW_TO_PBUFFER_ARB        0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB     0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB      0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB     0x2030
+#define WGL_PBUFFER_LARGEST_ARB        0x2033
+#define WGL_PBUFFER_WIDTH_ARB          0x2034
+#define WGL_PBUFFER_HEIGHT_ARB         0x2035
+#define WGL_PBUFFER_LOST_ARB           0x2036
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_BIND_TO_TEXTURE_RGB_ARB    0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB   0x2071
+#define WGL_TEXTURE_FORMAT_ARB         0x2072
+#define WGL_TEXTURE_TARGET_ARB         0x2073
+#define WGL_MIPMAP_TEXTURE_ARB         0x2074
+#define WGL_TEXTURE_RGB_ARB            0x2075
+#define WGL_TEXTURE_RGBA_ARB           0x2076
+#define WGL_NO_TEXTURE_ARB             0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB       0x2078
+#define WGL_TEXTURE_1D_ARB             0x2079
+#define WGL_TEXTURE_2D_ARB             0x207A
+#define WGL_MIPMAP_LEVEL_ARB           0x207B
+#define WGL_CUBE_MAP_FACE_ARB          0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB             0x2083
+#define WGL_FRONT_RIGHT_ARB            0x2084
+#define WGL_BACK_LEFT_ARB              0x2085
+#define WGL_BACK_RIGHT_ARB             0x2086
+#define WGL_AUX0_ARB                   0x2087
+#define WGL_AUX1_ARB                   0x2088
+#define WGL_AUX2_ARB                   0x2089
+#define WGL_AUX3_ARB                   0x208A
+#define WGL_AUX4_ARB                   0x208B
+#define WGL_AUX5_ARB                   0x208C
+#define WGL_AUX6_ARB                   0x208D
+#define WGL_AUX7_ARB                   0x208E
+#define WGL_AUX8_ARB                   0x208F
+#define WGL_AUX9_ARB                   0x2090
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ARB        0x21A0
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_CONTEXT_DEBUG_BIT_ARB      0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB  0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB  0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB    0x2093
+#define WGL_CONTEXT_FLAGS_ARB          0x2094
+#define ERROR_INVALID_VERSION_ARB      0x2095
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB   0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define ERROR_INVALID_PROFILE_ARB      0x2096
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB  0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB  0x8261
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_EXT   0x2043
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_EXT   0x2000
+#define WGL_DRAW_TO_WINDOW_EXT         0x2001
+#define WGL_DRAW_TO_BITMAP_EXT         0x2002
+#define WGL_ACCELERATION_EXT           0x2003
+#define WGL_NEED_PALETTE_EXT           0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT    0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT     0x2006
+#define WGL_SWAP_METHOD_EXT            0x2007
+#define WGL_NUMBER_OVERLAYS_EXT        0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT       0x2009
+#define WGL_TRANSPARENT_EXT            0x200A
+#define WGL_TRANSPARENT_VALUE_EXT      0x200B
+#define WGL_SHARE_DEPTH_EXT            0x200C
+#define WGL_SHARE_STENCIL_EXT          0x200D
+#define WGL_SHARE_ACCUM_EXT            0x200E
+#define WGL_SUPPORT_GDI_EXT            0x200F
+#define WGL_SUPPORT_OPENGL_EXT         0x2010
+#define WGL_DOUBLE_BUFFER_EXT          0x2011
+#define WGL_STEREO_EXT                 0x2012
+#define WGL_PIXEL_TYPE_EXT             0x2013
+#define WGL_COLOR_BITS_EXT             0x2014
+#define WGL_RED_BITS_EXT               0x2015
+#define WGL_RED_SHIFT_EXT              0x2016
+#define WGL_GREEN_BITS_EXT             0x2017
+#define WGL_GREEN_SHIFT_EXT            0x2018
+#define WGL_BLUE_BITS_EXT              0x2019
+#define WGL_BLUE_SHIFT_EXT             0x201A
+#define WGL_ALPHA_BITS_EXT             0x201B
+#define WGL_ALPHA_SHIFT_EXT            0x201C
+#define WGL_ACCUM_BITS_EXT             0x201D
+#define WGL_ACCUM_RED_BITS_EXT         0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT       0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT        0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT       0x2021
+#define WGL_DEPTH_BITS_EXT             0x2022
+#define WGL_STENCIL_BITS_EXT           0x2023
+#define WGL_AUX_BUFFERS_EXT            0x2024
+#define WGL_NO_ACCELERATION_EXT        0x2025
+#define WGL_GENERIC_ACCELERATION_EXT   0x2026
+#define WGL_FULL_ACCELERATION_EXT      0x2027
+#define WGL_SWAP_EXCHANGE_EXT          0x2028
+#define WGL_SWAP_COPY_EXT              0x2029
+#define WGL_SWAP_UNDEFINED_EXT         0x202A
+#define WGL_TYPE_RGBA_EXT              0x202B
+#define WGL_TYPE_COLORINDEX_EXT        0x202C
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_DRAW_TO_PBUFFER_EXT        0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT     0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT      0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT     0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT  0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT        0x2033
+#define WGL_PBUFFER_WIDTH_EXT          0x2034
+#define WGL_PBUFFER_HEIGHT_EXT         0x2035
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_DEPTH_FLOAT_EXT            0x2040
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_SAMPLE_BUFFERS_3DFX        0x2060
+#define WGL_SAMPLES_3DFX               0x2061
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_SAMPLE_BUFFERS_EXT         0x2041
+#define WGL_SAMPLES_EXT                0x2042
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_GAMMA_TABLE_SIZE_I3D       0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D  0x204F
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D      0x00000002
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#endif
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV   0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV    0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV         0x20A7
+#endif
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV       0x20A2
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ATI        0x21A0
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_FLOAT_COMPONENTS_NV        0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV         0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV        0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV       0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV      0x20B8
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_STEREO_EMITTER_ENABLE_3DL  0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NUM_VIDEO_SLOTS_NV         0x20F0
+#endif
+
+#ifndef WGL_NV_video_out
+#define WGL_BIND_TO_VIDEO_RGB_NV       0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV      0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV         0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV         0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV         0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME            0x20C8
+#define WGL_VIDEO_OUT_FIELD_1          0x20C9
+#define WGL_VIDEO_OUT_FIELD_2          0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+#endif
+
+#ifndef WGL_NV_swap_group
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_GPU_VENDOR_AMD             0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD    0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD                0x21A3
+#define WGL_GPU_CLOCK_AMD              0x21A4
+#define WGL_GPU_NUM_PIPES_AMD          0x21A5
+#define WGL_GPU_NUM_SIMD_AMD           0x21A6
+#define WGL_GPU_NUM_RB_AMD             0x21A7
+#define WGL_GPU_NUM_SPI_AMD            0x21A8
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_UNIQUE_ID_NV               0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+#endif
+
+#ifndef WGL_NV_copy_image
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_COVERAGE_SAMPLES_NV        0x2042
+#define WGL_COLOR_SAMPLES_NV           0x20B9
+#endif
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_ACCESS_READ_ONLY_NV        0x00000000
+#define WGL_ACCESS_READ_WRITE_NV       0x00000001
+#define WGL_ACCESS_WRITE_DISCARD_NV    0x00000002
+#endif
+
+
+/*************************************************************/
+
+#ifndef WGL_ARB_pbuffer
+DECLARE_HANDLE(HPBUFFERARB);
+#endif
+#ifndef WGL_EXT_pbuffer
+DECLARE_HANDLE(HPBUFFEREXT);
+#endif
+#ifndef WGL_NV_present_video
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+#endif
+#ifndef WGL_NV_video_output
+DECLARE_HANDLE(HPVIDEODEV);
+#endif
+#ifndef WGL_NV_gpu_affinity
+DECLARE_HANDLE(HPGPUNV);
+DECLARE_HANDLE(HGPUNV);
+
+typedef struct _GPU_DEVICE {
+    DWORD  cb;
+    CHAR   DeviceName[32];
+    CHAR   DeviceString[128];
+    DWORD  Flags;
+    RECT   rcVirtualScreen;
+} GPU_DEVICE, *PGPU_DEVICE;
+#endif
+#ifndef WGL_NV_video_capture
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+#endif
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
+extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
+extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
+extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringARB (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCARB (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
+extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
+extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+#endif
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
+extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
+extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
+extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+#endif
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
+extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
+extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSwapIntervalEXT (int interval);
+extern int WINAPI wglGetSwapIntervalEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+#endif
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+extern void WINAPI wglFreeMemoryNV (void *pointer);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+#endif
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
+extern INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+extern BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+extern BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
+extern BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
+extern BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
+extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
+extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
+extern BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
+extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
+extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
+extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
+extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
+extern BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
+extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableFrameLockI3D (void);
+extern BOOL WINAPI wglDisableFrameLockI3D (void);
+extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
+extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
+#endif
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
+extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
+extern BOOL WINAPI wglEndFrameTrackingI3D (void);
+extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+extern BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
+extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
+extern BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
+extern BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
+extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+extern BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
+extern BOOL WINAPI wglResetFrameCountNV (HDC hDC);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
+extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
+extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+extern BOOL WINAPI wglDeleteDCNV (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
+extern INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
+extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
+extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
+extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
+extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
+extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
+extern HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
+extern BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
+extern HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+extern BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
+extern BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
+extern BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+extern BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-- 
cgit v1.1