Чертеж SFML 2 не работает при подключении к OGRE

Сейчас я работаю над подключением OGRE и SFML. SFML следует использовать для 2D-рисования, сетевых материалов и ввода. OGRE предназначен для трехмерной графики.

В настоящее время все это работает в Linux.

Что работает: Подключение OGRE и SFML. Сначала я создаю окно рендеринга SFML, затем беру дескриптор этого окна и передаю его окну рендеринга OGRE при его создании. Теперь я могу использовать события SFML. Не тестировал сетевой материал, но я уверен, что это тоже сработает.

Что не работает: Рисование в окне SFML.

Случай 1: SFML и OGRE не связаны. OGRE не имеет дескриптора окна SFML и имеет собственное окно. SFML по-прежнему не может рисовать в собственном окне! Основной цикл выполняется максимум 3 раза, а затем просто останавливается. Больше ничего не происходит. Через несколько секунд (около 20) я получаю нарушение доступа к памяти, и программа завершается.

Случай 2: SFML и OGRE связаны. Происходит то же самое: основной цикл выполняется точно 53 раза, ничего не отрисовывается, а затем программа останавливается с сообщением терминала «прервано» (на самом деле это «Abgebrochen», потому что оно на немецком языке).

Странное поведение также происходит, когда я позволяю SFML рисовать в sf :: RenderTexture вместо sfml_window.

Вот мой код:

#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 (); команды, забыл те раньше!


person feider    schedule 09.01.2015    source источник
comment
Вы знаете, что OGRE объединяет свою собственную систему графического интерфейса, верно?   -  person Bartek Banachewicz    schedule 09.01.2015
comment
да, но SFML имеет гораздо более мощные возможности 2D. Использование OGRE для 2D-материалов было бы очень неудобным, потому что 2D-элементов слишком много для функций OGRE.   -  person feider    schedule 09.01.2015


Ответы (1)


Не совсем ответ, но слишком длинный для комментария:

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

Вы уверены, что в следующей строке можно передать адрес объекта, который вы уничтожаете, с помощью &parameters?

person nvoigt    schedule 09.01.2015
comment
Да, это нормально. Значения параметров устанавливаются в функции createRenderWindow, после этого параметры списка не используются. - person feider; 09.01.2015
comment
@nvoigt Ogre использует здесь указатель, потому что параметр является необязательным (можно использовать nullptr). - person Daerst; 09.01.2015
comment
@feider, хорошо, тогда просто игнорируй это :) - person nvoigt; 09.01.2015