qt5 위젯에 도형 애니메이션 만들려고 합니다 (스레드사용)

qkrtntjd의 이미지

일단 메인 윈도우에 위젯 하나를 띄웠습니다
클래스는 glwidget클래스와 mythread클래스를 만들었습니다

void MainWindow::on_pushButton_clicked()
{ //start
    qDebug() <<"start click";
    ui->widget->mThread->start();
}

메인윈도우에서 버튼을 누르면 스레드가 돌아가기 시작하는데 이 스레드는 glwidget클래스 멤버변수로 선언했습니다

GLWidget::GLWidget(QWidget *parent) :
    QGLWidget(parent)
{
    initializeGL();
    setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
    mThread = new MyThread(this);
    mThread->Stop = false;
    connect(mThread,SIGNAL(signalrender()),this,SLOT(playRender()));
}

스레드가 start하면 run에서 emit signalrender(); 루프가 돌게 됩니다 그런데 위에서 보셨듯이 GLWidget 생성자에서 playRender() 슬롯이 호출됩니다
void MyThread::run(){
 
    qDebug() << "run!";
 
    while(true){
        QMutex mutex;
        mutex.lock();
        if(this->Stop) break;
        mutex.unlock();
        emit signalrender();
        this->msleep(1);
    }
 
}

playRender()에서 currentFrame++을 해주면 미리 설정해놓은 배열의 인덱스값이 바뀌게 됩니다. 즉 애니메이션 효과를 주려고 이렇게 하였습니다.
void GLWidget::playRender()
{
    if(currentFrame <= markerData.frameSize){
        currentFrame++;
        updateGL();
    }
    updateGL();
}

마지막으로 그리는 부분입니다. 즉 어차피 paintGL은 updateGL될때마다 호출이 되므로 신경쓰지 않았고 스레드를 따로 만들어서 playRender()부분에서 인덱스를 계산하여 애니메이션처럼 돌아가도록 하였습니다 하지만 너무 버벅댑니다..
void GLWidget::paintGL(){
...
    for(int i=0;i<markerData.frameSize;i++){
        glTranslatef(markerData[i].x,markerData[i].y,markerData[i].z);
        gluSphere(p,15,35,35);
...
}

glwidget 클래스와 mythread 클래스를 두개로 나눌 필요가 있는지 확실하게 모르겠습니다 현재 업무상 qt를 제대로 공부하지 못하고 일을 시작하게되었습니다
도움 부탁드립니다. 코드도 첨부하였습니다
메일은 luxbada@gmail.com 입니다. 바쁘시겠지만 도움주시면 은혜 평생 잊지않겠습니다.

klara의 이미지

OpenGL과 스레드, Qt 어느것 하나라도 익숙하지 않다면 스레드는 쓰지 마세요. OpenGL과 스레드를 함께 써서 이득 보는 경우는 사실 별로 없습니다. 어차피 OpenGL의 명령들은 별도의 그래픽 드라이버가 관리하는 커맨드 큐로 들어가서 GPU로 전달되기 때문에 멀티 스레드를 써서 여러개의 씬(scene)을 동시에 렌더링해야하는게 아니라면 안쓰는게 좋습니다.

일정 시간 간격으로 뭔가를 해야한다면 굳이 스레드를 쓰지 않고 QTimer를 쓰면됩니다.

그리고 애니메이션 효과를 주려면 QAbstractAnimation클래스(와 하위 클래스들)를 한번 보시면 도움이 될 수 있습니다.
일일이 타이밍 재면서 할 필요없이 시작값과 끝값, duration설정하고 QAbstractAnimation객체(아마 이경우는 QVariantAnimation)에서 알려주는 타이밍대로 값받아서 렌더링하면됩니다.
다만 보통 애니메이션은 연속된 값 변화를 따라서 부분이 바뀌면서 렌더링되는데, 이경우에는 이산적인 프레임의 배열인덱스가 바뀌는 거니까 interpolation된 값을 적당히 반올림해서 쓰는 식으로 해야할 듯하네요.

qkrtntjd의 이미지

답변감사합니다
같은 프로그램을 저는 스레드로 구현하고 동료는 타이머로 구현하는데 스레드로 구현할 때 스레드에서는 단순히 계산작업만 해주는데
계산 후 화면에 업데이트?를 해줘야하는데 그때 저는 updateGL을 사용했지만 update로 바꿔보니 갑자기 버벅임이 현저히 줄었습니다
애니메이션 속도는 스레드재우는 시간으로 조절하려고 합니다
updateGL과 update가 이렇게 많은 차이를 내는지 몰랐습니다 단순히 위젯 하나에만 적용된다고 생각했거든요

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.