qt - Combination QQuickFramebufferObject+texturing+GridView doesn't show items when you scroll to them -
what i'm doing, in short:
- deriving
class myitemqquickframebufferobject. drawing simple textured triangle myitem. texture taken qml item. - wrapping
myiteminmyitemwrapper.qmlcomponent. oncomponent.oncompleted:, make delay , callmyitem.update() - i have scrollable (with mouse wheel)
gridviewofmyitemwrapperitems
the items in viewport show fine. when scroll down, items come viewport don't show @ all. show when hover them, since i've added test mousearea.onentered calls myitem.update(). i've observed 2 different systems different gpus.
i've tried enabling opengl debug logging testcase, prints no errors.
i've tried setting cachebuffer: number.max_safe_integer on gridview, no avail.
any ideas?
my code:
main.cpp:
#include <qqmlapplicationengine> #include <qguiapplication> #include "myitem.h" int main(int argc, char** argv) { qmlregistertype<myitem>("myitem", 1, 0, "myitem"); qguiapplication app(argc, argv); qqmlapplicationengine engine; engine.load(qurl(qstringliteral("qrc:/main.qml"))); return app.exec(); } myitem.cpp:
#include "myitem.h" #include <qopenglframebufferobject> #include <qsgtextureprovider> #include <qsgtexture> #include <qquickwindow> #include <qopenglbuffer> #include <qopenglshaderprogram> #include "mesh.h" class myitemrenderer : public qquickframebufferobject::renderer, protected qopenglfunctions { public: myitemrenderer() { initializeopenglfunctions(); m_program.addshaderfromsourcefile(qopenglshader::vertex, ":/flat.vert.glsl"); m_program.addshaderfromsourcefile(qopenglshader::fragment, ":/flat.frag.glsl"); m_program.bind(); m_program.bindattributelocation("apos", mesh::posattriblocation); m_program.link(); m_program.setuniformvalue("utex", 0); } void synchronize(qquickframebufferobject* qqfbo){ auto item = (myitem*)qqfbo; m_window = item->window(); m_tex = item->sourceitem()->textureprovider()->texture(); } qopenglframebufferobject *createframebufferobject(const qsize &size) { qopenglframebufferobjectformat format; format.setattachment(qopenglframebufferobject::combineddepthstencil); return new qopenglframebufferobject(size, format); } void render() { gldisable(gl_depth_test); glclearcolor(0.0, 0.0, 0.0, 0.0); glclear(gl_color_buffer_bit); m_program.bind(); m_mesh.vao.bind(); glactivetexture(gl_texture0); m_tex->bind(); gldrawarrays(gl_triangles, 0, 3); m_window->resetopenglstate(); } private: qquickwindow* m_window; mesh m_mesh; qsgtexture* m_tex; qopenglshaderprogram m_program; }; qquickframebufferobject::renderer *myitem::createrenderer() const { return new myitemrenderer(); } myitem.h:
#ifndef myitem_h #define myitem_h #include <qquickframebufferobject> #include "propertyhelper.h" // file http://syncor.blogspot.bg/2014/11/qt-auto-property.html class myitem : public qquickframebufferobject { q_object auto_property(qquickitem*, sourceitem) public: renderer *createrenderer() const; }; #endif mesh.h
#ifndef mesh_h #define mesh_h #include <qopenglfunctions> #include <qopenglvertexarrayobject> #include <qopenglbuffer> class mesh : protected qopenglfunctions { template<class t> int getnumbytes(std::vector<t> vec) { return vec.size() * sizeof(t); } public: mesh() : vertexposbuffer(qopenglbuffer::vertexbuffer) { initializeopenglfunctions(); std::vector<float> vertexposdata { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0 }; vao.create(); qopenglvertexarrayobject::binder binder(&vao); vertexposbuffer.create(); vertexposbuffer.bind(); vertexposbuffer.setusagepattern(qopenglbuffer::staticdraw); vertexposbuffer.allocate(vertexposdata.data(), getnumbytes(vertexposdata)); glenablevertexattribarray(posattriblocation); vertexposbuffer.bind(); glvertexattribpointer(posattriblocation, 2, gl_float, false, 0, 0); } qopenglbuffer vertexposbuffer; qopenglvertexarrayobject vao; static const int posattriblocation = 1; }; #endif // mesh_h main.qml:
import qtquick 2.5 import qtquick.window 2.2 window { visible: true id: window width: 700 height: 700 gridview { id: grid anchors.fill: parent cellwidth: 350 cellheight: 350 model: 20 delegate: myitemwrapper { } } } myitemwrapper.qml:
import qtquick 2.5 import myitem 1.0 item { width: grid.cellwidth height: grid.cellheight rectangle { id: texsource x: -10000 layer.enabled: true color: "red" width: 100 height: 100 } myitem { anchors.fill: parent id: myitem sourceitem: texsource } mousearea { id: mousearea hoverenabled: true anchors.fill: parent onentered: { myitem.update(); } } function connectsingleshot(sig, slot) { var f = function() { slot.apply(this, arguments) sig.disconnect(f) } sig.connect(f) } component.oncompleted: { connectsingleshot(window.afterrendering, function() { myitem.update(); }); } } flat.frag.glsl:
#version 150 in highp vec2 vtexcoord; out vec4 outputcolor; uniform sampler2d utex; void main() { outputcolor = texture(utex, vtexcoord); } flat.vert.glsl:
#version 150 in highp vec2 apos; out highp vec2 vtexcoord; void main() { gl_position = vec4(apos, 0.0, 1.0); vtexcoord = apos * .5 + .5; } i think problem related this older problem of mine. in mind, tried 2 things:
- reparent relevant items have parent
nullduringmyitem.update()line, reparent them back. intended avoid gl rendering being affected middleman component of gridview. result no items ever displayed, reason. - use
connectionsconnect onvisiblechanged signal of myitemwrapper, , of parent, , of it's parent's parents. in signal handler had console.log. never got executed.
i've traced qt code down point:
http://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickwindow.cpp?h=v5.9.1#n3148
here sets opacity=0 culled items. don't know how continue here though.
Comments
Post a Comment