Seite 2 von 2

Verfasst: 16.05.2007 17:20
von PureLust
Kaeru Gaman hat geschrieben:im gegensatz zu dir mache ich mir gedanken über die bedürfnisse der fragenden.
Sorry .... aber zu dem und auch allem weiteren von Dir: OHNE WORTE !!! :lol: :lol: :lol: :lol: :lol:

Nur für den Fall, dass es Dir entgangen ist (könnte ja sein, dass Du vor lauter Kaeru-Postings den Wald nicht mehr siehst :? ):
Du schaffst es gerade abermals einen Thread mit OffTopics zuzumüllen die dem Fragenden in keinster Weise helfen. :roll:

Verfasst: 16.05.2007 19:13
von ts-soft
Hab hier mal ein bissel abgeschnitten, findet ihr im Müll wieder. Der Schnitt
Geschah mehr aus dem Bauch heraus, ohne Schuldzuweisung :mrgreen:

Verfasst: 16.05.2007 19:29
von Fluid Byte
beleidigende Userbezeichnung entfernt, werde langsam Sauer hier (ts-soft)

Code: Alles auswählen

DisableDebugger

#SRPITES = 56
#ROWITEMS = 8
#SPACING = 3
#SMF = 64

Tempdir$ = GetTemporaryDirectory()

CreateImage(0,64,64)
StartDrawing(ImageOutput(0))
Box(0,0,32,64,#Red)
Box(32,0,32,64,#Blue)
StopDrawing()

For i=0 To #SRPITES-1
	SaveImage(0,Tempdir$ + "sprite" + Str(i+1) + ".bmp")
Next

InitSprite() : InitKeyboard()

OpenWindow(0,0,0,640,480,"void",#WS_SYSMENU | #WS_CAPTION | 1)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

For i=0 To #SRPITES-1
	LoadSprite(i,Tempdir$ + "sprite" + Str(i+1) + ".bmp")
Next

StartTime = ElapsedMilliseconds()

For i=0 To #SRPITES-1
	StartDrawing(SpriteOutput(i))
	
	IW = SpriteWidth(i) : IH = SpriteHeight(i)
	
	BufferPitch = DrawingBufferPitch() / 4	
	
	If IW <> BufferPitch : IW = BufferPitch : EndIf	
	
	*pxData.LONG = DrawingBuffer()

	For px=0 To (IW * IH) - 1
		R = *pxData\l & $FF
		G = *pxData\l >> 8 & $FF
		B = *pxData\l >> 16
		
		*pxData\l = B | G << 8 | R << 16	
		
		*pxData + 4
	Next
	
	StopDrawing()	
Next

MessageRequester("Result","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

Repeat
	EventID = WindowEvent()
	
	ExamineKeyboard()
	
	ClearScreen(0)
			
	For i=0 To #SRPITES-1
		SX = (i/#ROWITEMS) * ((#SMF + #SPACING) * #ROWITEMS)
			
		DisplaySprite(0,5 + i * (#SMF + #SPACING) - SX,5 + (i/#ROWITEMS) * (#SMF + #SPACING))			
	Next	
	
	FlipBuffers()
Until KeyboardPushed(1) Or EventID = 16
Dieser Code schafft es 56 Sprites mit einer Größe von 64x64 in ~875 Ms zu flippen. Wo hingegen der Code von PureDödel es bei mir (Pentium D, 3.0 GHz) mit einem Sprite von 100x100 auf ~406 Ms bringt. Der Code kann mit Sicherheit noch optimiert werden aber ist ein Anfang.

Verfasst: 16.05.2007 19:45
von AND51
Beitrag wegen TS-Soft wiederhergestellt


Wenn mir jemand erklären kann, wie das mit dem DrawingBuffer() funktioniert, das scheint ein Lichtblick zu sein, dann könnte ich es ja vielleicht auch mal versuchen.

Ich weiß, dass es der Buffer zu dem Sprite/Screen ist. Muss ich da einfach die RGB Farben rein und rauspoken? Desweiteren gibt mir der andere DrawingBuffer-Befehl ja die Länge einer zeile, aber woher weiß ich, wie viele zeilen das Ding hat? SpriteHeight()?
und das mit DrawingBufferPitch() verstehe ich noch nicht 100%ig...

Und vielleicht kann man ja das ganze noch mal beschleubnigen, indem man die Sprites mit dem Flag #PB_Sprite_Texture läd und erstellt? Habe vorhin mit der "Scheiß Board-Suche" (Augenzwinker@Kaeru) mal gesucht und gefunden, dass dieses Flag die Pixelmanipulation verschnellern soll.

Verfasst: 16.05.2007 20:12
von PureLust
@FB: In der Hoffnung dass Du's jetzt nicht wieder persönlich nimmst und wir mal bei der Sache bleiben können ...

Dein Code flippt nicht das Sprite, sondern macht momentan einfach nur eine Red<>Blue Invertierung jedes Pixels ... nix anderes.
(Wobei jedoch kein Zweifel daran besteht, dass es mit direktem Zugriff auf den DrawBuffer einiges flotter sein wird als mit Point/Plot).

@AND51:
AND51 hat geschrieben:Wenn mir jemand erklären kann, wie das mit dem DrawingBuffer() funktioniert, .....
Ich weiß, dass es der Buffer zu dem Sprite/Screen ist. Muss ich da einfach die RGB Farben rein und rauspoken? Desweiteren gibt mir der andere DrawingBuffer-Befehl ja die Länge einer zeile, aber woher weiß ich, wie viele zeilen das Ding hat? SpriteHeight()?
und das mit DrawingBufferPitch() verstehe ich noch nicht 100%ig...
Durch den DrawingBuffer() kommst Du an den Speicherbereich des Screens/Sprites heran.
DrawingBufferPitch() liefert Dir dir Länge einer Zeile in Bytes, wobei dies nicht unbedingt gleich zu setzen ist mit Screen/Sprite-Breite * BytesProPixel, da sich die interne Breite des Buffers von der angezeigten Breite unterscheiden kann.
Für Berechnungen der genauen Speicheradresse solltest Du also immer DrawingBufferPitch() und nicht die Screen/Sprite-Breite heranziehen.

Die Höhe ist tatsächlich die angegebene Sprite/Screen-Höhe die Du angegeben hast bzw. ja über die einschlägigen Befehle abfragen kannst.
Der gesamte Speicherbereich berechnet sich also aus DrawingBufferPitch * Screen/Sprite-Höhe.
Um nun z.B. die Offset-Adresse eines Pixels bei einem 32bit-Sprite zu berechnen brauchst Du im Grunde nur x*4+y*DrawingBufferPitch() zu berechnen (x*4 deswegen, da 32bit Farbtiefe = 4Byte).
Schwieriger wird es natürlich dann, wenn Du verschiedene Bittiefen von Screen/Sprites berücksichtigen musst. Dass ist dann halt etwas mehr Aufwand.

Um nun z.B. dann solche Dinge wie einen Flip zu realisieren kannst Du auf die berechneten Speicherstellen dann einfach per Peek/Poke oder eben per Pointer zugreifen.

Bei solchen Spritemanipulationen per direktem Speicherzugriffen ist es meist hilfreich, wenn man Sprites mit dem Flag #PB_Sprite_Memory erstellst, da der Speicherbereich des Sprites dann im schnellen Systemspeicher abgelegt wird und der Zugriff des Prozessors schneller erfolgen kann.
Dabei solltest Du jedoch auch bedenken, dass durch dieses Flag die spätere Darstellung auf dem Bildschirm wiederum langsamer von statten geht.

Hoffe ich habs einigermaßen verständlich hinbekommen. ;)
Gruß, PL.

Verfasst: 16.05.2007 20:14
von Kaeru Gaman
> brauchst Du im Grunde nur x*4+y*DrawingBufferPitch() zu berechnen (x*4 deswegen, da 32bit Farbtiefe = 4Byte).

anstatt der konstanten 4 würde ich vorschlagen, die rückgabe von DrawingBufferPixelFormat() auszuwerten...

Verfasst: 16.05.2007 20:18
von Fluid Byte
PureLust hat geschrieben:@FB: In der Hoffnung dass Du's jetzt nicht wieder perönlich nimmst und wir mal bei der Sache bleiben können ...
Ich fühl mich nicht "perönlich" angegriffen, höchstens persönlich.

Aber kack dich nicht zu, solange die Bemerkung angebracht ist kann ich mit leben. Außerdem bin ich dankbar! Ich hatte ein falsches Snippet verwendet (channel swap) und der korrigierte Code bringt nun bei gleichen Bedingungen 0 Ms!

Code: Alles auswählen

DisableDebugger

#SRPITES = 56
#ROWITEMS = 8
#SPACING = 3
#SMF = 64

Tempdir$ = GetTemporaryDirectory()

CreateImage(0,#SMF,#SMF)
StartDrawing(ImageOutput(0))
For i=0 To #SMF-1
	Box(i,0,1,#SMF,RGB(i*225/(#SMF-1)+30,0,0))
Next

StopDrawing()

For i=0 To #SRPITES-1
	SaveImage(0,Tempdir$ + "sprite" + Str(i+1) + ".bmp")
Next

InitSprite() : InitKeyboard()

OpenWindow(0,0,0,640,480,"void",#WS_SYSMENU | #WS_CAPTION | 1)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

For i=0 To #SRPITES-1
	LoadSprite(i,Tempdir$ + "sprite" + Str(i+1) + ".bmp",#PB_Sprite_Memory)
Next

StartTime = ElapsedMilliseconds()

For i=0 To #SRPITES-1
	StartDrawing(SpriteOutput(i))
	
	IW = SpriteWidth(i) : IH = SpriteHeight(i)
	
	BufferPitch = DrawingBufferPitch() / 4	
	
	If IW <> BufferPitch : IW = BufferPitch : EndIf
	
	*pxData1.LONG = DrawingBuffer()
	*pxData2.LONG = AllocateMemory(IW * IH * 4)
	
	CopyMemory(*pxData1,*pxData2,IW * IH * 4)
				
	*pxData2 + (IW * IH * 4)	

	For px=0 To (IW * IH) - 1
		R = *pxData2\l & $FF
		G = *pxData2\l >> 8 & $FF
		B = *pxData2\l >> 16
		
		*pxData1\l = R | G << 8 | B << 16	
		
		*pxData1 + 4
		*pxData2 - 4
	Next	

	StopDrawing()	
Next

MessageRequester("Result","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

Repeat
	EventID = WindowEvent()
	
	ExamineKeyboard()
	
	ClearScreen(0)
			
	For i=0 To #SRPITES-1
		SX = (i/#ROWITEMS) * ((#SMF + #SPACING) * #ROWITEMS)
			
		DisplaySprite(0,5 + i * (#SMF + #SPACING) - SX,5 + (i/#ROWITEMS) * (#SMF + #SPACING))			
	Next	
	
	FlipBuffers()
Until KeyboardPushed(1) Or EventID = 16

Verfasst: 16.05.2007 20:18
von PureLust
Kaeru Gaman hat geschrieben:> brauchst Du im Grunde nur x*4+y*DrawingBufferPitch() zu berechnen (x*4 deswegen, da 32bit Farbtiefe = 4Byte).

anstatt der konstanten 4 würde ich vorschlagen, die rückgabe von DrawingBufferPixelFormat() auszuwerten...
Korrekt. :allright:

@FB: Sorry, aber auch dein neuester Code macht keinen H- oder V-Flip sondern immer einen kompletten einen HV-Flip.
Nichts desto trotz wird die direkte Routine per DrawBuffer gute 10-15 mal schneller sein als per Plot/Point (natürlich auch abhängig von CPU und GraKa).
Bei mir sind's momentan 1532ms bei Point/Plot zu 151ms beim direkten Zugriff per Pointer (56 mal ein 64x64 Sprite flippen).

Verfasst: 17.05.2007 20:36
von Fluid Byte
So! Nu ham was aba. Ich hab das #PB_Sprite_Memory Flag wieder raus genommen. Es sollte optional sein denn es braucht länger zum Laden und außerdem gibts ja Leute die nicht soviel GFKA-Speicher haben. Ergebniss imma noch ~250 Ms:

Code: Alles auswählen

DisableDebugger

#SRPITES = 56
#ROWITEMS = 8
#SPACING = 3
#SMF = 64
#VFLIP = 0

Tempdir$ = GetTemporaryDirectory()

CreateImage(0,#SMF,#SMF)
StartDrawing(ImageOutput(0))
Box(0,0,#SMF,#SMF,#Red)
DrawText(0,0,"1")
DrawText(#SMF-10,0,"2")
DrawText(0,#SMF-15,"3")
DrawText(#SMF-10,#SMF-15,"4")
StopDrawing()

For i=0 To #SRPITES-1
	SaveImage(0,Tempdir$ + "sprite" + Str(i+1) + ".bmp")
Next

InitSprite() : InitKeyboard()

OpenWindow(0,0,0,640,480,"void",#WS_SYSMENU | #WS_CAPTION | 1)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

For i=0 To #SRPITES-1
	LoadSprite(i,Tempdir$ + "sprite" + Str(i+1) + ".bmp")
Next

StartTime = ElapsedMilliseconds()

For i=0 To #SRPITES-1
	StartDrawing(SpriteOutput(i))
	
	IW = SpriteWidth(i) : IH = SpriteHeight(i)
	
	BufferPitch = DrawingBufferPitch() / 4	
	
	If IW <> BufferPitch : IW = BufferPitch : EndIf
	
	*pxData1.LONG = DrawingBuffer()
	*pxData2.LONG = AllocateMemory((IW * IH * 4))
	
	CopyMemory(*pxData1,*pxData2,(IW * IH * 4))
	
	For Y=0 To IH-1   
		For X=0 To IW-1
			If #VFLIP
				colref = PeekL(*pxData2 + (Y * IW + X) << 2)
				
				PokeL(*pxData1 + ((IH-Y-1) * IW + X) << 2,colref)   			
			Else
				colref = PeekL(*pxData2 + (Y * IW + X) << 2)
				
				PokeL(*pxData1 + ((IW-X) + (Y * IW-1)) << 2,colref)
			EndIf
		Next
	Next

	StopDrawing()	
Next

MessageRequester("Result","Time: " + Str(ElapsedMilliseconds() - StartTime) + " Ms",64)

Repeat
	EventID = WindowEvent()
	
	ExamineKeyboard()
	
	ClearScreen(0)
			
	For i=0 To #SRPITES-1
		SX = (i/#ROWITEMS) * ((#SMF + #SPACING) * #ROWITEMS)
			
		DisplaySprite(0,5 + i * (#SMF + #SPACING) - SX,5 + (i/#ROWITEMS) * (#SMF + #SPACING))			
	Next	
	
	FlipBuffers()
Until KeyboardPushed(1) Or EventID = 16

Verfasst: 17.05.2007 20:42
von AND51
Hallo!

Wollte noch melden, dass ich deinen Beitrag gelesen habe, PureLust.
Leider hab ich keine pure Lust mehr, einen eigenen Code zu erstellen, weil mich das alles ein wenig verwirrt, diese ganzen Dinge, auf die man aufpassen muss...

Aber ich traue Fluid Byte's Code, weil ich des öfteren gesehen habe, dass seine Codes schön performant sind. <)


Sollte ich soetwas mal FlipSprite() brauchen und noch kein eigenes haben, dann wisst ihr, wie meine hochkarätigen Spiele ihre Sprites flippen... :lol: