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

24.01.2012, 16:40

Heute mal... 2D Layer rendern

Guten Tag,

ich hab Probleme "Layer" (über depth buffer) zu rendern:


(Link)


Links ist die Spielfigur hinter der Tilemap obwohl die z-Komponente auf -0.1 steht (Tilemap auf 0.0).
Ich versteh nicht ganz woran das liegen kann, der depth Test ist aktiviert und alles wird über einen Shader gerendert, außerdem wird der Spieler nach der Tilemap gerendert (auch wenns eigentlich nicht nötig währe).

So sieht die Render Funktion aus:

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
void render(){
    mat4 modelview, projection;

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glViewport(viewport[0].x, viewport[0].y, viewport[1].x, viewport[1].y);
    
    projection.setIdentity();
    projection.ortho(int(viewport[0].x), int(viewport[1].x), int(viewport[0].y), int(viewport[1].y), -1, 1);

    // Shader
    shader[0]->bindShader();
    shader[0]->sendUniform4x4("projection_matrix", projection.getArray());
    shader[0]->sendUniform("texture0", 0);

    // Karte rendern
    modelview = tilemap->getModelview();
    shader[0]->sendUniform4x4("modelview_matrix", modelview.getArray());
    tilemap->renderBuffer();

    // Spieler rendern
    modelview = character->getModelview();
    shader[0]->sendUniform4x4("modelview_matrix", modelview.getArray());
    character->renderBuffer();
        
    glutSwapBuffers();
}


Und die der Klassen (für beide gleich):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Tilemap::renderBuffer(){       
    glBindTexture(GL_TEXTURE_2D, m_texture->getTextureID());
    
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    
    glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
    glVertexAttribPointer((GLint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);               
    glBindBuffer(GL_ARRAY_BUFFER, m_texCoordBuffer);
    glVertexAttribPointer((GLint)1, 2, GL_FLOAT, GL_FALSE, 0, 0);
        
    glDrawArrays(GL_TRIANGLES, 0, m_vertices.size()/3);
    
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}


Vertexshader:

C-/C++-Quelltext

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

uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;

in vec3 a_Vertex;
in vec2 a_TexCoord;
out vec2 texCoord0;

void main(void){
    texCoord0 = a_TexCoord;
    gl_Position = projection_matrix*modelview_matrix*vec4(a_Vertex, 1.0);
    gl_Position.z = a_Vertex.z; // depth test
}


Die Z Komponente wird nochmal auf a_Vertex.z gesetzt da sie vorher vernichtet wurde (*0, ich hatte schonmal 2 Sprites in eingestellter Reihenfolge gerendert, nur hiermit ging es).

Ich hoffe das war ausführlich genug.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

24.01.2012, 17:44

Hast du überhaupt einen Depth Buffer?
Ist die glDepthMask() aktiviert?
Wann tritt das linke Bild auf?
Wieso willst du das mit dem Depth Buffer machen, sobald Transparenz im Spiel ist musst du sowieso wieder sortieren, das macht bei purem 2D mit Layern imo keinen Sinn, weil du sowieso einfach nach Layer sortiert rendern kannst.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

24.01.2012, 17:57

Zitat

Hast du überhaupt einen Depth Buffer?


Ja, ging mit 2 Sprites ja.

Zitat

Ist die glDepthMask() aktiviert?


Ja.

Zitat

Wann tritt das linke Bild auf?


Wenn die Figur "hinter" der Karte steht (obwohl sie natürlich davor sein soll).

Zitat

Wieso willst du das mit dem Depth Buffer machen


Damit kann ich die Tilemap sortieren ohne mehrere Buffer benutzen zu müssen oder den Aufwand zu haben im Buffer selbst zu sortieren. Außerdem ist z.B. die Karte nicht transparent.

Zitat

weil du sowieso einfach nach Layer sortiert rendern kannst


Das wird sowieso gemacht, trotzdem wüsste ich gerne warum es nicht geht.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

24.01.2012, 18:02

Zitat

Wann tritt das linke Bild auf?


Wenn die Figur "hinter" der Karte steht (obwohl sie natürlich davor sein soll).

Wenn ich dich richtig verstanden hab, gehst du davon aus dass die z-Achse in den Bildschirm hinein zeigt? Hast du auch eine entsprechende Projektionsmatrix gesetzt?


Zitat

Wieso willst du das mit dem Depth Buffer machen


Damit kann ich die Tilemap sortieren ohne mehrere Buffer benutzen zu müssen oder den Aufwand zu haben im Buffer selbst zu sortieren. Außerdem ist z.B. die Karte nicht transparent.

Wie müsstest du denn sortieren wenn sowieso alles auf einem Layer ist?

Zitat

weil du sowieso einfach nach Layer sortiert rendern kannst


Das wird sowieso gemacht, trotzdem wüsste ich gerne warum es nicht geht.

Wenn du sowieso sortierst dann is der Depth Buffer aber sinnlose Verschwendung von Speicher und Bandbreite...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

24.01.2012, 18:20

Kugelschieber, es klingt für mich etwas danach, als ob Du glaubst, dass der Z-Buffer eine Art Sortierung für Dich vornimmt. Das tut er nicht. Er verhindert nur, dass etwas gerendert wird, was von der Kamera weiter weg ist als etwas, was bereits vorher gerendert wurde.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

24.01.2012, 18:55

Gut ohne depth Buffer geht es, allerdings muss ich jetzt die Tilemap "selber" sortieren (gute Lösungsvorschläge, außer 3 Buffer zu nehmen?).
Und natürlich werden Dinge die "näher" (z = kleiner) sind vor anderen mit hohem z-Wert gerendert.

Zitat


"Kostenlose" Objektsortierung
Eine 3D-API braucht einen Tiefenpuffer um zu erkennen ob Fragmente verdeckt sind oder nicht und damit Overdraw zu vermeiden. Eine 2D-Anwendung kann diesen Tiefenpuffer aber auch nutzen, nämlich um Objekte zu sortieren. Man nutzt dann die Z-Koordinate der Objekte (= Tiefenkoordinate) quasi als Layer um zu kennzeichnen welches Objekt auf welcher "Höhe" liegt. Wenn man also z. B. einen 2D-Topdown-Shooter entwickelt bei dem der Spieler mit seinem Flugzeug über den Boden fliegt, dann nutzt man den Z-Puffer um die API (die das dann der Hardware überlässt) seine Objekte sortieren zu lassen. Das Flugzeug bekommt dann einen niedrigen Z-Wert (=oben) und Objekte auf dem Boden einen hohen Tiefenwert (=unten/hinten). Die Sortierung übernimmt dann die Grafikkarte und wir müssen uns darum keine Gedanken machen. Würden wir die Anwendung z. B. über die GDI realisieren, müssten wir diese Objekte selbst entsprechend ihrer Höhe sortieren.


Quelle: http://wiki.delphigl.com/index.php/Tutorial_2D

Die Sachen in diesem Wiki sind zwar alt, aber was sollte sich was den depth Buffer angeht geändert haben? Oder verstehe ich das falsch ODER ist dieser Eintrag generell falsch?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

24.01.2012, 19:00

Ich sagte es bereits: Ein Z-Buffer nimmt KEINE Tiefensortierung vor, sondern verhindert ein Overdraw von Objekten, die man ohnehin nicht sehen dürfte.


Zwei Beispiele (unter der Annahme dass die *übliche* kleiner-gleich-Funktion für den Buffer verwendet wird):

A) Es werden zwei Quads in der Größe des Viewports gerendert. Erst ein rotes nahe an der Kamera und danach ein blaues weiter weg. Was man sieht ist das rote, da das blaue durch den Z-Buffer blockiert wird.

B) Es werden zwei Quads in der Größe des Viewports gerendert. Erst ein rotes weit weg von der Kamera und danach ein blaues näher dran. Was man sieht ist das blaue, da die Z-Werte kleiner sind als die des roten und damit durchkommen.

Problem hierbei sind transparente Objekte, denn für den Z-Buffer sind sie nicht transparent, sondern absolut opak. Der Artikel da oben ist daher entweder sehr schlecht ausgedrückt oder schlichter Unfug.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

24.01.2012, 19:00

Wo vorne und hinten ist hängt von deiner Projektionsmatrix ab und nicht von irgendwelchen Wiki Artikeln...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

9

24.01.2012, 19:08

Gut gut ich lass den depth Buffer raus...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

24.01.2012, 19:12

Achso @BlueCobold: Ich hab das genau so verstanden, aber müsste dann der depth Buffer nicht auch in 2D verhindern das Dinge die "weiter weg" sind nicht angezeigt werden (bzw. ein Teil der Pixel)?

Zitat

Wo vorne und hinten ist hängt von deiner Projektionsmatrix ab und nicht von irgendwelchen Wiki Artikeln...


Darum geht es doch nicht, ich weiß "wierum" meine Projektionsmatrix aufgebaut ist, es ging alleine um die Funktion des depth buffers im orthogonalen Raum. Übrigens wird hier die Matrix dazu aufgesetzt:

C-/C++-Quelltext

1
2
projection.setIdentity();
projection.ortho(int(viewport[0].x), int(viewport[1].x), int(viewport[0].y), int(viewport[1].y), -1, 1);


ortho() macht genau das gleich wie glOrtho, also z-near = -1 und far = 1.

Werbeanzeige