Russian Qt Forum
Ноябрь 22, 2024, 12:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Вывод текста в QGLWidget  (Прочитано 7308 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Октябрь 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();
}
 

Как поступить?
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #1 : Октябрь 08, 2014, 17:19 »

а разве нет там функции paint(..)?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Октябрь 08, 2014, 20:49 »

Да, вроде разобрался.
painter сбрасывает много настроек, вроде бы некоторые даже не документированы, например, цвет очистки.
Также, на сколько я понял, в присутствии painter виджет QGLWidget не любит autoSwap.
Почему-то ещё происходит влияние на матрицы преобразований (вроде бы на них, точно не проверял, но геометрия смещается)
В качестве простого примера удалось вывести нативно точку и с помощью painter надпись. Но при попытке внедрить в существующий код, написанный с использованием шейдеров, вышел пустой экран.
В итоге решил нарисовать 3D подписи.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Октябрь 09, 2014, 07:52 »

А пример "overpainting" не котируется?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #4 : Октябрь 09, 2014, 09:04 »

я рассматривал hellogl_es2. Там вывод fps.
Вот, он мне и дал пищу для ума.
На простом примере у меня всё получилось. Внедрить в свой проект не удалось, так как мало пытался. Решил использовать 3D подписи.
Я подписываю оси координат.
Записан
vulko
Гость
« Ответ #5 : Октябрь 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);
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #6 : Апрель 01, 2015, 09:50 »

Ой. тему нужно перенести...
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.074 секунд. Запросов: 22.