Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Sectoid от Октябрь 12, 2006, 09:47



Название: [Qt 4.1.4] Painting over QGLWidget
Отправлено: Sectoid от Октябрь 12, 2006, 09:47
Всем привет.

Возникла необходимость совмещать вывод OpenGL и QPainter. Посмотрел на пример "Overpainting". Вроде бы всё работает. В процессе "тыкания" наткнулся на вот такой момент: функция glClear() не работает как положено при вызове её внутри скобок QPainter::begin(), QPainter::end(). Например такой код:

Файл Test.hpp:
Код:

#ifndef __TEST_HPP
#define __TEST_HPP

#include <QGLWidget>

class QPaintEvent;

class Test : public QGLWidget
{
    Q_OBJECT

public:
    Test(QWidget * parent = NULL);
    ~Test() {};

protected:
    void resizeGL(int w, int h);
    void paintEvent(QPaintEvent * event);
    void initializeGL();

};

#endif


Файл Test.cpp:
Код:

#include <QtOpenGL>
#include <QPainter>
#include <QPaintEvent>

#include <Test.hpp>

using namespace MPCAM;

Test::Test(QWidget * parent)
    : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
     setAttribute(Qt::WA_NoSystemBackground);
};

void Test::initializeGL()
{
    glClearColor(0.7, 0.0, 0.0, 0.7);
};

void Test::resizeGL(int width, int height)
{
    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0, +1.0, +1.0, -1.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
}

void Test::paintEvent(QPaintEvent * event)
{
    QPainter painter;
    painter.begin(this);
    painter.setRenderHint(QPainter::Antialiasing);

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    resizeGL(width(), height());

    glEnable(GL_CULL_FACE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glPopAttrib();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glDisable(GL_CULL_FACE);
    painter.end();


Файл main.cpp:
Код:

#include <QApplication>
#include <Test.hpp>

int main(int argc, char ** argv)
{
    QApplication app(argc, argv);

    Test * test(new Test());

    test->show();

    return app.exec();
};


Код должен (по моему розумению) выводить окно красного цвета. Но этого не происходит - выводится обычное окно. Куда копать?


Название: [Qt 4.1.4] Painting over QGLWidget
Отправлено: Dendy от Октябрь 12, 2006, 23:29
Попробуй разделить GL-методьІ рисования и растрового движка отдельно по:

Код:
void paintEvent( QPaintEvent * e );
void paintGL();


Насколько я понимаю - при рисовании с помощью QPainter на QGLWidget вьІзьІваются методьІ именно OpenGL. Как тьІ предполагаешь мешать неатомарньІе операции OpenGL: свои и QPainter'а? Сомневаюсь, что ето будет работать. Попробуй не вьІзьІвать функции OpenGL в пределах QPainter::begin() / QPainter::end().


Название: [Qt 4.1.4] Painting over QGLWidget
Отправлено: Sectoid от Октябрь 13, 2006, 09:43
Цитата: "Dendy"
Сомневаюсь, что ето будет работать. Попробуй не вьІзьІвать функции OpenGL в пределах QPainter::begin() / QPainter::end().


Это как раз должно работать, если верить троллям. И работает. Но как-то странно. Попробуй запустить код, который я привёл - поймёшь о чём я. glClear() не отрабатывает. Но если попробывать что-то нарисовать, ну хоть так:
Код:

glColor3d(0.0, 0.0, 1.0);
glBegin(GL_QUADS);
glVertex2d(-0.5, 0.5);
glVertex2d(0.5, 0.5);
glVertex2d(0.5, -0.5);
glVertex2d(-0.5, -0.5);
glEnd();

То синий квадратик нарисуется. Но фон всё равно не очистится в цвет, установленный glClearColor()... Баг?


Название: [Qt 4.1.4] Painting over QGLWidget
Отправлено: Dendy от Октябрь 13, 2006, 14:02
ТьІ не можешь бьІть уверен, что внутри QPainter'а не вьІзьІвается свой glClearColor(), или другие функции так или иначе влияющие на машину состояния OpenGL.

Не забьІвай, что OpenGL не обьектная библиотека, а процедурная.

Операции QPainter'а неатомарньІ так же как и OpenGL. О результате операций QPainter'а можно судить только ПОСЛЕ завершения его работьІ.

Иначе - результат непредсказуем. Ибо ето нигде не оговорено в документации. В любой момент они что-то добавляют в либу и результат твоего кодп будет другим.


Название: [Qt 4.1.4] Painting over QGLWidget
Отправлено: Sectoid от Октябрь 13, 2006, 14:37
Цитата: "Dendy"
ТьІ не можешь бьІть уверен, что внутри QPainter'а не вьІзьІвается свой glClearColor(), или другие функции так или иначе влияющие на машину состояния OpenGL.


Да. Ты был прав. Добавление glClearColor() перед glClear() решает проблему. Спасибо. Тема закрыта.


Название: [Qt 4.1.4] Painting over QGLWidget
Отправлено: Dendy от Октябрь 13, 2006, 15:38
Да, и так, к слову. У тебя утечка памяти в функции main() - не удаляется екземпляр класса Test.