2011-01-06 7 views
6

Modifica: rotoglup ha trovato i problemi nel mio codice, aggiungendo gli ombreggiatori che avevo rimosso completato la soluzione. Vedere la mia risposta sotto per il codice corretto (con shader).openGL di base, buffer di vertici e pyglet

Ciao a tutti!

Sto cercando di imparare alcune nozioni di base della moderna OpenGL da this tutorial.

Mi piacerebbe farlo con python/pyglet invece di C++. So che Pyglet può astrarre molto del livello basso OpenGL di distanza; Voglio capire alcune delle basi prima di passare a nascondendole dietro strati di astrazione però.

Il mio problema è estremamente semplice: il codice seguente disegna solo un punto invece del 3 che mi aspetto. Il mio codice è, per quanto posso dire, identico al C++ nel tutorial, fatta eccezione per la rimozione di vertex e framment shaders (eseguita tramite gletools in python), che sembra non fare alcuna differenza per il mio problema.

Semplificare le cose in un singolo punto mostra un comportamento che non capisco (la prima coordinata sembra essere l'unica che influisce su qualsiasi cosa), riportandomi alla mia convinzione che semplicemente non sono riuscito a capire qualcosa di molto basilare su entrambi pyglet, OpenGL, o anche in 3D in generale: p

Ecco il codice in questione:

import pyglet 
from pyglet.gl import * 

window = pyglet.window.Window() 

positionBufferObject = GLuint() 
vao = GLuint() 

vertexPositions = [0.0, 0.0, 0.0, 
        0.25, 0.0, 0.0, 
        1.75, 1.75, 0.0] 

vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions) 

@window.event 
def on_draw(): 
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
    glEnableVertexAttribArray(0) 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0) 
    glDrawArrays(GL_POINTS, 0, 3) 
    glDisableVertexAttribArray(0) 

glGenBuffers(1, positionBufferObject) 
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 

glClearColor(0.0, 0.0, 0.0, 0.0) 
pyglet.app.run() 
+0

Vuoi dire che con il codice corretto, hai ancora un punto tracciato? Questo punto è disegnato al centro dello schermo? Se cambi le prime coordinate, il punto si muove? – rotoglup

+0

Con il codice corretto, il meglio che ottengo è ancora un singolo punto che non si sposta con la coordinata w in 1 e passando la dimensione in byte. Se rimuovo le coordinate w e cambio glVertexAttribPointer di conseguenza, non ottengo nulla. Sono completamente confuso! Correzione –

+0

: w deve essere a 0 per far comparire qualcosa, il che mi rende solo più confuso. –

risposta

5
glDrawArrays(GL_POINTS, 0, 1) 

istruisce per disegnare 1 punto, nel tuo tutorial, 1 è 3:

glDrawArrays(GL_POINTS, 0, 3) 

Si noti inoltre che la componente 4 ° (w) dei vertici dovrebbe essere 1, non è 0:

vertexPositions = [0.0, 0.0, 0.0, 1.0, 
        0.25, 0.0, 0.0, 1.0, 
        1.75, 1.75, 0.0, 1.0] 

alternativa, è possibile rimuovere il componente w,

vertexPositions = [0.0, 0.0, 0.0, 
        0.25, 0.0, 0.0, 
        1.75, 1.75, 0.0] 

e cambiare la seguente chiamata a:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0) 

Un'altra cosa, io non sono un esperto in pyglet, ma è possibile che glBufferData, come la sua controparte C, prende una dimensione in byte, non in elementi. Ogni galleggiante essendo 4 byte, si potrebbe provare:

glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW) 
+0

Grazie per la risposta! Ho modificato la mia domanda con i tuoi suggerimenti (avevo effettivamente provato la versione corretta della chiamata a drawArray ma ho dimenticato di ripristinarla prima di copiare il mio codice). Il problema esiste ancora però ... Sto iniziando a chiedermi se c'è qualcosa di sbagliato nella mia versione di pyglet, ho dovuto installare la versione di sviluppo per poter utilizzare gletools. –

+0

Modificata la risposta per aggiungere un'altra correzione possibile. – rotoglup

+0

Grazie per la (ulteriore) risposta! Ancora nessuna gioia purtroppo ... Sto iniziando a chiedermi se questo è specifico per Pyglet invece di essere un problema OpenGL. Proverò la mailing list di pyglet e riferirò! –

4

finalmente ho questo diritto!

Sembra che venissi fuorviato dal fatto che manipolare i vertici, glDrawArrays e glVertexAttribPointer a volte comportava la visualizzazione di un singolo punto. Questo sembra essere un incidente: con le correzioni fornite dalla risposta di rotoglup, nulla viene disegnato. Questo è il comportamento "corretto" per il codice nella mia domanda originale.

Un inventario dei miei errori in caso aiuta chiunque:

  • impostando il w coordinata a 0, invece di 1, mancano completamente le spiegazioni per clip-trasformazione dello spazio nel tutorial.

  • dando a glBufferData la dimensione del buffer in vertici quando si aspetta byte.

  • rimozione di vertex e framment shader (per semplificare il codice durante la ricerca dei due problemi precedenti). Ciò ha assicurato che nulla sarebbe mai stato reso ... tranne il punto singolo (buggy?) Che a volte ricevevo.

Per la cronologia, il codice seguente mostra un singolo triangolo, con passanti di ombreggiatura, in quello che spero di essere aggiornato e correggere OpenGL. I requisiti sono pyglet e sguardi.

import pyglet 
from pyglet.gl import * 
from gletools import ShaderProgram, FragmentShader, VertexShader 

window = pyglet.window.Window() 

positionBufferObject = GLuint() 

vertexPositions = [0.75, 0.75, 0.0, 1.0, 
        0.75, -0.75, 0.0, 1.0, 
        -0.75, -0.75, 0.0, 1.0] 
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions) 

program = ShaderProgram(
    FragmentShader(''' 
    #version 330 
    out vec4 outputColor; 
    void main() 
    { 
     outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); 
    }'''), 
    VertexShader(''' 
    #version 330 
    layout(location = 0) in vec4 position; 
    void main() 
    { 
     gl_Position = position; 
    }''') 
) 

@window.event 
def on_draw(): 
    with program: 
     glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
     glEnableVertexAttribArray(0) 
     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0) 
     glDrawArrays(GL_TRIANGLES, 0, 3) 
     glDisableVertexAttribArray(0) 

glGenBuffers(1, positionBufferObject) 
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject) 
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 

pyglet.app.run()