Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QImage + OpenGL


Автор: hawk3500 13.4.2013, 14:19
Доброго времени суток.
Нужен пример простого вывода QImage через opengl.
Не могу найти простой пример такого вывода.
Если у кого есть поделитесь....
Заранее благодарен.
С уважением,
hawk3500

Автор: Amp 13.4.2013, 16:07
У QGLWidget есть статический методо convertToGLFormat, который принимает на вход QImage и выдает тоже QImage пригодный к использованию в GL. Потом стандартно через glTexImage2D загружаешь текстуру в видеопамять, передавая последним аргументом сконвертированный QImage::bits().

Автор: hawk3500 13.4.2013, 21:00
Не могли бы привести пример такого класса 
с initializeGL() и paintGL()....у меня явно что то не так(((
Заранее благодарен

Автор: Amp 13.4.2013, 22:15
Пример есть в стандартных примерах - opengl/hellogl

Автор: hawk3500 14.4.2013, 11:12
Прочитав мануалы , я понял что вроде нет необходимости для вывода простого двумерного изображения обращаться к методам  void initializeGL(); и
        void paintGL();. Достаточно просто унаследовать свой класс у QGLWidget   и вся работа с выводом изображения будет организованна аппаратнно.
Так ли это?
И второе что мне не ясно.
У QImage есть метод scaled, который занимает много времени , нет ли у него аппаратного аналога?

Добавлено через 3 минуты и 4 секунды
http://symmetrica.net/qtworld/qtvideo.pdf

Автор: Amp 14.4.2013, 17:36
Да, можно выводить в QPainter в методе paintEvent() наследника QGLWidget-а - смотри пример opengl\2dpainting. Тогда initializeGL и paintGL не понадобятся. А можно просто в QPainter без QGLWidget-а рисовать, применяя матрицы трансорфмации. Еще вопрос, что быстрее - аппаратное ускорение QPainter в Qt не блещет производительностью. Впрочем есть варианты в виде QGraphicsView и QML, с ними может быть даже проще будет работать.

Автор: hawk3500 14.4.2013, 19:44
Спасибо за ответы)
Сделал программу которая просто выводит изображение(файл) но при изменении размеров окна изображение начинает рисоваться в нескольких местах и вообще возникают какието не заданные мной линии.
Код

#include "paint_gl.h"

Paint_GL::Paint_GL(QWidget *parent)
    : QGLWidget(parent)
{
     wid=500; hid=500; // начальный размер окна
     resize(wid,hid);
     IMG = new QImage("C:\\qt.png");
     Time= new QTimer(this);
     bool K=  connect(Time,SIGNAL(timeout(void)),this,SLOT(TimeOut_l(void)));
     Time->start(100);
}

Paint_GL::~Paint_GL()
{

}
void Paint_GL::resizeGL(int nWidth, int nHeight)
{
    wid=nWidth;
    hid=nHeight;
    //////////////////////////////////////
    glViewport (0, 0, wid, hid);
    // Использовать матрицу Projection
    glMatrixMode(GL_PROJECTION);
    // Загрузить единичную матрицу преобразований
    glLoadIdentity();
    // В зависимости от размеров окна создаем параллельную проекцию
    glOrtho (0,1,1,0,0,1);
    // задаем область просмотра
    //update();
}
void Paint_GL::TimeOut_l(void)
{
    
    update();
}

void Paint_GL::paintGL()
{
    Zeta=QGLWidget::convertToGLFormat(*IMG);
/*
    if(IMG->height()>hid)
    {
        glRasterPos2d(0,hid);
    }
    else
    {
        glRasterPos2d(0,IMG->height());
    }
    */
    glPixelZoom(1,1);
    glDrawPixels(IMG->width(),IMG->height(), GL_RGBA,GL_UNSIGNED_BYTE,Zeta.bits());
}


#include <QTimer>
#include <Windows.h>

class Paint_GL : public QGLWidget
{
    Q_OBJECT

public:
    Paint_GL(QWidget *parent = 0);
    ~Paint_GL();
    int wid,hid;
    QImage *IMG;
    QImage Zeta;
    GLuint Texture[2];
    QTimer *Time;
    DWORD SubTime;
protected:
    /*
    void initializeGL();
    void paintGL();
    void resizeGL(int nWidth, int nHeight);
    */
    void resizeGL(int nWidth, int nHeight);
    //void resizeEvent(QResizeEvent* EVA);
    //void paintEvent(QPaintEvent* EVA);
    void paintGL();
    public slots:
        void TimeOut_l(void);
};

#endif // PAINT_GL_H




Если не сложно подскажите что может быть не так...
И ещё не совсем ясно , если прорисовка идёт через OpenGL то по нажатию PrintScreen и вставив результат из буффера в пэйнт я должен увидеть чёрный квадрат...а тут картинка.

Автор: Amp 14.4.2013, 22:50
Ты зачем-то на каждый вызов paintGL конвертируешь изображение и рисуешь через glDrawPixels, а не посредством полигонов и текстур - это все очень сильно просаживает производительность. Мой совет - если не знаком с OpenGL, то лучше и не используй его. Рисуй через QPainter.

Цитата(hawk3500 @  14.4.2013,  19:44 Найти цитируемый пост)
И ещё не совсем ясно , если прорисовка идёт через OpenGL то по нажатию PrintScreen и вставив результат из буффера в пэйнт я должен увидеть чёрный квадрат...а тут картинка.

Ничего подобного.

Автор: Jeka178RUS 15.4.2013, 08:15
Вот рабочий пример на шейдерах, только все самое свежее ))

Инициализация
Код

void glWindow::initializeGL()
{
    mShaderProgram = new QGLShaderProgram(this);
    mShaderProgram->addShaderFromSourceCode(QGLShader::Vertex,
                        "#version 330\n"
                        "in vec4 verts;\n"
                        "in vec2 texCoords;\n"
                        "out vec4 gl_Position;\n"
                        "out vec2 uv;\n"
                        "void main(){\n"
                        "    gl_Position = verts;\n"
                        "    uv = texCoords;\n"
                        "}"
        );

    mShaderProgram->addShaderFromSourceCode( QGLShader::Fragment,
                         "#version 330\n"
                         "in vec2 uv;\n"
                         "uniform sampler2D texture0;\n"
                         "out vec4 gl_FragColor;\n"
                         "void main(){\n"
                         "    gl_FragColor = texture( texture0, uv);\n"
                         "}"
        );

    mShaderProgram->link();

    mVerts = new QGLBuffer();
    mTex =  new QGLBuffer();

    QVector<float> verts;
    verts <<-1 << -1 << 0 << 1
          << 1 << -1 << 0 << 1
          << 1 <<  1 << 0 << 1
          <<-1 <<  1 << 0 << 1;

    mVerts->create();
    mVerts->bind();
    mVerts->allocate( verts.data(), verts.size()*sizeof(float) );

    verts.clear();
    verts << 0 << 0
          << 1 << 0
          << 1 << 1
          << 0 << 1;

    mTex->create();
    mTex->bind();
    mTex->allocate( verts.data(), verts.size()*sizeof(float) );

    glewInit();
    qglClearColor(Qt::black);

    QImage img = QImage("./img.png");
    glGenTextures(1, &mglTex);
    glBindTexture(GL_TEXTURE_2D, mglTex);

    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_RGBA,
        img.width(),
        img.height(),
        0,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        convertToGLFormat( img ).bits()
    );

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}


Рисование:
Код

void glWindow::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    mShaderProgram->bind();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mglTex);
    mShaderProgram->setUniformValue( "texture0", 0 );

    mVerts->bind();
    mShaderProgram->setAttributeBuffer( "verts",
                                        GL_FLOAT,
                                        0,
                                        4
                        );
    mShaderProgram->enableAttributeArray( "verts" );

    mTex->bind();
    mShaderProgram->setAttributeBuffer("texCoords",
                                       GL_FLOAT,
                                       0,
                                       2
                    );
    mShaderProgram->enableAttributeArray( "texCoords" );

    glDrawArrays( GL_QUADS, 0, 4 );

    mShaderProgram->disableAttributeArray( "texCoords" );
    mShaderProgram->disableAttributeArray( "verts" );

    glBindTexture(GL_TEXTURE_2D, 0);
}

void glWindow::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}



Скриншот берет отлично



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)