2015-01-09 7 views
0

현재 OGRE 및 SFML 연결에 착수 중입니다. 2D 도면, 네트워크 항목 및 입력에 SFML을 사용해야합니다. OGRE는 3D 그래픽 용입니다.OGRE와 연결된 경우 SFML 2 도면이 작동하지 않습니다.

현재 모든 것은 Linux에 있습니다.

작동 방식 : OGRE와 SFML 연결. 먼저 SFML 렌더링 창을 만든 다음이 창 핸들을 가져 와서 OGRE 렌더링 창에 제공합니다. 지금 SFML 이벤트를 사용할 수 있습니다. 네트워크 물건을 테스트하지 않았지만 이것이 효과가있을 것이라고 확신합니다.

작동하지 않는 항목 : SFML 창에서 그리기.

사례 1 : SFML과 OGRE가 연결되지 않았습니다. OGRE에는 SFML 창 핸들이없고 고유 한 창이 있습니다. SFML은 여전히 ​​자체 창을 그릴 수 없습니다! 메인 루프는 최대 3 회 실행 한 다음 중지합니다. 더 이상은 일어나지 않습니다. 몇 초 후 (약 20 정도) 메모리 액세스 위반이 발생하고 프로그램이 종료됩니다.

사례 2 : SFML과 OGRE가 연결됩니다. 비슷한 일이 일어난다. 메인 루프는 53 번 실행되고 아무 것도 그려지지 않고 터미널 메시지 "aborted"로 멈춘다. (독일어로되어 있기 때문에 실제로 "Abgebrochen")

이상한 행동이 일어난다. SFML에서 sfml_window 대신 sf :: RenderTexture를 그리게 만들었습니다.

#include <SFML/Graphics.hpp> 
#include <SFML/Window.hpp> 
#include <SFML/System.hpp> 
#include <iostream> 
#include <OGRE/Ogre.h> 
#include <vector> 
#include <stdio.h> 

int main(int argc, char * argv[]) 
{ 

if(argc == 1) 
    return -1; 


// start with "1" and you get 1 window, start with "0" and you get two 
bool together = atoi(argv[1]); 


// create the SFML window 
sf::RenderWindow sfml_window(sf::VideoMode(800, 600), "test"); 
sf::WindowHandle sfml_system_handle = sfml_window.getSystemHandle(); 
sfml_window.setVerticalSyncEnabled(true); 
std::cout<<sfml_system_handle<<std::endl; 


// init ogre 
Ogre::Root * ogre_root = new Ogre::Root("", "", ""); 
std::vector<Ogre::String> plugins; 
plugins.push_back("/usr/lib/x86_64-linux-gnu/OGRE-1.8.0/RenderSystem_GL"); 

for(auto p : plugins) 
{ 
    ogre_root->loadPlugin(p); 
} 

const Ogre::RenderSystemList& render_systems = ogre_root->getAvailableRenderers(); 

if(render_systems.size() == 0) 
{ 
    std::cerr<<"no rendersystem found"<<std::endl; 
    return -1; 

} 

Ogre::RenderSystem * render_system = render_systems[0]; 
ogre_root->setRenderSystem(render_system); 

ogre_root->initialise(false, "", ""); 



// create the ogre window 
Ogre::RenderWindow * ogre_window= NULL; 
{ 
    Ogre::NameValuePairList parameters; 
    parameters["FSAA"] = "0"; 
    parameters["vsync"] = "true"; 

    // if started with 1, connect the windows 
    if(together) parameters["externalWindowHandle"] = std::to_string(sfml_system_handle); 
    ogre_window = ogre_root->createRenderWindow("ogre window", 800, 600, false, &parameters); 
} 


// ogre stuff 
Ogre::SceneManager * scene = ogre_root->createSceneManager(Ogre::ST_GENERIC, "Scene"); 
Ogre::SceneNode * root_node = scene->getRootSceneNode(); 
Ogre::Camera * cam = scene->createCamera("Cam"); 
Ogre::SceneNode * cam_node = root_node->createChildSceneNode("cam_node"); 
cam_node->attachObject(cam); 

Ogre::Viewport * vp = ogre_window->addViewport(cam); 
vp->setAutoUpdated(false); 
vp->setBackgroundColour(Ogre::ColourValue(0, 1, 1)); 

ogre_window->setAutoUpdated(false); 
ogre_root->clearEventTimes(); 

//sfml image loading 
sf::Texture ring; 
std::cout<<"ring loading: "<<ring.loadFromFile("ring.png")<<std::endl; 

sf::Sprite sprite; 
sprite.setTexture(ring); 


// main loop 
int counter = 0; 
while(!ogre_window->isClosed() && sfml_window.isOpen()) 
{ 
    std::cout<<counter<<std::endl; 
    counter++; 
    std::cout<<"a"<<std::endl; 

    // sfml events 
    sf::Event event; 
    while(sfml_window.pollEvent(event)) 
    { 
     if(event.type == sf::Event::Closed) 
     { 
      sfml_window.close(); 
     } 
    } 
    std::cout<<"b"<<std::endl; 


    std::cout<<"c"<<std::endl; 
    ogre_root->renderOneFrame(); 


    std::cout<<"d"<<std::endl; 



    // here the strange behaviour happens 
    // if this line (draw) isn't present, everything works 
    sfml_window.pushGLStates(); 
    sfml_window.draw(sprite); 
    sfml_window.popGLStates(); 


    vp->update(); 
    std::cout<<"e"<<std::endl; 
    sfml_window.display(); 

    // only needs to be done for separated windows 
    // sfml display updates otherwise, both use double buffering 
    if(!together) ogre_window->update(true); 
} 
return 0; 
} 

도움말 정말 감사하겠습니다 :

여기 내 코드입니다.

편집 : pushGLStates(); 및 popGLStates(); 명령, 그 전에 잊어 버렸어!

+0

OGRE는 자체 GUI 시스템을 번들로 제공합니다. –

+0

예.하지만 SFML에는 훨씬 강력한 2D 기능이 있습니다. OGRE 기능을위한 2D 재료가 너무 많기 때문에 2D 재료로 OGRE를 사용하는 것은 매우 불편할 것입니다. – feider

답변

0

별로,하지만 너무 오래 코멘트에 대한 답변 : 당신은 당신이 &parameters와 바로 다음 라인을 여기 파괴하는 객체의 주소를 전달하는 괜찮아 있는지

ogre_window = ogre_root->createRenderWindow("ogre window", 800, 600, false, &parameters); 

있습니까?

+0

예, 괜찮습니다. 매개 변수의 값은 createRenderWindow 함수에서 설정되며, 그 후에 "parameters"목록은 사용되지 않습니다. – feider

+0

@nvoigt 오우거는 매개 변수가 선택적이기 때문에 여기에서 포인터를 사용합니다 ('nullptr'이 사용될 수 있습니다). – Daerst

+0

@feider 좋아, 그럼 그냥 무시해. :) – nvoigt