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

1

21.05.2013, 18:31

[C++ OpenGL] Vertex Buffer und seine Probleme

Hi,
Da mir des öfteren empfohlen wurde speziell für Tilemaps einen Vertex Buffer zu benutzen, habe ich mich tatsächlich mal daran versucht. Nach einigen Tutorials und Dokumentationen war ich in der Lage einen Renderer hinzu klatschen der für die Testmap (Tile-Anzahl: 128*64) wunderbar funktioniert hat (auch sehr viel schneller wie ich dank dem High Perfomance Timer gemessen habe). In einer anderen Map dagegen (150*50) gab es sehr komische Ausgaben (siehe Bild im Anhang). Da ich mich mit dem Vertex Buffer noch kaum auskenne, wäre ich dankbar wenn ihr mir sagen könntet was ich falsch mache.
Weiterhin sei gesagt, dass ich noch eine Kompatibilität für Computer zu wahren habe, die keinen Vertex Buffer unterstützen, weswegen ich die langsame Methode noch einschalten kann mit der beide Maps korrekt angezeigt werden (leider dafür nur halb so schnell), die Mapdaten also nicht korrupt sind.
Mfg Helco

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
        bool TileLayerBuffered::Load (Stream* str)
        {
            if (!TileLayer::Load (str))
                return false;
            vboID=Framework->GetNewBufferID ();
            glBindBufferARB(GL_ARRAY_BUFFER_ARB,vboID);
            glEnableClientState(GL_VERTEX_ARRAY);
            uint len=(uint)size.x*(uint)size.y*20*sizeof(float);
            glBufferDataARB(GL_ARRAY_BUFFER_ARB,len,0,GL_STATIC_DRAW);
            if (glGetError ()==GL_OUT_OF_MEMORY) {
                cout << "Couldn't allocate " << len << "Bytes for tilelayer graphic buffer!" << endl;
                return false;
            }
            float* tiles=(float*)(glMapBufferARB(GL_ARRAY_BUFFER,GL_WRITE_ONLY_ARB));
            byte* dataPtr=data;
            float w=size.x*16.0f;
            float h=size.y*16.0f;
            FPoint oneTile(1.0f/image->tileCount.x,1.0f/image->tileCount.y);
            for (float y=h;y>=0.0f;y-=16.0f) {
                for (float x=0.0f;x<w;x+=16.0f,dataPtr++,tiles+=20) {
                    tiles[0]=(*dataPtr%image->tileCount.x)*oneTile.x; //0.0f,1.0f x,y
                    tiles[1]=(*dataPtr/image->tileCount.y+1)*oneTile.y;
                    tiles[2]=x;
                    tiles[3]=y-16.0f;
                    tiles[4]=0.0f;

                    tiles[5]=(*dataPtr%image->tileCount.x+1)*oneTile.x; //1.0f,1.0f w,y
                    tiles[6]=(*dataPtr/image->tileCount.y+1)*oneTile.x;
                    tiles[7]=x+16.0f;
                    tiles[8]=y-16.0f;
                    tiles[9]=0.0f;

                    tiles[10]=(*dataPtr%image->tileCount.x+1)*oneTile.x; //1.0f,0.0f w,h
                    tiles[11]=(*dataPtr/image->tileCount.y)*oneTile.x;
                    tiles[12]=x+16.0f;
                    tiles[13]=y;
                    tiles[14]=0.0f;

                    tiles[15]=(*dataPtr%image->tileCount.x)*oneTile.x; //0.0f,0.0f x,h
                    tiles[16]=(*dataPtr/image->tileCount.y)*oneTile.x;
                    tiles[17]=x;
                    tiles[18]=y;
                    tiles[19]=0.0f;
                }
            }
            glUnmapBufferARB (GL_ARRAY_BUFFER_ARB);
            glDisableClientState(GL_VERTEX_ARRAY);
            glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
            return true;
        }
        void TileLayerBuffered::Render ()
        {
            uint len=5*((uint)size.x)*((uint)size.y);
            glTranslatef(pos.x,pos.y,0.0f);
            glBindTexture(GL_TEXTURE_2D,image->texture.id);
            glBindBufferARB(GL_ARRAY_BUFFER_ARB,vboID);
            glEnableClientState(GL_VERTEX_ARRAY);
            glInterleavedArrays(GL_T2F_V3F,5*sizeof(float),0);
            glDrawArrays(GL_QUADS,0,len);
            glDisableClientState(GL_VERTEX_ARRAY);
            glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
            glTranslatef(-pos.x,-pos.y,0.0f);
        }
»Helco« hat folgendes Bild angehängt:
  • bug001.png

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

21.05.2013, 19:07

Von OpenGL habe ich selbst so gut wie keine Ahnung. SFML2 kann im Prinzip was du möchtest. Vielleicht hilft da ein Blick in den Code um dein System aufzubauen. Ansonsten wäre es vielleicht praktisch wenn du noch dazu schreiben würdest was in dem Bild nicht nach deinen Vorstellungen ist. Mir würde auffallen, die Tiles wirken irgendwie falsch. Auf mich wirkt es abgeschnitten. Also so, als wenn die Tiles jeweils größer sein sollten. Und alles ist irgendwie mitten im Bild. Wobei letzteres ja eigentlich nur eine Renderfrage ist. Zu ersterem würde ich gucken ob die Texturkoordinaten richtig sind. Aber gut wäre es allgemein wenn du noch einen Screenshot posten würdest wie es aussehen soll;)
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

3

21.05.2013, 20:21

In Zeile 28, 34, und 40 soll es vermutlich "oneTile.y" heißen.

Nebenbei solltest du dir angewöhnen, nach Kommas bzw. um binäre Operatoren Leerzeichen zu setzen und eine konsistentere Formatierung zu verwenden. Das würde die Lesbarkeit des Codes unglaublich steigern.
Ein heißer Tipp für das "Tiles"-Array wäre übrigens das Verwenden einer Struktur.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

21.05.2013, 20:52

Definitiv, da fehlen jede Menge Leerzeichen, damit das lesbar wird.
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]

5

21.05.2013, 21:02

Wow danke, das hätte einen Platz im "WTF-Codeschnipsel" Thread verdient...
Das mit der Struktur: Ja, ich hab nur immer (die vermutlich eher paranoide) Angst dass die Struktur nicht genau 20Bytes groß wird (da manche Compiler Strukturen auf Vielfaches von 8 aufblähen) und ich dann beim Debuggen dumm aus der Wäsche schau...

Edit: Der Vollständigkeits halber: wenn man nun noch in den Zeilen 22, 28, 34 und 40 tileCount.y durch tileCount.x ersetzt, funktioniert der Code auch für Tilesets die nicht quadratisch sind...
Und die Moral von der Geschichte: Neuen Code mit neuen Methoden nicht abends schnell hinschreiben sondern das Hirn einschalten und das Ganze in Ruhe machen...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Helco« (21.05.2013, 21:15)


DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

21.05.2013, 21:27

Zitat von »Helco«

Wow danke, das hätte einen Platz im "WTF-Codeschnipsel" Thread verdient...

Nur wenns in sich nicht logisch wäre...

Ich würde außerdem ein paar Leerzeilen einfügen. Sind ja auch nur gut gemeinte Tipps ;)

Werbeanzeige