Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

11.03.2012, 15:59

Teil eines Mesh zeichnen

Hallo,

[hier stand ganz viel Unsinn]

[EDIT]

Ah gerade gesehen das sich das auf den Vertexbuffer bezieht und nicht auf die Indices :thumbdown:
Wie rendere ich dann Vertexgruppen über die Indices am besten als zusammenhängendes Mesh?

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »DeKugelschieber« (11.03.2012, 17:27)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

11.03.2012, 16:33

Ich versteh nicht ganz wo jetzt genau dein Problem liegt...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

11.03.2012, 17:25

Für meine skeletale Animation würde ich gerne für jedes Bone die modelview berechnen und an den Shader übergeben. Dazu dann den passenden Satz Vertices über Indices rendern.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

11.03.2012, 17:59

Und warum zeichnest du nicht das ganze Mesh auf einmal?
Es ist doch kein Problem, Matrizen für viele, viele Bones gleichzeitig an den Shader zu übergeben.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

11.03.2012, 18:07

Zitat

Es ist doch kein Problem, Matrizen für viele, viele Bones gleichzeitig an den Shader zu übergeben.


Da bin ich auch gerade drauf gekommen :P ich konnte mir das nur nicht so ganz vorstellen. Ich glaube aber ich weiß jetzt wie ichs mache:

- Bone Hierarchie erstellen
- Bone Daten für jedes Frame einlesen (also Rotation usw. für das gesamte Skeleton pro Frame)
- Frames einlesen (mit offset der Bone Daten pro Frame)

Mit dem "root"-Bone anfangen und die Kamera-Modelview einlesen, Transformationen dafür ausführen. Nächstes Bone anwählen, die Modelview aus dem parent Bone für dieses einlesen, Tranformationen ausführen... alle Matrizen + Indices + Vertexgruppen als index_offset + index_count an den Vertex Shader übergeben.
Und der rest sollte ja kein Problem sein.

Was haltet ihr davon, ist das so realisierbar? Geht es vielleicht einfacher?
Ich vernachlässige erstmal Vertex weights usw.
Hier die structs die das Skelet representieren.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

11.03.2012, 18:44

Ich werde aus deiner beschriebenen Vorgehensweise nicht ganz schlau.
Normalerweise speichert man pro Vertex 4 Integer und 4 Floats (muss nicht unbedingt 4 sein, aber bietet sich an und sollte normalerweise ausreichen).
Die Integer geben an, welche (maximal 4) Bones den Vertex beeinflussen.
Die Floats geben die Gewichte der Bones an. Wenn du nur 1, 2 oder 3 Bones für einen Vertex hast, dann sind die übrigen Gewichte einfach 0.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

7

12.03.2012, 16:29

So jetzt hab ich noch ein Problem(chen): ich bekomme es gerade nicht hin 2 Matrizen in ein uniform Array einzulesen (weil ich das noch nie gemacht habe, Schande). Heißt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
shader->bindShader();
shader->sendUniform4x4("projection_matrix", projection.getArray());
shader->sendUniform4x4("modelview_matrix", modelview.getArray());
shader->sendUniform4x4("bone_matrix", &m_bone_matrices[0]); // <- m_bone_matrices hat 32 Elemente (float)

void GLSLProgram::sendUniform4x4(const string &name, const float *matrix, bool transpose){ // Elternklasse von Shader
    GLuint location = getUniformLocation(name);
    glUniformMatrix4fv(location, sizeof(matrix), transpose, matrix);
}


Quellcode

1
2
3
4
5
6
7
8
9
10
// [...]
uniform mat4 bone_matrix[2]; // <- hier sollen die floats rein...

in vec3 a_Vertex;
in int bone_Index;
//in float bone_Weight; <- kommt noch

void main(void){
    gl_Position = projection_matrix*modelview_matrix*bone_matrix[bone_Index]*vec4(a_Vertex, 1.0); // (erstmal nur ein Bone pro Vertex)
}


Also, wie sende ich die Matrizen an den Shader?

[EDIT]

Übrignes funktioniert das ganze wenn ich zwei uniforms statt einem Array nehme... später geht das natürlich nicht mehr (bei z.B. 20 Bones).

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

8

12.03.2012, 20:02

Ok es liegt scheinbar nicht am übergeben der Matrizen (ich hab sie von Hand hintereinander gerendert) sondern eher am "bone_Index" Buffer. Ich find den Fehler nur gerade nicht...

Vielleicht findet ihr ihn, hier die relevanten Stellen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// irgendwo beim laden
shader.push_back(new Shader("res/shader/sam.shv", "res/shader/sam.shf"));
shader[0]->bindAttrib(SHADER_VERTEX, 0, "a_Vertex", 3);
shader[0]->bindAttrib(SHADER_INDEX, 1, "bone_Index", 1);
shader[0]->linkProgram();

// Bone Indices erstellen (eine hälfte "0" eine "1")
for(unsigned int i = 0; i < 17; i++){
    m_bone_indices[i] = 0;
}

for(unsigned int i = 17; i < 34; i++){
    m_bone_indices[i] = 1;
}

// Buffer mit den Indices als ints
glGenBuffers(1, &m_boneBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_boneBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(int)*m_bone_indices.size(), &m_bone_indices[0], GL_STATIC_DRAW);

// in der Renderfunktion (Bone Matrizen werden vorher berechnet, sind richtig und getestet)
shader->bindShader();
shader->sendUniform4x4("projection_matrix", projection.getArray());
shader->sendUniform4x4("modelview_matrix", modelview.getArray());
shader->sendUniform4x4("bone_matrix", &m_bone_matrices[0], 2);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_boneBuffer);
glVertexAttribPointer(1, 1, GL_INT, GL_FALSE, 0, 0);
        
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, &m_indices[0]);
    
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);


Hier nochmal der Shader:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#version 150

uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;

uniform mat4 bone_matrix[2];

in vec3 a_Vertex;
in int bone_Index;
//in float bone_Weight;

void main(void){
    gl_Position = projection_matrix*modelview_matrix*bone_matrix[1]*vec4(a_Vertex, 1.0);
}


Wobei wenn ich z.B. über eine if im Shader teste ob "bone_Index" == 0 ist wird die eine hälfte auch gerendert, allerdings nicht die andere in der scheinbar 1 stehen sollte. Also mache ich wohl einen Fehler beim füllen des Buffers.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

12.03.2012, 20:12

Ich würde dir empfehlen, die Vertextransformation erstmal auf der CPU zu rechnen um ordentlich debuggen zu können. Hast du z.B. schonmal überprüft ob deine Matritzen überhaupt stimmen?

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

12.03.2012, 21:02

Es liegt nicht an den Matrizen, wenn ich mit einer von beiden rendere (die erste rotiert um 45° die ander um 90°) wird die Box (die ich zum testen nutze, sie besteht aus 12 Vertices) auch so angezeigt (also passend gedreht). Es liegt scheinbar an der Auswahl der Matrix zur passenden Vertex Gruppe.

Heißt das:

C-/C++-Quelltext

1
gl_Position = projection_matrix*modelview_matrix*bone_matrix[bone_Index]*vec4(a_Vertex, 1.0);


bei bone_matrix[bone_Index] mit 0 und 1 von Hand eingetragen zwar funktioniert, aber nicht wenn ich jedem Vertex über den bone_Index Buffer einem Bone zuordnen will. In dem Buffer sollte 0 oder 1 stehen (Bone 0 oder 1 eben) was aber nur für 0 funktioniert. Heißt das nur das halbe Modell gerendert wird.
Also bone_matrix[2] enthält die korrekten Matrizen, ich kann mit 0 oder 1 einfach im Shader rendern. Aber nicht über den Buffer. Also muss der Buffer wohl fehlerhaft sein.

Werbeanzeige