OpenGL Isomap mit mehreren "Layern"

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

PhillipK

Betreff: OpenGL Isomap mit mehreren "Layern"

BeitragDi, Okt 25, 2011 17:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Heyho!

Mich plagt grade ein problem, welches ich beim zeichnen meiner map auftritt.
Aufgrund von unterschiedlichen Texturen (mehrere Atlas-texturen, eine für Blöcke, eine für "Möbel", eine für Vegetation) ist es nicht möglich, alles schön sortiert in einem VertexArray zu halten.
Wegen einer Performancefrage möchte ich allerdings so wenig wie möglich an leistung für das Rendern "ausgeben".

Im moment halte ich 3 "ebenen" sichtbar - eine untere, eine "aktive", eine "darüber" zum interagieren.

Für diese 3 ebenen erstelle ich jeweils 6 vertex arrays - eine für texturen, eine für die vertexdaten.

Diese sollen nun von unten nach oben gezeichnet werden.
Die einzig sinnvolle lösung die ich hätte, um mein Reihenfolgeproblem zu lösen, wäre die map von "vorne" nach "hinten" zu sortieren, wodurch ich aber kaum 100 vertices pro Vertex-array halten würde. Ausserdem müsste ich zu oft die texturen wechseln, weshalb das performancetechnisch wohl nach hinten losgehen würde.


Eine weitere idee die ich hatte, wäre multitexture zu verwenden und dem shader einen wert mitzugeben, welche textur tatsächlich von nöten ist. Allerdings waren bisherige shaderversuche ebenfalls ziemlich unperformant - selbst kleinere if abfragen im Fragmentshader brachten 60fps einbuße (oder ich bin hier einfach zu blöd zu programmieren?)

Hier mal ein screenshot wie es aussieht:
(als link: Z ORDER PROBLEM , da auf 200% skaliert für bessere sichtbarkeit)

Das Rot umramte zeigt mein problem - die Bäume, die eigentlich "hinter" den blöcken seien sollten, liegen davor, da der Array später gezeichnet wird.

Das Rendern:

BlitzMax: [AUSKLAPPEN]
	Method RenderArray(map:TLandscape)
If Len(map.array) > 0 And Len(map.texarray) > 0 Then
'If Len(map.array) <> Len(map.texarray) Then RuntimeError("Array längen unterschiedlich")
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)

Local i:Int, j:Int, depth_test:Int = 1

For i = 0 Until Len(map.array)
For j = 0 Until Len(map.array[i])
Select j
Case 0
glBindTexture(GL_TEXTURE_2D, TBlock_data.Block_Tex)
Case 1
glBindTexture(GL_TEXTURE_2D, TBlock_data.Vegetation_tex)
Case 2
glBindTexture(GL_TEXTURE_2D, TBlock_data.Furniture_tex)
End Select

glVertexPointer(3, GL_FLOAT, 0, map.array[i][j])
glTexCoordPointer(2, GL_FLOAT, 0, map.texarray[i][j])

glDrawArrays(GL_QUADS, 0, Len(map.array[i][j]) / 3)

Next

Next
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
EndIf
End Method


Das bauen der Arrays:

BlitzMax: [AUSKLAPPEN]
	Method buildArray(blocks:TDRawTest[][][])
array = array[..3]
texarray = texarray[..3]
Local i:Int, j:Int
For i = 0 Until 3
array[i] = array[i][..3]
texarray[i] = texarray[i][..3]
For j = 0 Until 3
array[i][j] = New Float[12 * 2000]
texarray[i][j] = New Float[8 * 2000]
Next
Next


i = 0
Local indices:Int[][][]
indices = indices[..3]
For j:Int = 0 Until 3
indices[j] = indices[j][..3]

For Local a:Int = 0 Until 3
indices[j][a] = New Int[2]
Next
Next

' blocks[_y2][block_sorte][indices[_y2]]
Local y:Int = 0
Local block_sorte:Int = 0
Local tile:TDrawTest
For y = 0 Until 3

For block_sorte = 0 Until 3

For i = 0 Until Len(blocks[y][block_sorte])
tile = blocks[y][block_sorte][i]

If tile Then
tile.tile.GetArray(tile.x, tile.y, tile.z, array[y][block_sorte], texarray[y][block_sorte], indices[y][block_sorte], tile.offsetX, tile.offsetY)
indices[y][block_sorte][0]:+12
indices[y][block_sorte][1]:+8
EndIf
Next

Next

Next


Und die eigentliche funktion, wo die vertexdaten zusammengetragen werden (ausgelagert für bessere sichtbarkeit)
BlitzMax: [AUSKLAPPEN]
	Method GetArray:Float[] (x:Int, y:Int, z:Int, vArr:Float[], tArr:Float[], index:Int[], offsetX:Int, offsetY:Int)

Local u1:Float = Self.sx / 1024.0
Local u2:Float = (Self.sX + Self.width) / 1024.0

Local v1:Float = Self.sY / 1024.0
Local v2:Float = (Self.sY + Self.height) / 1024.0

Local _X:Float, _Y:Float, _Z:Float

_X = (x * 36) - (z * 36) - offsetX
_Y = -y * 44 + (x * 18) + (z * 18) - offsetY
_Z = 0 '((x / 1000.0) + (z / 1000.0) + (y / 1000.0))

vArr[index[0]] = _X
vArr[index[0] + 1] = _Y
vArr[index[0] + 2] = _Z

tArr[index[1]] = u1
tArr[index[1] + 1] = v1

vArr[index[0] + 3] = _X + width
vArr[index[0] + 4] = _Y
vArr[index[0] + 5] = _Z

tArr[index[1] + 2] = u2
tArr[index[1] + 3] = v1

vArr[index[0] + 6] = _X + width
vArr[index[0] + 7] = _Y + height
vArr[index[0] + 8] = _Z

tArr[index[1] + 4] = u2
tArr[index[1] + 5] = v2

vArr[index[0] + 9] = _X
vArr[index[0] + 10] = _Y + height
vArr[index[0] + 11] = _Z

tArr[index[1] + 6] = u1
tArr[index[1] + 7] = v2

End Method


- Wie man im letzten codeblock erkennen kann, habe ich bereits versucht, ein wenig mit der Z tiefe rumzuspielen. Ohne wirklichen erfolg.

Der genaue betrachter wird erkennen, das es sich bei den blöcken tatsächlich nur um ein Rechteckiges bild handelt.
Offset X und Y ist etwas, was noch nicht ganz optimiert ist. Gedacht ist es dafür, das größere objekte, also größer als ein Block, etwas versetzt gezeichnet werden. Hier denke ich liegt auch ein teilproblem.

Aber ich komme beim besten willen nicht drauf, was ich nun umändern könnte, damit ich die Z-order probleme aus der welt schaffen kann.

ganz nebenbei, vielleicht ist es hilfreich- hier die states, die eigentlich immer aktiv sind:
BlitzMax: [AUSKLAPPEN]
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glEnable (GL_BLEND) ; glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
glAlphaFunc(GL_GREATER, 0.2)
glEnable(GL_ALPHA_TEST)


Hat jemand einen rat?^^

Gruß, PhillipK
 

Shaman

BeitragDo, Okt 27, 2011 5:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein Vorschlag:

Setzte den Rendermode auf glOrtho --> Parallelprojektion
Und nun rendere mit z-Werten, die der Reihenfolge auf dem Bildschirm entschprechen,
also oben im Bild --> z-Wert tief im Bild , unten --> z-Wert nah zur Kamera.
Wenn dann der z-Buffer-Test eingeschaltet ist, solltest du die Layer korrekt rendern können.

Ich hoffe ich konnte dir helfen, und viel erfolg
 

PhillipK

BeitragDo, Okt 27, 2011 6:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich nicht vollkommen blöde bin, tue ich das grade sogar.
Ortho ist so oder so aktiviert.
Zur Z-tiefe würde ich dann die Y tiefe nutzen (allerdings umgekehrt - bei mir ist y= 0 "oben" - dh zb y*-1 als ztiefe)
Um das zu bewerkstelligen baue ich grade meinen Editor um, um den Bilder-ursprung auf die untere kante zu berechnen - daran liegt es *denk*

Da ein bild meist 72x80 pixel groß ist, und ich an der oberen kante von der Ztiefe spreche, können zu große bilder (bäume..) von anderen, weiter "vorne" liegenden blöcken verdeckt werden. In meinem kleinhirn ergibt es sinn, wenn ich das ganze andersrum zeichne - dh statt x,y,x+width,y+height -> x,y,x-width, y-height =)

Man darf gespannt sein Sad

(ps: Danke, dein vorschlag deckt sich komplett mit einem weiteren den ich bekommen habe - für den ich grade alles umwälze. Da scheint also mehr dran zu sein Very Happy )

EDIT:
Nachtrag 28.10.2011 - 10:26

Das problem hat sich mittlerweile erledigt!

Falls es jemanden intressiert, eine 3d beschleunigte Isomap zu bauen - nur mut - es funktioniert! =)

Ich hatte einen richtig miesen denkfehler drin:
Meine kacheln wurden "von oben nach unten" und "von links nach rechts" gezeichnet.
Dh ausgehend von der position die ich angegeben habe, nach links, nach unten, nach rechts -> Quad war fertig.

Nun bei gleichrgroßen teilen ist das relativ egal - aber bei meinem vorhaben (insg. 9 vertexarrays, 3 pro ebene! dh nicht so einfach zu bestimmende Z-Tiefen!) gestaltete sich das als hauptproblem.
Lösung: Umdrehen der "Zeichenrichtung"

Die errechneten X und Y positionen diehnen nun als "untere rechte ecke" des Quads was ich zeichne, bedeutet ich ziehe breite und höhe ab.
ZTiefe lässt sich nun ganz einfach durch x+y+z (blockposition! also: Position im 3d-array) bestimmen.

Hier mal ein beweisscreenshot *g*:

user posted image

Da ich die angewohntheit habe, sachen nicht ordentlich erklären zu können, darf mir jeder eine PM schicken, falls er probleme beim selben thema hat - solange ich mich noch an die lösung erinnere, werde ich versuchen zu helfen =)

Gruß, PhillipK
(ps: hier kann geschlossen werden)

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group