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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Убрать мерцание при отрисовке  (Прочитано 4600 раз)
AndeRVRN
Гость
« : Октябрь 01, 2015, 00:58 »

Отрисовываю движение шарика, следующим образом. Рисую на заданных координатах, потом стираю и рисую на координатах +1.
Естественно все делаю таймером и когда шарик движется, видно его мерцание.
Подскажите, как можно уменьшить видимость мерцания или убрать вовсе... Попробовал ускорить таймер, не особо помогло, все равно видно как мерцает.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Октябрь 01, 2015, 01:48 »

Qgraphicscene ?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Не стирать, а перерисовывать все с новым шариком
Записан
Bepec
Гость
« Ответ #3 : Октябрь 01, 2015, 07:38 »

Или же использовать буфер для рисования.
Но нужно посмотреть ваш код, кто знает где у вас таймер Улыбающийся
Записан
AndeRVRN
Гость
« Ответ #4 : Октябрь 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));
    }
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Октябрь 01, 2015, 14:22 »

Кину код работы программы,
Так не кидают Улыбающийся  Никому не интересно выцарапывать файлы через copy/paste. Выкладывают компилябельный прект в zip.

И второе: конечно дело Ваше, но препод может и не принять, т.к. QGLWidget имеет смысл если шарик - 3D объект, а не круг отрисованный QPainter. Может и смотреть смысла нет?
Записан
AndeRVRN
Гость
« Ответ #6 : Октябрь 01, 2015, 14:33 »

Кину код работы программы,
Так не кидают Улыбающийся  Никому не интересно выцарапывать файлы через copy/paste. Выкладывают компилябельный прект в zip.

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

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

P.S. Закинул проект целиком.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Октябрь 01, 2015, 14:57 »

Можете подкинуть небольшой пример с 3D объектом, чтобы помогло разобраться.
Под рукой нет, но такое проще нагуглить. Вот первая ссылка навскидку
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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