Я использую это для рендеринга текста в QGLWidget.
QGLWidget::renderText(x, y, z, text, font)
Строка отображается на глубине ~0,5 (получается с помощью glReadPixel()).
Однако в моем случае он должен быть ближе к ~0,9. Когда я конвертирую координаты x, y, z в координаты экрана с текущими матрицами, я также нахожу результат ~ 0,9.
Почему такая разница? Это заставляет текст всегда появляться впереди.
Я создал простой проект QT в Visual Studio, чтобы воспроизвести проблему. Он рисует зеленый квадрат с текстом впереди и позади квадрата. Оба текста выглядят перед квадратом. А глубину пикселя можно прочитать по наведению мышки.
Я использую Qt версии 5.5, созданную для 64-битной платформы.
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 up 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 up model view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5, // eye
0,0,0, // look at
0,1,0); // up
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// draw a 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 some blue text behind the square
QFont font;
font.setPointSize(20);
glColor4f(0,0,1,1);
renderText(-2,-0.5,-1, "BEHIND_BEHIND_BEHIND_BEHIND", font);
// render some red text in front of the 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 for QT origin is top left while OpenGL origin is 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);
}
рендертексттест.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
рендертексттест.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 from reading UI file 'rendertexttest.ui'
**
** Created by: Qt User Interface Compiler version 5.3.1
**
** WARNING! All changes made in this file will be 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