Vertex & Textur & Dampfende Köpfe

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

Infected

Betreff: Vertex & Textur & Dampfende Köpfe

BeitragDi, Sep 17, 2013 16:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo! Ich denke mal, dass dieses Problem öfter mal auftritt, deshalb frag ich mal in einem eigenständigen Thread.

Nach viel rumtüfteln, hab ich nun herausgefunden wie das Texturieren von Blöcken wie bei Minecraft funnktioniert. Für meine Frage stelle ich mal folgendes Scenario auf:

4EckPunkte, zu einer quadratischen Fläche verbunden.
Eine Textur, die in 4 gleich große Teile aufgeteilt wird. (2 Teile oben, 2 Unten)

Theoretisch, muss ich beim erstellen der Eckpunkte, die UV Coordinaten entsprechend anpassen:
AddVertex(Surface,X,Y,Z,U,V)

Nach meiner Logik, wenn ich dieser fläche jetzt die obere Rechte Textur zuordnen möchte, muss ich das ganze so erstellen:

obenlinks=AddVertex(Surface,X,Y,Z,0.5,1)
untenlinks=AddVertex(Surface,X,Y,Z,0.5,0.5)
obenrechts=AddVertex(Surface,X,Y,Z,1,1)
untenrechts=AddVertex(Surface,X,Y,Z,1,0.5)

So sollte dieser Fläche doch theoretisch die rechte-obere Textur zugewiesen werden, oder irre ich mich da?
Das ergebnis mit diesen U/V Werten: das selbe wie bei

obenlinks=AddVertex(Surface,X,Y,Z,0,1)
untenlinks=AddVertex(Surface,X,Y,Z,0,0)
obenrechts=AddVertex(Surface,X,Y,Z,1,1)
untenrechts=AddVertex(Surface,X,Y,Z,1,0)


Entweder stimmt meine Logik nicht, oder aber die Nachkommastellen werden einfach abgeschnitten.. was ich mir allerdings auch nicht erklären könnte.

Hat jemand eine Idee für mich?


Edit:
Problem gelöst.
bzw. Probleme..
1. Problem .. U und V wurden zum neu aufbauen des surface nicht als float übergeben
2. Problem Theoretisch ist 0/0 ja links unten in der textur.. bei MInib3d aber links oben..

Angenommen ich hätte jetzt 50 verschiedene texturen zur auswahl, wie würde ich das am besten anstellen?

Edit2:
Kann mir noch jemand sagen wodurch diese Fehler entstehen? Also a) die kleinen pixelbreiten abstände zwischen den blöcken und b) die querstriche bei der zweiten textur

user posted image


Das ist die zugehörige Textur:
user posted image


Und hier passiert die U/V zuweisung:

Code: [AUSKLAPPEN]

        'Oben
   Vertex[00]=AddVertex(Surface,X#-1,Y#+1,Z#+1,0.333,0.333) 'Links oben
   Vertex[01]=AddVertex(Surface,X#+1,Y#+1,Z#+1,0.666,0.333) ' Rechts oben
   Vertex[02]=AddVertex(Surface,X#+1,Y#+1,Z#-1,0.666,0.666) 'rechts unten
   Vertex[03]=AddVertex(Surface,X#-1,Y#+1,Z#-1,0.333,0.666) 'links unten
   'Unten
   Vertex[04]=AddVertex(Surface,X#-1,Y#-1,Z#-1,0.5,1)
   Vertex[05]=AddVertex(Surface,X#+1,Y#-1,Z#-1,1,1)
   Vertex[06]=AddVertex(Surface,X#+1,Y#-1,Z#+1,1,0.5)
   Vertex[07]=AddVertex(Surface,X#-1,Y#-1,Z#+1,0,0)
   'Vorn
   Vertex[08]=AddVertex(Surface,X#-1,Y#+1,Z#-1,0,0.333) 'links oben
   Vertex[09]=AddVertex(Surface,X#+1,Y#+1,Z#-1,0.333,0.333)   ' rechts oben
   Vertex[10]=AddVertex(Surface,X#+1,Y#-1,Z#-1,0,0.666) ' links unten
   Vertex[11]=AddVertex(Surface,X#-1,Y#-1,Z#-1,0.333,0.666)  ' rechts unten
   'Hinten
   Vertex[12]=AddVertex(Surface,X#+1,Y#+1,Z#+1,0,0.333)
   Vertex[13]=AddVertex(Surface,X#-1,Y#+1,Z#+1,0.333,0.333)
   Vertex[14]=AddVertex(Surface,X#-1,Y#-1,Z#+1,0,0.666)
   Vertex[15]=AddVertex(Surface,X#+1,Y#-1,Z#+1,0.333,0.666)
   'Rechts
   Vertex[20]=AddVertex(Surface,X#+1,Y#+1,Z#-1,0,0.333)
   Vertex[21]=AddVertex(Surface,X#+1,Y#+1,Z#+1,0.333,0.333)
   Vertex[22]=AddVertex(Surface,X#+1,Y#-1,Z#+1,0,0.666)
   Vertex[23]=AddVertex(Surface,X#+1,Y#-1,Z#-1,0.333,0.666)
   'Links
   Vertex[16]=AddVertex(Surface,X#-1,Y#+1,Z#+1,0,0.333)
   Vertex[17]=AddVertex(Surface,X#-1,Y#+1,Z#-1,0.333,0.333)
   Vertex[18]=AddVertex(Surface,X#-1,Y#-1,Z#-1,0,0.666)
   Vertex[19]=AddVertex(Surface,X#-1,Y#-1,Z#+1,0.333,0.666)
 

Kruemelator

BeitragMi, Sep 18, 2013 0:46
Antworten mit Zitat
Benutzer-Profile anzeigen
zu a):
Erklärt es ganz gut und hat auch noch Bilder: http://msdn.microsoft.com/en-u...85%29.aspx
zu b):
Die diagonale Kante entsteht weil du die UV zweier Punkte vertauscht hast.
Code: [AUSKLAPPEN]
12
34

12
43

Der grüne Strich ist der Rand zu der Nachbar Gras-Textur (der eigendlich vertikal sein sollte). Wenn du genau hinkuckst erkennst du einen Unterschied wenn du die Textur mit einer Würfelseite vergleichst.
Einfach bei den beiden unteren Punkten der Seiten die UV Koordinaten tauschen. (P1 bekommt die von P2 und umgekehrt)

Versuche auch soetwas wie 0.333 zu vermeiden und wenn es nicht geht dann schreib besser 1/3.0 hat nämlich mehr Stellen als deine 0.333. Besser ist es 2,4... Tiles nebeneinander zu packen.
 

Infected

BeitragMi, Sep 18, 2013 17:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey! Hab es jetzt soweit hin bekommen.. nur türmen sich die probleme..
Es werden jetzt einfach einige Chunks gar nicht erst gezeichnet.. bei 3x3 ist alles in ordnung, alles drüber.. ja da fehlt dann was.. sogar von den blocks fehlen einige seiten.. keine ahnung warum.. und bei 6x6chunks gibt es kaum noch perfomance... 9x9 gibt mir sogar einen memory violation fehler aus..
Hab hier mal den code und einige .exe dateien mit angehängt.

Exe Dateien: 3x3chunks, 4x4chunks,5x5chunks(sehr slow)

vielleicht hat ja jemand ideen woran die probleme liegen können =/
http://www.dudecraft.de/ablage/testgame.rar
 

Kruemelator

BeitragDo, Sep 19, 2013 9:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Meshes dürfen eine bestimmte Größe nicht überschreiten, also weder zuviele Eckpunkte noch zuviele Dreiecke haben. Man kein einfach in mehrere unterteilen.
Um bessere Performenz zu erreichen sollte sowenig gezeichnet werden wie nur möglich.

DAK

BeitragDo, Sep 19, 2013 10:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Du könntest eventuell größere Blöcke zu einem zusammenfassen, also wenn du zwei gleiche Blöcke nebeneinander hast, die Vertices zwischen ihnen weglassen, so dass es ein größerer Block wird. So könntest du dir enorm viele Vertices und Faces sparen.

Außerdem könntest du den Sichtbarkeitscheck auch chunkübergreifend machen. Dadurch würdest du dir auch Unmengen an Faces und Vertices sparen.
Gewinner der 6. und der 68. BlitzCodeCompo
 

Infected

BeitragMo, Sep 23, 2013 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Huhu, danke für eure Hinweise, hab das meiste umsetzen können!
Allerdings hab ich schon wieder Probleme:
user posted image

Dann überleg ich hin und her wie ich das mache, chunk übergreifend nach nachbarblöcken zu prüfen(ob die seiten gann eben gemalt werden oder nicht). Leider fällt mir dazu nix ein =/

Hier noch Code+Exe+Textur: http://www.dudecraft.de/ablage/testgame.rar


Ja ich weiß, sehr unübersichtlich mein Code ... Mad

Vllt weiß auch einer eine bessere möglichkeit als meine, den Blöcken je nach Typ die passenden texturen zuzuweisen

DAK

BeitragMo, Sep 23, 2013 22:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiß nicht, wie du deine Chunks speicherst (hab nicht durch den Code geschaut). Ich nehme an, du speicherst das Ganze in dreidimensionalen Arrays, oder?

Das mit dem chunkübergreifenden Prüfen würde ich dann so machen:

Ist der zu überprüfende Block kein Randblock -> return
Ansonsten:
z.B. der Block befindet sich am niedrigen x-Rand (also x=0).
Überprüfe ob im angrenzenden Chunk (der mit z = aktuelles (Chunk) z und x = aktuelles (Chunk) x-1) der Block an der Stelle x = maximales x (bei einer Chunkgröße von 5x5 also 5), y = aktuelles y, z = aktuelles z gesetzt ist.
Ist der Block frei -> Face zeichnen
Ansonsten -> Face nicht zeichnen
Gewinner der 6. und der 68. BlitzCodeCompo
 

Infected

BeitragDi, Sep 24, 2013 22:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke für den Tipp! Smile Werde ich umsetzen sobald ich mit folgendem Problem fertig geworden bin.

Momentan ist der Plan, dass immer nur 9x9 Chunks gleichzeitig angezeigt werden.

Leider weiß ich jetzt gar nicht wie ich das am besten mache.

Also die Spielervariablen x und y habe ich gegeben, also muss ich Theoretisch alle Chunks malen dessen X und Y innerhalb dieses Bereichs liegen (1 chunk hat breite und länge 32) PlayerX-(32*5) - PlayerX+(32*5)
PlayerY-(32*5) - PlayerY+(32*5)

oder denke ich mir das jetzt falsch?

Und wie überprüfe ich ob der chunk schon besteht oder nicht?
Da ich das ganze ja nur in die chunklist eintrage, und kein Array dafür habe(da die map ja erstmal keine größenrestriktionen hat)
 

PhillipK

BeitragDi, Sep 24, 2013 23:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du einen Chunk hast, solltest du ihn auch wie einen behandeln^^
Ein Chunk ist sowas wie eine map in einer map. Oder noch besser: Ein array in einem array.

Wenn du weißt, das du 9x9 chunks um den player rum malen willst, dann willst du erstmal den chunk wissen, wo der player sich befindet.

Da du schreibst, das deine chunks 32x32 groß sind, ist es also: ChunkX = Player.X / 32 und ChunkY= Player.Z / 32.

Nun gehts ganz einfach, sofern du die sektoren aka chunks in einem array sortiert hast:
Zeichne alle sektoren mit 2 forschleifen:
BlitzMax: [AUSKLAPPEN]
For Local __X: Int = ChunkX - 4 To ChunkY + 4
If __X < 0 Then Continue
If __X >= MAX_CHUNKS Then Continue
For Local __Y:Int = ChunkY - 4 To ChunkY + 4
If __Y < 0 Then Continue
If __Y >= MAX_CHUNKS Then Continue

ChunkObjekte[__X,__Y].RendeR()
Next
Next


falls du verstehst Smile

Hast du deine chunks allerdings anders, undzwar nur gedachter weise, so lohnt es trotzdem, erst auf die chunk-position zu brechen.

Beispiel: Du hast einen mega-block array. Du "denkst" dir alle 32 blöcke eine linie, welche einen chunk darstellt.
Wenn du nun auf eine Integer-Chunkposition runterrechnest, hast du immernoch den effekt "richtige sektoren" zu haben und kannst viel einfacher rechnern Smile
Aber vorallem: Du sparst unmengen If-abfragen ein, wenn du nur alle 32x32 schritte ein wenig was prüfst und den rest vorraussetzt.
Würdest du für jeden block eine im-sichtfeld prüfung machen & gucken ob der denn noch grob in der nähe des spielers ist, kann das ein ziemlicher bottleneck sein.

EDIT:

uuuuups, hab grade nochmal deine anfrage durchgelesen.
Die letzte zeile, das du keinen array dafür verwendest..
Okay, das is schon trickier.
Ich rate hier zu einem quadtree.

Das hat den vorteil, das sie unendliche maps unterstützen können - theoretisch.

Hier in deinem speziellen fall könnte es sich sogar anbieten, das ganze ein wenig aufzupeppen.
Grundlegend ist ein Quadtree nichts weiter wie ein Baumdiagram wenn du so willst, wo beliebig viele knoten hinzukommen, allerdings pro knoten max. 4 äste zu niedriegeren stufen.
Stell dir vor, du hast ein Quadrat, deine map.
Nun teile die map in 2x2 teile, das werden einzelne äste - dahinter steht also je ein kleinerer map ausschnitt.
Dies verfeinert sich so weit, bis ein so ein mapausschnitt einem Sektor entspricht.

Allerdings erfordert ein Quadtree, so einfach sie auch aussehen mögen, dennoch ein wenig einlesen.. also ist das vielleicht nicht das gelbe vom ei.

Als alternative könnte die TMap herhalten - ebenfalls eine art Baum. Binärtree, um genau zu sein (wenn ich das richtig in erinnerung habe)

In einer TMap kannst du beliebige objekte einfügen und ihnen einen String bezeichner geben.
Ein stringbezeichner für deine sektoren könnte zb 0011,0001 sein (ChunkX,ChunkY).
Diesen string müsstest du dann für deine wunsch sektoren anfertigen und aus der tmap anfordern. Könnte aber mitunter, recht performance lastig sein.
Allerdings ist die TList ebenso performance lastig, wenn zuviele objekte drin sind - stell dir vor, du musst bis zum ende iterieren und hast 256x256 chunks - 65536 chunks in der liste, und zu dem letzten willst du ^^


Zu der frage, ob ein chunk schon erstellt ist: Da bleibt dir wohl nichts anderes übrig, als die liste einmal komplett zu durchlaufen und den passenden sektor zu suchen. Ist er nicht gefunden worden, existiert er nicht.
 

Infected

BeitragMi, Sep 25, 2013 0:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke erstmal für deine riesen Antwort.
Ich merke gerade, dass meine Art nicht grade die beste ist.
Jedes mal alle chunks abzugrasen ob nun der richtige dabei ist, ist sehr perfomance lastig, und es gibt immer (alle X schritte) einen dicken ruckler.. nicht so optimal.

Würde ich das ganze jetzt per Array lösen wollen, wie sollte ich daran gehen?
Nen Type brauch ich trotzdem, das ist schonmal klar. Ich kann die Map ja auch meinetwegen auf 256x256 Chunks beschränken, muss ja nicht unendlich groß sein, ist denke ich einfacher.

Aber.. Angenommen das Programm weiß jetzt, dass mein Block der zu überprüfen ist ein Randblock ist..
Wie geh ich weiter vor? Wonach frag ich ab? Ich muss dann ja wieder durch die ChunkList durch blättern um zumindest an die cubelist des benachbarten Chunks zu kommen..
Kann man nicht einfach einen Chunk direkt ansteuern?
quasi als abfrage Suche einen chunk mit chunk.x = x und chunk.y = y ?
 

PhillipK

BeitragMi, Sep 25, 2013 0:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Kommt auf die umsetzung an Razz

Das vorhaben, eine unendliche map zu erschaffen, ist nobel. Aber wenn das deine erste map in die richtung ist, solltest du dir das lieber für eine später version aufbewahren.

Wenn du mit arrays arbeitest, lohnen sich als erstes fixe werte. Du hast zum einen eine ChunkCountX, ChunkCountY und dazu BlocksPerChunksX BlocksPerChunksY

position auf chunk brechen ist dann einfach:
Pos / BlocksPerChunksX/Y = ChunkX/Y < 0 oder ChunkX/Y >= ChunkCountX/Y dann ist es ausserhalb der map.
Ansonsten kannst du mit ChunkX-1 zb auf den Linken chunk zugreifen.

Soviel zur chunkposition im array.
Nun gehts weiter:
Hast du die blockdaten "global" in der map gespeichert? Dann solltest du intern beim rechnen die aktive blockposition an gewissen stellen auf die chunkposition brechen und mit dem aktuellen chunk vergleichen.
Diese "gewisse stelle" könnte zb sein, wenn du nachbar blöcke anfrägst.

Ein - meiner meinung nach - besserer ansatz ist allerdings, das jder chunk seinen eigenen block array hat.
Dieser hat fixe größen 32x256x32 (32x32 auf x und z, 256 in der höhe. Wobei du hier argh vorsichtig sein solltest ^^).
Beim checken, welchen nachbar du brauchst, kannst du leicht feststellen, ob die sektor interne blockposition < 0 oder >= BlocksPerChunksX , dann brauchst du einen benachbarten sektor, den du über die map anfragst.

Alles ganz einfach - aber kommt auf die umsetzung an Razz


Die aufgabe an dich wird nun sein, überlege dir, wie du deine daten verwalten willst. Liste? Quadtree? Octree? Array?
Eine idee meinerseits die ich mal hatte: 2x2 arrays, um unendliche maps zu realisieren? (ein array wird gespiegelt auf x dargestellt, einer wird gespiegelt auf y dargestellt, einer auf xy gespielt, einer normal...) Hab ich aber nie umgesetzt *grins*

Danach musst du den code präsentieren und weitere schritte können durchdacht werden Smile Oder dir fällt beim einbauen des ganzen auf, wie man das lösen könnte. wer weiß^^

Ps. Hier mal ein link zum quadtree den ich eben gefunden habe.
Vielleicht hilfts zum verstehen, was das eigl fürn ding ist Smile
(stell dir jedes zielquadrat als sektor vor, welches im dreidimensionalen raum existiert, der quadtree ist allerdings nur 2d - bezieht sich auf x,z wärend y die höhe der map ist)
http://www.informatik.uni-trie...ithmus.htm
 

Infected

BeitragMi, Sep 25, 2013 0:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke erstmal. Das ist grad ein wenig verwirrend für mich und ich werde es mir morgen nochmal ausgeschlafen ansehen Very Happy



Edit.: Commando zurück, dummer fehler meinerseits.. Hab vergessen nach der Z position des Chunks abzufragen Embarassed

Also die Seiten werden jetzt nicht mehr gezeichnet wenn im nachbarchunk ein block an der stelle ist, also das passt alles Smile

allerdings weiß ich nicht wie ich das machen soll, dass tatsächlich nur die chunks gezeichnet werden, die gerade benötigt werden. bzw vor allem wie ich es anstelle dass nur die jenigen surfaces gelöscht werden, die ausm sichtbereich gelangt sind, und wie ich die frei gewordenen plätze (in dem erdachten 9x9chunks sichtfeld) neu gefüllt werden.. ich habs versucht und bin kläglich gescheitert.. hab nochmal angehängt das ganze :s

http://www.xup.in/dl,20017963/testgame.rar/

DAK

BeitragMi, Sep 25, 2013 10:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Was du noch machen könntest, (nicht so schön wie ein Quadtree, aber deutlich einfacher) ist, die Quads in ein Array zu packen (so 64x64 Quads oder so), und die dann in eine Liste. Auf die Art kombinierst du das einfache Verwalten von Arrays mit unendlichen Welten. Und solange der Spieler nicht ewig weit weg rennt (-> richtig große Welten generiert) ist dann auch mit der Performance alles ok.

Was auch möglich wäre, ist wenn du in jedem Chunk einen Link auf jeden benachbarten Chunk hast. Dann brauchst du nur noch einen Link vom Spieler auf den aktuellen Chunk um die ganze Struktur am Leben zu erhalten.
Du beginnst die Updates dann von dem Spielerchunk aus, und gehst dann so Floodfill-Mäßig von dem Chunk aus die anderen ab, und achtest jeweils darauf, dass du nur eine bestimmte Distanz weit vom Spieler weg zeichnest.
Gewinner der 6. und der 68. BlitzCodeCompo
 

Infected

BeitragDo, Sep 26, 2013 15:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey! Also bisher hab ich noch jedes Problem gelöst bekommen! (Ich bin arg stolz auf mich, normalerweise geb ich bei solch scheinbar unlösbaren problemen einfach auf)
Jetzt fehlt mir nur noch eine Sache bis ich endlich an den einfachen und spaßigen teil des ganzen gehe...

Wie prüfe ich am besten ob ein Chunk überhaupt schon generiert wurde? Ich will, dass unerforschte gebiete in laufzeit generiert werden, damit die anfängliche Ladezeit beim map erstellen nicht zu lang wird(welche jetzt bei 9x9 Chunks schon ziemlich lang ist). Im original minecraft wird das auch genauso gemacht..
Aber wie mach ich das jetzt am besten? vor allem.. ohne massive einbußen der perfomance?


Aaalso.. es werden jetzt, wenn man nah genug an den Rand geht.. neue Chunks erstellt, allerdings geht das immer mit nem mächtigen Ruckler einher..


Momentan werden Chunks so hergestellt: Jeder Vertex und jedes Triangle wird einmal gezeichnet.
Wenn der Chunk dann gebraucht wird, wird dieser neu aufgebaut, er wird erst gecleared,dann nur noch mit den Vertices und Triangles die auch vom Spieler gesehen werden können wieder aufgebaut.
D.h. die anderen Daten die beim anfänglichen aufbauen entstanden sind(die vertices der seiten die nicht gezeichnet werden, und deren u/v coordinaten) sind verschwunden.
Ich hab in einem Array ( Cubes[x,y,z] ) die Inhalte der Cubes gespeichert.. also ob es ein "leerer cube", gras, stein oder was auch immer ist..
Das wird beim ersten aufbauen der scene genommen um die cubes einmal komplett aufzubauen.

Wenn ich jetzt aber einen Cube lösche, wo krieg ich dann die Daten für die umliegenden blöcke und deren vorher verdeckten seiten her?

Ich denke ich hab hier irgendwo einen fatalen fehler gemacht und befürchte dass ich irgendwas auch komplett umstrukturieren muss..

Das hängt alles auch zusammen mit meinem anfänglichen Problem mit den neu erstellten Chunks und den rucklern. Die entstehen, weil die Chunks eben so (unnötig) kompliziert erstellt werden.
Wie mach ich es jetzt besser?
Wie mach ich das mit der Cube erstellung?
Ich würde auch ungern zweimal die U/V Coordinaten übergeben müssen.. es sei denn es geht nicht anders.. Dann müsste ich die texturen als einzelne dateien speichern, und im code dann zu einem Bild mit 1*x Texturtiles zusammenfügen, dann lassen sich die passenden uv coordinaten ja relativ einfach berechnen..

Bitte, jemand der diesen Post verstanden hat.. hilfe! Very Happy

http://www.xup.in/dl,11487465/testgamenew.rar/ (Hier exe, code und textur, momentan erstellen sich nur chunks in zwei richtungen, da das array nicht in den minusbereich geht)
 

Kruemelator

BeitragFr, Sep 27, 2013 0:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich das richtig verstehe hast du ein Array Cubes(x,y,z) wo du die Art des Cubes speicherst, z.B. 0=leer, 1=gras, 2=stein?
Diese würde ich dann nicht mehr ändern es sei den du baust in deiner Welt rum. Wenn du jetzt einen neuen Chunk brauchst dann gehst du einfach alle Cubes durch die zum Chunk gehören und prüfst ob ein "leerer" Cube angrenzt. Du musst alle sechs Seiten prüfen: oben,unten,links,rechts,vorne,hinten. Wenn mindestens ein "Nachbar" leer ist dann musst du den Cube zu deinem Mesh hinzufügen. Es werden nur die Seiten(Quads) des Cubes hinzugefügt die an einen "Leeren" grenzen.

Um Dinge in Laufzeit zu generieren musst du einach den Vorgang in mehrere Teile unterteilen.
 

Infected

BeitragFr, Sep 27, 2013 15:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Kruemelator hat Folgendes geschrieben:
Wenn ich das richtig verstehe hast du ein Array Cubes(x,y,z) wo du die Art des Cubes speicherst, z.B. 0=leer, 1=gras, 2=stein?
Diese würde ich dann nicht mehr ändern es sei den du baust in deiner Welt rum. Wenn du jetzt einen neuen Chunk brauchst dann gehst du einfach alle Cubes durch die zum Chunk gehören und prüfst ob ein "leerer" Cube angrenzt. Du musst alle sechs Seiten prüfen: oben,unten,links,rechts,vorne,hinten. Wenn mindestens ein "Nachbar" leer ist dann musst du den Cube zu deinem Mesh hinzufügen. Es werden nur die Seiten(Quads) des Cubes hinzugefügt die an einen "Leeren" grenzen.

Um Dinge in Laufzeit zu generieren musst du einach den Vorgang in mehrere Teile unterteilen.


Genauso mach ich es momentan, aber wie meinst du das mit "In mehrere Teile unterteilen" ?


Edit: hab jetzt den Code mal vollständig überarbeitet, funktionen zusammen gefasst, unnötiges weggelassen etc.

leider funktioniert es jetzt nur noch teilweise.. :/
Also es wird alles soweit aufgebaut, nur sobald ich mich bewege, und ein rebuild aufgerufen wird.. fängts an zu buggen, und ich weiß nicht warum. wenn man lang genug umher-buggt sind auch aufeinmal total verzogene triangles zusehen, was aber keinen sinn ergibt, weil ich in der funktion (rebuild()) keine fehler bei der vertexerstellung finden kann..
Habe mich jetzt entschlossen, dass die maps nicht in laufzeit generiert werden, also zumindest wird jeder Chunk(types) erstellt, und das darin befindliche block-array gefüllt.
Die texturen werden jetzt anders zugeordnet(klappt allerdings noch nicht so wie ich es mir vorstelle, keine ahnung warum) dafür werden alle einzelnen texturen im programm zu einer großen textur zusammen genommen, und dann als png gespeichert. danach wird dieses png als textur geladen(ist der leichteste weg, habs nicht hinbekommen aus ner pixmap direkt eine TTexture zu machen)

In laufzeit wird jetzt geprüft welche chunks in sichtweite sind, und ob diese schon gezeichnet sind.
Zusätzlich wird noch geprüft welche gezeichneten chunks nicht mehr in sichtweite sind, die werden gecleared.
aber das gibt nen riesen ruckler..
ausserdem bleiben manchmal einige chunks(erscheint mir sehr willkürlich) irgendwo im nirvana zurück, d.h. sie werden einfach nicht mit aufgebaut, obwohl sie nah genug am spieler dran sind..
Kurzum: die rebuild funktion ist irgendwie total vermurkst

Ich hab mal den Code nochmal beigefügt, und eine ausführbare compilierte .exe
Der code ist jetzt wie gesagt etwas aufgeräumt und meiner ansicht nach viel übersichtlicher.


Hier mal die rebuild funktion:
Code: [AUSKLAPPEN]
Function Rebuild()
   
   Local eX2:Float=EntityX(Camera)/16
   Local eY2:Float=EntityY(Camera)/16
   Local eZ2:Float=EntityZ(Camera)/16
   Local x:Int,y:Int,z:Int
   
   Local btype:Int
   
   
   
   
   
   For chunkx:chunk=EachIn ChunkLIst

   
   
   
               If chunkx.x < (ex2-5) Or  chunkx.x > (ex2+5)
               If chunkx.active > 0 Then chunkx.active = 1
               EndIf
               
               
         
               
               If chunkx.z < (ez2-5) Or chunkx.z > (ez2+5)
               If chunkx.active > 0 Then chunkx.active = 1
               EndIf
               
            
               
               
               If chunkx.x > (ex2-5) And chunkx.x < (ex2+5) And chunkx.z > (ez2-5) And chunkx.z < (ez2+5)
               If chunkx.active = 0 Then chunkx.active = 2
               EndIf
               

               

               

               





   If chunkx.active = 1
   ClearSurface chunkx.surface
   chunkx.active = 0
   EndIf
   
If chunkx.active = 2

   chunkx.active = 3
   
   ClearSurface(chunkx.surface)
   
   

   
   
   
   
   
   



   
For xx = 1 To 16
For zz = 1 To 16
For yy = 1 To 64
   '''''''''''''''''
   btype=chunkx.cubes[xx,zz,yy] ' Blocktyp(nötig für texturzuweisung)
      x= xx-16
      z= zz-16
      y= yy-50


   'OBEN'

   If chunkx.cubes[xx,zz,yy]>0      ' Cube wird nur gezeichnet wenn es einen Cubetype hat(keine Luft ist)   
   
      
      
      
      ';========================================================================================
      ';============================================TOP=========================================
   
      If chunkx.cubes[xx,zz,yy+1]=0
      
         V[00]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y+1,(Z+1)+chunkx.z*16,(btype-1)*128,0)   'Links oben
         V[01]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y+1,(Z+1)+chunkx.z*16,(btype)*128,0)   ' Rechts oben
         V[02]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y+1,(Z-1)+chunkx.z*16,(btype)*128,1) 'rechts unten
         V[03]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y+1,(Z-1)+chunkx.z*16,(btype-1)*128,1) 'links unten

         VertexNormal (chunkx.Surface,V[00],0,+1,0)
         VertexNormal (chunkx.Surface,V[01],0,+1,0)
         VertexNormal (chunkx.Surface,V[02],0,+1,0)
         VertexNormal (chunkx.Surface,V[03],0,+1,0)
         AddTriangle(chunkx.Surface,V[00],V[01],V[03])
         AddTriangle(chunkx.Surface,V[01],V[02],V[03])
         
      EndIf
      
   
   
   
   
   
   
   
   
   
   
   
    ';========================================================================================
    ';============================================BOTTOM======================================
   
   
   If chunkx.cubes[xx,zz,yy-1]=0
   
      V[04]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y-1,(Z-1)+chunkx.z*16,(btype-1)*128,0) 'links oben
      V[05]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y-1,(Z-1)+chunkx.z*16,(btype)*128,0)   ' rechts oben
      V[06]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y-1,(Z+1)+chunkx.z*16,(btype)*128,1) ' links unten
      V[07]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y-1,(Z+1)+chunkx.z*16,(btype-1)*128,1) ' rechts unten
   
      VertexNormal (chunkx.Surface,V[04],0,+1,0)
      VertexNormal (chunkx.Surface,V[05],0,+1,0)
      VertexNormal (chunkx.Surface,V[06],0,+1,0)
      VertexNormal (chunkx.Surface,V[07],0,+1,0)
      AddTriangle(chunkx.Surface,V[04],V[05],V[07])
      AddTriangle(chunkx.Surface,V[05],V[06],V[07])
      
   EndIf   
   
   
   
   
   
   
   
   
   ';========================================================================================
   ';============================================'VORNE======================================

      If zz = 1
         For aChunk:chunk = EachIn chunklist
      
            If aChunk.z = chunkx.z-1
            If achunk.x = chunkx.x
               If aChunk.cubes[xx,16,yy] = 0
         
                  Goto check3
               Else
                  Goto nocheck3
               EndIf
            EndIf
            EndIf
         
         Next
         
      EndIf
   
   
   #check3
   If chunkx.cubes[xx,zz-1,yy]=0

      V[08]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y+1,(Z-1)+chunkx.z*16,(btype-1)*128,0) ' links oben
      V[09]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y+1,(Z-1)+chunkx.z*16,(btype)*128,0)  ' rechts oben
      V[10]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y-1,(Z-1)+chunkx.z*16,(btype)*128,1) ' rechts unten
      V[11]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y-1,(Z-1)+chunkx.z*16,(btype-1)*128,1) ' links unten

      VertexNormal (chunkx.Surface,V[08],0,0,-1)
      VertexNormal (chunkx.Surface,V[09],0,0,-1)
      VertexNormal (chunkx.Surface,V[10],0,0,-1)
      VertexNormal (chunkx.Surface,V[11],0,0,-1)
      AddTriangle(chunkx.Surface,V[08],V[09],V[11])
      AddTriangle(chunkx.Surface,V[09],V[10],V[11])
      
   EndIf   
   
   #nocheck3
   
   
   
   
   ';========================================================================================
   ';============================================Hinten======================================
      If zz = 16
         For aChunk:chunk = EachIn chunklist
      
            If aChunk.z = chunkx.z+1
            If achunk.x = chunkx.x
               If aChunk.cubes[xx,1,yy] = 0
         
                  Goto check4
               Else
                  Goto nocheck4
               EndIf
            EndIf
            EndIf
         
         Next
         
      EndIf
   
   
   

   #check4
         
   If chunkx.cubes[xx,zz+1,yy]=0

      V[12]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y+1,(Z+1)+chunkx.z*16,(btype-1)*128,0) 'links oben
      V[13]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y+1,(Z+1)+chunkx.z*16,(btype)*128,0)  ' rechts oben
      V[14]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y-1,(Z+1)+chunkx.z*16,(btype)*128,1)  ' rechts unten
      V[15]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y-1,(Z+1)+chunkx.z*16,(btype-1)*128,1) ' links unten
      
      VertexNormal (chunkx.Surface,V[12],0,0,+1)
      VertexNormal (chunkx.Surface,V[13],0,0,+1)
      VertexNormal (chunkx.Surface,V[14],0,0,+1)
      VertexNormal (chunkx.Surface,V[15],0,0,+1)
      
      AddTriangle(chunkx.Surface,V[12],V[13],V[15])
      AddTriangle(chunkx.Surface,V[13],V[14],V[15])
      
   EndIf   
   
      #nocheck4
      
      
      
   ';========================================================================================
   ';============================================Links=======================================
      If xx = 1
         For aChunk:chunk = EachIn chunklist
      
            If aChunk.x = chunkx.x-1
            If achunk.z = chunkx.z
               If aChunk.cubes[16,zz,yy] = 0
         
                  Goto check5
               Else
                  Goto nocheck5
               EndIf
            EndIf
            EndIf
         
         Next
         
      EndIf

   '''''''''''''''''''''
   #check5
   
   If Not chunkx.cubes[xx-1,zz,yy]>0
      ';============================================
   ';============================================Left
   V[16]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y+1,(Z+1)+chunkx.z*16,(btype-1)*128,0) 'links oben
   V[17]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y+1,(Z-1)+chunkx.z*16,(btype)*128,0)  ' rechts oben
   V[18]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y-1,(Z-1)+chunkx.z*16,(btype)*128,1)  ' rechts unten
   V[19]=AddVertex(chunkx.Surface,(X-1)+chunkx.x*16,Y-1,(Z+1)+chunkx.z*16,(btype-1)*128,1) ' links unten
      VertexNormal (chunkx.Surface,V[16],-1,0,0)
      VertexNormal (chunkx.Surface,V[17],-1,0,0)
      VertexNormal (chunkx.Surface,V[18],-1,0,0)
      VertexNormal (chunkx.Surface,V[19],-1,0,0)
      AddTriangle(chunkx.Surface,V[16],V[17],V[19])
      AddTriangle(chunkx.Surface,V[17],V[18],V[19])
      
   EndIf   
   #nocheck5

      

   
   ';========================================================================================
   ';============================================Rechts======================================
      If xx = 16
         For aChunk:chunk = EachIn chunklist
      
            If aChunk.x = chunkx.x+1
            If achunk.z = chunkx.z
               If aChunk.cubes[1,zz,yy] = 0
         
                  Goto check6
               Else
                  Goto nocheck6
               EndIf
            EndIf
            EndIf
         
         Next
         
      EndIf
         
   #check6
   
   If Not chunkx.cubes[xx+1,zz,yy] > 0
      
      V[20]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y+1,(Z-1)+chunkx.z*16,(btype-1)*128,0)'links oben
      V[21]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y+1,(Z+1)+chunkx.z*16,(btype)*128,0) ' rechts oben
      V[22]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y-1,(Z+1)+chunkx.z*16,(btype)*128,1)' rechts unten
      V[23]=AddVertex(chunkx.Surface,(X+1)+chunkx.x*16,Y-1,(Z-1)+chunkx.z*16,(btype-1)*128,1) ' links unten
      
      VertexNormal (chunkx.Surface,V[20],+1,0,0)
      VertexNormal (chunkx.Surface,V[21],+1,0,0)
      VertexNormal (chunkx.Surface,V[22],+1,0,0)
      VertexNormal (chunkx.Surface,V[23],+1,0,0)
      
      AddTriangle(chunkx.Surface,V[20],V[21],V[23])
      AddTriangle(chunkx.Surface,V[21],V[22],V[23])
      
   EndIf   
   
   
   EntityTexture chunkx.mesh,TextureF
   #nocheck6
   
   
EndIf
   
   

Next
Next
Next

EndIf

   
Next
End Function



Hier die exe und der code:
http://www.xup.in/dl,15563884/Upload.rar/

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group