Hello guys!
I need your help. I didnt good at OpenGL and maybe I asked not in approriate topic. But I have some problem with using SFML in pair with Qt, and maybe you can point me the way where problem happens.
Screenshot with problem in attachment.
Here code of my main.cpp file:
main.cpp
#include "MyQmlGUIWin.h"
#include "SFMLItem.h"
#include "SFMLEngine.h"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <QQmlContext>
#include <QApplication>
#include <QDebug>
int main(int argc, char **argv)
{
QApplication *app;
app = new QApplication(argc, argv);
SFMLEngine *engine;
engine = new SFMLEngine();
sf::Font font;
font.loadFromFile("data/fonts/DejaVuSans.ttf");
sf::Text text;
text.setFont(font);
text.setString("Hello world");
text.setCharacterSize(24);
text.setColor(sf::Color::Red);
text.setStyle(sf::Text::Bold | sf::Text::Underlined);
sf::CircleShape shape(50);
shape.setFillColor(sf::Color(150, 50, 250));
shape.setRadius(40);
shape.setPosition(100, 100);
// set a 10-pixel wide orange outline
shape.setOutlineThickness(10);
shape.setOutlineColor(sf::Color(250, 150, 100));
engine->clear();
engine->draw(text);
engine->draw(shape);
engine->display();
engine->saveOnHDD();
int returnCode;
//returnCode = app->exec();
delete app;
return 0;
}
SFMLEngine is custom sf::RenderTarget. And here is code.
SFMLEngine.h
#ifndef SFMLEngine_H
#define SFMLEngine_H
#include <SFML/Graphics/RenderTarget.hpp>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObjectFormat>
#include <QSGTexture>
#include <QQuickWindow>
#include <QOffscreenSurface>
class SFMLEngine: public QObject, public sf::RenderTarget
{
Q_OBJECT
private:
QOffscreenSurface *m_surface;
QOpenGLContext *m_sfmlContext;
QOpenGLFramebufferObject *m_fbo;
public:
SFMLEngine();
~SFMLEngine();
GLuint getTextureID();
void saveOnHDD();
void display();
protected:
virtual sf::Vector2u getSize() const;
virtual bool activate(bool par_active);
};
#endif
SFMLEngine.cpp
#include "SFMLEngine.h"
#include "SFMLItem.h"
#include "SFMLEngine.h"
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QDebug>
SFMLEngine::SFMLEngine(): QObject(0)
{
qmlRegisterType<SFMLItem>("SFML", 1, 0, "SFMLItem");
qmlRegisterType<SFMLEngine>("SFML", 1, 0, "SFMLEngine");
QSurfaceFormat surfaceFormat;
surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
m_surface = new QOffscreenSurface();
m_surface->create();
m_sfmlContext = new QOpenGLContext();
m_sfmlContext->setFormat(surfaceFormat);
if(m_sfmlContext->create() == false)
qDebug()<<Q_FUNC_INFO<<"Shit happens with QOpenGLContext create";
if(m_sfmlContext->makeCurrent(m_surface) == false)
qDebug()<<Q_FUNC_INFO<<"Shit happens with QOpenGLContext makeCurrent";
QOpenGLFramebufferObjectFormat fboFormat;
//fboFormat.setSamples(16);
fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
m_fbo = new QOpenGLFramebufferObject(800, 600, fboFormat);
if(m_fbo->bind() == false)
qDebug()<<Q_FUNC_INFO<<"Shit happens with QOpenGLFramebufferObject bind";
}
SFMLEngine::~SFMLEngine()
{
delete m_sfmlContext;
}
GLuint SFMLEngine::getTextureID()
{
return m_fbo->texture();
}
void SFMLEngine::saveOnHDD()
{
m_fbo->toImage().save("test.png");
}
void SFMLEngine::display()
{
m_sfmlContext->swapBuffers(m_surface);
}
sf::Vector2u SFMLEngine::getSize() const
{
qDebug()<<"SFMLEngine::getSize";
sf::Vector2u size;
size.x = 800;
size.y = 600;
return size;
}
bool SFMLEngine::activate(bool par_active)
{
qDebug()<<"SFMLEngine::activate"<<par_active;
bool returnValue;
returnValue = false;
if(par_active)
{
qDebug()<<"SFMLEngine::activateSFMLContent";
returnValue = m_sfmlContext->makeCurrent(m_surface);
if(!m_fbo->isBound())
{
qDebug()<<"SFMLEngine::m_fbo->bind()";
m_fbo->bind();
}
}
else
{
qDebug()<<"SFMLEngine::doneSFMLContent";
m_fbo->release();
m_sfmlContext->doneCurrent();
}
return returnValue;
}
Here what I get at output:
QML debugging is enabled. Only use this in a safe environment.
SFMLEngine::activate true
SFMLEngine::activateSFMLContent
SFMLEngine::activate true
SFMLEngine::activateSFMLContent
SFMLEngine::activate true
SFMLEngine::activateSFMLContent
SFMLEngine::getSize
SFMLEngine::getSize
SFMLEngine::getSize
SFMLEngine::activate true
SFMLEngine::activateSFMLContent
SFMLEngine::activate true
SFMLEngine::activateSFMLContent
Entire project you can find at https://github.com/Hronom/GraphicSystem this code from GraphicSystemTest4. I am try to make some integration of SFML in QML. I am using latest SFML version from repo and Qt 5.2. My OS is lubuntu 13.10
Hello guys!
After several hours of working I found that I dont call method sf::RenderTarget::initialize(); in my class. So I call this method and some glitches are gone. But bug with text remained. I add new screenshot in attachment.
So here new code:
main.cpp
#include "MyQmlGUIWin.h"
#include "SFMLItem.h"
#include "SFMLEngine.h"
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <QQmlContext>
#include <QApplication>
#include <QDebug>
int main(int argc, char **argv)
{
QApplication *app;
app = new QApplication(argc, argv);
SFMLEngine *engine;
engine = new SFMLEngine();
sf::Font font;
font.loadFromFile("data/fonts/DejaVuSans.ttf");
sf::Text text;
text.setFont(font);
text.setString("Hello world");
text.setCharacterSize(24);
text.setColor(sf::Color::Red);
text.setStyle(sf::Text::Bold | sf::Text::Underlined);
sf::CircleShape shape(50);
shape.setFillColor(sf::Color(150, 50, 250));
shape.setRadius(40);
shape.setPosition(100, 100);
// set a 10-pixel wide orange outline
shape.setOutlineThickness(10);
shape.setOutlineColor(sf::Color(250, 150, 100));
engine->clear();
engine->draw(text);
engine->draw(shape);
engine->display();
engine->saveOnHDD();
int returnCode;
//returnCode = app->exec();
delete app;
return 0;
}
SFMLEngine is custom sf::RenderTarget. And here is code.
SFMLEngine.h
#ifndef SFMLEngine_H
#define SFMLEngine_H
#include <SFML/Graphics/RenderTarget.hpp>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObjectFormat>
#include <QSGTexture>
#include <QQuickWindow>
#include <QOffscreenSurface>
class SFMLEngine: public QObject, public sf::RenderTarget
{
Q_OBJECT
private:
QOffscreenSurface *m_surface;
QOpenGLContext *m_sfmlContext;
QOpenGLFramebufferObject *m_fbo;
sf::Vector2u m_size;
public:
SFMLEngine();
~SFMLEngine();
GLuint getTextureID();
void saveOnHDD();
void display();
protected:
virtual sf::Vector2u getSize() const;
virtual bool activate(bool par_active);
};
#endif
SFMLEngine.cpp
#include "SFMLEngine.h"
#include "SFMLItem.h"
#include "SFMLEngine.h"
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QDebug>
#include <QOpenGLTexture>
SFMLEngine::SFMLEngine(): QObject(0), RenderTarget()
{
qDebug()<<"SFMLEngine::SFMLEngine";
qmlRegisterType<SFMLItem>("SFML", 1, 0, "SFMLItem");
qmlRegisterType<SFMLEngine>("SFML", 1, 0, "SFMLEngine");
QSurfaceFormat surfaceFormat;
surfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
surfaceFormat.setProfile(QSurfaceFormat::CompatibilityProfile);
m_surface = new QOffscreenSurface();
m_surface->setFormat(surfaceFormat);
m_surface->create();
m_sfmlContext = new QOpenGLContext();
m_sfmlContext->setFormat(surfaceFormat);
if(m_sfmlContext->create() == false)
qDebug()<<Q_FUNC_INFO<<"Shit happens with QOpenGLContext create";
if(m_sfmlContext->makeCurrent(m_surface) == false)
qDebug()<<Q_FUNC_INFO<<"Shit happens with QOpenGLContext makeCurrent";
QOpenGLFramebufferObjectFormat fboFormat;
fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
fboFormat.setTextureTarget(GL_TEXTURE_2D);
fboFormat.setInternalTextureFormat(GL_RGBA8);
m_size.x = 800;
m_size.y = 600;
m_fbo = new QOpenGLFramebufferObject(m_size.x, m_size.y, fboFormat);
if(m_fbo->bind() == false)
qDebug()<<Q_FUNC_INFO<<"Shit happens with QOpenGLFramebufferObject bind";
sf::RenderTarget::initialize();
}
SFMLEngine::~SFMLEngine()
{
qDebug()<<"SFMLEngine::~SFMLEngine";
delete m_sfmlContext;
}
GLuint SFMLEngine::getTextureID()
{
qDebug()<<"SFMLEngine::getTextureID";
return m_fbo->texture();
}
void SFMLEngine::saveOnHDD()
{
qDebug()<<"SFMLEngine::saveOnHDD";
m_fbo->toImage().save("test.png", "PNG", 100);
}
void SFMLEngine::display()
{
qDebug()<<"SFMLEngine::display";
m_sfmlContext->swapBuffers(m_surface);
}
sf::Vector2u SFMLEngine::getSize() const
{
qDebug()<<"SFMLEngine::getSize";
return m_size;
}
bool SFMLEngine::activate(bool par_active)
{
qDebug()<<"SFMLEngine::activate";
bool returnValue;
returnValue = false;
if(par_active)
{
qDebug()<<"activate SFML content";
QOpenGLContext *currentContext;
currentContext = QOpenGLContext::currentContext();
if(currentContext != 0)
currentContext->doneCurrent();
returnValue = m_sfmlContext->makeCurrent(m_surface);
if(!m_fbo->isBound())
{
qDebug()<<"m_fbo->bind()";
m_fbo->bind();
}
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
else
{
qDebug()<<"done SFML content";
m_fbo->release();
m_sfmlContext->doneCurrent();
}
return returnValue;
}
Here what I get at output:
QML debugging is enabled. Only use this in a safe environment.
SFMLEngine::SFMLEngine
SFMLEngine::getSize
SFMLEngine::getSize
SFMLEngine::activate
activate SFML content
SFMLEngine::activate
activate SFML content
SFMLEngine::activate
activate SFML content
SFMLEngine::getSize
SFMLEngine::getSize
SFMLEngine::getSize
SFMLEngine::activate
activate SFML content
SFMLEngine::activate
activate SFML content
SFMLEngine::display
SFMLEngine::saveOnHDD
I call draw method in main:
engine->clear();
engine->draw(text);
engine->draw(shape);
engine->display();
And I recieve 5 calls of method bool SFMLEngine::activate(bool par_active) with par_active=true I didnt understand is this right or not. And I didnt understand what can do bug in text like on screenshot in attachment.