diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 36e31da..1fbad89 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,8 +1,8 @@ configure_file(${CMAKE_SOURCE_DIR}/cmake/resources.cfg.in ${CMAKE_SOURCE_DIR}/bin/resources.cfg) -add_executable(CaelumDemo ${CMAKE_SOURCE_DIR}/samples/src/CaelumDemo.cpp) -target_link_libraries(CaelumDemo PRIVATE Caelum OgreBites) +add_executable(CaelumDemo ${CMAKE_SOURCE_DIR}/samples/src/CaelumDemo.cpp) +target_link_libraries(CaelumDemo PRIVATE Caelum OgreBites OgreTerrain) target_include_directories(CaelumDemo PRIVATE ${CMAKE_SOURCE_DIR}/samples/include) add_executable(CaelumTest ${CMAKE_SOURCE_DIR}/samples/src/CaelumTest.cpp) diff --git a/samples/include/CaelumDemo.h b/samples/include/CaelumDemo.h index 61f608d..3514a67 100644 --- a/samples/include/CaelumDemo.h +++ b/samples/include/CaelumDemo.h @@ -4,6 +4,7 @@ #include "CaelumDemoCommon.h" #include "ExampleApplication.h" +#include "LegacyTerrainLoader.h" class CaelumSampleFrameListener : public OgreBites::InputListener { @@ -133,13 +134,13 @@ class CaelumSampleApplication : public ExampleApplication void createScene () { - mSceneMgr->getRootSceneNode()->attachObject( - mSceneMgr->createEntity("House", "TudorHouse.mesh")); - // needs porting to new terrain system -#if 0 + + SceneNode* houseNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + houseNode->setPosition(Vector3 (775, 60, 1150)); + houseNode->setScale(0.05, 0.05, 0.05); + houseNode->yaw(Degree(45)); + houseNode->attachObject(mSceneMgr->createEntity("House", "TudorHouse.mesh")); // Put some terrain in the scene - std::string terrain_cfg("CaelumDemoTerrain.cfg"); - mSceneMgr->setWorldGeometry (terrain_cfg); -#endif + loadLegacyTerrain("CaelumDemoTerrain.cfg", mSceneMgr); } }; diff --git a/samples/include/ExampleApplication.h b/samples/include/ExampleApplication.h index 9a6a341..c578b8f 100644 --- a/samples/include/ExampleApplication.h +++ b/samples/include/ExampleApplication.h @@ -25,6 +25,7 @@ Description: Base class for all the OGRE examples #include "OgreConfigFile.h" #include #include +#include using namespace Ogre; @@ -67,8 +68,7 @@ class ExampleApplication : public OgreBites::ApplicationContext OgreBites::InputListener* mFrameListener; // These internal methods package up the stages in the startup process - /** Sets up the application - returns false if the user chooses to abandon configuration. */ - virtual void setup(void) + void setup(void) override { OgreBites::ApplicationContext::setup(); @@ -86,6 +86,9 @@ class ExampleApplication : public OgreBites::ApplicationContext { // Create the SceneManager, in this case a generic one mSceneMgr = mRoot->createSceneManager("DefaultSceneManager", "ExampleSMInstance"); +#ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM + mShaderGenerator->addSceneManager(mSceneMgr); +#endif } virtual void createCamera(void) { @@ -118,6 +121,13 @@ class ExampleApplication : public OgreBites::ApplicationContext Viewport* vp = getRenderWindow()->addViewport(mCamera); vp->setBackgroundColour(ColourValue(0,0,0)); +#ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM + // Make this viewport work with shader generator scheme. + vp->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + // update scheme for FFP supporting rendersystems + MaterialManager::getSingleton().setActiveScheme(vp->getMaterialScheme()); +#endif + // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio( Real(vp->getActualWidth()) / Real(vp->getActualHeight())); diff --git a/samples/include/LegacyTerrainLoader.h b/samples/include/LegacyTerrainLoader.h new file mode 100644 index 0000000..5825f3d --- /dev/null +++ b/samples/include/LegacyTerrainLoader.h @@ -0,0 +1,99 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org/ + +Copyright (c) 2000-2009 Torus Knot Software Ltd +Also see acknowledgements in Readme.html + +You may use this sample code for anything you like, it is not covered by the +same license as the rest of the engine. +----------------------------------------------------------------------------- +*/ + +#include +#include +#include + +namespace Ogre +{ +class CustomMatGenerator : public Ogre::TerrainMaterialGenerator +{ + MaterialPtr mMaterial; + bool mIsInit; + bool mNormalMapRequired; +public: + CustomMatGenerator(const String& matName) : mIsInit(false), mNormalMapRequired(true) + { + auto terrainGlobals = TerrainGlobalOptions::getSingletonPtr(); + mMaterial = + MaterialManager::getSingleton().getByName(matName, terrainGlobals->getDefaultResourceGroup()); + } + + bool isVertexCompressionSupported() const { return false; } + + void setNormalMapRequired(bool enable) { mNormalMapRequired = enable; } + + MaterialPtr generate(const Terrain* terrain) + { + if (!mIsInit && mNormalMapRequired) + { + // Get default pass + Pass *p = mMaterial->getTechnique(0)->getPass(0); + + // Add terrain's global normalmap to renderpass so the fragment program can find it. + p->createTextureUnitState()->_setTexturePtr(terrain->getTerrainNormalMap()); + + } + mIsInit = true; + + return mMaterial; + } + MaterialPtr generateForCompositeMap(const Terrain* terrain) + { + return terrain->_getCompositeMapMaterial(); + } + void updateCompositeMap(const Terrain* terrain, const Rect& rect) {} + void setLightmapEnabled(bool enabled) {} + uint8 getMaxLayers(const Terrain* terrain) const { return 0; } + + void updateParams(const MaterialPtr& mat, const Terrain* terrain) {} + void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) {} + void requestOptions(Terrain* terrain) + { + terrain->_setLightMapRequired(false); + terrain->_setCompositeMapRequired(false); + terrain->_setNormalMapRequired(mNormalMapRequired); + } +}; +} // namespace Ogre + +inline Ogre::TerrainGroup* loadLegacyTerrain(const Ogre::String& cfgFileName, Ogre::SceneManager* sceneMgr) +{ + using namespace Ogre; + + auto terrainGroup = new TerrainGroup(sceneMgr); + + ConfigFile cfg; + cfg.loadFromResourceSystem(cfgFileName, terrainGroup->getResourceGroup()); + + auto terrainGlobals = TerrainGlobalOptions::getSingletonPtr(); + if(!terrainGlobals) + terrainGlobals = new TerrainGlobalOptions(); + + const String& customMatName = cfg.getSetting("CustomMaterialName"); + + if(!customMatName.empty()) + { + auto generator = new CustomMatGenerator(customMatName); + generator->setNormalMapRequired(StringConverter::parseBool(cfg.getSetting("VertexNormals"))); + terrainGlobals->setDefaultMaterialGenerator(Ogre::TerrainMaterialGeneratorPtr(generator)); + } + +#if OGRE_VERSION >= ((1 << 16) | (11 << 8) | 6) + terrainGroup->loadLegacyTerrain(cfg); +#endif + + return terrainGroup; +} diff --git a/samples/resources/CaelumSample.cg b/samples/resources/CaelumSample.cg index 1eaa0cb..cce6301 100644 --- a/samples/resources/CaelumSample.cg +++ b/samples/resources/CaelumSample.cg @@ -144,6 +144,7 @@ void MainFP uniform sampler mainTexture : register(s0), #if TERRAIN uniform sampler detailTexture : register(s1), + uniform sampler normalTexture : register(s2), #endif #endif @@ -203,9 +204,15 @@ void MainFP oColour += baseColour * derived_scene_colour; #endif -#if ONE_LIGHT - float3 normal = normalize(iNormal); +#if ONE_LIGHT || TWO_LIGHTS + #if TERRAIN + float3 normal = tex2D(normalTexture, iTexcoord).rgb * 2 - 1; + #else + float3 normal = normalize(iNormal); + #endif +#endif +#if ONE_LIGHT float diffuse_factor = max(0, dot(float4(normal, 1), light_position_view_space)); float4 light_colour = diffuse_factor * derived_light_diffuse_colour * shadowing; @@ -213,8 +220,6 @@ void MainFP #endif #if TWO_LIGHTS - float3 normal = normalize(iNormal); - // Accumulate two lights float4 light_colour = float4(0, 0, 0, 0);