Hello.
I'm pretty sure it is related to the driver that changed.
To what i see i'd rather think that the solution may come from config of the driver, or from inside ogre close to the gpu.
Here is a little sample based on Samples/Tutorials/Bootstrap.cpp
It creates a scene with a walking boy.
As a user, pressing 'm' key steps the animation.
Pressing 'f' as "go Far" makes the camera to be far => showing empty scene
Pressing 'c' as "come Close" makes the camera back to face the walking boy.
For Mesa driver or nvidia 610.57.04 this application works fine :
when it start it shows the boy, pressing m shows the animation (step by step), pressing 'F' and 'C' do what is expected (show nothing, show the boy in the state it was left).
For new version of the driver 615.71.09 it's NOK :
when it starts the aspect of the boy is "no animation applied",
when pressing 'm' it shows correct animation,
then pressing f shows nothing (normal)
then pressing c shows boy "no animation applied".
--> as if animation shader had been unloaded ?!
Code: Select all
#include <Ogre.h>
#include <OgreApplicationContext.h>
int main(int argc, char* argv[])
{
(void)(argc);
(void)(argv);
const auto data_filepath = "!!SOME_PATH_TO_SOURCE!!/scene_data";
const auto conf_dir = "!!SOME_PATH_TO_THE_BIN!!";
const auto scene_res_group_name = "SceneData";
const auto character_mesh = "man1-tshirt02.005.mesh"; // cf. mesh
const auto walk_anim_name = "walk"; // cf. skeleton
setenv("OGRE_CONFIG_DIR", conf_dir, 1);
// Required in linux fedora context to grant use of nvidia gpu (would use mesa if not)
setenv("__NV_PRIME_RENDER_OFFLOAD", "1", 1);
setenv("__GLX_VENDOR_LIBRARY_NAME", "nvidia", 1);
// Create context
OgreBites::ApplicationContext ctx("TestApp");
ctx.initApp();
Ogre::Root* root = ctx.getRoot();
Ogre::SceneManager* scnMgr = root->createSceneManager();
Ogre::ResourceGroupManager& resMgr = Ogre::ResourceGroupManager::getSingleton();
resMgr.createResourceGroup(scene_res_group_name);
resMgr.addResourceLocation(data_filepath, "FileSystem", scene_res_group_name);
resMgr.initialiseResourceGroup(scene_res_group_name);
resMgr.loadResourceGroup(scene_res_group_name);
Ogre::RTShader::ShaderGenerator* shadergen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
shadergen->addSceneManager(scnMgr);
// Create light
Ogre::Light* light = scnMgr->createLight("MainLight");
Ogre::SceneNode* lightNode = scnMgr->getRootSceneNode()->createChildSceneNode();
lightNode->setPosition(15, 10, 0);
lightNode->attachObject(light);
// Create camera
Ogre::Camera* cam = scnMgr->createCamera("MainCam");
cam->setNearClipDistance(5);
cam->setFarClipDistance(25);
cam->setAutoAspectRatio(true);
cam->setFOVy(Ogre::Radian(0.3f));
Ogre::SceneNode* camNode = scnMgr->getRootSceneNode()->createChildSceneNode();
camNode->setPosition(15, 0, 0);
camNode->lookAt(Ogre::Vector3(0, 0, 0), Ogre::Node::TS_PARENT);
camNode->attachObject(cam);
auto* viewport = ctx.getRenderWindow()->addViewport(cam);
viewport->setBackgroundColour(Ogre::ColourValue::Blue);
viewport->setMaterialScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
// Create "walking" character
Ogre::Entity* ent = scnMgr->createEntity(
Ogre::MeshManager::getSingleton().load(character_mesh, scene_res_group_name));
Ogre::SceneNode* boyNode = scnMgr->getRootSceneNode()->createChildSceneNode();
boyNode->attachObject(ent);
Ogre::AnimationState* walkAnim = nullptr;
auto* allAnims = ent->getAllAnimationStates();
if (allAnims) {
for (auto it : allAnims->getAnimationStates()) {
auto* anim = it.second;
anim->setLoop(true);
anim->setEnabled(false);
anim->setTimePosition(0.0f);
if (it.first == walk_anim_name) {
walkAnim = anim;
}
}
}
boyNode->setPosition(0, 0, 0);
if (walkAnim != nullptr) {
walkAnim->setEnabled(true);
}
// Handle user actions (keys)
class KeyHandler : public OgreBites::InputListener
{
public:
Ogre::SceneNode* m_camNode = nullptr;
Ogre::AnimationState* m_walkAnim = nullptr;
bool keyPressed(const OgreBites::KeyboardEvent& evt) override
{
if (evt.keysym.sym == OgreBites::SDLK_ESCAPE) {
Ogre::Root::getSingleton().queueEndRendering();
} else if (evt.keysym.sym == 'f') {
// go far from scene
if (m_camNode != nullptr) {
m_camNode->setPosition(3015, 0, 0);
}
} else if (evt.keysym.sym == 'c') {
// come close to scene
if (m_camNode != nullptr) {
m_camNode->setPosition(15, 0, 0);
}
} else if (evt.keysym.sym == 'm') {
// animate the walking boy (step into animation)
if (m_walkAnim != nullptr) {
m_walkAnim->addTime(0.1f);
}
}
return true;
}
};
KeyHandler keyHandler;
ctx.addInputListener(&keyHandler);
keyHandler.m_camNode = camNode;
keyHandler.m_walkAnim = walkAnim;
// Play
ctx.getRoot()->startRendering();
ctx.closeApp();
return 0;
}
I think that any mesh with animation skeleton can work (i'll try to use one from the samples)
Incorrect initial state could be tackled playing with setTimePosition and/or enable/disable , force update ..., although i'm not really happy with doing applicative modifications to handle such problems.
But incorrect aspect after being far from camera is a big issue and much more difficult to handle from the application perspective : need to listen to 'far from camera' state, or listen to "unload" if it's really what this is...