Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[OpenGL z Qt] niska wydajność - jak poprawić?

Ostatnio zmodyfikowano 2016-10-29 10:25
Autor Wiadomość
fokusx
Temat założony przez niniejszego użytkownika
[OpenGL z Qt] niska wydajność - jak poprawić?
» 2016-10-28 22:39:16
Witam,
używając czystego GLFW dla obsługi OpenGL uzyskuje ~320 klatek na sekunde.
Po migracji do Qt FPS spadły do ~120.
Jest to zbyt duża różnica żeby ją zignorować.
Czy jest jakiś sposób na zwiększenie wydajności?

Kod (ważniejsze fragmenty okna):
C/C++
#include <Windows.h>
#include <iostream>

#include "glwidget.hpp"
#include <GL/glew.h>

#include <sstream>
// ...

using namespace std;
using namespace GameEngine;

GLWidget::GLWidget( QWidget * parent )
    : QGLWidget( parent )
     , terrain( 0 )
     , camera( 0 )
     , fps( 0 )
{
    QGLFormat glFormat;
    glFormat.setVersion( 4, 2 );
    glFormat.setProfile( QGLFormat::CompatibilityProfile );
    glFormat.setSampleBuffers( true );
   
    this->setContext( new QGLContext( glFormat ) );
}

GLWidget::~GLWidget()
{
    // ...
}


void GLWidget::initializeGL()
{
    glSetup();
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LESS );
   
    LoadShaders();
   
    // ...
   
    QTimer * timer = new QTimer();
    QObject::connect( timer, SIGNAL( timeout() ), this, SLOT( processing() ) );
    timer->start( 0 );
   
    glCheckError();
}

void GLWidget::resizeGL( int width, int height )
{
    glViewport(( width - side ) / 2,( height - side ) / 2, side, side ); */
    glViewport( 0, 0, width, height );
    camera->SetPerspectiveProj( mFovy, width, height, mNear, mFar );
   
   
    glCheckError();
}
void GLWidget::paintGL()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
   
    camera->UpdateMatrix();
    test->Render();
   
    glCheckError();
    swapBuffers();
}

void GLWidget::mousePressEvent( QMouseEvent * event )
{
    lastMousePos = event->pos();
}

void GLWidget::mouseMoveEvent( QMouseEvent * event )
{
    int dx = event->x() - lastMousePos.x();
    int dy = event->y() - lastMousePos.y();
   
    if( event->buttons() & Qt::LeftButton ) {
        camera->LocalRotate( Eigen::Quaternion < float, 2 >( Eigen::AngleAxisf(( static_cast < float >( dy ) / this->height() ) * mMouseMoveCameraFactor, Eigen::Vector3f::UnitX() ) ) );
        camera->LocalRotate( Eigen::Quaternion < float, 2 >( Eigen::AngleAxisf(( static_cast < float >( dx ) / this->width() ) * mMouseMoveCameraFactor, Eigen::Vector3f::UnitY() ) ) );
    }
   
    lastMousePos = event->pos();
}

void GLWidget::glCheckError()
{
    GLenum err( glGetError() );
   
    while( err != GL_NO_ERROR ) {
        string error;
       
        switch( err ) {
        case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break;
        case GL_INVALID_ENUM: error = "INVALID_ENUM"; break;
        case GL_INVALID_VALUE: error = "INVALID_VALUE"; break;
        case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break;
        case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
        }
       
        CriticalLog::Write( "GL_" + error, error );
        err = glGetError();
    }
}
void GLWidget::glSetup()
{
    #if defined(Q_OS_WIN32)
    makeCurrent();
    glewExperimental = true;
    GLint GlewInitResult = glewInit();
    if( GlewInitResult != GLEW_OK ) {
        const GLubyte * errorStr = glewGetErrorString( GlewInitResult );
        int size = strlen( reinterpret_cast < const char *>( errorStr ) );
        CriticalLog::Write(( "Glew error " + QString::fromUtf8( reinterpret_cast < const char *>( errorStr ), size ) ).toStdString(),( "Glew error " + QString::fromUtf8( reinterpret_cast < const char *>( errorStr ), size ) ).toStdString() );
       
    }
    #endif
}

void GLWidget::LoadShaders()
{
    // Shaders
    // ...
}
void GLWidget::processing()
{
    updateGL();
    fps++;
}
unsigned & GLWidget::FPS() { return fps; }
 
P-153016
Gibas11
» 2016-10-29 10:25:28
Qt niestety nie grzeszy wydajnością w takich zastosowaniach, możesz spróbować wstawić silnik gry do osobnego wątku, wtedy powinno być dużo lepiej, ale możesz mieć pewne problemy z synchronizacją i będziesz musiał naklepać trochę dodatkowego kodu.

//edit: W każdym razie na pewno ogarnij gdzieś tam normalną pętlę a nie QTimer wywołujący to co chwilę przez sygnał timeout, to nie ma prawa być szybkie.
P-153023
« 1 »
  Strona 1 z 1