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

Popular posts from this blog

python - Healpy: From Data to Healpix map -

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -