Russian Qt Forum

Qt => Вопросы новичков => Тема начата: AndeRVRN от Октябрь 01, 2015, 00:58



Название: Убрать мерцание при отрисовке
Отправлено: AndeRVRN от Октябрь 01, 2015, 00:58
Отрисовываю движение шарика, следующим образом. Рисую на заданных координатах, потом стираю и рисую на координатах +1.
Естественно все делаю таймером и когда шарик движется, видно его мерцание.
Подскажите, как можно уменьшить видимость мерцания или убрать вовсе... Попробовал ускорить таймер, не особо помогло, все равно видно как мерцает.


Название: Re: Убрать мерцание при отрисовке
Отправлено: Racheengel от Октябрь 01, 2015, 01:48
Qgraphicscene ?


Название: Re: Убрать мерцание при отрисовке
Отправлено: Igors от Октябрь 01, 2015, 05:49
Не стирать, а перерисовывать все с новым шариком


Название: Re: Убрать мерцание при отрисовке
Отправлено: Bepec от Октябрь 01, 2015, 07:38
Или же использовать буфер для рисования.
Но нужно посмотреть ваш код, кто знает где у вас таймер :)


Название: Re: Убрать мерцание при отрисовке
Отправлено: AndeRVRN от Октябрь 01, 2015, 14:13
Кину код работы программы, может у кого будут идеи.
P.S. Там много мусора есть, еще не рефакторил код, поэтому просьба на это внимание не обращать, потом все сделаю. Сейчас пытаюсь решить эту проблему.

Таймер создается в классе Window, в котором создается GLWidget.
Код:
Window::Window()
{
    setWindowTitle(tr("OpenGL"));

    GLWidget *openGL = new GLWidget(&helper, this);
    this->setFixedSize(300,300);
    openGL->resize(this->width(),this->height());

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), openGL, SLOT(animate()));
    timer->start(1);
}

Таймер связывается со слотом Animate, класса GLWidget и там же происходит paintEvent
Код:
void GLWidget::animate()
{
    elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 10;
    update();
}

void GLWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter;
    painter.begin(this);
    painter.setRenderHint(QPainter::Antialiasing);
    helper->paint(&painter, event, elapsed);
    painter.end();
}

В paintEvent вызывается функция paint, класса helper, в которой сначала рисуется прямоугольник заполняющий всю форму одним цветом. И следом рисуется или стирается шарик, в зависимости от того, нарисован ли он в данном случае.
 
Код:
void Helper::paint(QPainter *painter, QPaintEvent *event, int elapsed)
{

    painter->fillRect(event->rect(), background);
    QPen penRect(Qt::black);
    penRect.setWidth(2);
    painter->setPen(penRect);
    painter->drawRect(GL_WINDOW_MIN_SIZE.x(),GL_WINDOW_MIN_SIZE.y(),GL_WINDOW_MAX_SIZE.x(),GL_WINDOW_MAX_SIZE.y());
    painter->setViewport(0,0,300,300);
    painter->save();

    if (CheckPaint == 0)
    {
        painter->setBrush(circleBrush);
        painter->setPen(circlePen);
        painter->drawEllipse(CircleCoord.x(),CircleCoord.y(),
                             CircleSize.x(),CircleSize.y());
        CheckPaint = 1;
    }
    else if (CheckPaint == 1)
    {
        painter->setBrush(clearCircleBrush);
        painter->setPen(clearCirclePen);
        painter->drawEllipse(CircleCoord.x(),CircleCoord.y(),
                             CircleSize.x(),CircleSize.y());
        CheckPaint = 0;
        ChangeCoord();

    }
    painter->restore();
}

Функция класса helper, которая отвечает за изменения следующих координат шарика:
Код:
void Helper::ChangeCoord()
{
    CircleCoord.setX(CircleCoord.x()+CircleStep.x());
    CircleCoord.setY(CircleCoord.y()+CircleStep.y());

    if (CircleCoord.x() < GL_WINDOW_MIN_SIZE.x())
    {
        CircleStep.setX(-CircleStep.x());
        CircleCoord.setX(GL_WINDOW_MIN_SIZE.x() - (CircleCoord.x() - GL_WINDOW_MIN_SIZE.x()));
    }
    if (CircleCoord.y() < GL_WINDOW_MIN_SIZE.y())
    {
        CircleStep.setY(-CircleStep.y());
        CircleCoord.setY(GL_WINDOW_MIN_SIZE.y() - (CircleCoord.y() - GL_WINDOW_MIN_SIZE.y()));
    }
    int bufMaxX = GL_WINDOW_MAX_SIZE.x()-CircleSize.x();
    int bufMaxY = GL_WINDOW_MAX_SIZE.y()-CircleSize.x();
    if (CircleCoord.x() > bufMaxX)
    {
        CircleStep.setX(-CircleStep.x());
        CircleCoord.setX(CircleCoord.x() - (CircleCoord.x()- bufMaxX ));
    }
    if (CircleCoord.y() > bufMaxY)
    {
        CircleStep.setY(-CircleStep.y());
        CircleCoord.setY(CircleCoord.y() - (CircleCoord.y() - bufMaxY));
    }
}


Название: Re: Убрать мерцание при отрисовке
Отправлено: Igors от Октябрь 01, 2015, 14:22
Кину код работы программы,
Так не кидают :)  Никому не интересно выцарапывать файлы через copy/paste. Выкладывают компилябельный прект в zip.

И второе: конечно дело Ваше, но препод может и не принять, т.к. QGLWidget имеет смысл если шарик - 3D объект, а не круг отрисованный QPainter. Может и смотреть смысла нет?


Название: Re: Убрать мерцание при отрисовке
Отправлено: AndeRVRN от Октябрь 01, 2015, 14:33
Кину код работы программы,
Так не кидают :)  Никому не интересно выцарапывать файлы через copy/paste. Выкладывают компилябельный прект в zip.

И второе: конечно дело Ваше, но препод может и не принять, т.к. QGLWidget имеет смысл если шарик - 3D объект, а не круг отрисованный QPainter. Может и смотреть смысла нет?

Можете подкинуть небольшой пример с 3D объектом, чтобы помогло разобраться. Изначально хотел так и сделать, но не особо понял и поэтому решил организовать проще.

P.S. Закинул проект целиком.


Название: Re: Убрать мерцание при отрисовке
Отправлено: Igors от Октябрь 01, 2015, 14:57
Можете подкинуть небольшой пример с 3D объектом, чтобы помогло разобраться.
Под рукой нет, но такое проще нагуглить. Вот первая ссылка (http://forum.vingrad.ru/topic-265482.html) навскидку