OpenGL: Matrix mit Vektor multiplizieren



  • Eine Display-Liste haette genau das erledigt was Du jetzt manuell machen willst, naemlich alle Primitiven vortransformiert in einem Vertexbuffer zu sammeln.
    Aber wenn die Loesung mit VBOs erfolgen soll musst Du wohl selber ran.
    Die Hinweise zur Deprecation werden sicherlich nicht sonderlich zeitnah greifen weil man zB unter Windows immer erstmal bei OpenGL 1.1 startet...



  • David_pb schrieb:

    Hinzu kommt noch, dass du die MV-Matrix entsprechend anpassen (=> Identity) musst, wenn du deine Idee umsetzen willst.

    Heisst das also, das z. B. ein

    glTranslatef(...);
    glVertex3f(...);
    

    nicht äquivalent ist zu

    glTranslatef(...);
    glGetFloatv(GL_MODELVIEW_MATRIX, fvViewMatrix );
    new_vertex = fvViewMatrix * vertex; //Pseudo
    glDrawElements(new_vertex); //Pseudo
    

    ???



  • Nein, du transformierst ja dann zweimal.



  • wo transformiere ich denn zweimal?

    //edit
    Achso, erst denken, dann schreiben!

    Also muss ich dann vor meinem glDrawElements() die Identity laden?

    glTranslatef(...);
    glGetFloatv(GL_MODELVIEW_MATRIX, fvViewMatrix );
    new_vertex = fvViewMatrix * vertex; //Pseudo
    glLoadIdentity();
    glDrawElements(new_vertex); //Pseudo
    


  • Ja, das wär ganz sinnvoll. Aber wieso stellst du die Matrix nicht einfach selbst auf und lässt bei GL einfach immer die Einheitsmatrix für die Model->View Transformation?



  • Vor meinen eigenen Transformationen werden schon fünf andere gemacht.
    Wäre es denn performanter, wenn ich die vorherige Matrix auslese und dann darauf meine Matrizen multipliziere, also alles ohne glTranslate, glScale und glRotate?

    Danke für Eure Hilfe!



  • curry-king schrieb:

    Vor meinen eigenen Transformationen werden schon fünf andere gemacht.
    Wäre es denn performanter, wenn ich die vorherige Matrix auslese und dann darauf meine Matrizen multipliziere, also alles ohne glTranslate, glScale und glRotate?

    Einfach ausprobieren! 🙂



  • Sooo.

    Leider funktioniert das nicht so ganz wie ich mir das vorgestellt habe.
    Ich vermute, das irgendetwas bei der Erstellung der Vertex-Liste nicht funktioniert.

    Am Code hat sich nicht viel geändert.

    glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
    glRotatef(10.0f, 1.0f, 0.0f, 0.0f);
    glRotatef(-4.0f, 0.0f, 0.0f, 1.0f);
    glTranslatef(getLength()/2, 0.0f, -getTriangleHeight());
    GLfloat fvViewMatrix[16];
    glGetFloatv(GL_MODELVIEW_MATRIX, fvViewMatrix);
    transform(fvViewMatrix);
    

    Die Methode transform() Multipliziert nun die Matrix mit mehreren Vektoren und speichert die Ergebnisse.

    void TetrahedronOpt::transform(GLfloat *matrix) {
            Vertex *v = getVertices();
    
    	float m_x = v[0].getPosition()[0];
    	float m_y = v[0].getPosition()[1];
    	float m_z = v[0].getPosition()[2];
    	float m_w = v[0].getPosition()[3];
    
    	GLfloat x = matrix[0]*m_x + 
    				matrix[1]*m_y + 
    				matrix[2]*m_z + 
    				matrix[3]*m_w;
    
    	GLfloat y = matrix[4]*m_x + 
    				matrix[5]*m_y + 
    				matrix[6]*m_z + 
    				matrix[7]*m_w;
    
    	GLfloat z = matrix[8]*m_x + 
    				matrix[9]*m_y + 
    				matrix[10]*m_z + 
    				matrix[11]*m_w;
    
    	GLfloat w = matrix[12]*m_x + 
    				matrix[13]*m_y + 
    				matrix[14]*m_z + 
    				matrix[15]*m_w;
    
    	m_vertices_opt[m_counter].setPosition(x, y, z, w);
    	m_vertices_opt[m_counter++].setColor(0.5f, 0.5f, 0.5f, 1.0f);
    }
    

    Darauf folgt der Draw-Call:

    // Anordnen der Vertexdaten		
    	glVertexPointer(4, GL_FLOAT, sizeof(Vertex), &m_vertices_opt[0].getPosition()[0]);
    
    	// Anordnen der Colordaten
    	glColorPointer(4, GL_FLOAT, sizeof(Vertex),  &m_vertices_opt[0].getColor()[0]);	
    
    	glLoadIdentity();
    
    	// DRAW
    	glDrawElements(GL_TRIANGLE_STRIP, m_numIndices, GL_UNSIGNED_BYTE, m_arrayIndices_opt);
    

    Noch ein Hinweis. Wenn ich statt der Matrixmultiplikation etwas schreibe wie

    glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
    glRotatef(10.0f, 1.0f, 0.0f, 0.0f);
    glRotatef(-4.0f, 0.0f, 0.0f, 1.0f);
    glTranslatef(getLength()/2, 0.0f, -getTriangleHeight());
    
    glBegin(...)
    // objektkoordinaten
    glEnd(...)
    

    , dann wird das Objekt an die richtige Stelle gezeichnet.

    Blickt da jemand durch, was ich falsch mache?

    Vielen Dank für Eure Hilfe!



  • Die OpenGL-Matrizen sind spaltenweise abgelegt:

    GLfloat x = matrix[0]*m_x +
                    matrix[4]*m_y +
                    matrix[8]*m_z +
                    matrix[12]*m_w;
    


  • Dankeschön, das hat wunderbar geklappt!

    Habt ihr ne Kaffeekasse 😉

    👍


Anmelden zum Antworten