Seite 2 von 2
Einfarbige Sprites...
Verfasst: 22.08.2005 13:22
von Nalfein
Wenn ich bei TransformSprite3D (zusätzlich zu einer normale Verformung in X- und Y-Richtung noch z-Werte angebe, kann ich NICHT mehr erkennen, ob diese korrekt berücksichtigt werden, da dann alle Sprites einfarbig sind! (meistens die dunkelste Farbe der Textur...)
Ich wollte eine einfache 3D-Engine machen und TransformSprite3D für die Texturen beutzen. Funktioniert soweit. Die Z-Sortierung funktioniert nicht so ganz (ich weise jedem Sprite eine Tiefe zu, die dem Durchschnitt der Tiefen der 4 Eckpunkte entspricht. Danach wird absteigend sortiert (so daß die Sprites mit niedriger Tiefe weiter hinten kommen und später angezeigt werden und somit andere überschreiben).
Funktioniert leidlich. Im Detail wollte ich die Z-Werte benutzen. Funktioniert nicht ! (s.o.)
Weiß einer woran DAS schon wieder liegen kann?
Mir ist auch aufgefallen, daß wenn ich EINMAL einen Sprite MIT z-Werten versuche anzuzeigen, alle denselben Fehler aufweisen, auch wenn ich die Angabe von z-Werten an-aus-schaltbar gemacht habe und wieder aus stelle. Aber ohne Neustart des Programms zeigt er sie nicht mehr richtig an...
Verfasst: 22.08.2005 14:43
von unix
Ich hatte auch das Problem mit den Z Werten ich wollte das ein Sprite mit weniger Z das andere Überdekt.
Nur leider habe ich herausgefunden das des nicht klappt.
Also Sortierte ich ebenfalls die Sprites in einer Linket List nach den Z Wert
Ich bin dafür das dieser Befehl von irgendjemanden nochmal überarbeitet werden sollte
Danke
überarbeiten!
Verfasst: 22.08.2005 14:55
von Nalfein
Der Befehl tut anscheinend etwas. Nur funktioniert es bei dem einen bei dem andern anscheinend nicht. Meine Grafikkarte ist nich SO alt (G-Force 4 MX oder so...) und sollte schon z-buffer unterstützung kennen (falls das nicht eh in purebasic selbst irgendwo verwaltet wird).
Ich hab's grad auch nochmal ausprobiert. Zusätzlich zu den Koordinaten der 4 Eckpunkte laß ich ihn sauber den Z-Unterschied und die Z-werte ausrechnen.
Die Z-werte einfach wie im beispiel der hilfe [,z] anzugeben führt zu einem irgendwie psychodelischen Bild. Textur ist total verzogen.
Die Z-Unterschiede der 4 Punkte zueinander zu übergeben bewirkt, daß die Textur bei gleichen Werten sich zwischen den Punkten bewegt bis alles verwaschen aussieht....
Falls dieser Befehl generell benutzbar ist (bzw. sein soll), müßte man kontrollieren, warum er es bei dem einen tut und bei dem anderen nicht!
Ein Beispiel mehr könnte (generell) der Anleitung bzw. Hilfe-Funktion nicht schaden! Ein "dieser Befehl ist nur für fortschrittliche Programmierer" (mit einem zwischen den Zeilen gelesenen "probieren Sie selbst aus! - Wenn nicht läuft, nicht unser Fehler!") sollte in keiner Anleitung stehen.... (gefunden bei Blending Mode aus Sprite3D-Library...)
Verfasst: 22.08.2005 20:59
von Batze
Ich kann ja mal die Unfertige Version meiner Batzengine posten. Da ist z-Sortierung drin.
Code: Alles auswählen
; 3D-Engine
; IncludeFile "batzengine.pb"
; in die Hauptdatei schreiben und diese Datei in den selben Ordner legen.
;————————————————————————————————————————————————————————————————————————
; Befehlsreferenz:
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
; So weit bin ich noch nicht ;)
;
;- Konstanten
; Hier können sie Einstellungen vornehmen:
#Drehgenauigkeit = 3600 ; Werte von 360 - 9000 sind zu empfehlen (3600 = Standard)
#Pi = 3.14159256 ; Es wäre unklug diesen Wert zu ändern (Pi = 3.1415956)
distanz = 500 ; Distanz zum Objekt: 0-400000 (500 = Standard)
;- Init
If InitSprite3D() = 0
; Hier können sie eine Fehlermeldung eintragen
End
EndIf
Sprite3DQuality(1) ; Qualität des Spriterendering
Dim sinus.f (#Drehgenauigkeit) ; Sinuswerte für Drehungen
Dim cosinus.f(#Drehgenauigkeit) ; Cosinuswerte für Drehung
For i=1 To #Drehgenauigkeit ; Schleife zum Füllen
sinus (i) = Sin(i / #Drehgenauigkeit * 2 * #Pi) ; Sinuswert
cosinus(i) = Cos(i / #Drehgenauigkeit * 2 * #Pi) ; Cosinuswert
Next
;###########################################################################################
Structure Object3D ; Struktur für einfache 3D-Objekte
Mem_P.l ; Speicheraddresse an der sich die Punktdaten befinden
Mem_F.l ; Speicheraddresse an der sich die Flächendaten befinden
Faces.w ; Anzahl der Vierecke des Objektes
Points.w ; Anzahl der Punkte des Objektes
x.f ; x-Position des Objektes
y.f ; y-Position des Objektes
z.f ; z-Position des Objektes
Rx.l ; Rotation in x-Richtung
Ry.l ; Rotation in y-Richtung
Rz.l ; Rotation in z-Richtung
EndStructure
NewList Obj.Object3D() ; Objektliste
Procedure P_(Nr) ; Gibt die Memoryaddresse eines Punktes aus
ProcedureReturn Obj()\Mem_P + Nr*12 ; F+F+F = 12
EndProcedure
Procedure F_(Nr) ; Gibt die Memoryaddresse eines Viereckes aus
ProcedureReturn Obj()\Mem_F + Nr*12 ; W+W+W+W+L = 12
EndProcedure
Procedure RotateObject(Mem, Wx.l, Wy.l, Wz.l) ; 3DObjekt drehen
Protected temp.f, x.f, y.f, z.f ; interne Variablen
ChangeCurrentElement(Obj(), Mem) ; Objekt auswählen
Obj()\Rx + Wx ; Drehung in der Struktur speichern
Obj()\Ry + Wy
Obj()\Rz + Wz
If Obj()\Rx > #Drehgenauigkeit : Obj()\Rx - #Drehgenauigkeit : EndIf ; Bei einem ...
If Obj()\Ry > #Drehgenauigkeit : Obj()\Ry - #Drehgenauigkeit : EndIf ; Überlauf einen Kreis ...
If Obj()\Rz > #Drehgenauigkeit : Obj()\Rz - #Drehgenauigkeit : EndIf ; abziehen.
For i=0 To Obj()\Points-1 ; Jeden Punkt durchgehen
x = PeekF(P_(i)) ; X-Koordinate des Punktes
y = PeekF(P_(i)+4) ; Y-Koordinate des Punktes
z = PeekF(P_(i)+8) ; Z-Koordinate des Punktes
; X-Rotation:
temp = y*cosinus(Wx) - z*sinus(Wx)
z = z*cosinus(Wx) + y*sinus(Wx)
y = temp
; Y-Rotation:
temp = z*cosinus(Wy) - x*sinus(Wy)
x = x*cosinus(Wy) + z*sinus(Wy)
z = temp
; Z-Rotation:
temp = x*cosinus(Wz) - y*sinus(Wz)
y = y*cosinus(Wz) + x*sinus(Wz)
x = temp
PokeF(P_(i), x) ; Werte wieder in die Struktur schreiben
PokeF(P_(i)+4, y)
PokeF(P_(i)+8, z)
Next
ProcedureReturn @Obj ; Addresse wird zurückgegeben
EndProcedure
Procedure CreateObject(x, y, z) ; 3DObjekt erstellen
AddElement( Obj() ) ; Objekt zur Liste hinzufügen
Obj()\Faces = 0 ; Werte auf 0 setzen
Obj()\Points = 0
Obj()\Mem_P = 0
Obj()\Mem_F = 0
Obj()\x = x ; Werte mit definierbarem Inhalt
Obj()\y = y
Obj()\z = z
Obj()\Rx = 0
Obj()\Ry = 0
Obj()\Rz = 0
ProcedureReturn @Obj() ; Adresse zurückgeben
EndProcedure
Procedure ObjectID(Nr) ; Objekt-ID ausgeben
If Nr = -1 ; Wenn #PB_Any ->
ProcedureReturn @Obj() ; Aktuelle ID
EndIf
; Ansonsten ->
SelectElement(Obj(), Nr) ; Element auswählen ...
ProcedureReturn @Obj ; und Addresse zurückgeben
EndProcedure
;******** Edit Objects *************************************************************************
Procedure StartEditing(Mem, Anzahl.l) ; Startet die Bearbeitung
ChangeCurrentElement(Obj(), Mem) ; Objkekt zur Bearbeitung auswählen
Obj()\Mem_P = ReAllocateMemory( Obj()\Mem_P, Anzahl*12*4) ; Speicher verändern (oder Erstellen)
Obj()\Mem_F = ReAllocateMemory( Obj()\Mem_F, Anzahl*12 ) ; " "
ProcedureReturn @Obj()
EndProcedure
Procedure AddPoint(Nr.w, x.f, y.f, z.f) ; Punkt hinzufügen
If Nr = -1 ; #PB_Any als Nr ->
Nr = Obj()\Points ; Am Ende einfügen
Obj()\Points + 1 ; Ein Punkt mehr ist vorhanden
EndIf
PokeF(P_(Nr), x) ; X-Position angeben
PokeF(P_(Nr)+4, y) ; Y-Position angeben
PokeF(P_(Nr)+8, z) ; Z-Position angeben
ProcedureReturn Nr ; Position zurückgeben
EndProcedure
Procedure AddFace(Nr.w, e1.w, e2.w, e3.w, e4.w, textur.l) ; Viereck hinzufügen
If Nr = -1 ; #PB_Any als NR ->
Nr = Obj()\Faces ; Am Ende einfügen
Obj()\Faces + 1 ; Ein Viereck mehr ist vorhanden
EndIf
PokeW(F_(Nr), e1) ; Ecke 1 2-----3
PokeW(F_(Nr)+2, e2) ; Ecke 2 | |
PokeW(F_(Nr)+4, e3) ; Ecke 3 | |
PokeW(F_(Nr)+6, e4) ; Ecke 4 1-----4
PokeL(F_(Nr)+8, textur) ; Textur = Sprite3D
ProcedureReturn Nr ; Position zurückgeben
EndProcedure
Procedure StopEditing() ; Stopt die Bearbeitung
Obj()\Mem_P = ReAllocateMemory( Obj()\Mem_P, Obj()\Points * 12) ; Speicher auf verbrauchte ...
Obj()\Mem_F = ReAllocateMemory( Obj()\Mem_F, Obj()\Faces * 12) ; Größe reduzieren.
ProcedureReturn @Obj() ; Objekt zurückgeben
EndProcedure
;***********************************************************************************************
;**************** Rendering ********************************************************************
Procedure GetTexture(Nr.w) ; TexturNr ermitteln
ProcedureReturn PeekL(F_(Nr)+8) ; Liest die SpriteNummer aus
EndProcedure
Procedure ScreenX(Nr.w) ; X-Wert auf dem Screen
Shared distanz ; Variable aus dem Hauptbereich
ProcedureReturn PeekF(P_(Nr)) * distanz / (PeekF(P_(Nr)+8) - distanz)
EndProcedure
Procedure ScreenY(Nr.w) ; Y-Wert auf dem Screen
Shared distanz ; Variable aus dem Hauptbereich
ProcedureReturn PeekF(P_(Nr)+4) * distanz / (PeekF(P_(Nr)+8) - distanz)
EndProcedure
Procedure ZPos(Nr.w) ; Z-Position eines Punkts für Sprite 3D
Shared distanz ; Variable aus dem Hauptbereich
ProcedureReturn PeekF(P_(Nr)) - distanz
EndProcedure
Procedure Render3D() ; Objekte Rendern
Shared distanz ; Variable aus dem Hauptbereich
Start3D()
ForEach Obj()
For i=0 To Obj()\Faces -1
e1 = PeekW(F_(i) )
e2 = PeekW(F_(i)+2)
e3 = PeekW(F_(i)+4)
e4 = PeekW(F_(i)+6)
TransformSprite3D(GetTexture(i), ScreenX(e1), ScreenY(e1), ZPos(e1), ScreenX(e2), ScreenY(e2), ZPos(e2), ScreenX(e3), ScreenY(e3), ZPos(e3), ScreenX(e4), ScreenY(e4), ZPos(e4))
DisplaySprite3D (GetTexture(i), 500, 400, 255)
Next
Next
Stop3D()
ProcedureReturn 1
EndProcedure
Naja, drehen geht noch nicht richtig aber sonst funktionierts