[B2D] Bilder drehen (fast) in Echtzeit
Übersicht

![]() |
ToeBBetreff: [B2D] Bilder drehen (fast) in Echtzeit |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also ich hab mal drüber nachgedacht wie man ohne zeitfressende laden und drehen der Bilder vereinfachen kann, und bin zu dem schluss gekommen, das man sie EINMAL läd und dann rotiert hinzeichnet (ähnlich Draw3D). Die Brechnung dazu st noch nicht perfect und auch noch sehr ausbaufähig, aber wenn man sie braucht ist sie nützlich :
Das ganze funzt so, dass ich jeden pixel im bild so wie es ist auslese, dann den winkel und abstand zur mitte messe und dann mit Sin+Cos in den winkel+den eigenen winkel zeichne mit dem errechneten abstand. Code: [AUSKLAPPEN] Function DrawRotateImage(bild,x#,y#,w#=0,mask=$FF000000,ZielBuffer=0)
If w# = 0 DrawImage bild,x,y Else If ZielBuffer = 0 ZielBuffer = BackBuffer() Local Buffer_draw = ZielBuffer Local Buffer_get = ImageBuffer(bild) Local Image_w = ImageWidth(bild) Local Image_h = ImageHeight(bild) Local Image_mx# = Image_w/2.0 Local Image_my# = Image_h/2.0 LockBuffer Buffer_draw LockBuffer Buffer_get For xx = 0 To Image_w -1 For yy = 0 To Image_h -1 pix_r = ReadPixelFast(xx,yy,Buffer_Get) If pix_r <> mask rad# = Sqr( ( xx - Image_mx ) ^ 2 + ( yy - Image_my ) ^ 2 ) winkel# = (-ATan2((xx - Image_mx),(yy - Image_my))) + w#+90 ;DebugLog winkel WritePixel(x#+Cos(winkel#)*rad#,y#+Sin(winkel#)*rad#,pix_r,Buffer_draw) EndIf Next Next UnlockBuffer Buffer_get UnlockBuffer Buffer_draw EndIf End Function und hier mal ein Beispiel wers gebrauchen kann : Code: [AUSKLAPPEN] Graphics 800,600,16,2
SetBuffer BackBuffer() SeedRnd MilliSecs() Global wcrate = LoadImage("smile.png") : MidHandle wcrate : MaskImage wcrate,255,0,255 If wcrate = 0 RuntimeError("Bild exestiert nicht") Global MaskWCrate = $FFFF00FF Global anz = 9 Dim xp(anz) Dim yp(anz) Dim wp(anz) For i = 0 To anz xp(i) = Rand(800) yp(i) = Rand(600) Next Repeat FPS_C = FPS_C + 1 If FPS_MS <= MilliSecs() - 1000 FPS = FPS_C : FPS_C = 0 : FPS_Ms = MilliSecs() Cls For i = 0 To anz wp(i) = -ATan2(xp(i)-MouseX(),yp(i)-MouseY()) DrawRotateImage(wcrate,xp(i),yp(i),wp(i),MaskWCrate,BackBuffer()) Next ;DrawImage wcrate,100,100 ;Rot = (Rot + 1) Mod 360 Text 0,0,FPS ;Text 0,15,rot Flip Until KeyHit(1) End Function DrawRotateImage(bild,x#,y#,w#=0,mask=$FF000000,ZielBuffer=0) If w# = 0 DrawImage bild,x,y Else If ZielBuffer = 0 ZielBuffer = BackBuffer() Local Buffer_draw = ZielBuffer Local Buffer_get = ImageBuffer(bild) Local Image_w = ImageWidth(bild) Local Image_h = ImageHeight(bild) Local Image_mx# = Image_w/2.0 Local Image_my# = Image_h/2.0 LockBuffer Buffer_draw LockBuffer Buffer_get For xx = 0 To Image_w -1 For yy = 0 To Image_h -1 pix_r = ReadPixelFast(xx,yy,Buffer_Get) If pix_r <> mask rad# = Sqr( ( xx - Image_mx ) ^ 2 + ( yy - Image_my ) ^ 2 ) winkel# = (-ATan2((xx - Image_mx),(yy - Image_my))) + w#+90 ;DebugLog winkel WritePixel(x#+Cos(winkel#)*rad#,y#+Sin(winkel#)*rad#,pix_r,Buffer_draw) EndIf Next Next UnlockBuffer Buffer_get UnlockBuffer Buffer_draw EndIf End Function Parameter : DrawRotateImage(Handle%,xPos#,yPos#,Winkel#[,Mask%][,Buffer%]) Handle = Bild Handle (weches mit LoadImage angegeben wird) xPos/yPos = Position des Bildes (!!Beachten!! das bild wird mittig gezeichnet !) Winkel = Winkel des Bildes (0-360) Mask = Maskcolor (in Hexadezimalcode, z.b. für MaskImage 255,0,255 -> $FFFF00FF) Buffer = Der Buffer auf dem das Bild gezeichnet werden soll(somit sind z.B. das Speichern in Bildern möglich) mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
ke^kx |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Äh da gibt es extra nen befehl für:
https://www.blitzforum.de/help/TFormImage Ansonsten ist die idee mit dem vorher laden natürlich gut anwendbar aber wohl auch nicht neu ![]() |
||
http://i3u8.blogspot.com
Asus Striker II Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-) Geforce 9800 GTX 2GB RAM |
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja aber es ging ja auch darum mal was selber zu machen...
Von dem Befehl allerdings wusst ich nich wie ich den anwenden soll... mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
![]() |
ozzi789 |
![]() Antworten mit Zitat ![]() |
---|---|---|
nice! ![]() mit kleineren bilder gehts in echtzeit ![]() |
||
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5 |
![]() |
Eingeproggt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich fand da mal was im englischen Codearchiv, um Bilder mithilfe von 3D-Beschleunigung (Nein, kein Draw3D-artiges System sondern mit 2D-Images, aber seht selbst) in Echtzeit zu skalieren.
Mir kam der Gedanke, auf dieselbe Art eine Echtzeit-Rotation hinzukriegen. Leider scheiterte ich bei der Berechnung der Abmessungen des neuen Bildes ![]() Code: [AUSKLAPPEN] ; yet another QUICK SCALE
; An example on how to use 3D Hardware to speed up scaling of 2D images. ; written by jfk of csp ; results: scaling a 1024*768 image to half the size was ; 109 times faster than ResizeImage() with TFormFiter on ; 36 times faster than ResizeImage() with TFormFiter off ; There are some limits with this method: ; images may not be bigger than 1024*1024 prior scaling. ; images may not be bigger than the current Graphics Resolution after scaling. Graphics3D 1024,768,32,2 ;Graphics3D 800,600,32,2 ;Graphics3D 640,480,32,2 SetBuffer BackBuffer() ClsColor 100,100,100 Global testfile$="testbmp.bmp" ;-------------------------- Demo:------------------------------- TFormFilter 1 ;test speed of blitzs built in scaling img=LoadImage(testfile$) ; a test image, max 1024 * 1024 ! t1=MilliSecs() ResizeImage img,ImageWidth(img)/2,ImageHeight(img)/2 t2=MilliSecs() Cls:DrawImage img,10,10 Text 0,580,"TFormFiler on, Blitz Scaling: "+(t2-t1)+" ms" Flip 0 WaitKey() FreeImage img ;--------------------------------------------------------------- TFormFilter 0 ;test speed of blitzs built in scaling (now with Filter off) img=LoadImage(testfile$) t1=MilliSecs() ResizeImage img,ImageWidth(img)/2,ImageHeight(img)/2 t2=MilliSecs() Cls:DrawImage img,10,10 Text 0,580,"TFormFiler off, Blitz Scaling: "+(t2-t1)+" ms" Flip 0 WaitKey FreeImage img ;--------------------------------------------------------------- ; now test speed of faster scaling utilizing 3D Hardware img=LoadImage(testfile$) t1=MilliSecs() img=myResizeImage(img,ImageWidth(img)/2,ImageHeight(img)/2) t2=MilliSecs() Cls:DrawImage img,10,10 Text 0,580,"3D Image Scaling: "+(t2-t1)+" ms" Flip 0 WaitKey() End Function myResizeImage(img,w#,h#,cam0=0) ; img-handle, desired width and height, optional camera handle that may be deactivated during rescaling ; note: width and height may not be bigger than current Graphics resolution, or they will be clipped! Local img_w#=ImageWidth(img) Local img_h#=ImageHeight(img) If img_w>1024 Then img_w=1024 If img_h>1024 Then img_h=1024 If img_w<1 Then img_w=1 If img_h<1 Then img_h=1 If w>1024 Then w=1024 If h>1024 Then h=1024 If w<1 Then w=1 If h<1 Then h=1 w_rel#=w#/img_w# h_rel#=h#/img_h# g_rel#=1024.0/GraphicsWidth() Local cam1=CreateCamera() CameraProjMode cam1,0 Local Quad=CreateQuad() Local Tex=CreateTexture(1024,1024,256 Or 16 Or 32) EntityTexture Quad,Tex EntityFX Quad,1 CameraRange cam1,.001,10 TranslateEntity cam1,(1.0/1024.0),-(1.0/1024.0),-1.0 EntityParent Quad,cam1,1 PositionEntity cam1,32000,16000,16000 CopyRect 0,0,img_w,img_h,512-(img_w/2.0),512-(img_h/2.0),ImageBuffer(img),TextureBuffer(Tex) ScaleEntity Quad,w_rel*g_rel,h_rel*g_rel,0.0001 If cam0<>0 Then CameraProjMode cam0,0 CameraProjMode cam1,1 RenderWorld() CameraProjMode cam1,0 If cam0<>0 Then CameraProjMode cam0,1 Local img2=CreateImage(w,h) CopyRect (GraphicsWidth()/2.0)-(w/2.0),(GraphicsHeight()/2.0)-(h/2.0),w,h,0,0,BackBuffer(),ImageBuffer(img2) FreeImage img FreeTexture Tex FreeEntity Quad Return img2 End Function Function CreateQuad() ;creates a quad, facing To the -Z side mesh=CreateMesh() surf=CreateSurface(mesh) v0=AddVertex(surf, -1.0, 1.0,0, 0,0 ) v1=AddVertex(surf, 1.0, 1.0,0, 1,0 ) v2=AddVertex(surf, 1.0, -1.0,0, 1,1 ) v3=AddVertex(surf, -1.0, -1.0,0, 0,1 ) AddTriangle(surf,v0,v1,v2) AddTriangle(surf,v0,v2,v3) UpdateNormals mesh Return mesh End Function (Code gepostet, da ich den Code im englischen Archiv grad nicht finden kann...) Sollte eig nicht so schwer sein und ich versprech euch das is sauschnell ![]() Mahlzeit, Christoph. EDIT. Ja, natürlich ist 3D immer dasselbe Prinzip, man zieht eine Textur über 2 Triangles oh Wunder ![]() Aber das Einzeichnen erfolgt hier als 2D-image, das mein ich. |
||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
- Zuletzt bearbeitet von Eingeproggt am Mi, Jan 07, 2009 19:36, insgesamt einmal bearbeitet
![]() |
tedy |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ist doch ziemlich das selbe was draw3d auch macht :O nur benutzt Draw3d meines wissens Sprites | ||
01010100 01100101 01000100 01111001 00100000 00111010 01000100 |
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also Draw3D benutz keine Sprites sondern läuft mit SimgleSurface (Sonst würde man die hohen FPS-Zahlen gar nicht hinbekommen)
Und das gleiche tut diese Function hier auch, nur das das glaub ich über den BackBuffer geregelt wird, also sowas ähnliches wie Screenshots. mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Der gepostete Code von Eingeproggt macht folgendes. Es lädt ein 2D-Image und jagt das Handle in die Funktion myResizeImage. In dieser wird dann ungeachtet der notwendigen Größe eine Textur mit dem Ausmaß von 1024x1024 (4MB Grafikkartenspeicher) erstellt und mit CopyRect![]() ![]() ![]() Die bisher uneffizienteste Lösung die ich bisher gesehen habe. Und wie ToeB schon eben sagte, die Draw3D benutzt keine Sprites, denn dann wäre bereits nach 500 Objekten schon eine schöne Diaschow zu bewundern. - - - @ToeB Du kannst deine Funktion noch optimieren, indem du nicht für jedes Pixel Cos ![]() ![]() Tipp: Man kann im übrigen die transparente Pixelstellen wegbekommen, wenn man das Zeichnen umgekehrt macht. Also nicht die neue Position eines jeden Pixels ausrechnen, sondern den Farbwert eines Pixels anhand der Quellvorlage ausgehend zeichnen. Das heisst, man rendert eher als das man zeichnet. Im Zusammenhang mit meinem vorherigem Vorschlag allerdings kein so einfaches unterfangen, wenn man das noch nie gemacht hat. Du kannst dir aber gerne den Grundgedanken aus GetTexel3D ![]() - - - Edit1: In anbetracht des Beitrages unter mir von Noboody erkenne ich den Grund für so ein Vorgehen nun besser dieser komischen Funktion myResizeImage. Man sollte aber beachten, dass der 2D-Modus schon allein deshalb langsamer sein kann, indem man Graphics3D macht. Denn in diesem Modus laufen so einige Grafikkarten dann schon langsamer, auch wenn man kein 3D selbst anwendet. |
||
- Zuletzt bearbeitet von hectic am Mi, Jan 07, 2009 20:47, insgesamt einmal bearbeitet
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Naja, die Funktion macht nichts anderes, als das Bild per Quad einzuzeichnen und das gerenderte Bild wieder in einem Bild zu speichern.
Das ist wohl hauptsächlich für Anwendungen ausserhalb der Hauptschleife gedacht - ein System wie die Draw3D ist viel geeigneter, wenn die Bilder in Echtzeit skaliert eingezeichnet werden sollen. Die Funktion hier ist wohl eher dafür gedacht, einen Ersatz für das bisherige ResizeImage zu bieten, um beispielsweise bei einer geänderten Auflösung die Bilder kurz neu zu skalieren. EDIT: Da war hectic wohl schneller ![]() |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
Eingeproggt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Na toll, dabei find ich die Funktion gar ned so übel... Sie ist jedenfalls näher an "Echtzeit" dran als die Lösung von Toeb. Klar ist die Draw3D schneller, hab ich auch nie bezweifelt, aber wer sein Spiel in 2D großgezogen hat und nicht alles umschreiben will ist damit finde ich besser bedient. (Und jetzt bitte keine Diskussion über den Aufwand des Umschreibens von B2D nach Draw3D, das wurde schon oft genug geklärt und ich weiß dass er gar nicht so groß ist wie ich es hier grad darstelle) | ||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Probier es selbst. Sobald man Graphics3D macht, sollte man auch mit 3D arbeiten, denn allein schon dieser Befehl macht das echte 2D langsamer.
Code: [AUSKLAPPEN] Graphics3D 800,600,0,1
;Graphics 800,600,0,1 SetBuffer BackBuffer() Local Q,Image=LoadImage("e:\bild.jpg") While Not KeyHit(1) For Q=1 To 1000 DrawImage Image,Rand(20,700),Rand(0,500),0 Next Text 0,0,fps:msc=MilliSecs() If msc>mts Then mts=msc+1001:fps=frm:frm=0 Else frm=frm+1 Flip 0 Cls Wend End Bei mir z.Z. 53 FPS (2D) zu 45 FPS (3D). Daher ist der Geschwindigkeitsvorteil so einer Funktion in allen anderen Bereichen dahin. Bei meiner alten Grafikkarte war die Leistung sogar auf 80% bis 60% runter gegangen. Ich will niemanden von meiner Draw3D überzeugen, hab ja dieses Thema auch nicht in den Raum geworfen. Ich möchte nur darauf hinweisen, dass Graphics3D unter echtem 2D nichts zu suchen hat. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
![]() |
Eingeproggt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich wollte auch keinesfalls die Draw3D madig machen ![]() Ich wollte nur eine andere Art einer "Echtzeit"-Rotation vorstellen obwohl ich sie ja eig nicht hab, hab nur mal die Idee in den Raum geworfen. Du hast mit 3D vs 2D recht, bei mir etwa 21 zu 11. Allerdings arbeite ich ständig im Fenstermodus, wo Graphics und Graphics3D exakt gleich sind (auf nur 11FPS bei mir... äh Erklärung hab ich dafür grad keine, bin aber auch grad im Stress, sry) mfG, Christoph. |
||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group