Russian Qt Forum

Qt => OpenGL => Тема начата: Igors от Апрель 25, 2015, 07:57



Название: Опять вывод текста
Отправлено: Igors от Апрель 25, 2015, 07:57
Добрый день

Рисую текст на QOpenGLWidget с помощью QPainter::drawText. В какой-то момент вместо нормального текста прут кракозябры (см аттач), от которых уже не избавиться до перезапуска приложения. Перебрал варианты drawText и проверил входной текст - ничего не дало.

Самое мерзкое - отсутствие каких-то зацепок. Придется наугад отключать куски в приложении (типа "может это влияет"). Если знаете секреты - поделитесь

Спасибо


Название: Re: Опять вывод текста
Отправлено: Racheengel от Июнь 08, 2015, 14:11
QPainter::drawText это, боюсь, моветон. Текстурой надо кракозябры давить...

Мы это примерно так решаем (спасибо добрым индусам):

Код:
void CQt3dText::draw(QGLPainter *painter, const QString& _str, const QVector3D& coords, const QFont& _font, const QPen& _pen, const Qt::Alignment& align)
{
if (_str.isEmpty())
return;

QFontMetrics fm(_font);
QRect rect = fm.boundingRect(_str); // text bounding box
rect.adjust(0, 0, 1, 1);

QImage image(rect.size(), QImage::Format_ARGB32);
image.fill(0); // set to transparent

// Draw the text on an image
QPainter p2d(&image);
p2d.setFont(_font);
p2d.setPen(_pen);
p2d.drawText(0, 0, rect.width(), rect.height(), Qt::AlignCenter, _str);
p2d.end();

// Get viewport
GLint view[4];
glGetIntegerv(GL_VIEWPORT, view);

// Convert the object coordinate to screen coordinate
GLdouble winx, winy, winz; // the screen coordinate of the object
QMatrix4x4 model = painter->modelViewMatrix().top();
QMatrix4x4 proj = painter->projectionMatrix().top();

GLdouble modelMatrix[16];
for (int i = 0; i < 16; i++)
modelMatrix[i] = model.data()[i];

GLdouble projMatrix[16];
for (int i = 0; i < 16; i++)
projMatrix[i] = proj.data()[i];

gluProject(coords.x(), coords.y(), coords.z(),
modelMatrix, projMatrix, view,
&winx, &winy, &winz);

// Define the font rectangle
int x = (int) winx, y = (int) winy;

if (align & Qt::AlignLeft){
x -= rect.width();
}
if (align & Qt::AlignTop){
y -= rect.height();
}
if (align & Qt::AlignHCenter){
x -= rect.width() / 2;
}
if (align & Qt::AlignVCenter){
y -= rect.height() / 2;
}

QVector2DArray vertices;
vertices.append(x, y);
vertices.append(x, y + rect.height());
vertices.append(x + rect.width(), y + rect.height());
vertices.append(x + rect.width(), y);

// Texture coordinates
QVector2DArray texCoord;
texCoord.append(0.0f, 0.0f);
texCoord.append(0.0f, 1.0f);
texCoord.append(1.0f, 1.0f);
texCoord.append(1.0f, 0.0f);

// Map the image to texture
QGLTexture2D texture;
texture.setImage(image);

// Set projection matrix stack
painter->modelViewMatrix().push();
painter->modelViewMatrix().setToIdentity();

// Use ortho projection to draw the text
QMatrix4x4 projm;
projm.ortho(view[0], view[2], view[1], view[3], 0, 1);

painter->projectionMatrix().push();
painter->projectionMatrix() = projm;

// Enable blend to make the background transparency of the text
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
painter->clearAttributes();
painter->setStandardEffect(QGL::FlatReplaceTexture2D);
texture.bind();
painter->setVertexAttribute(QGL::Position, vertices);
painter->setVertexAttribute(QGL::TextureCoord0, texCoord);
painter->draw(QGL::TriangleFan, 4);
painter->setStandardEffect (QGL::FlatColor);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);

// Restore the matrix stack
painter->projectionMatrix().pop();
painter->modelViewMatrix().pop();
}

Такой методой можно не только текст, но и вообще все что угодно выводить поверх GL-контекста.


Название: Re: Опять вывод текста
Отправлено: Igors от Июнь 08, 2015, 15:48
QPainter::drawText это, боюсь, моветон. Текстурой надо кракозябры давить...

Мы это примерно так решаем (спасибо добрым индусам):
Круто (червона рута). Но все-таки одна строчка painter.drawText как-то проще выглядит :) Или уже painter.drawImage или glWritePixels.


Название: Re: Опять вывод текста
Отправлено: Racheengel от Июнь 08, 2015, 15:59
Дык CQt3dText::draw(...) - это тоже одна строчка :)
А с glWritePixels мутотени еще больше будет, чем с текстурой.


Название: Re: Опять вывод текста
Отправлено: Igors от Июнь 08, 2015, 16:21
Дык CQt3dText::draw(...) - это тоже одна строчка :)
Зато какая  :)

А с glWritePixels мутотени еще больше будет, чем с текстурой.
Не, там довольно компактно получается - кстати в этом месте и сидела та зараза что калечила текст


Название: Re: Опять вывод текста
Отправлено: Racheengel от Июнь 08, 2015, 16:57
а производительность?


Название: Re: Опять вывод текста
Отправлено: Igors от Июнь 09, 2015, 13:03
а производительность?
В смысле glWritePixels? Так это пара рядовых вызовов glXXX она никак не может быть медленнее чем эпопея с созданием текстуры


Название: Re: Опять вывод текста
Отправлено: Racheengel от Июнь 10, 2015, 00:40
хм, ну это смотря как драйвер все это представляет... я лично не тестил, но народ на низкую скорость жаловался...к тому же насколько я понял, эта функция начиная с GL 3.2 больше не поддерживается