2015-01-30 10 views
6

Ho postato una domanda in precedenza su come ottenere OpenGL funzionante su Qt, ma ora voglio essere in grado di utilizzare le ultime funzioni che OpenGL ha per l'uso. Prima di Qt, stavo usando glew; ma Qt sta dicendo che glew è in conflitto con il suo file di intestazione QtOpenGL. Ho esaminato QGLWidget e QGLFunctions, ma per essere sincero sono confuso su cosa dovrei fare per poter semplicemente accedere alle funzioni di OpenGL.Uso delle ultime funzioni OpenGL tra le classi in Qt 5.4

Ora ho ottenuto Qt 5.4 utilizzando Qt Creator 3.3.0 e sto utilizzando il nuovo QOpenGLWidget; tuttavia, la mancanza di una guida su come dovrebbe essere usato mi allontana un po ': la documentazione Qt è presente e aiuta, ma dimostra solo come istanziarla, piuttosto che utilizzarla in altre posizioni del programma. Capisco che questo QOpenGLWidget funzioni come QGLWidget. Qt dettagli che dovrei ereditare da esso; tuttavia non sto istanziando un contesto OpenGL all'interno della classe che vuole usare le funzioni OpenGL; ciò accade nella classe 'glWidget', che eredita da QOpenGLWidget.

Per esempio, prendiamo questo estratto da una delle mie classi che utilizza il codice OpenGL:

void Mesh::init() 
{ 
    pNumIndices = pIndices.size(); 

    glGenVertexArrays(1, &pVAO); 
    glGenBuffers(1, &pVertexBuffer); 
    glGenBuffers(1, &pIndexBuffer); 
    glBindVertexArray(pVAO); 

    glBindBuffer(GL_ARRAY_BUFFER, pVertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, pVertices.size() * sizeof(Vertex), 
       &pVertices[0], GL_STATIC_DRAW); 

    // etc.. 
} 

Mesh è una classe che non eredita da qualsiasi cosa. Originariamente, usava solo glew in modo che potesse ottenere dichiarazioni di funzioni OpenGL; non aveva bisogno di sapere se erano validi o meno, dato che quello è il lavoro di glew. Quindi nella classe mainApp, vorrei creare un'istantanea di glew. Capisco anche che esiste anche una classe QOpenGLFunctions che funziona in qualche modo simile a quella di glew, ma con tutte queste classi GL è spudoratamente confusionario sapere cosa usare. Inoltre, ho provato a cercare glGenVertexArrays (..) ma non è stato trovato in QOpenGLBuffer, QOpenGLFunctions o QOpenGLWidget; e per quanto ne so, a partire da OpenGL 4.5 fa ancora parte delle specifiche; ma i miei driver grafici non usano OpenGL 4.5, quindi uso OpenGL 4.3. Basti dire che sono disposto ad abbandonare l'approccio di Qt per chiamare le funzioni OpenGL.

In un programma in cui varie classi utilizzano le funzioni OpenGL, come posso utilizzare Qt per poterle chiamare senza l'uso di glew? La mesh è una di quelle classi che non crea un'istanza di OpenGL, ma ne utilizza semplicemente le funzioni.

Solo così la gente sa, ho usato Qt per un po 'di tempo (non abbastanza però!) E mi piace Qt; ma ho bisogno di sapere come posso usare Qt in congiunzione con OpenGL per continuare lo sviluppo. La maggior parte delle esercitazioni là fuori utilizza ancora materiale pre-5.4.

+1

'glGenVertexArrays' è per gli oggetti Array vertice, così qual è il nome della classe che dovresti cercare? Esatto, ['QOpenGLVertexArrayObject'] (http://doc.qt.io/qt-5/qopenglvertexarrayobject.html)! – peppe

+0

Personalmente non mi piace la roba di Q in cui incapsula le cose di OpenGL centralmente. Preferisco di gran lunga fare questo genere di cose con le mie lezioni. – Poriferous

risposta

4

In Qt 5.4, ci sono intestazioni con versione specifica Funzioni OpenGL, quindi:

#include <QOpenGLFunctions_3_3_Core> 

O qualunque versione che si desidera utilizzare.Poi da qualche parte con un contesto OpenGL valido come QOpenGLWidget :: initializeGL() creare e inizializzare un oggetto QOpenGLFunctions:

QOpenGLFunctions_3_3_Core *fun = new QOpenGLFunctions_3_3_Core; 
fun->initializeOpenGLFunctions(); 

E poi nel codice pareggio, basta usare le funzioni OpenGL di tale oggetto:

fun->glSomething(1,2,3) 
+3

Un'altra opzione è * l'ereditare * da tale classe, quindi puoi semplicemente scrivere 'glSomething' e funzionerà. – peppe

+0

Ok, e se ho un'altra classe che non è un QOpenGLWidget ma usa le funzioni OpenGL 4.3, cosa devo fare allora? – Poriferous

+0

Creare un oggetto QOpenGLFunctions_3_3_Core o derivarne. Nulla a riguardo dipende da QOpenGLWidget in alcun modo. Hai appena bisogno di un contesto OpenGL valido quando lo avvii. – wrosecrans

1

L'approccio diretto con OpenGL è quello di creare una struttura che contiene i puntatori a funzione:

struct sLGLAPI 
{ 
    sLGLAPI() { memset(this, 0, sizeof(*this)); }; 
    PFNGLACTIVETEXTUREPROC  glActiveTexture; 
    PFNGLATTACHSHADERPROC  glAttachShader; 
    PFNGLBEGINQUERYPROC   glBeginQuery; 
    PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; 
    ... 

riempirlo con i puntatori dlsym -ED dalla libreria OpenGL comune:

API->glActiveTexture = (PFNGLACTIVETEXTUREPROC)GetGLProc("glActiveTexture"); 
API->glAttachShader = (PFNGLATTACHSHADERPROC)GetGLProc("glAttachShader"); 
API->glBeginQuery = (PFNGLBEGINQUERYPROC)GetGLProc("glBeginQuery"); 
API->glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)GetGLProc("glBindAttribLocation"); 

E l'accesso OpenGL nella vostra codice solo attraverso questa struttura. Per esempio:

API->glShaderSource(Shader, 1, &Code, nullptr); 
API->glCompileShader(Shader); 

In questo modo si sarà in grado di nascondere le API OpenGL completa e anche utilizzare le funzioni di stub, ove necessario, per esempio, per registrare i parametri o per passare da OpenGL e OpenGL ES.

+0

La tua soluzione è adatta; ma dlsym è disponibile solo su Linux e sistemi simili. Io uso anche Linux; ma devo anche far funzionare il mio codice sotto Windows. Non avrebbe un modo multipiattaforma di gestire tale compito? – Poriferous

+1

@Poriferous GetProcAddress è la cosa più vicina a dlsym – BlamKiwi

+0

Questa non è la soluzione che sto cercando, tanto interessante quanto sembra; Ho bisogno di qualcosa di più coerente con Qt. – Poriferous

1
#include <QOpenGLFunctions_3_3_Core> 

class Mesh : public QOpenGLFunctions_3_3_Core 
{ 
public: 
    Mesh();//initializeOpenGLFunctions() 
    ~Mesh();  

    void func();//glxxx in it. when using it ,you need an opengl context. 
       //for example, use makeCurrent() in QOpenGLWidget subclass. 
}; 
1

L'utilizzo di QOpenGLFunctions_X_X_ * non risolverà questo problema! È necessario impostare la versione del contesto openGL prima di poter utilizzare QOpenGLFunctions_X_X_ *. Qt utilizzare la versione di default (credo 1.x) quindi è necessario aggiungere questo codice nel file main.cpp

 QSurfaceFormat format; 
//  format.setDepthBufferSize(24); 
    // format.setStencilBufferSize(8); 

     format.setMajorVersion(3); //whatever version 
     format.setMinorVersion(3); // 
     format.setProfile(QSurfaceFormat::CoreProfile); 
     QSurfaceFormat::setDefaultFormat(format); 

Cheers, Nai

Problemi correlati