Horde3D http://www.horde3d.org/forums/ |
|
Knight example not displaying correctly in a Qt QWindow http://www.horde3d.org/forums/viewtopic.php?f=2&t=2276 |
Page 1 of 1 |
Author: | cornbibies [ 05.03.2015, 15:47 ] |
Post subject: | Knight example not displaying correctly in a Qt QWindow |
Hi everyone, first off - congratulations on this engine. I was kinda skepictal when I decided to switch from Ogre3d a few days ago and was surprised how easy and accessible Horde3D is. I really want to use it which makes this problem a very frustrating one. I have an existing Qt Application with lots of code and other dependencies that make it impossible for me to switch to any other framework. Following the Qt "OpenGL Window Example" (http://doc.qt.io/qt-5/qtgui-openglwindow-example.html), integrating the Knight-example from the Horde3D source was straightforward and painless. But then an I realized, that the offical example binary (using glfw) looked a lot better than what was displayed in the QWindow ![]() Here is a comparison: Original Display (source example using glfw) ![]() QWindow Display ![]() There is an existing thread on Stackoverflow reporting the same problem 3 years ago, but it is still unresolved: http://stackoverflow.com/questions/8594805/horde3d-particle-system-not-rendering-in-qt-opengl I have attached the complete source at the bottom - just like in the SO post above, it is the exact same code used in the Knight example but with a bit of Qt framework around. My machine is running Ubuntu 14.10, I am using the current NVIDIA driver version 311.11, Qt 5.4 and the latest Horde3D, freshly built from the Github repo. Here are some things I tried out already, but didn't work:
So right now, I am ready to give up ![]() Does anybody here have a working Qt-integration of Horde3D that looks as it should? Any help would be greatly appreciated. Cheers and thank you, - Clemens For reference, here is the complete code of the Qt Knight example application: KnightExample.pro Code: QT += core gui widgets CONFIG += c++11 TARGET = KnightExample TEMPLATE = app SOURCES += main.cpp \ hordewindow.cpp HEADERS += \ hordewindow.h INCLUDEPATH += >>>HARDCODED PATH TO:/Horde3D/Horde3D/Bindings/C++/ LIBS += -L>>>HARDCODED PATH TO:/Horde3D/libs -lHorde3D -lHorde3DUtils # I created the libs folder for convenience LIBS += -L/usr/lib/nvidia-331-updates/ # fixes a linker bug in Ubuntu 14.10 main.cpp Code: #include "horde3dwindow.h" #include <QApplication> int main(int argc, char *argv[]) { // doesn't change anything... QApplication::setAttribute(Qt::AA_UseDesktopOpenGL); // changes the context version, but nothing visually... QSurfaceFormat format; format.setVersion(4,3); format.setProfile(QSurfaceFormat::CompatibilityProfile); QSurfaceFormat::setDefaultFormat(format); QApplication a(argc, argv); Horde3DWindow w; w.setAnimating(true); w.show(); w.resize(1024, 576); // same as the example return a.exec(); } horde3dwindow.h Code: #ifndef HORDE3DWINDOW_H #define HORDE3DWINDOW_H #include <sstream> #include <string> #include <QWindow> #include "Horde3D.h" class QOpenGLContext; class Horde3DWindow : public QWindow { Q_OBJECT public: explicit Horde3DWindow(QWindow *parent = nullptr); ~Horde3DWindow(); void initialize(); void render(); void setAnimating(bool animating); public slots: void renderNow(); void renderLater(); protected: bool event(QEvent *event) override; void exposeEvent(QExposeEvent *event) override; private: QOpenGLContext *m_context; bool m_isUpdateRequested; bool m_isAnimated; private: // knight example members float _x, _y, _z, _rx, _ry; // Viewer position and orientation float _velocity; // Velocity for movement float _curFPS; std::stringstream _text; int _statMode; int _freezeMode; bool _debugViewMode, _wireframeMode; float _animTime, _weight; // Engine objects H3DRes _fontMatRes, _panelMatRes; H3DRes _pipeRes, _logoMatRes, _hdrPipeRes, _forwardPipeRes; H3DNode _cam, _knight, _particleSys; std::string _contentDir; }; #endif // HORDE3DWINDOW_H horde3dwindow.cpp Code: #include "horde3dwindow.h"
#include <math.h> #include <iomanip> #include <QCoreApplication> #include <QDebug> #include <QOpenGLContext> #include <QSurfaceFormat> #include <Horde3DUtils.h> Horde3DWindow::Horde3DWindow(QWindow *parent) : QWindow(parent) , m_context(nullptr) , m_isUpdateRequested(false) , m_isAnimated(false) { // indicate that the window is to be used for OpenGL rendering setSurfaceType(QWindow::OpenGLSurface); // knight example initializations _x = 5; _y = 3; _z = 19; _rx = 7; _ry = 15; _velocity = 10.0f; _curFPS = 30; _statMode = 1; _freezeMode = 0; _debugViewMode = false; _wireframeMode = false; _animTime = 0; _weight = 1.0f; _cam = 0; _contentDir = >>>HARDCODED PATH TO:"/Horde3D/Horde3D/Binaries/Content"; } Horde3DWindow::~Horde3DWindow() { // Release engine h3dutDumpMessages(); h3dRelease(); } // This is an exact copy of the original example's source void Horde3DWindow::initialize() { h3dInit(); // Set options h3dSetOption( H3DOptions::LoadTextures, 1 ); h3dSetOption( H3DOptions::TexCompression, 0 ); h3dSetOption( H3DOptions::FastAnimation, 0 ); h3dSetOption( H3DOptions::MaxAnisotropy, 4 ); h3dSetOption( H3DOptions::ShadowMapSize, 2048 ); // Add resources // Pipelines _hdrPipeRes = h3dAddResource( H3DResTypes::Pipeline, "pipelines/hdr.pipeline.xml", 0 ); _forwardPipeRes = h3dAddResource( H3DResTypes::Pipeline, "pipelines/forward.pipeline.xml", 0 ); // Overlays _fontMatRes = h3dAddResource( H3DResTypes::Material, "overlays/font.material.xml", 0 ); _panelMatRes = h3dAddResource( H3DResTypes::Material, "overlays/panel.material.xml", 0 ); _logoMatRes = h3dAddResource( H3DResTypes::Material, "overlays/logo.material.xml", 0 ); // Environment H3DRes envRes = h3dAddResource( H3DResTypes::SceneGraph, "models/sphere/sphere.scene.xml", 0 ); // Knight H3DRes knightRes = h3dAddResource( H3DResTypes::SceneGraph, "models/knight/knight.scene.xml", 0 ); H3DRes knightAnim1Res = h3dAddResource( H3DResTypes::Animation, "animations/knight_order.anim", 0 ); H3DRes knightAnim2Res = h3dAddResource( H3DResTypes::Animation, "animations/knight_attack.anim", 0 ); // Particle system H3DRes particleSysRes = h3dAddResource( H3DResTypes::SceneGraph, "particles/particleSys1/particleSys1.scene.xml", 0 ); // Load resources h3dutLoadResourcesFromDisk( _contentDir.c_str() ); // Add scene nodes // Add camera _cam = h3dAddCameraNode( H3DRootNode, "Camera", _hdrPipeRes ); //h3dSetNodeParamI( _cam, H3DCamera::OccCullingI, 1 ); // Add environment H3DNode env = h3dAddNodes( H3DRootNode, envRes ); h3dSetNodeTransform( env, 0, -20, 0, 0, 0, 0, 20, 20, 20 ); // Add knight _knight = h3dAddNodes( H3DRootNode, knightRes ); h3dSetNodeTransform( _knight, 0, 0, 0, 0, 180, 0, 0.1f, 0.1f, 0.1f ); h3dSetupModelAnimStage( _knight, 0, knightAnim1Res, 0, "", false ); h3dSetupModelAnimStage( _knight, 1, knightAnim2Res, 0, "", false ); // Attach particle system to hand joint h3dFindNodes( _knight, "Bip01_R_Hand", H3DNodeTypes::Joint ); H3DNode hand = h3dGetNodeFindResult( 0 ); _particleSys = h3dAddNodes( hand, particleSysRes ); h3dSetNodeTransform( _particleSys, 0, 40, 0, 90, 0, 0, 1, 1, 1 ); // Add light source H3DNode light = h3dAddLightNode( H3DRootNode, "Light1", 0, "LIGHTING", "SHADOWMAP" ); h3dSetNodeTransform( light, 0, 15, 10, -60, 0, 0, 1, 1, 1 ); h3dSetNodeParamF( light, H3DLight::RadiusF, 0, 30 ); h3dSetNodeParamF( light, H3DLight::FovF, 0, 90 ); h3dSetNodeParamI( light, H3DLight::ShadowMapCountI, 1 ); h3dSetNodeParamF( light, H3DLight::ShadowMapBiasF, 0, 0.01f ); h3dSetNodeParamF( light, H3DLight::ColorF3, 0, 1.0f ); h3dSetNodeParamF( light, H3DLight::ColorF3, 1, 0.8f ); h3dSetNodeParamF( light, H3DLight::ColorF3, 2, 0.7f ); h3dSetNodeParamF( light, H3DLight::ColorMultiplierF, 0, 1.0f ); // Customize post processing effects H3DNode matRes = h3dFindResource( H3DResTypes::Material, "pipelines/postHDR.material.xml" ); h3dSetMaterialUniform( matRes, "hdrExposure", 2.5f, 0, 0, 0 ); h3dSetMaterialUniform( matRes, "hdrBrightThres", 0.5f, 0, 0, 0 ); h3dSetMaterialUniform( matRes, "hdrBrightOffset", 0.08f, 0, 0, 0 ); } // This is an (almost) exact copy of the original example's source void Horde3DWindow::render() { _curFPS = 30; // just hardcode the fps for now h3dSetOption( H3DOptions::DebugViewMode, _debugViewMode ? 1.0f : 0.0f ); h3dSetOption( H3DOptions::WireframeMode, _wireframeMode ? 1.0f : 0.0f ); if( !_freezeMode ) { _animTime += 1.0f / _curFPS; // Do animation blending h3dSetModelAnimParams( _knight, 0, _animTime * 24.0f, _weight ); h3dSetModelAnimParams( _knight, 1, _animTime * 24.0f, 1.0f - _weight ); h3dUpdateModel( _knight, H3DModelUpdateFlags::Animation | H3DModelUpdateFlags::Geometry ); // Animate particle systems (several emitters in a group node) unsigned int cnt = h3dFindNodes( _particleSys, "", H3DNodeTypes::Emitter ); for( unsigned int i = 0; i < cnt; ++i ) h3dUpdateEmitter( h3dGetNodeFindResult( i ), 1.0f / _curFPS ); } // Set camera parameters h3dSetNodeTransform( _cam, _x, _y, _z, _rx ,_ry, 0, 1, 1, 1 ); // Show stats h3dutShowFrameStats( _fontMatRes, _panelMatRes, _statMode ); if( _statMode > 0 ) { // Display weight _text.str( "" ); _text << std::fixed << std::setprecision( 2 ) << "Weight: " << _weight; h3dutShowText( _text.str().c_str(), 0.03f, 0.24f, 0.026f, 1, 1, 1, _fontMatRes ); } // Show logo const float ww = (float)h3dGetNodeParamI( _cam, H3DCamera::ViewportWidthI ) / (float)h3dGetNodeParamI( _cam, H3DCamera::ViewportHeightI ); const float ovLogo[] = { ww-0.4f, 0.8f, 0, 1, ww-0.4f, 1, 0, 0, ww, 1, 1, 0, ww, 0.8f, 1, 1 }; h3dShowOverlays( ovLogo, 4, 1.f, 1.f, 1.f, 1.f, _logoMatRes, 0 ); // Render scene h3dRender( _cam ); // Finish rendering of frame h3dFinalizeFrame(); // Remove all overlays h3dClearOverlays(); // Write all messages to log file h3dutDumpMessages(); } void Horde3DWindow::setAnimating(bool animating) { m_isAnimated = animating; if (m_isAnimated) { renderLater(); } } void Horde3DWindow::renderNow() { // return early if the Window is not visible on the screen if (!isExposed()){ return; } // create a new context, if there is none yet... if (!m_context) { // create the Context with the same QSurfaceFormat as the Horde3DWindow m_context = new QOpenGLContext(this); m_context->setFormat(requestedFormat()); qDebug() << m_context->format(); // print out the context format .. I think this is were the problem is? m_context->create(); m_context->makeCurrent(this); initialize(); // ...otherwise just make it current } else { m_context->makeCurrent(this); } // render the Window and make its contents visible render(); m_context->swapBuffers(this); // if the window is animated, automatically trigger an update on the next vertical refresh if (m_isAnimated) { renderLater(); } } void Horde3DWindow::renderLater() { // only post one request at a time if (!m_isUpdateRequested) { m_isUpdateRequested = true; QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); } } bool Horde3DWindow::event(QEvent *event) { // handle update requests by rendering... if(event->type() == QEvent::UpdateRequest){ m_isUpdateRequested = false; renderNow(); return true; } // ... and pass everything else up to QWindow return QWindow::event(event); } void Horde3DWindow::exposeEvent(QExposeEvent *event) { Q_UNUSED(event); if (isExposed()){ renderNow(); } } |
Author: | Volker [ 05.03.2015, 21:47 ] |
Post subject: | Re: Knight example not displaying correctly in a Qt QWindow |
Maybe Qt modifies the OpenGL states. See also this thread viewtopic.php?f=1&t=1734&p=9104 |
Author: | cornbibies [ 05.03.2015, 23:32 ] |
Post subject: | Re: Knight example not displaying correctly in a Qt QWindow |
Hi Volker, thanks for the quick answer! I took a look at the link, but sadly it didn't help. I also dug a little further and found your old post and example of the Knight in Qt here: http://www.horde3d.org/forums/viewtopic.php?p=6355#p6355 but it produces the same result as what I have been getting so far. I am pretty convinced that the problem lies not with the code but with some internal Qt strangeness. Perhaps the library-loading issue that is discussed the the above thread? Anyway, for now the quality of the output is sufficient as I am mainly interested in displaying animation and not visual fidelity. Let's hope that whatever is going wrong does not manifest itself in other, more destructive ways ![]() |
Page 1 of 1 | All times are UTC + 1 hour |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |