Zeitversetzte Berechnung
Übersicht

KrischanBetreff: Zeitversetzte Berechnung |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Eigentlich ein Ding fürs Codearchiv, allerdings bin ich mit meiner Lösung noch nicht so ganz glücklich, vielleicht können wir das gemeinsam noch verbessern. Worum geht es?
Es gibt viele Wege, eine Heightmap für einen zufälligen Planeten zu erstellen, mir waren aber alle bisherigen Lösungen zu langsam oder zu speicherintensiv. Die Idee hinter meinen Script ist es, einen halbwegs realistischen Planeten "on the fly" schrittweise zu generieren, und zwar in der Zeit, in der man auf ihn zufliegt (idealerweise unter 10 Sekunden). Der Code macht folgendes: - erstelle ein Farbverlaufsarray - erstelle ein Array mit der Grösse 512x256 (Heightmapgrösse) - würfele dieses Array zufällig durcheinander - suche 4 Heightmaps aus 10 vorberechneten Heightmaps heraus - finde heraus, wie viele Pixel pro Durchlauf berechnet werden können - berechne die Pixelpositionen anhand des Arrays - blende sie mit drei verschiedenen Filtern ineinander - berechne die Pixelfarben anhand des Farbverlaufs - schreibe die Pixel auf die Planetentextur Ich habe dazu eine Demo vorbereitet: Delayed Demo Ablauf wie folgt: anfangs ist man 20 Units vom Planeten entfernt. Mit LMB könnt ihr wahnsinnig nah heranzoomen, am Anfang besteht der Planet nur aus Wasser. Drückt man nun die SPACE-Taste beginnt die Funktion, einen zufälligen Planeten schrittweise zu berechnen. Der Effekt ist fast nicht sichtbar, wenn man ohne Zoom mit der Pfeil-hoch-Taste losfliegt und kurz danach die SPACE-Taste drückt. Ist man am Planeten angelangt sieht dieser völlig anders aus und als Spieler hat man von der Generierung idealerweise gar nichts mitbekommen. Das mit dem zufälligen Array deshalb, weil man eine zeilenweise Berechnung auch aus grosser Distanz bemerken würde, so fällt das gar nicht auf ![]() Mit dieser Methode kann man aus nur 10 vorberechneten Heightmaps tausende verschiedene Planeten berechnen, je nach Filterkombination. Mein Problem ist nur: auf manchen Geräten, auf denen ich es getestet habe brechen die FPS sehr stark ein und ich muss die Variable pixelstep% reduzieren (manche schaffen 8192, andere nur 512, alles Core2Duo), dann dauert es aber länger, den Planeten zu erstellen. Frage an Euch: kann man das irgendwie verbessern? Hier der Code, aber ohne Media nicht lauffähig: Code: [AUSKLAPPEN] Graphics3D 800,600,32,2
; Deklarationen Dim GradientR%(0),GradientG%(0),GradientB%(0),Prozent%(0),Rot%(0),Gruen%(0),Blau%(0) Dim images%(9) Dim Array%(0) Global maxx%=512 Global maxy%=256 Global max%=maxx*maxy Global pixelstep%=512 ; alles total zufällig SeedRnd MilliSecs() ; Farbverlauf erstellen Restore ClassMT : CreateGradient(9,255) ; Quellbilder einlesen : For i%=0 To 9 : images(i)=LoadImage("512/planet"+i+".jpg") : Next ; Zufallsarray erstellen CreateRandomArray(max) ; Zieltextur erstellen output=CreateTexture(maxx,maxy,16+32) buff5=TextureBuffer(output) survey=CreateImage(maxx,maxy) width=ImageWidth(survey) buff6=ImageBuffer(survey) ; Grundfarbe der Textur festlegen SetBuffer buff5 Color 17, 82,112 Rect 0,0,maxx,maxy,1 Color 255,255,255 SetBuffer BackBuffer() ; Planet planet=CreateSphere(32) ScaleEntity planet,10,10,10 PositionEntity planet,0,0,1000 EntityFX planet,2 EntityTexture planet,output,0,1 TextureBlend output,2 EntityShininess planet,0.25 ; Wolkentextur Clouds=CreateSphere(32,planet) ctex=LoadTexture("clouds.png",2) EntityTexture Clouds,ctex,0,1 ScaleTexture ctex,0.5,1 RotateTexture ctex,90 TextureBlend ctex,2 EntityBlend clouds,1 EntityOrder clouds,-1 ; Licht light=CreateLight(1) AmbientLight 8,8,8 ; Kamera camera=CreateCamera() PositionEntity camera,20,0,0 CameraRange camera,0.1,1000 ; Maus in die Mitte, Kamera zielt auf Planet MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 HidePointer() PointEntity camera,planet ; anfangs keine Welt erstellen newworld=False ; Zeit messen time=MilliSecs() ; Hauptschleife While Not KeyHit(1) ; FPS messung FPS_C=FPS_C+1 : If fms<MilliSecs() Then fms=MilliSecs()+1000 : FPS=FPS_C : FPS_C=0 ; Frame tweening Tween#=Float(MilliSecs()-FrameTime)/10.0 : FrameTime=MilliSecs() ; einfache Steuerung mxs#=MouseXSpeed() mys#=MouseYSpeed() ;RotateEntity camera,EntityPitch(camera)+(mys#/5),EntityYaw(camera)-(mxs#/5),0 If KeyDown(200) Then MoveEntity camera,0,0, 1*Tween If KeyDown(208) Then MoveEntity camera,0,0,-1*Tween ; aktuelle Zeit messen ms=MilliSecs() ; SPACE und Newworld-Flag False? dann neue Karte erstellen If KeyHit(57) Then ; Startzeit messen starttime=ms ; Pixelcounter rücksetzen i=0 water%=0 land%=0 ; vier Planeten als Basis wählen map$=ZERO(Rand(0,9999),4) ; Planetencodes extrahieren i1=Int(Left(map,1)) i2=Int(Mid(map,1,1)) i2=Int(Mid(map,2,1)) i4=Int(Right(map,1)) ; neue Bildpuffer setzen buff1=ImageBuffer(images(i1)) buff2=ImageBuffer(images(i2)) buff3=ImageBuffer(images(i3)) buff4=ImageBuffer(images(i4)) ; Newworld-Flag auf True setzen newworld=True EndIf ; LMB = Kamerazoom erhöhen, um die Veränderung zu sehen If MouseDown(1) Then CameraZoom camera,50 Else CameraZoom camera,1 ; Planet und Wolken ein wenig drehen TurnEntity planet,0,-0.1*Tween,0 ; SPACE gedrückt, 30ms vergangen und Berechnungsflag wahr? Dann weiter If ms>time And newworld Then roundstart=ms ; Vergleichszeit = aktuelle Zeit + 60ms time=ms+30 ; Anzahl Pixel pro Durchgang berechnen adder%=(pixelstep/Tween) ; Start/Ende für aktuellen Schleifendurchlauf setzen start=i ende=i+adder ; Ende grösser als Pixelanzahl? Dann Ende=Pixelanzahl If ende>max-1 Then ende=max-1 ; Puffer sperren LockBuffer buff1 LockBuffer buff2 LockBuffer buff3 LockBuffer buff4 LockBuffer buff5 LockBuffer buff6 ; aktueller Schleifendurchlauf For j=start To ende ; Pixelinkrement i=i+1 ; Pixel grösser als Pixelanzahl? Ende If i>max-1 Then newworld=False Goto skip EndIf ; X/Y-Position des Pixels aus dem Zufallsarray berechnen y=Int(Array(i)/maxx) x=Array(i)-(y*maxx) ; Quellfarben einlesen rgb1=ReadPixelFast(x,y,buff1) rgb2=ReadPixelFast(x,y,buff2) rgb3=ReadPixelFast(x,y,buff3) rgb4=ReadPixelFast(x,y,buff4) ; aufsplitten r1=255-(rgb1 And $ff0000)/$10000 r2=(rgb2 And $ff0000)/$10000 r3=255-(rgb3 And $ff0000)/$10000 r4=(rgb4 And $ff0000)/$10000 ; mit Filter mischen r=Average(r1,r2) r=Lighten(r,r3) r=HardLight(r,r4) ; Legende brauchbarer Filterkombinationen: ; ; S = Softlight ; M = Multiply ; L = Lighten ; A = Average ; H = Hardlight ; O = Overlay ; E = exclusion ; D = Difference ; N = Negation ; ; SSM = um 99% Land ; SSS = 25-75% Land ; SSL = 75-25% Land, flacher ; ALH = 35-65% Land, kontinental ; AMM = 100% Land, gebirgig ; OLS = 25-75% Land ; OLC = <10% Land, ozeanisch ; MMM = 100% Land, verschneites Gebirge ; EDN = verschieden, erdähnlich, Archipelagos ; MNS = verschieden, erdännlich, Archipelagos ; über 128: unter Wasser, sonst Land If r>=128 Then water=water+1 Else land=land+1 ; Zielfarbe aus Farbverlauf bestimmen rgb5=GradientR(r)*$10000+GradientG(r)*$100+GradientB(r) ; in Textur schreiben WritePixelFast x,y,rgb5,buff5 WritePixelFast x,y,rgb5,buff6 Next .skip endtime=MilliSecs() ; Puffer entsperren UnlockBuffer buff6 UnlockBuffer buff5 UnlockBuffer buff4 UnlockBuffer buff3 UnlockBuffer buff2 UnlockBuffer buff1 ; verbrauchte Millisekunden pro Durchgang berechnen midtime=(midtime+(endtime-roundstart))/2.0 EndIf RenderWorld ; Ausgabe Text 0, 0,"Planet Source Maps: "+map Text 0, 15,"Pixels blended....: "+(i*100)/max+"%" Text 0, 30,"Transition Time...: "+(endtime-starttime)+"ms" Text 0, 45,"Used ms per cycle.: "+midtime+"ms" Text 0, 60,"Pixels per cycle..: "+adder Text 0, 75,"Water coverage....: "+(water*100.0)/max+"%" Text 0, 90,"Land coverage.....: "+(land*100.0)/max+"%" Text 0,105,"FPS...............: "+FPS Text 0,120,"Tris rendered.....: "+TrisRendered() DrawImage survey,GraphicsWidth()-width,0 Flip 0 Wend End ; Soft Light Filter Function SoftLight(a%,b%) Local c% c=a*b Shr 8 Return (c+a*(255-((255-a)*(255-b) Shr 8)-c) Shr 8) End Function ; Hard Light Filter Function HardLight(a%,b%) If b<128 Then Return (a*b) Shr 7 Else Return 255-((255-b)*(255-a) Shr 7) End Function ; Differenz Filter Function Difference(a%,b%) Return Abs(a-b) End Function ; Multiply Filter Function Multiply(a%,b%) Return (a*b) Shr 8 End Function ; Durchschnittsfilter Function Average(a%,b%) Return (a+b) Shr 1 End Function ; Screenfilter Function Screen(a%,b%) Return 255-((255-a)*(255-b) Shr 8) End Function ; Aufhellfilter Function Lighten(a%,b%) If a>b Then Return a Else Return b End Function ; Abdunkelfilter Function Darken(a%,b%) If a<b Then Return a Else Return b End Function ; Negativfilter Function Negation(a%,b%) Return 255-Abs(255-a-b) End Function ; Ausschlussfilter Function Exclusion(a%,b%) Return a+b-(a*b Shr 7) End Function ; Overlayfilter Function Overlay(a%,b%) If a<128 Then Return (a*b) Shr 7 Else Return 255-((255-a)*(255-b) Shr 7) End Function ; Farbbrandfilter Function ColorDodge(a%,b%) If b=255 Then Return 255 Else Local c%=Floor((a Shl 8)/(255-b)) If c>255 Then Return 255 Else Return c EndIf End Function ; Farbverlauf erstellen Function CreateGradient(colors%,steps%) Dim GradientR%(steps),GradientG%(steps),GradientB%(steps),Prozent%(colors),Rot%(colors),Gruen%(colors),Blau%(colors) Local i%,pos1%,pos2%,pdiff% Local rdiff%,gdiff%,bdiff% Local rstep#,gstep#,bstep# Local counter%=1 ; Farbcodes einlesen For i=1 To colors : Read Prozent(i),Rot(i),Gruen(i),Blau(i) : Next ; Gradient berechnen While counter<colors ; Prozent in Step-Position umrechnen pos1=Prozent(counter)*steps/100 pos2=Prozent(counter+1)*steps/100 ; Abstand berechnen pdiff=pos2-pos1 ; Differenz zwischen den Farben berechnen rdiff%=Rot(counter)-Rot(counter+1) gdiff%=Gruen(counter)-Gruen(counter+1) bdiff%=Blau(counter)-Blau(counter+1) ; Schrittweite zwischen den Farben berechnen rstep#=rdiff*1.0/pdiff gstep#=gdiff*1.0/pdiff bstep#=bdiff*1.0/pdiff ; Zwischenfarbcodes berechnen For i=0 To pdiff GradientR(pos1+i)=Int(Rot(counter)-(rstep*i)) GradientG(pos1+i)=Int(Gruen(counter)-(gstep*i)) GradientB(pos1+i)=Int(Blau(counter)-(bstep*i)) Next ; Zähler erhöhen counter=counter+1 Wend End Function ; Zufallsarray erstellen. Es werden alle Werte zufällig durcheinandergewürfelt, so dass jeder Wert nur 1x vorkommt Function CreateRandomArray(size%) ; Array neu dimensionieren Dim Array(size) ; Array mit allen Zahlen von 1...size füllen For i = 0 To size-1 : Array(i) = i : Next ; Würfeln For N% = 0 To size-2 M% = Rand( N%, size - 1) Z% = Array(N%) Array(N%) = Array(M%) Array(M%) = Z% Next End Function ; Zahl mit immer gleicher Anzahl an Stellen rückgeben, mit vorangestellen Nullen Function ZERO$(number%,lenght%=2) Local r$="" For i=1 To lenght-Len(Str(number)) r$=r$+"0" Next Return r$+Str(number) End Function ; Farbverlaufcodes für einen Klasse-M-Planeten .ClassMT Data 0,255,255,255 Data 5,179,179,179 Data 10,153,143, 92 Data 25,115,128, 77 Data 48, 42,102, 41 Data 50, 69,108,118 Data 52, 17, 82,112 Data 75, 9, 62, 92 Data 100, 2, 43, 68 EDIT: wenn ihr auch ein wenig herumfliegen wollt, einfach die Zeile mit "Rotateentity camera" entkommentieren. |
||
![]() |
aMulSieger des Minimalist Compo 01/13 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du könntest deine viermal ReadPixelFast weglassen, wenn du deine Vorlagen vorher in Arrays/Banks lädst, das sollte schon mal einen ordentlichen Schub geben.
Weiterhin könntest du überlegen, ob du die Größe der Textur vielleicht der Entfernung zum Planeten anpassen möchtest. Ich weiß nicht inwiefern man hier Leistung sparen kann, aber wenn man zum Beispiel zuerst nur eine 64*64 große Textur füllt und sobald man näher kommt diese durch immer größere ersetzt kriegt man vielleicht auch noch ein paar FPS(wenn man sich schlau anstellt). Zudem spart man so Speicher wenn die Planeten weit entfernt sind und man kann sich sollte man an einem Planeten nur in einiger Entfernung vorbeifliegen(sollte die Möglichkeit vorgesehen sein) die Berechnung einer größeren Textur ganz sparen. Ansonsten ist das was du da hast eine sehr interessante Idee und die Ergebnisse sehen sehr überzeugend aus. Weiter so! EDIT: Achja, du könntest auch mal versuchen den VRAM-Parameter(256) von CreateTexture ![]() |
||
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans! Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver |
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Danke für den Tip mit den Banks, ich habe meinen eigenen Code noch nicht umgeschrieben, aber mein Testbed spricht schon Bände: im Vergleich zu einer normalen Readpixelfast/Writepixelfastcombo ist das Auslesen aus einer Bank etwa 50x schneller, hier eine Demo (waynes interessiert - die Grafik "planet0.jpg" befindet sich in meiner oben verlinkten Demo):
Code: [AUSKLAPPEN] sizex%=512
sizey%=256 gfx$="planet0.jpg" Graphics sizex,sizey*2,32,2 bank=LoadImageBank(gfx$) ;SaveBankImage(bank,"test.img") ;bank=LoadBankImage("test.img",sizex,sizey) vergleich=LoadImage(gfx$) While Not KeyHit(1) ms1=MilliSecs() DrawImageBank bank,sizex,sizey zeit1=MilliSecs()-ms1 ms2=MilliSecs() DrawVergleichImage(vergleich,sizey) zeit2=MilliSecs()-ms2 Text 0,0,"Bank: "+zeit1+"ms" Text 0,sizey,"Readpixelfast: "+zeit2+"ms" Flip Wend End Function LoadImageBank(filename$) Local x%,y%,rgb%,h%,offset% Local image%=LoadImage(filename$) Local width%=ImageWidth(image) Local height%=ImageHeight(image) Local bank%=CreateBank(width*height) Local buffer%=ImageBuffer(image) LockBuffer buffer For x=0 To width-1 For y=0 To height-1 rgb=ReadPixelFast(x,y,buffer) h=(rgb And $ff0000)/$10000 offset=(y*width)+x PokeByte bank,offset,h Next Next UnlockBuffer buffer FreeImage image Return bank End Function Function SaveBankImage(bank%,filename$) Local f%=WriteFile(filename$) WriteBytes (bank,f,0,BankSize(bank)) CloseFile f End Function Function LoadBankImage(filename$,width%,height%) Local f%=OpenFile(filename$) Local bank%=CreateBank(width*height) ReadBytes(bank,f,0,BankSize(bank)) CloseFile f Return bank End Function Function DrawImageBank(bank%,width%,height%) Local x%,y%,h%,offset%,rgb% Local buffer%=FrontBuffer() LockBuffer buffer For x=0 To width-1 For y=0 To height-1 offset=(y*width)+x h=PeekByte(bank,offset) rgb=h*$10000+h*$100+h WritePixel x,y,rgb,buffer Next Next UnlockBuffer buffer End Function Function DrawVergleichImage(image,offsety) Local x%,y%,rgb%,h% Local width%=ImageWidth(image) Local height%=ImageHeight(image) Local buffer1%=FrontBuffer Local buffer2%=ImageBuffer(image) LockBuffer buffer1 LockBuffer buffer2 For x=0 To width-1 For y=0 To height-1 rgb=ReadPixelFast(x,y,buffer2) h=(rgb And $ff0000)/$10000 rgb=h*$10000+h*$100+h WritePixelFast x,y+offsety,rgb,buffer1 Next Next UnlockBuffer buffer2 UnlockBuffer buffer1 End Function |
||
Omenaton_2 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich bin ein weniger technisch denkender Mensch. Ich würde nicht so aufwendig einen Zufallsplaneten berechnen lassen, sondern gleich über "Faken" des Ganzen nachdenken. Ich bevorzuge eine Lösung die schnell zu machen ist und dann auch im Porgrammverlauf möglichst schnell läuft.
Ich würde eigenlich so vorgehen, als ob ich eine Zufallskarte für ein Spiel wie Civilisation errechnen würde. Also erst alles mit Wasser füllen, dann aus einigen vorberechneten Quadraten mit Land darauf paar Kontinente zusammenfügen. Das alles zusammen als 1 Textur abspeichern und dem Planeten zuweisen. Es mag sein, daß das letztendlich genauso aufwendig wäre, wie deine jetztige Pixelberechnung, aber ich denke das Ergebnis wäre natürlicher und die Berechnung eine Frage von Millisekunden. |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Glaub mir, ich habe schon alle Möglichkeiten durch und das Thema beschäftigt mich seit Jahren (!). Ich habe die Bank-Lösung nun in meinen Code eingebaut und ich muss sagen: ich bin extremst begeistert und hätte nicht gedacht, dass es so einen Performancegewinn dadurch gibt. Ich kann z.B. nun einen Planeten in 250ms berechnen und habe dafür einen Aufwand von etwa 5ms pro Durchgang bei einem Pixelstep von 16384 bei einer Texturgrösse von 1024x512! In FPS ausgedrückt ein Drop von nur noch 4 FPS bei 375 FPS! Ich kann nun ein ganzes Sonnensystem in 1-2 Sekunden "nebenher" beim Anflug berechnen lassen und dabei zehntausende verschieden aussehende Planeten generieren (es sind ja nicht nur die Kombinationen der 10 verschiedenen Vorlagen oder der Blendfilter, nein ich kann die ja auch noch verschieden einfärben und mal ein Klasse M Planet, mal einen Lavaplaneten, mal einen Mond generieren).
Hast Du eine Demo für Deinen Ansatz? Ich bin natürlich immer offen für Verbesserungen, wobei die Welt, die ich im Moment erzeuge für meine Zwecke voll und ganz ausreicht. Code für das o.g. reiche ich noch nach, hab im Moment keine Zeit das ein wenig aufzubereiten. |
||
Matthias |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hay ich habe mich auch mal daran versucht. Nunja ich arbeite mit Dim felder, weil diese noch ein Tick schneller sind.
Texture 1024x512 wird auf meinen Rechner im Durchnitt mit 40-50ms berechnet. Wenn die Pixelpositionen nicht getauscht werden (Area()). Wenn sie aber getauscht werden dauerts 160-180ms. Seltsamm. Ich weiß nicht an was es liegt. Egal. Auf jedenfall gehts schon sehr schnell. Code: [AUSKLAPPEN] Graphics 1024,512,32,2 Dim GPTexturen(0),GPGradient(256),GPRandMap(0) Global GPTexSizeX,GPTexSizeY Global GPMapNumber,GPlanetCount Global TImg=CreateImage(1024,512) Timer=CreateTimer(60) InitPlanetGenerator() UpdPlanetTextur() SetBuffer BackBuffer() Repeat If KeyHit(57)=1 Then GPMapNumber=MilliSecs():GPlanetCount=0 End If If GPlanetCount>-1 Then UpdPlanetTextur(10) DrawBlock TImg,0,0 Flip 0:WaitTimer(Timer) Until KeyDown(1)=1 End Function UpdPlanetTextur(MaxMS=1000) Zeit=MilliSecs() Tween=MilliSecs()+MaxMS MNumber$=Right("0000"+GPMapNumber,4) TexSize=(GPTexSizeX*GPTexSizeY) PTDataOfset0=(Asc(Mid(MNumber,1,1))-48)*TexSize PTDataOfset1=(Asc(Mid(MNumber,2,1))-48)*TexSize PTDataOfset2=(Asc(Mid(MNumber,3,1))-48)*TexSize PTDataOfset3=(Asc(Mid(MNumber,4,1))-48)*TexSize IBuff=ImageBuffer(TImg):LockBuffer IBuff Repeat:Pos=GPRandMap(GPlanetCount) X=Int(Pos/GPTexSizeY):Y=Pos-X*GPTexSizeY R1=GPTexturen(PTDataOfset0+Pos) R2=255-GPTexturen(PTDataOfset1+Pos) R3=GPTexturen(PTDataOfset2+Pos) R4=255-GPTexturen(PTDataOfset3+Pos) r=Average(r1,r2) r=Lighten(r,r3) r=HardLight(r,r4) GPlanetCount=GPlanetCount+1:Count=Count+1 WritePixelFast(X,Y,GPGradient(R),IBuff) If GPlanetCount=TexSize Then GPlanetCount=-1 Exit If Count>65536 Then Count=0:If MilliSecs()>Tween Then Exit Forever:UnlockBuffer IBuff If MaxMS=1000 Then AppTitle (MilliSecs()-Zeit) End Function Function HardLight(a%,b%) If b<128 Then Return (a*b) Shr 7 Else Return 255-((255-b)*(255-a) Shr 7) End Function Function Average(a%,b%) Return (a+b) Shr 1 End Function Function Lighten(a%,b%) If a>b Then Return a Else Return b End Function Function InitPlanetGenerator() CreateGradient() For TexCount=0 To 9:TexName$="1024\Planet"+TexCount+".jpg" Image=LoadImage(TexName):GPTexSizeX=ImageWidth(Image) GPTexSizeY=ImageHeight(Image):IBuff=ImageBuffer(Image) If TexCount=0 Then TexSize=GPTexSizeX*GPTexSizeY If TexCount=0 Then Dim GPTexturen(TexSize*10) LockBuffer IBuff:Count=TexCount*TexSize For X=0 To GPTexSizeX-1:For Y=0 To GPTexSizeY-1 RGB=(ReadPixelFast(X,Y,IBuff) Shl 8) Shr 24 GPTexturen(Count)=RGB:Count=Count+1 Next:Next:UnlockBuffer IBuff:FreeImage Image Next:TexSize=TexSize-1 Dim GPRandMap(TexSize+1) For I=0 To TexSize:GPRandMap(i)=i:Next ;Return For N=0 To TexSize M=Rand(N,TexSize-2):Z=GPRandMap(N) GPRandMap(N)=GPRandMap(M) GPRandMap(M)=Z Next End Function Function CreateGradient() Repeat:LevA=LevB RedA=RedB:GreenA=GreenB:BlueA=BlueB Read LevB,RedB,GreenB,BlueB M#=(LevB-LevA):C=0:R#=(RedB-RedA)/M G#=(GreenB-GreenA)/M:B#=(BlueB-BlueA)/M For I=LevA To LevB RR=R*C+RedA GG=G*C+GreenA BB=B*C+BlueA GPGradient(I)=RR*65536+GG*256+BB:C=C+1 Next Until LevB=255 End Function Data 0,255,255,255 Data 12,179,179,179 Data 25,153,143, 92 Data 64,115,128, 77 Data 122, 42,102, 41 Data 128, 69,108,118 Data 133, 17, 82,112 Data 191, 9, 62, 92 Data 255, 2, 43, 68 PS: Wird bestimmt ein Hammerspiel mit sooooooooooooooo viele Planeten. ![]() |
||
Krischan |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dein Code braucht bei mir 38ms, allerdings dafür Ewigkeiten bis mal was kommt... ich habe jetzt mal schnell was zusammengeschnürt. Mit dabei: der original Planetengenerator, der aus einer 3D Perlin Noise Cloud diese Karten "herausschält", so dass sie nahtlos auf eine Sphere mappen (auch an den Polen). Speichern tut dieser gleich im Bank-Format, welches von der delayed.bb eingelesen wird (ich habe die "original" 10 Planeten in diesem Format beigelegt).
Selbst wenn Arrays ein wenig schneller sind: meine Bank benutzt nur ein Byte pro Höheninfo (Array dann wohl volles Int, also zwei Bytes?), also ist der Speicherverbrauch geringer. Andererseits sind es nur 10 Planeten, die als Basis ausreichen sollten. Im Moment bin ich ja noch in Techdemos und Machbarkeitsstudien, aber wenn ich das alles einmal zu einen Spiel zusammenfüge, möchte ich schon bis zu 1000 Sterne besuchen können, die dann bis zu 10.000 Planeten haben (realistisch sind wohl eher 100 Sterne mit 500 Planeten, sonst dauert das ja ewig bis man alle besucht hat - mal sehen...). Die Planeten werden dann aber realtime aus einem Seed berechnet. Download: Delayed Planet Generator Zum Vergleich: ich bekomme hier 538FPS und wenn ich ständig auf der SPACE-Taste herumhämmere nicht weniger als 430FPS (die FPS droppen hier mehr, da ich die Cam nun viel näher am Planeten positioniert habe - später im Spiel wird der Planet ja schon erstellt, bevor man auch nur einen Pixel von ihm sieht). |
||
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Selbst bei meiner Onboard-Karte mit 64 MB schafft das Programm beim Erzeugen des Planeten 20 FPS . Gar nicht mal so schlecht... ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group