A simple starter project for Ogre 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

417 lines
13 KiB

#include <stdio.h>
#include "Compositor/OgreCompositorManager2.h"
#include "OgreArchiveManager.h"
#include "OgreCamera.h"
#include "OgreConfigFile.h"
#include "OgreHlmsManager.h"
#include "OgreHlmsPbs.h"
#include "OgreHlmsPbsDatablock.h"
#include "OgreHlmsSamplerblock.h"
#include "OgreHlmsUnlit.h"
#include "OgreItem.h"
#include "OgreMesh.h"
#include "OgreMesh2.h"
#include "OgreMeshManager.h"
#include "OgreMeshManager2.h"
#include "OgreRoot.h"
#include "OgreSceneManager.h"
#include "OgreTextureFilters.h"
#include "OgreTextureGpuManager.h"
#include "OgreWindow.h"
#include "OgreWindowEventUtilities.h"
Ogre::Root* gOgreRoot = nullptr;
static Ogre::SceneManager* gSceneManager = nullptr;
static Ogre::Window* gOgreWindow = nullptr;
static bool gGraphicsIntialized = false;
static bool g_ogre_window_should_quit = false;
class MyWindowEventListener : public Ogre::WindowEventListener
{
public:
virtual void windowClosed(Ogre::Window* window)
{
printf("Window closed!\n");
g_ogre_window_should_quit = true;
}
};
MyWindowEventListener g_myWindowEventListener;
static void registerHlms()
{
Ogre::String resourcePath = "data/";
Ogre::ConfigFile config;
config.load((resourcePath + "resources2.cfg"));
Ogre::String rootHlmsFolder =
(resourcePath + config.getSetting("DoNotUseAsResource", "Hlms", "Hlms"));
if (rootHlmsFolder.empty())
{
rootHlmsFolder = "./";
}
else if ((*(rootHlmsFolder.end() - 1)) != '/')
{
rootHlmsFolder = (rootHlmsFolder + "/");
}
Ogre::HlmsUnlit* hlmsUnlit = nullptr;
Ogre::HlmsPbs* hlmsPbs = nullptr;
Ogre::String mainFolderPath;
Ogre::StringVector libraryFoldersPaths;
Ogre::StringVector::const_iterator libraryFolderPathIt;
Ogre::StringVector::const_iterator libraryFolderPathEn;
Ogre::ArchiveManager& archiveManager = Ogre::ArchiveManager::getSingleton();
// Unlit
{
Ogre::HlmsUnlit::getDefaultPaths(mainFolderPath, libraryFoldersPaths);
Ogre::Archive* archiveUnlit =
archiveManager.load((rootHlmsFolder + mainFolderPath), "FileSystem", true);
Ogre::ArchiveVec archiveUnlitLibraryFolders;
libraryFolderPathIt = libraryFoldersPaths.begin();
libraryFolderPathEn = libraryFoldersPaths.end();
while (libraryFolderPathIt != libraryFolderPathEn)
{
Ogre::Archive* archiveLibrary =
archiveManager.load((rootHlmsFolder + (*libraryFolderPathIt)), "FileSystem", true);
archiveUnlitLibraryFolders.push_back(archiveLibrary);
++libraryFolderPathIt;
}
hlmsUnlit = OGRE_NEW Ogre::HlmsUnlit(archiveUnlit, (&archiveUnlitLibraryFolders));
Ogre::Root::getSingleton().getHlmsManager()->registerHlms(hlmsUnlit);
}
// PBS (lit)
{
Ogre::HlmsPbs::getDefaultPaths(mainFolderPath, libraryFoldersPaths);
Ogre::Archive* archivePbs =
archiveManager.load((rootHlmsFolder + mainFolderPath), "FileSystem", true);
Ogre::ArchiveVec archivePbsLibraryFolders;
libraryFolderPathIt = libraryFoldersPaths.begin();
libraryFolderPathEn = libraryFoldersPaths.end();
while (libraryFolderPathIt != libraryFolderPathEn)
{
Ogre::Archive* archiveLibrary =
archiveManager.load((rootHlmsFolder + (*libraryFolderPathIt)), "FileSystem", true);
archivePbsLibraryFolders.push_back(archiveLibrary);
++libraryFolderPathIt;
}
hlmsPbs = OGRE_NEW Ogre::HlmsPbs(archivePbs, (&archivePbsLibraryFolders));
Ogre::Root::getSingleton().getHlmsManager()->registerHlms(hlmsPbs);
}
Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
if (renderSystem->getName() == "Direct3D11 Rendering Subsystem")
{
bool supportsNoOverwriteOnTextureBuffers;
renderSystem->getCustomAttribute("MapNoOverwriteOnDynamicBufferSRV",
(&supportsNoOverwriteOnTextureBuffers));
if (!(supportsNoOverwriteOnTextureBuffers))
{
hlmsPbs->setTextureBufferDefaultSize((512 * 1024));
hlmsUnlit->setTextureBufferDefaultSize((512 * 1024));
}
}
}
bool ogreInitializeInternal(bool useCurrentWindow)
{
const Ogre::String pluginsFolder = "./data/";
const Ogre::String writeAccessFolder = "./output/";
const char* pluginsFile = "plugins_d.cfg";
gOgreRoot = OGRE_NEW Ogre::Root((pluginsFolder + pluginsFile), (writeAccessFolder + "ogre.cfg"),
(writeAccessFolder + "Ogre.log"));
// This allows the user to configure the graphics. It's damn annoying during dev though
// if (!root->showConfigDialog())
// return false;
Ogre::RenderSystem* renderSystem =
gOgreRoot->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
if (!(renderSystem))
{
printf("Render system not found!\n");
return false;
}
renderSystem->setConfigOption("Full Screen", "No");
renderSystem->setConfigOption("Video Mode", "1920 x 1080");
renderSystem->setConfigOption("sRGB Gamma Conversion", "Yes");
gOgreRoot->setRenderSystem(renderSystem);
gOgreWindow = gOgreRoot->initialise(!(useCurrentWindow), "OgreStartProject");
if (useCurrentWindow)
{
Ogre::NameValuePairList windowSettings;
windowSettings["currentGLDrawable"] = Ogre::String("True");
windowSettings["currentGLContext"] = Ogre::String("True");
int winWidth = 1920;
int winHeight = 1080;
gOgreWindow = gOgreRoot->createRenderWindow("OgreStartProject", winWidth, winHeight, false,
(&windowSettings));
}
registerHlms();
const size_t numThreads = 1u;
gSceneManager = gOgreRoot->createSceneManager(Ogre::ST_GENERIC, numThreads, "SceneManager");
Ogre::Camera* camera = gSceneManager->createCamera("Main Camera");
{
camera->setPosition(Ogre::Vector3(0, 5, 15));
camera->lookAt(Ogre::Vector3(0, 0, 0));
camera->setNearClipDistance(0.2f);
camera->setFarClipDistance(1000.0f);
camera->setAutoAspectRatio(true);
}
Ogre::CompositorManager2* compositorManager = gOgreRoot->getCompositorManager2();
const Ogre::String workspaceName = "Main Workspace";
const Ogre::ColourValue backgroundColour(0.0302f, 0.03f, 0.03f);
compositorManager->createBasicWorkspaceDef(workspaceName, backgroundColour, Ogre::IdString());
compositorManager->addWorkspace(gSceneManager, gOgreWindow->getTexture(), camera, workspaceName,
true);
Ogre::ResourceGroupManager& resourceGroupManager = Ogre::ResourceGroupManager::getSingleton();
resourceGroupManager.addResourceLocation("data/Models", "FileSystem", "Models");
resourceGroupManager.addResourceLocation("data/Materials/Textures", "FileSystem", "Textures");
{
resourceGroupManager.createResourceGroup("Materials");
resourceGroupManager.addResourceLocation("data/Materials", "FileSystem", "Materials");
resourceGroupManager.initialiseResourceGroup("Materials", true);
resourceGroupManager.loadResourceGroup("Materials");
}
if (!useCurrentWindow)
{
Ogre::WindowEventUtilities::addWindowEventListener(gOgreWindow, &g_myWindowEventListener);
}
gGraphicsIntialized = true;
return true;
}
void ogreShutdown()
{
Ogre::WindowEventUtilities::removeWindowEventListener(gOgreWindow, &g_myWindowEventListener);
OGRE_DELETE(gOgreRoot);
gOgreRoot = nullptr;
}
Ogre::SceneManager* ogreGetSceneManager()
{
return gSceneManager;
}
//
// Interface
//
bool ogreInitialize()
{
return ogreInitializeInternal(false);
}
// Assumes an already created SDL window with OpenGL context
bool ogreInitializeSdl()
{
return ogreInitializeInternal(true);
}
bool ogreRenderFrame()
{
return gOgreRoot->renderOneFrame();
}
// Only necessary for old V1 models. You should try not to use this
Ogre::Item* ogreLoadMeshFromV1(const char* name)
{
Ogre::SceneManager* sceneManager = ogreGetSceneManager();
Ogre::v1::MeshPtr meshV1 = Ogre::v1::MeshManager::getSingleton().load(
name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,
Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC);
bool halfPosition = true;
bool halfUVs = true;
bool useQTangents = true;
const Ogre::String meshNameV2 = (name + Ogre::String(" Imported"));
Ogre::MeshPtr v2Mesh = Ogre::MeshManager::getSingleton().createByImportingV1(
meshNameV2, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, meshV1.get(),
halfPosition, halfUVs, useQTangents);
meshV1->unload();
Ogre::Item* item = sceneManager->createItem(
meshNameV2, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,
Ogre::SCENE_DYNAMIC);
return item;
}
// V2 mesh loading
Ogre::Item* ogreLoadMesh(const char* name)
{
Ogre::SceneManager* sceneManager = ogreGetSceneManager();
Ogre::MeshPtr v2Mesh = Ogre::MeshManager::getSingleton().load(
name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Item* item = sceneManager->createItem(
name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, Ogre::SCENE_DYNAMIC);
return item;
}
Ogre::SceneNode* ogreNodeFromItem(Ogre::Item* meshHandle)
{
Ogre::SceneNode* newSceneNode = nullptr;
Ogre::SceneManager* sceneManager = ogreGetSceneManager();
Ogre::SceneNode* rootSceneNode = sceneManager->getRootSceneNode();
if (rootSceneNode)
{
Ogre::SceneNode* sceneNode = ((Ogre::SceneNode*)rootSceneNode->createChild());
if (sceneNode)
{
sceneNode->attachObject(meshHandle);
newSceneNode = sceneNode;
}
}
return newSceneNode;
}
// An example only: Create a directional light. Feel free to tear this function apart to make more
// programmable lights
Ogre::SceneNode* ogreCreateLight()
{
Ogre::SceneNode* newLightNode = nullptr;
Ogre::SceneManager* sceneManager = ogreGetSceneManager();
Ogre::SceneNode* rootSceneNode = sceneManager->getRootSceneNode();
if (rootSceneNode)
{
Ogre::Light* light = sceneManager->createLight();
Ogre::SceneNode* lightNode = ((Ogre::SceneNode*)rootSceneNode->createChild());
newLightNode = lightNode;
lightNode->attachObject(light);
light->setPowerScale(1.0f);
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(Ogre::Vector3(-1, -1, -1).normalisedCopy());
sceneManager->setAmbientLight((Ogre::ColourValue(0.3f, 0.5f, 0.7f) * 0.1f * 0.75f),
(Ogre::ColourValue(0.6f, 0.45f, 0.3f) * 0.065f * 0.75f),
((-light->getDirection()) + (Ogre::Vector3::UNIT_Y * 0.2f)));
}
return newLightNode;
}
// This is an example of the high-level material system. Copied largely from PBS Materials sample
// (and modified). Read https://ogrecave.github.io/ogre-next/api/2.2/hlms.html !
void ogreCreatePbsSpheres(Ogre::Root* root, Ogre::SceneManager* sceneManager)
{
int numSpheres = 0;
Ogre::HlmsManager* hlmsManager = root->getHlmsManager();
assert(dynamic_cast<Ogre::HlmsPbs*>(hlmsManager->getHlms(Ogre::HLMS_PBS)));
Ogre::HlmsPbs* hlmsPbs = static_cast<Ogre::HlmsPbs*>(hlmsManager->getHlms(Ogre::HLMS_PBS));
const int numX = 8;
const int numZ = 8;
const float armsLength = 1.f;
const float startX = (numX - 1) / 2.0f;
const float startZ = (numZ - 1) / 2.0f;
Ogre::TextureGpuManager* textureMgr = root->getRenderSystem()->getTextureGpuManager();
Ogre::SceneNode* rootSceneNode = sceneManager->getRootSceneNode();
// const Ogre::String meshNameV2 = "Sphere.mesh";
const Ogre::String meshNameV2 = "Suzanne.mesh";
{
Ogre::MeshPtr v2Mesh = Ogre::MeshManager::getSingleton().load(
meshNameV2, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
}
for (int x = 0; x < numX; ++x)
{
for (int z = 0; z < numZ; ++z)
{
Ogre::String datablockName = "Test" + Ogre::StringConverter::toString(numSpheres++);
Ogre::HlmsPbsDatablock* datablock = static_cast<Ogre::HlmsPbsDatablock*>(
hlmsPbs->createDatablock(datablockName, datablockName, Ogre::HlmsMacroblock(),
Ogre::HlmsBlendblock(), Ogre::HlmsParamVec()));
// Reflection texture. Uncomment once you've copied SaintPetersBasilica.dds to Materials/Textures
// {
// Ogre::TextureGpu* texture = textureMgr->createOrRetrieveTexture(
// "SaintPetersBasilica.dds", Ogre::GpuPageOutStrategy::Discard,
// Ogre::TextureFlags::PrefersLoadingFromFileAsSRGB, Ogre::TextureTypes::TypeCube,
// Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,
// Ogre::TextureFilter::TypeGenerateDefaultMipmaps);
// datablock->setTexture(Ogre::PBSM_REFLECTION, texture);
// }
datablock->setDiffuse(Ogre::Vector3(0.0f, 1.0f, 0.0f));
datablock->setRoughness(std::max(0.02f, x / std::max(1.0f, (float)(numX - 1))));
datablock->setFresnel(Ogre::Vector3(z / std::max(1.0f, (float)(numZ - 1))), false);
Ogre::Item* item = nullptr;
{
item = sceneManager->createItem(
meshNameV2, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,
Ogre::SCENE_DYNAMIC);
}
// Example using a .material (must be hlms) instead of using manual C++:
// item->setDatablock("MyMaterial");
item->setDatablock(datablock);
item->setVisibilityFlags(0x000000002);
Ogre::SceneNode* sceneNode = ((Ogre::SceneNode*)rootSceneNode->createChild());
if (!sceneNode)
return;
sceneNode->setPosition(
Ogre::Vector3(armsLength * x - startX, -3.0f, armsLength * z - startZ));
sceneNode->attachObject(item);
}
}
}
//
// main!
//
int main()
{
ogreInitialize();
Ogre::Item* monkeyMesh = ogreLoadMesh("Suzanne.mesh");
Ogre::SceneNode* monkeyNode = ogreNodeFromItem(monkeyMesh);
Ogre::SceneNode* lightNode = ogreCreateLight();
ogreCreatePbsSpheres(gOgreRoot, gSceneManager);
float x = 0.f;
float y = 0.f;
float z = 0.f;
while (true)
{
Ogre::WindowEventUtilities::messagePump();
if (g_ogre_window_should_quit)
break;
monkeyNode->setPosition(x, y, z);
x = (x + 0.01f);
if (!(ogreRenderFrame()))
{
// Something bad happened
break;
}
}
ogreShutdown();
return 0;
}