qt - QGLWidget renders text at incorrect depth -
i use render text in qglwidget
qglwidget::rendertext(x, y, z, text, font)
the string rendered @ depth of ~0.5 (obtained via glreadpixel()).
however, in case should closer ~0.9. when convert x,y,z coords screen coords current matrices find result of ~0.9.
why such difference? makes text appear in front.
i created simple qt project in visual studio reproduce issue. draws green square text in front , behind square. both text in front of square. , depth of pixel can read hovering mouse.
i use qt version 5.5 built 64bit platform.
myglwidget.h
#include <qglwidget> #include <qmouseevent> class myglwidget : public qglwidget { q_object private: float _depth; public: myglwidget(qwidget * parent = 0); virtual ~myglwidget(); virtual void initializegl(); virtual void paintgl(); void mousemoveevent(qmouseevent * event); signals: void depthread(float); };
myglwidget.cpp
#include "myglwidget.h" #include <gl/glu.h> #include <qfont> myglwidget::myglwidget(qwidget * parent) : qglwidget(parent) { } myglwidget::~myglwidget() { } void myglwidget::initializegl() { } void myglwidget::paintgl() { // set projection glmatrixmode(gl_projection); glloadidentity(); float width = this->width(); float height = this->height(); glviewport(0, 0, width, height); gluperspective(45, width / height, 1, 100); // set model view glmatrixmode(gl_modelview); glloadidentity(); glulookat(0,0,5, // eye 0,0,0, // @ 0,1,0); // glclear(gl_color_buffer_bit | gl_depth_buffer_bit); glenable(gl_depth_test); // draw green square glcolor4f(0,1,0,1); glbegin(gl_quads); glvertex3f(-1,-1,0); glvertex3f(1,-1,0); glvertex3f(1,1,0); glvertex3f(-1,1,0); glend(); // render blue text behind square qfont font; font.setpointsize(20); glcolor4f(0,0,1,1); rendertext(-2,-0.5,-1, "behind_behind_behind_behind", font); // render red text in front of square glcolor4f(1,0,0,1); rendertext(-2,0.5,+1, "in_front_in_front_in_front_i", font); } void myglwidget::mousemoveevent(qmouseevent * event) { int x = event->x(); // flip y qt origin top left while opengl origin bottom left int y = this->height() - event->y(); // read pixel depth glreadpixels(x, y, 1, 1, gl_depth_component, gl_float, &_depth); // update ui emit depthread(_depth); }
rendertexttest.h
#ifndef rendertexttest_h #define rendertexttest_h #include <qtwidgets/qmainwindow> #include "ui_rendertexttest.h" #include "myglwidget.h" class rendertexttest : public qmainwindow { q_object public: rendertexttest(qwidget *parent = 0); ~rendertexttest(); public slots: void ondepthread(float depth); private: ui::rendertexttestclass ui; myglwidget * _glwidget; }; #endif // rendertexttest_h
rendertexttest.cpp
#include "rendertexttest.h" rendertexttest::rendertexttest(qwidget *parent) : qmainwindow(parent) { ui.setupui(this); _glwidget = new myglwidget(this); _glwidget->setmousetracking(true); qobject::connect(_glwidget, signal(depthread(float)), this, slot(ondepthread(float))); ui._mainlayout->addwidget(_glwidget); } rendertexttest::~rendertexttest() { } void rendertexttest::ondepthread(float depth) { ui._lbldepth->settext(qstring::number(depth)); }
ui_rendertexttest.h
/******************************************************************************** ** form generated reading ui file 'rendertexttest.ui' ** ** created by: qt user interface compiler version 5.3.1 ** ** warning! changes made in file lost when recompiling ui file! ********************************************************************************/ #ifndef ui_rendertexttest_h #define ui_rendertexttest_h #include <qtcore/qvariant> #include <qtwidgets/qaction> #include <qtwidgets/qapplication> #include <qtwidgets/qbuttongroup> #include <qtwidgets/qheaderview> #include <qtwidgets/qlabel> #include <qtwidgets/qmainwindow> #include <qtwidgets/qvboxlayout> #include <qtwidgets/qwidget> qt_begin_namespace class ui_rendertexttestclass { public: qwidget *centralwidget; qwidget *verticallayoutwidget; qvboxlayout *_mainlayout; qlabel *_lbldepth; void setupui(qmainwindow *rendertexttestclass) { if (rendertexttestclass->objectname().isempty()) rendertexttestclass->setobjectname(qstringliteral("rendertexttestclass")); rendertexttestclass->resize(600, 438); centralwidget = new qwidget(rendertexttestclass); centralwidget->setobjectname(qstringliteral("centralwidget")); verticallayoutwidget = new qwidget(centralwidget); verticallayoutwidget->setobjectname(qstringliteral("verticallayoutwidget")); verticallayoutwidget->setgeometry(qrect(9, 9, 581, 381)); _mainlayout = new qvboxlayout(verticallayoutwidget); _mainlayout->setspacing(6); _mainlayout->setcontentsmargins(11, 11, 11, 11); _mainlayout->setobjectname(qstringliteral("_mainlayout")); _mainlayout->setsizeconstraint(qlayout::setdefaultconstraint); _mainlayout->setcontentsmargins(0, 0, 0, 0); _lbldepth = new qlabel(centralwidget); _lbldepth->setobjectname(qstringliteral("_lbldepth")); _lbldepth->setgeometry(qrect(10, 410, 581, 16)); rendertexttestclass->setcentralwidget(centralwidget); retranslateui(rendertexttestclass); qmetaobject::connectslotsbyname(rendertexttestclass); } // setupui void retranslateui(qmainwindow *rendertexttestclass) { rendertexttestclass->setwindowtitle(qapplication::translate("rendertexttestclass", "rendertexttest", 0)); _lbldepth->settext(qapplication::translate("rendertexttestclass", "depth:", 0)); } // retranslateui }; namespace ui { class rendertexttestclass: public ui_rendertexttestclass {}; } // namespace ui qt_end_namespace #endif // ui_rendertexttest_h
there might 3 issues
1- target depth computed correctly in qglwidget::rendertext() , passed paintengine via settranslatez(). vertex shader not set value directly in vertex clipped coordinates. instead translate value.
2- sign of translatez seems incorrect. explain why depth of text pixels increases when text comes closer.
3- seems clipped coordinates [0, 1] mapped range [0.5 , 1] yet did not see call gldepthrange() in qt's source.
if change code of qglslcomplexgeometrypositiononlyvertexshader in qglengineshadersource_p.h following, fixes problem.
static const char* const qglslcomplexgeometrypositiononlyvertexshader = "\n\ uniform highp mat3 matrix; \n\ uniform highp float translatez; \n\ attribute highp vec2 vertexcoordsarray; \n\ void setposition(void) \n\ { \n\ vec3 v = matrix * vec3(vertexcoordsarray, 1.0); \n\ v.z = (-translatez - 0.5f) * 2.0f; \n\ gl_position = vec4(v.xyz, 1.0);\n\ } \n";
Comments
Post a Comment