我将重新发布what I posted on the OGRE forums:
我不确定在这里发帖或者在“在实践中使用OGRE”论坛是否更好,但我会试一试,因为这是主板上最常用的部分。
所以我正在为我自己的框架进行绑定,它在内部使用OGRE,我绑定了核心对象,并且大多数情况下它们工作正常(输入和窗口正常工作),但我有这个问题我无法到达底部 - Python应用程序的视口始终是黑色的(除了相机之外我没有其他对象,只是设置视口的背景颜色)。
奇怪的是 - C ++中的完全等效工作正常,但python绑定的代码却没有。日志中没有显示任何重要信息。
以下是我绑定对象的方法:
#include "boost/python.hpp"
#include "boost/exception/diagnostic_information.hpp"
#include "Demo.hpp"
#include "Demo.cpp"
#include "XMLLevelLoader.h"
void addResourceLocation(const Crimson::String& group, const Crimson::String& loc)
{
Ogre::ResourceGroupManager* resmgr = Ogre::ResourceGroupManager::getSingletonPtr();
resmgr->addResourceLocation(loc, "FileSystem", group);
}
void initResourceGroup(const Crimson::String& group)
{
Ogre::ResourceGroupManager* resmgr = Ogre::ResourceGroupManager::getSingletonPtr();
resmgr->initialiseResourceGroup(group);
}
class AppWrapper : public Crimson::Application, public boost::python::wrapper<Crimson::Application>
{
public:
void onKeyDown(const SDL_KeyboardEvent& e)
{
boost::python::override over = this->get_override("onKeyDown");
if (over)
over(e);
}
using Crimson::Application::mQuit;
};
BOOST_PYTHON_MODULE(PyEngine)
{
using namespace boost::python;
def("initResourceGroup", initResourceGroup);
def("addResourceLocation", addResourceLocation);
enum_<SDL_Scancode>("SDL_Scancode");
class_<Ogre::ColourValue>("Color", init<const float, const float, const float, const float>())
.def_readwrite("r", &Ogre::ColourValue::r)
.def_readwrite("g", &Ogre::ColourValue::g)
.def_readwrite("b", &Ogre::ColourValue::b)
.def_readwrite("a", &Ogre::ColourValue::a);
class_<Ogre::Viewport>("Viewport", init<Ogre::Camera* , Ogre::RenderTarget*, float, float, float, float, int>())
.def("setBackgroundColour", &Ogre::Viewport::setBackgroundColour);
class_<Crimson::WindowInfo>("WindowInfo")
.def_readonly("renderWnd", &Crimson::WindowInfo::renderWnd)
.def_readonly("sdlWnd", &Crimson::WindowInfo::sdlWnd)
.def("addViewport", &Crimson::WindowInfo::addViewport, return_value_policy<reference_existing_object>())
.def("getAspectRatio", &Crimson::WindowInfo::getAspectRatio)
.def("getWidth", &Crimson::WindowInfo::getWidth)
.def("getHeight", &Crimson::WindowInfo::getHeight);
class_<Crimson::Kernel>("Kernel")
.def("initialize", &Crimson::Kernel::initialize)
.def("createRenderWindow", &Crimson::Kernel::createRenderWindow, return_value_policy<reference_existing_object>())
.def("getWindowInfo", &Crimson::Kernel::getWindowInfo, return_value_policy<reference_existing_object>())
.def("destroy", &Crimson::Kernel::destroy)
.def("render", &Crimson::Kernel::render);
class_<Crimson::Actor>("Actor", init<Crimson::Level*, const Crimson::String&, Crimson::Actor*>())
.def("setPosition", static_cast<void(Crimson::Actor::*)(const Crimson::Vector3&)>(&Crimson::Actor::setPosition))
.def("getPosition", &Crimson::Actor::getPosition);
class_ <Crimson::Mesh, bases<Crimson::Actor>>("Mesh", init<Crimson::Level*, const Crimson::String&, const Crimson::String&, Crimson::Actor*>());
class_ <Crimson::Camera, bases<Crimson::Actor>>("Camera", init<Crimson::Level*, const Crimson::String&, Crimson::Actor*>())
.def("setAspectRatio", &Crimson::Camera::setAspectRatio);
class_<rapidxml::xml_node<>, boost::noncopyable>("xml_node", init<rapidxml::node_type>())
.def("first_node", &rapidxml::xml_node<>::first_node, return_value_policy<reference_existing_object>());
class_<rapidxml::xml_document<>, boost::noncopyable>("xml_document")
.def("first_node", &rapidxml::xml_document<>::first_node, return_value_policy<reference_existing_object>())
.def("parse", &rapidxml::xml_document<>::parse<0>);
class_<Crimson::Level>("Level", init<Crimson::Kernel*>())
.def("initialize", &Crimson::Level::initialize)
.def("destroy", &Crimson::Level::destroy)
.def("createActor", &Crimson::Level::createActor, return_value_policy<reference_existing_object>())
.def("createMesh", &Crimson::Level::createMesh, return_value_policy<reference_existing_object>())
.def("createCamera", &Crimson::Level::createCamera, return_value_policy<reference_existing_object>());
class_<Crimson::XMLLevelLoader>("XMLLevelLoader", init<Crimson::String>())
.def("load", &Crimson::XMLLevelLoader::load)
.def("loadFileAsString", &Crimson::XMLLevelLoader::loadFileAsString)
.def("loadResources", &Crimson::XMLLevelLoader::loadResources)
.staticmethod("loadFileAsString")
.staticmethod("loadResources");
class_<AppWrapper, boost::noncopyable>("Application")
.def("initialize", &Crimson::Application::initialize)
.def("destroy", &Crimson::Application::destroy)
.def("onKeyDown", &Crimson::Application::onKeyDown)
.def("start", &Crimson::Application::start)
.def("updateGraphics", &Crimson::Application::updateGraphics)
.def("updateInput", &Crimson::Application::updateInput)
.def("isRunning", &Crimson::Application::isRunning)
.def("quit", &Crimson::Application::quit)
.def("getKernel", &Crimson::Application::getKernel, return_value_policy<reference_existing_object>());
class_<SDL_Keysym>("SDL_Keysym")
.def_readonly("mod", &SDL_Keysym::mod)
.def_readonly("scancode", &SDL_Keysym::scancode);
class_<SDL_KeyboardEvent>("SDL_KeyboardEvent")
.def_readonly("keysym", &SDL_KeyboardEvent::keysym);
class_<Ogre::Vector3>("Vector3", init<const float, const float, const float>())
.def_readwrite("x", &Ogre::Vector3::x)
.def_readwrite("y", &Ogre::Vector3::y)
.def_readwrite("z", &Ogre::Vector3::z);
}
Python代码(空白视口):
import sys
from PyEngine import *
# Class definition
class TestPythonApp(Application):
def initialize(self):
Application.initialize(self)
mLevel = Level(self.getKernel())
mLevel.initialize()
mCamera = mLevel.createCamera("test", None)
vp = self.getKernel().getWindowInfo().addViewport(mCamera)
vp.setBackgroundColour(Color(0.8, 0, 0, 1))
def start(self):
while self.isRunning():
self.updateInput()
self.updateGraphics(1)
mLevel = None
mCamera = None
# /Class definition
# Script execution
app = TestPythonApp()
app.initialize()
app.start()
app.destroy()
C ++等价物(彩色视口):
- 标题
#ifndef PYAPP_HPP
#define PYAPP_HPP
#include "Application.h"
#include "XMLLevelLoader.h"
class PythonApp : public Crimson::Application
{
public:
bool initialize();
void start();
protected:
Crimson::Camera* mCamera;
Crimson::Level* mLevel;
};
#endif
-- Source:
bool PythonApp::initialize()
{
Application::initialize();
mLevel = new Crimson::Level(mKernel);
mLevel->initialize();
mCamera = mLevel->createCamera("cam");
Ogre::Viewport* vp = mKernel->getWindowInfo()->addViewport(mCamera);
vp->setBackgroundColour(Ogre::ColourValue(0.7f, 0.8f, 0.7f));
return true;
}
void PythonApp::start()
{
while (isRunning())
{
updateInput();
updateGraphics(1);
}
}
int main(int argc, char* argv[])
{
PythonApp game;
game.initialize();
game.start();
game.destroy();
return 0;
}
我做了检查 - mBackColor
(在 Ogre :: Viewport 中)通过Python正确设置,所以这不是问题。
此外,如果我将渲染循环放在initialize()
函数中,Python代码可以正常工作,但如果它不在其中,则不行。因此,我感觉这是一个上下文问题(当解释器退出初始化函数时,可能会损坏数据。
这是奇怪的Python代码:
import sys
from PyEngine import *
# Class definition
class TestPythonApp(Application):
def initialize(self):
Application.initialize(self)
mLevel = Level(self.getKernel())
mLevel.initialize()
mCamera = mLevel.createCamera("test", None)
vp = self.getKernel().getWindowInfo().addViewport(mCamera)
vp.setBackgroundColour(Color(0.8, 0, 0, 1))
self.start() # Moved line app.start() to here.
def start(self):
while self.isRunning():
self.updateInput()
self.updateGraphics(1)
mLevel = None
mCamera = None
# /Class definition
# Script execution
app = TestPythonApp()
app.initialize()
#app.start() # This moved up to initialize makes it work
app.destroy()
- 关于我的框架的一些信息:内核包含和调用Ogre::Root
,mLevel
包含一个场景管理器,mCamera
是一个普通的OGRE摄像头,只是通过我自己的API包装易用性WindowInfo是另一个处理窗口设置的包装类(在OGRE和SDL之间),我只需在renderOneFrame()
函数中调用updateGraphics(delta)
。
那么我错误的是,与C ++调用具有相同调用的python代码导致了不同的结果?
答案 0 :(得分:0)
好的,所以在设置了很多断点后,我发现当解释器退出函数initialize()
时,它会销毁mLevel
和mCamera
对象,因为(我是Python的新手,我是)我忘了在Python中自我/这并不暗示,因此我的对象因Ogre::SceneManager
的破坏而被破坏(删除mLevel
时)。
更新(工作)代码:
import sys
from PyEngine import *
# Class definition
class TestPythonApp(Application):
def initialize(self):
Application.initialize(self)
self.mLevel = Level(self.getKernel())
self.mLevel.initialize()
self.mCamera = self.mLevel.createCamera("test", None)
self.mViewport = self.getKernel().getWindowInfo().addViewport(self.mCamera)
self.mViewport.setBackgroundColour(Color(0.8, 0, 0, 1))
print("Object: %s, of size: %d" % (self.mViewport, sys.getsizeof(self.mViewport)))
#self.start();
def start(self):
while self.isRunning():
self.updateInput()
self.updateGraphics(1)
mLevel = None
mViewport = None
mCamera = None
# /Class definition
# Script execution
app = TestPythonApp()
print("Initing");
app.initialize()
print("Object: %s, of size: %d" % (app.mViewport, sys.getsizeof(app.mViewport)))
app.start() # This moved up to initialize makes it work
app.destroy()