Название: Вывод текста в QGLWidget
Отправлено: __Heaven__ от Октябрь 07, 2014, 16:38
Привет друзья! Никак не пойму, каким образом нужно выводить текст поверх OpenGL. Имею QGLWidget. Пробовал QPainter - выдаёт чёрный или серый экран: C++ (Qt) void GLWidget::paintGL() { QPainter painter; painter.begin(this); painter.beginNativePainting(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); QMatrix4x4 modelViewProj = proj * modelView; program->setUniformValue("modelViewProj", modelViewProj); renderAxis3D(); painter.endNativePainting(); painter.end(); }
Как поступить?
Название: Re: Вывод текста в QGLWidget
Отправлено: Fregloin от Октябрь 08, 2014, 17:19
а разве нет там функции paint(..)?
Название: Re: Вывод текста в QGLWidget
Отправлено: __Heaven__ от Октябрь 08, 2014, 20:49
Да, вроде разобрался. painter сбрасывает много настроек, вроде бы некоторые даже не документированы, например, цвет очистки. Также, на сколько я понял, в присутствии painter виджет QGLWidget не любит autoSwap. Почему-то ещё происходит влияние на матрицы преобразований (вроде бы на них, точно не проверял, но геометрия смещается) В качестве простого примера удалось вывести нативно точку и с помощью painter надпись. Но при попытке внедрить в существующий код, написанный с использованием шейдеров, вышел пустой экран. В итоге решил нарисовать 3D подписи.
Название: Re: Вывод текста в QGLWidget
Отправлено: Igors от Октябрь 09, 2014, 07:52
А пример "overpainting" не котируется?
Название: Re: Вывод текста в QGLWidget
Отправлено: __Heaven__ от Октябрь 09, 2014, 09:04
я рассматривал hellogl_es2. Там вывод fps. Вот, он мне и дал пищу для ума. На простом примере у меня всё получилось. Внедрить в свой проект не удалось, так как мало пытался. Решил использовать 3D подписи. Я подписываю оси координат.
Название: Re: Вывод текста в QGLWidget
Отправлено: vulko от Октябрь 22, 2014, 14:35
Лучший способ по производительности, это отрисовка букв из текстуры. Плюсом - можно любой шрифт сделать. Слегка модифицированный код из интернета. Текстура во вложении. Там только нужные мне символы, при желании можно создать любую текстуры с любыми символами. #ifndef GL_FONT_H #define GL_FONT_H
#include <GL/gl.h>
#define BPP 4 // Byptes per pixel (32 bit = 4 bytes)
class TextureImage { public: TextureImage(); ~TextureImage();
void loadTGAImage(const char * filename); void flip(); bool isLoaded() { return isTextureLoaded; };
GLuint buildTexture();
private: bool isTextureLoaded = false; GLuint width; GLuint height; GLubyte* databuf; };
class oglFont { public: oglFont(); oglFont(GLuint init_m_width, GLuint init_m_height, GLuint init_c_width, GLuint init_c_height); void drawText(GLfloat w, GLfloat h, char * txt); GLuint getTextureID() { return textureId; };
private: TextureImage textureImage; GLuint textureId; GLint c_per_row; // bitmap setting GLuint m_width; GLuint m_height; // character settings GLuint c_width; GLuint c_height;
int getCharIndex(char *c); };
#endif // GL_FONT_H
#include "oglfont.h" #include <stdio.h> #include <string.h> #include <QDebug> #include <QCoreApplication>
TextureImage::TextureImage() : width(0), height(0), databuf(NULL) { }
TextureImage::~TextureImage() { if (databuf) delete[] databuf; }
void TextureImage::loadTGAImage(const char *filename) { FILE *file = NULL; GLubyte TGAheader[12] = {0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header GLubyte TGAcompare[12] = {0}; // Used To Compare TGA Header GLubyte header[6] = {0}; // First 6 Useful Bytes From The Header GLuint bytesPerPixel = 0; // Holds Number Of Bytes Per Pixel Used In The TGA File GLuint imageSize = 0; // Used To Store The Image Size When Setting Aside Ram GLuint bitsPerPixel = 0;
isTextureLoaded = false; if (!(file = fopen(filename, "rb"))) { qDebug() << "Error opening file " << filename; }
if ( fread( TGAcompare, 1, sizeof(TGAcompare), file ) != sizeof( TGAcompare ) || memcmp( TGAheader, TGAcompare, sizeof(TGAheader) ) != 0 || fread( header, 1, sizeof(header), file ) != sizeof( header ) ) { fclose(file); qDebug() << "TGA format error " << filename;
return; }
width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte) height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte) bitsPerPixel = header[4];
if( width <= 0 || height <= 0 || bitsPerPixel != 32 ) { fclose(file); qDebug() << "TGA format error " << filename;
return; }
if (databuf) delete[] databuf;
bytesPerPixel = bitsPerPixel / 8; imageSize = width * height * bytesPerPixel; databuf = new GLubyte[imageSize];
if ( fread(databuf, 1, imageSize, file) != imageSize ) { delete[] databuf; fclose(file); qDebug() << "TGA format error " << filename;
return; }
// Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) for(GLuint i = 0; i < imageSize; i += bytesPerPixel) { databuf[i] ^= databuf[i + 2]; databuf[i + 2] ^= databuf[i]; databuf[i] ^= databuf[i + 2]; } fclose(file);
isTextureLoaded = true; }
void TextureImage::flip() { for( int h = 0; h < height; h++ ) { for( int w = 0; w < width/2; w++ ) { int index_l = h * width * BPP + w * BPP; int index_r = h * width * BPP + BPP * (width - w); for( int d = 0; d < 4; d++ ) { databuf[index_l + d] ^= databuf[index_r + d]; databuf[index_r + d] ^= databuf[index_l + d]; databuf[index_l + d] ^= databuf[index_r + d]; } } } }
GLuint TextureImage::buildTexture() { if(!isTextureLoaded) { qDebug() << "glFont: BUILD TEXTURE FAILED!";
return 0; }
GLuint tex_id = 0; glGenTextures(1, &tex_id);
glBindTexture(GL_TEXTURE_2D, tex_id); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, databuf);
return tex_id; }
oglFont::oglFont() { // oglFont(256, 256, 19, 38); // init font }
oglFont::oglFont(GLuint init_m_width, GLuint init_m_height, GLuint init_c_width, GLuint init_c_height) : m_width(init_m_width), m_height(init_m_height), c_width(init_c_width), c_height(init_c_height) { c_per_row = m_width / c_width; if(!textureImage.isLoaded()) { QString texFile = QCoreApplication::applicationDirPath() + "/res/font.tga"; textureImage.loadTGAImage(texFile.toLocal8Bit()); textureId = textureImage.buildTexture(); } }
int oglFont::getCharIndex(char *c) { int retVal = -1; switch (c[0]) { case '0': retVal = 0; break; case '1': retVal = 1; break; case '2': retVal = 2; break; case '3': retVal = 3; break; case '4': retVal = 4; break; case '5': retVal = 5; break; case '6': retVal = 6; break; case '7': retVal = 7; break; case '8': retVal = 8; break; case '9': retVal = 9; break; case ',': case '.': retVal = 10; break; case '/': retVal = 11; break; case ' ': retVal = 42; break; }
return retVal; }
void oglFont::drawText(GLfloat cw, GLfloat ch, char *txt) { glBegin(GL_QUADS);
//character location and dimensions GLfloat cx = 0.0f; GLfloat cy = 0.0f;
//calculate how wide each character is in term of texture coords GLfloat dtx = float(c_width) / float(m_width); GLfloat dty = float(c_height) / float(m_height);
for (char * c = txt; *c != 0; c++, cx += cw) { int index = getCharIndex(c); int row = index / c_per_row; int col = index % c_per_row;
if (index < 0) { //qDebug() << "glFont: Character outside of font! char: " << c; }
// find the texture coords GLfloat tx = float(col * c_width) / float(m_width); GLfloat ty = float(row * c_height) / float(m_height);
glTexCoord2f(tx, ty); glVertex2f(cx, cy); glTexCoord2f(tx + dtx, ty); glVertex2f(cx + cw, cy); glTexCoord2f(tx + dtx, ty + dty); glVertex2f(cx + cw, cy + ch); glTexCoord2f(tx, ty + dty); glVertex2f(cx, cy + ch); } glEnd(); }
Собсно использование: glFont = new oglFont(256, 256, 20, 35); glFont->drawText(labelWidth, labelHeight, txt);
Название: Re: Вывод текста в QGLWidget
Отправлено: __Heaven__ от Апрель 01, 2015, 09:50
Ой. тему нужно перенести...
|