1
Graphics / Re: SFML + Qt + render to QImage problem
« on: December 14, 2013, 01:03:48 pm »
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
SFMLEngine is custom sf::RenderTarget. And here is code.
SFMLEngine.h
SFMLEngine.cpp
Here what I get at output:
I call draw method in main:
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.
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;
}
#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
#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;
}
#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
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();
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.