[B3D] Prozedurale 3D Spiralgalaxie

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Krischan

Betreff: [B3D] Prozedurale 3D Spiralgalaxie

BeitragDi, Okt 12, 2010 16:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe ein wenig mit Single Surface Techniken experimentiert und das ist dabei herausgekommen. Eine schöne prozedurale Galaxie in 3D, es sind zwar "nur" 24.000 Sterne sichtbar aber man kann deren Anzahl bis zum Vertex/Surface-Limit erhöhen, sofern dann noch CPU und Grafikkarte mitspielen. Die Galaxie selbst wird mittels einer generischen Archimedischen Spirale erzeugt. Ihr könnt mit den konstanten Parametern herumspielen, standardmässig sieht es Andromeda-Galaxiemässig aus, unsere eigene Milchstrasse hat z.B. nur zwei "Arme". Die Anzahl der Sterne erstreckt sich über die gesamte Galaxie, so dass auch kleinere Mengen die Umrisse zeigen können (dann halt mit weniger Details).

Die Single Surface Technik hier erzeugt virtuelle "Quads" mit je 4 Vertices und richtet diese mittels zweier Tformvector Befehle auf die Kamera aus. Es gibt nur eine Entity (die Galaxie) mit einer oder mehreren Surfaces (max. 32000 vertices=32000/4=8000 Sterne/Quads pro Surface). Die Sternentextur wird ebenfalls procedural aus dem Nichts erzeugt.

Zur Steuerung: Pfeiltasten und Maus, aber Ihr werdet keine Bewegung feststellen solange Ihr nicht eine (schnell) oder beide Maustasten (sehr schnell) gedrückt haltet. Wenn Ihr nahe einem Sternenfeld seid lasst beide Maustasten los und benutzt höchstens noch eine um schneller voranzukommen, damit man auch einzelne Sterne fliegen sieht, die man "besuchen" kann.

user posted image

BlitzBasic: [AUSKLAPPEN]
Graphics3D 800,600,32,2

SetBuffer BackBuffer()

Const TurnSpeed# = 4.000 ; cam turn speed
Const RollSpeed# = 0.500 ; cam roll speed
Const CameraSpeed# = 0.005 ; cam move speed
Const Stars% = 24000 ; number of stars
Const Spiralarms% = 4 ; number of spiral arms
Const Spread# = 20.0 ; star spread
Const Rotation# = 4.0 ; how many spiral rotations
Const Range# = 100.0 ; milkyway radius

Global WIDTH%=GraphicsWidth()
Global HEIGHT%=GraphicsHeight()
Global TIMER%=CreateTimer(60)
Global Scale#=WIDTH/3.0 ; star scale

Global total%,vis%

Local cam%,galaxy%,tex%

Type quad

Field surf%
Field x#,y#,z#
Field v%
Field scale#
Field r%,g%,b%

End Type

; init galaxy
galaxy=InitGalaxy(Stars,Spiralarms,Spread,Rotation,Range)
EntityFX galaxy,1+2
EntityBlend galaxy,3
tex=CreateSunTexture(256,128,128,128)
TextureBlend tex,3
EntityTexture galaxy,tex

; init camera
cam=CreateCamera()
CameraRange cam,0.1,1000
PositionEntity cam,0,90,150
PointEntity cam,galaxy

MoveMouse WIDTH/2,HEIGHT/2

; main loop
While Not KeyHit(1)

Local ms%,me%

Movement(cam)

ms=MilliSecs()
UpdateGalaxy(cam,Scale)
me=MilliSecs()-ms

RenderWorld

WaitTimer TIMER

AppTitle vis+" Stars visible ["+total+" Stars total] "+me+"ms"

Flip 0

Wend

End

; update quads in single surface mesh
Function UpdateGalaxy(cam%,scale#=256.0)

Local cx#=EntityX(cam)
Local cy#=EntityY(cam)
Local cz#=EntityZ(cam)

Local q.quad,d#,s#

total=0
vis=0

For q.quad = Each quad

; check if star is visible
TFormPoint q\x,q\y,q\z,0,cam

; in front of cam?
If TFormedZ()>0 Then

; adaptive size
d#=Distance3D(q\x,q\y,q\z,cx,cy,cz)
s#=(q\scale/d)+(d/scale)
If s<d/scale Then s=d/scale

; align single surface quads to cam
UpdateQuad(q.quad,s,cam)

vis=vis+1

EndIf

total=total+1

Next

End Function

; create galaxy
Function InitGalaxy%(stars%=10000,arms%=4,spread#=40.0,rot#=2.0,range#=100.0)

Local mesh%=CreateMesh()
Local surf%=CreateSurface(mesh)
Local q.quad
Local angle#,dist#,turb#
Local i%,col#,multi#,lum#,bulge%,counter%

For i=1 To stars

q.quad = New quad

; color
col=Rnd(1)
If col>0.90 And col<=1.00 Then q\r=255 : q\g= 0 : q\b= 0
If col>0.70 And col<=0.90 Then q\r=255 : q\g=255 : q\b= 0
If col>0.50 And col<=0.70 Then q\r= 0 : q\g= 0 : q\b=255
If col>0.00 And col<=0.50 Then q\r=255 : q\g=255 : q\b=255

; angle
angle=Int(Floor(i*1.0/(stars/arms)))*(360.0/arms)

; center / arm relation
If Rnd(1)>0.5 Then multi=Rnd(0.1,1) Else multi=Rnd(1,2)

; distance and turbulence
dist=Rnd(0,range)*Rnd(1,Rnd(Rnd(multi)))
turb=Rnd(0,Rnd(spread)) : If Rnd(1)>0.5 Then turb=-turb

; more red/yellow stars in bulge
lum=Rnd(1)
If dist<range/2*lum Then

If lum>0.75 Then

q\r=255 : q\g=0 : q\b=0 ; red stars

Else If lum>0.5 Then

q\r=255 : q\g=255 : q\b=0 ; yellow stars

EndIf

Else

If lum>0.75 Then

q\r=0 : q\g=0 : q\b=255 ; blue stars

Else If lum>0.5 Then

q\r=255 : q\g=255 : q\b=255 ; white stars

EndIf

EndIf

; star position x/z
q\x=dist*Cos(angle+(dist*rot))+Rnd(Rnd(Rnd(-spread)),Rnd(Rnd(spread)))
q\z=dist*Sin(angle+(dist*rot))+Rnd(Rnd(Rnd(-spread)),Rnd(Rnd(spread)))

; star position y
bulge=Normalize(Distance2D(q\x,q\z,0,0),0,range/2.0,0,180)/2.0
If bulge>90 Then bulge=90
q\y=(Cos(bulge)*Rnd(Rnd(-spread),Rnd(spread))/2.0)+(turb/10.0)

; scale
q\scale=Rnd(0.01,Rnd(0.02,Rnd(0.04,0.08)))

; create new surface if too many vertices
If counter+4>32000 Then surf=CreateSurface(mesh) : counter=0
q\surf=surf

; add vertices
q\v=AddVertex(q\surf,0,0,0,0,0)
AddVertex(q\surf,0,0,0,1,0)
AddVertex(q\surf,0,0,0,1,1)
AddVertex(q\surf,0,0,0,0,1)

; color vertices
VertexColor q\surf,q\v,q\r,q\g,q\b
VertexColor q\surf,q\v+1,q\r,q\g,q\b
VertexColor q\surf,q\v+2,q\r,q\g,q\b
VertexColor q\surf,q\v+3,q\r,q\g,q\b

; add triangles
AddTriangle(q\surf,q\v,q\v+1,q\v+2)
AddTriangle(q\surf,q\v,q\v+2,q\v+3)

; vertex counter
counter=counter+4

Next

Return mesh

End Function

; align single surface quad to cam
Function UpdateQuad(q.quad,s#,target%)

Local x1#,y1#,z1#,x2#,y2#,z2#

TFormVector -s,0,0,target,0
x1=TFormedX()
y1=TFormedY()
z1=TFormedZ()

TFormVector 0,-s,0,target,0
x2=TFormedX()
y2=TFormedY()
z2=TFormedZ()

VertexCoords q\surf,q\v+0,q\x-x1-x2,q\y-y1-y2,q\z-z1-z2
VertexCoords q\surf,q\v+1,q\x-x1+x2,q\y-y1+y2,q\z-z1+z2
VertexCoords q\surf,q\v+2,q\x+x1+x2,q\y+y1+y2,q\z+z1+z2
VertexCoords q\surf,q\v+3,q\x+x1-x2,q\y+y1-y2,q\z+z1-z2

End Function

; calculate 2D Distance
Function Distance2D#(x1#,y1#,x2#,y2#)

Local x#=x1-x2
Local y#=y1-y2

Return Sqr((x*x)+(y*y))

End Function

; calucate 3D Distance
Function Distance3D#(x1#,y1#,z1#,x2#,y2#,z2#)

Local x#=x1-x2
Local y#=y1-y2
Local z#=z1-z2

Return Sqr((x*x)+(y*y)+(z*z))

End Function

; normalize a value
Function Normalize#(value#=128.0,vmin#=0.0,vmax#=255.0,nmin#=0.0,nmax#=1.0)

Return ((value#-vmin#)/(vmax#-vmin#))*(nmax#-nmin#)+nmin#

End Function

; camera movement
Function Movement(cam%,sensitivity#=1.0)

Local roll#,cz#,tx#,ty#,multi%=1

; arrows = move / LMB = Turbo / RMB = Lightspeed / LMB+RMB = incredible speed
cz=(KeyDown(200)-KeyDown(208))*CameraSpeed
roll=(KeyDown(203)-KeyDown(205))*RollSpeed
If MouseDown(1) Then multi=10
If MouseDown(2) Then multi=multi*10

tx=Normalize(MouseX(),0,WIDTH , 1,-1)
ty=Normalize(MouseY(),0,HEIGHT,-1, 1)

If ty<0 Then ty=(Abs(ty)^sensitivity)*-1 Else ty=ty^sensitivity
If tx<0 Then tx=(Abs(tx)^sensitivity)*-1 Else tx=tx^sensitivity

TurnEntity cam,ty*TurnSpeed,tx*TurnSpeed,roll*TurnSpeed
MoveEntity cam,0,0,cz*multi

End Function

; create a stunning sun texture
Function CreateSunTexture(size%=512,r%=255,g%=255,b%=255)

Local tex%=CreateTexture(size,size,3)
Local tb%=TextureBuffer(tex)

Local i#,j%,col%,rgb%
Local x%,y%,xx%,yy%
Local a%

LockBuffer tb

For j=0 To (size/2)-1

col=255-Normalize(j,0,(size/2.0)-1,0,255)
If col>255 Then col=255
rgb=col*$1000000+col*$10000+col*$100+col

For i=0 To 360 Step 0.05

WritePixelFast (size/2)+(Sin(i)*j),(size/2)+(Cos(i)*j),rgb,tb

Next

Next

UnlockBuffer tb

; temp camera
Local tempcam%=CreateCamera()
CameraRange tempcam,1,WIDTH*2

; temp pivot
Local tempsun%=CreatePivot()

; create 4 layers
CreateQuad(tempsun,size/4.0,tex,3,1+8+16,r*1.00,g*1.00,b*1.00,1.00)
CreateQuad(tempsun,size/1.5,tex,3,1+8+16,r*1.00,g*1.00,b*1.00,1.00)
CreateQuad(tempsun,size/1.2,tex,3,1+8+16,r*0.75,g*0.75,b*0.50,0.75)
CreateQuad(tempsun,size/1.0,tex,3,1+8+16,r*0.50,g*0.50,b*0.50,0.50)

PositionEntity tempsun,0,0,WIDTH

; render it
RenderWorld

; delete pivot
FreeEntity tempsun

LockBuffer BackBuffer()
LockBuffer tb

; grab image
For x=0 To size-1

For y=0 To size-1

xx=(WIDTH/2)-(size/2)+x
yy=(HEIGHT/2)-(size/2)+y

rgb=ReadPixelFast(xx,yy,BackBuffer())

r=(rgb And $ff0000)/$10000
g=(rgb And $ff00)/$100
b=(rgb And $ff)
a=255

; alpha
If (r+g+b)/3 < 32 Then a=Normalize((r+g+b)/3,0,32,0,255)

; rgb
rgb=(r+g+b)/3*$1000000+r*$10000+g*$100+b

WritePixelFast x,y,rgb,tb

Next

Next

UnlockBuffer tb
UnlockBuffer BackBuffer()

RenderWorld

; delete temp cam
FreeEntity tempcam

Return tex

End Function

; advanced quad creation
Function CreateQuad(parent%=False,scale#=1.0,tex%=False,blend%=False , fx%=False,r%=255,g%=255,b%=255,a#=1.0)

Local mesh%=CreateMesh()
Local surf%=CreateSurface(mesh)

Local v0%=AddVertex(surf, 1, 1,0,0,0)
Local v1%=AddVertex(surf,-1, 1,0,1,0)
Local v2%=AddVertex(surf,-1,-1,0,1,1)
Local v3%=AddVertex(surf, 1,-1,0,0,1)

AddTriangle surf,v0,v1,v2
AddTriangle surf,v0,v2,v3

If parent Then EntityParent mesh,parent
If fx Then EntityFX mesh,fx
If tex Then EntityTexture mesh,tex
If blend Then EntityBlend mesh,blend

EntityColor mesh,r,g,b
EntityAlpha mesh,a

VertexColor surf,v0,r,g,b,a
VertexColor surf,v1,r,g,b,a
VertexColor surf,v2,r,g,b,a
VertexColor surf,v3,r,g,b,a

ScaleEntity mesh,scale,scale,scale

Return mesh

End Function
  • Zuletzt bearbeitet von Krischan am Mi, Okt 13, 2010 14:56, insgesamt einmal bearbeitet

Alkan

Betreff: Gute Arbeit,...

BeitragDi, Okt 12, 2010 21:00
Antworten mit Zitat
Benutzer-Profile anzeigen
...das hast du sehr gut hingekriegt Wink
Aber das einzige was mich stört ist, dass ich bei 240000 Sternen nur 9 FPS kriege, wobei meine Grafikkarte eine maximale Auslastung von nur 10% hat.
Vielleicht könnte man die Berechnung die der Prozessor macht, der Grafikkarte übergeben, mit einer selbst erstellten DLL die OpenCL o.ä benutzt.
Denn so welche Berechnungen lassen sich ja gut Parallelisieren.
Ich werds dann auch mal probieren.
Aber auf jedenfall sieht es sehr gut aus und bugs hab ich auch noch nicht gefunden.

MfG
Alkan
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD
Worklog: Planetensimulation
Homepage(Under Construction): alkan96.dyndns.org
Wenn schon falsch, dann richtig falsch.

Die Kiste

BeitragDi, Okt 12, 2010 21:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich hab bei 24.0000 Gefühlte 1 Fps xD
 

Krischan

BeitragDi, Okt 12, 2010 22:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja interessant - CPU und GPU langweilen sich bei mir regelrecht. Woran das liegt kann ich allerdings nicht sagen...

Hier am Screenshot auf der rechten Seite gut zu sehen, GPU 5% Auslastung, i7 1.6GHz @ 2.4GHz Turbo mit 20-40% Auslastung. Die Galaxie sieht mit 10x mehr Sternen aber auch viel geiler aus. So 1 Million wären nicht schlecht als Ziel.

user posted image

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Okt 12, 2010 23:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Was habt ihr denn für Rechner?

Alkan, ich hoffe du verwechselst FPS nicht mit den angezeigten ms.

Auf meiner Onboard ATI HD 4200 erreiche ich 9 ms mit insgesamt 47 FPS. Dabei rendert mein Rechner z.Zt. noch nebenbei auf allen vier Kernen.

Die Spirale an sich ist schon ganz nett. Klar sollte sein, das nicht jedes Frame ein Update gemacht werden muss. Krischan wird den Code sicherlich nur als Demo so ausgeführt haben.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

Krischan

BeitragDi, Okt 12, 2010 23:14
Antworten mit Zitat
Benutzer-Profile anzeigen
hectic hat Folgendes geschrieben:
Klar sollte sein, das nicht jedes Frame ein Update gemacht werden muss. Krischan wird den Code sicherlich nur als Demo so ausgeführt haben.


Es reicht, wenn man alle paar ms updated, könnte aber bestimmt noch weiter optimiert werden (irgendwelche Verbesserungsvorschläge, hectic?). Eine "Verbesserung" habe ich noch entdeckt, aus einem mir noch nicht erfindlichen Grund läuft es schneller, wenn man in der Funktion UpdateGalaxy folgende Tformpoint Prüfung ausschaltet, die als schnellerer Ersatz für EntityInView dienen sollte:

; check if star is visible
;TFormPoint q\x,q\y,q\z,0,cam

; in front of cam?
;If TFormedZ()>0 Then
...
;EndIf

Das bringt bei mir ein paar FPS mehr.
 

Krischan

BeitragMi, Okt 13, 2010 0:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Nachtrag: hab jetzt 240.000 Sterne bei 20-40 FPS. Wie das? Mit folgende Optimierungen:

- bei bestimmter Anzahl von Surfaces wird neues Mesh erstellt (unklar obs was bringt)
- Quads werden nun in 10 verschiedenen Durchgängen aktualisiert (hier: Quad 1...24000 / 24001...48000 usw...)
- nur bei aktuellem Durchgang oder wenn Quads nahe sind wird überhaupt ein Quad aktualisiert

Und so siehts dann aus, gleich viel besser:
user posted image

BlitzBasic: [AUSKLAPPEN]
Graphics3D 800,600,32,2

SetBuffer BackBuffer()

Const TurnSpeed# = 4.000 ; cam turn speed
Const RollSpeed# = 0.500 ; cam roll speed
Const CameraSpeed# = 0.005 ; cam move speed
Const Stars% = 240000 ; number of stars
Const Spiralarms% = 4 ; number of spiral arms
Const Spread# = 20.0 ; star spread
Const Rotation# = 4.0 ; how many spiral rotations
Const Range# = 100.0 ; milkyway radius

Global WIDTH%=GraphicsWidth()
Global HEIGHT%=GraphicsHeight()
Global TIMER%=CreateTimer(60)
Global Scale#=WIDTH/3.0 ; star scale

Global meshes%[256]

Global total%,vis%

Local cam%,galaxy%,tex%

Type quad

Field surf%
Field x#,y#,z#
Field v%
Field scale#
Field r%,g%,b%
Field lastdist#

End Type

tex=CreateSunTexture(256,128,128,128)
TextureBlend tex,3

; init galaxy
galaxy=InitGalaxy(Stars,Spiralarms,Spread,Rotation,Range)

For i=0 To galaxy

If meshes[i]>0 Then

EntityFX meshes[i],1+2
EntityBlend meshes[i],3
EntityTexture meshes[i],tex

EndIf

Next

; init camera
cam=CreateCamera()
CameraRange cam,0.1,1000
PositionEntity cam,0,90,150
PointEntity cam,meshes[0]

; update galaxy once
Local cx#=EntityX(cam)
Local cy#=EntityY(cam)
Local cz#=EntityZ(cam)
Local q.quad,d#,s#
For q.quad = Each quad
; adaptive size
d=Distance3D(q\x,q\y,q\z,cx,cy,cz)
s=(q\scale/d)+(d/Scale)
If s<d/Scale Then s=d/Scale
; align single surface quads to cam
UpdateQuad(q.quad,s,cam)
q\lastdist=d
Next

MoveMouse WIDTH/2,HEIGHT/2

; main loop
While Not KeyHit(1)

Local ms%,me%

Movement(cam)


ms=MilliSecs()
i=i+1 : If i>=10 Then i=0
UpdateGalaxy(cam,Scale,i)
me=MilliSecs()-ms


RenderWorld

;WaitTimer TIMER

AppTitle vis+" Stars updated ["+total+" Stars total] "+me+"ms"

Flip 0

Wend

End

; update quads in single surface mesh
Function UpdateGalaxy(cam%,scale#=256.0,part%)

Local cx#=EntityX(cam)
Local cy#=EntityY(cam)
Local cz#=EntityZ(cam)

Local q.quad,d#,s#,steps%,i%,start%,ende%

total=0
vis=0

steps=Stars/10

For q.quad = Each quad

; set start and end
start=part*steps
ende=(part+1)*steps

; check only current part or nearby stars
If i>=start And i<ende Or q\lastdist<5 Then

TFormPoint q\x,q\y,q\z,0,cam

; in front of cam?
If TFormedZ()>0 Then

; adaptive size
d#=Distance3D(q\x,q\y,q\z,cx,cy,cz)
s#=(q\scale/d)+(d/scale)
If s<d/scale Then s=d/scale

; store last distance calculation
q\lastdist=d

; align single surface quads to cam
UpdateQuad(q.quad,s,cam)

vis=vis+1

EndIf

EndIf

i=i+1

total=total+1

Next

End Function

; create galaxy
Function InitGalaxy%(stars%=10000,arms%=4,spread#=40.0,rot#=2.0,range#=100.0)

Local mesh%=CreateMesh()
Local surf%=CreateSurface(mesh)
Local q.quad
Local angle#,dist#,turb#
Local i%,col#,multi#,lum#,bulge%,counter%,surfs%=1,m%=0

meshes[0]=mesh

For i=1 To stars

q.quad = New quad

; color
col=Rnd(1)
If col>0.90 And col<=1.00 Then q\r=255 : q\g= 0 : q\b= 0
If col>0.70 And col<=0.90 Then q\r=255 : q\g=255 : q\b= 0
If col>0.50 And col<=0.70 Then q\r= 0 : q\g= 0 : q\b=255
If col>0.00 And col<=0.50 Then q\r=255 : q\g=255 : q\b=255

; angle
angle=Int(Floor(i*1.0/(stars/arms)))*(360.0/arms)

; center / arm relation
If Rnd(1)>0.5 Then multi=Rnd(0.1,1) Else multi=Rnd(1,2)

; distance and turbulence
dist=Rnd(0,range)*Rnd(1,Rnd(Rnd(multi)))
turb=Rnd(0,Rnd(spread)) : If Rnd(1)>0.5 Then turb=-turb

; more red/yellow stars in bulge
lum=Rnd(1)
If dist<range/2*lum Then

If lum>0.75 Then

q\r=255 : q\g=0 : q\b=0 ; red stars

Else If lum>0.5 Then

q\r=255 : q\g=255 : q\b=0 ; yellow stars

EndIf

Else

If lum>0.75 Then

q\r=0 : q\g=0 : q\b=255 ; blue stars

Else If lum>0.5 Then

q\r=255 : q\g=255 : q\b=255 ; white stars

EndIf

EndIf

; star position x/z
q\x=dist*Cos(angle+(dist*rot))+Rnd(Rnd(Rnd(-spread)),Rnd(Rnd(spread)))
q\z=dist*Sin(angle+(dist*rot))+Rnd(Rnd(Rnd(-spread)),Rnd(Rnd(spread)))

; star position y
bulge=Normalize(Distance2D(q\x,q\z,0,0),0,range/2.0,0,180)/2.0
If bulge>90 Then bulge=90
q\y=(Cos(bulge)*Rnd(Rnd(-spread),Rnd(spread))/2.0)+(turb/10.0)

; scale
q\scale=Rnd(0.01,Rnd(0.02,Rnd(0.04,0.08)))

; create new surface if too many vertices
If counter+4>32000 Then

If surfs+1>7 Then
m=m+1
mesh=CreateMesh()
meshes[m]=mesh
surfs=0
EndIf

surf=CreateSurface(mesh)
counter=0
surfs=surfs+1

EndIf

q\surf=surf

; add vertices
q\v=AddVertex(q\surf,0,0,0,0,0)
AddVertex(q\surf,0,0,0,1,0)
AddVertex(q\surf,0,0,0,1,1)
AddVertex(q\surf,0,0,0,0,1)

; color vertices
VertexColor q\surf,q\v,q\r,q\g,q\b
VertexColor q\surf,q\v+1,q\r,q\g,q\b
VertexColor q\surf,q\v+2,q\r,q\g,q\b
VertexColor q\surf,q\v+3,q\r,q\g,q\b

; add triangles
AddTriangle(q\surf,q\v,q\v+1,q\v+2)
AddTriangle(q\surf,q\v,q\v+2,q\v+3)

; vertex counter
counter=counter+4

Next

DebugLog m

Return m

End Function

; align single surface quad to cam
Function UpdateQuad(q.quad,s#,target%)

Local x1#,y1#,z1#,x2#,y2#,z2#

TFormVector -s,0,0,target,0
x1=TFormedX()
y1=TFormedY()
z1=TFormedZ()

TFormVector 0,-s,0,target,0
x2=TFormedX()
y2=TFormedY()
z2=TFormedZ()

VertexCoords q\surf,q\v+0,q\x-x1-x2,q\y-y1-y2,q\z-z1-z2
VertexCoords q\surf,q\v+1,q\x-x1+x2,q\y-y1+y2,q\z-z1+z2
VertexCoords q\surf,q\v+2,q\x+x1+x2,q\y+y1+y2,q\z+z1+z2
VertexCoords q\surf,q\v+3,q\x+x1-x2,q\y+y1-y2,q\z+z1-z2

End Function

; calculate 2D Distance
Function Distance2D#(x1#,y1#,x2#,y2#)

Local x#=x1-x2
Local y#=y1-y2

Return Sqr((x*x)+(y*y))

End Function

; calucate 3D Distance
Function Distance3D#(x1#,y1#,z1#,x2#,y2#,z2#)

Local x#=x1-x2
Local y#=y1-y2
Local z#=z1-z2

Return Sqr((x*x)+(y*y)+(z*z))

End Function

; normalize a value
Function Normalize#(value#=128.0,vmin#=0.0,vmax#=255.0,nmin#=0.0,nmax#=1.0)

Return ((value#-vmin#)/(vmax#-vmin#))*(nmax#-nmin#)+nmin#

End Function

; camera movement
Function Movement(cam%,sensitivity#=1.0)

Local roll#,cz#,tx#,ty#,multi%=1

; arrows = move / LMB = Turbo / RMB = Lightspeed / LMB+RMB = incredible speed
cz=(KeyDown(200)-KeyDown(208))*CameraSpeed
roll=(KeyDown(203)-KeyDown(205))*RollSpeed
If MouseDown(1) Then multi=10
If MouseDown(2) Then multi=multi*10

tx=Normalize(MouseX(),0,WIDTH , 1,-1)
ty=Normalize(MouseY(),0,HEIGHT,-1, 1)

If ty<0 Then ty=(Abs(ty)^sensitivity)*-1 Else ty=ty^sensitivity
If tx<0 Then tx=(Abs(tx)^sensitivity)*-1 Else tx=tx^sensitivity

TurnEntity cam,ty*TurnSpeed,tx*TurnSpeed,roll*TurnSpeed
MoveEntity cam,0,0,cz*multi

End Function

; create a stunning sun texture
Function CreateSunTexture(size%=512,r%=255,g%=255,b%=255)

Local tex%=CreateTexture(size,size,3)
Local tb%=TextureBuffer(tex)

Local i#,j%,col%,rgb%
Local x%,y%,xx%,yy%
Local a%

LockBuffer tb

For j=0 To (size/2)-1

col=255-Normalize(j,0,(size/2.0)-1,0,255)
If col>255 Then col=255
rgb=col*$1000000+col*$10000+col*$100+col

For i=0 To 360 Step 0.05

WritePixelFast (size/2)+(Sin(i)*j),(size/2)+(Cos(i)*j),rgb,tb

Next

Next

UnlockBuffer tb

; temp camera
Local tempcam%=CreateCamera()
CameraRange tempcam,1,WIDTH*2

; temp pivot
Local tempsun%=CreatePivot()

; create 4 layers
CreateQuad(tempsun,size/4.0,tex,3,1+8+16,r*1.00,g*1.00,b*1.00,1.00)
CreateQuad(tempsun,size/1.5,tex,3,1+8+16,r*1.00,g*1.00,b*1.00,1.00)
CreateQuad(tempsun,size/1.2,tex,3,1+8+16,r*0.75,g*0.75,b*0.50,0.75)
CreateQuad(tempsun,size/1.0,tex,3,1+8+16,r*0.50,g*0.50,b*0.50,0.50)

PositionEntity tempsun,0,0,WIDTH

; render it
RenderWorld

; delete pivot
FreeEntity tempsun

LockBuffer BackBuffer()
LockBuffer tb

; grab image
For x=0 To size-1

For y=0 To size-1

xx=(WIDTH/2)-(size/2)+x
yy=(HEIGHT/2)-(size/2)+y

rgb=ReadPixelFast(xx,yy,BackBuffer())

r=(rgb And $ff0000)/$10000
g=(rgb And $ff00)/$100
b=(rgb And $ff)
a=255

; alpha
If (r+g+b)/3 < 32 Then a=Normalize((r+g+b)/3,0,32,0,255)

; rgb
rgb=(r+g+b)/3*$1000000+r*$10000+g*$100+b

WritePixelFast x,y,rgb,tb

Next

Next

UnlockBuffer tb
UnlockBuffer BackBuffer()

RenderWorld

; delete temp cam
FreeEntity tempcam

Return tex

End Function

; advanced quad creation
Function CreateQuad(parent%=False,scale#=1.0,tex%=False,blend%=False , fx%=False,r%=255,g%=255,b%=255,a#=1.0)

Local mesh%=CreateMesh()
Local surf%=CreateSurface(mesh)

Local v0%=AddVertex(surf, 1, 1,0,0,0)
Local v1%=AddVertex(surf,-1, 1,0,1,0)
Local v2%=AddVertex(surf,-1,-1,0,1,1)
Local v3%=AddVertex(surf, 1,-1,0,0,1)

AddTriangle surf,v0,v1,v2
AddTriangle surf,v0,v2,v3

If parent Then EntityParent mesh,parent
If fx Then EntityFX mesh,fx
If tex Then EntityTexture mesh,tex
If blend Then EntityBlend mesh,blend

EntityColor mesh,r,g,b
EntityAlpha mesh,a

VertexColor surf,v0,r,g,b,a
VertexColor surf,v1,r,g,b,a
VertexColor surf,v2,r,g,b,a
VertexColor surf,v3,r,g,b,a

ScaleEntity mesh,scale,scale,scale

Return mesh

End Function
  • Zuletzt bearbeitet von Krischan am Do, Okt 14, 2010 17:23, insgesamt 2-mal bearbeitet

tft

BeitragMi, Okt 13, 2010 11:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich weis nicht woran das liegt. Aber ich kann den Code nicht mit Copy und Paste in den BB Editor übertragen ..... die Return byts fehlen.

Gruss TFT
TFT
https://www.sourcemagic.ch
Monkey,HTML5,CSS3,W 10 64 Bit, 32 GB Ram, GTX Titan, W8 ist Müll !!!!!!
 

Krischan

BeitragMi, Okt 13, 2010 11:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Beide Codes lassen sich hier bei mir auf mehreren Rechnern problemlos pasten, sowohl in der B3D IDE als auch in Ideal - am Code liegt es nicht. Was sind denn "Return byts"?

TimBo

BeitragMi, Okt 13, 2010 13:44
Antworten mit Zitat
Benutzer-Profile anzeigen
ich glaube er meint damit die Bytefolge 13,10.

Aber es liegt nur am IE9, welcher die Bytes nicht mitmakiert und folglich nicht mitkopiert.

LG
TimBo
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.

Nicdel

BeitragMi, Okt 13, 2010 15:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Sieht sehr nice aus.

Läuft mit 30 FPS auf Notebook, siehe Signatur.
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

Alkan

BeitragMi, Okt 13, 2010 15:44
Antworten mit Zitat
Benutzer-Profile anzeigen
@hectic:
Nein das war keine Verwechselung, ich meine FPS. Wink
Außerdem hab ich 240000 Sterne und nicht 24000 geschrieben.
Oder hast du mit deinem Onboard-Grafikchip wirklich 48 FPS bei 240000 Sternen?(ich habe da 9 FPS und bei der neuen Version 43-44 FPS)

@Krischan:
Ja die neue Version ist wirklich viel schneller, hab da auch so 20-40 FPS je nachdem wie weit man von dem Mittelpunkt der Galaxie entfernt ist.
Außerdem wird jetzt auch die Grafikkarte mehr beansprucht( bei mir ca. 90%).
Bei 2.400.000 Sternen hab ich jetzt immerhin noch ca. 3-4 und bei 1.200.000 Sternen 7 FPS .
Aber immer wenn ich bei so vielen Sternen zu nah an den Quads bin krieg ich immer eine Mav.
Außerdem wird dann die Grafikkarte nicht mehr so sehr beansprucht, da wieder alles an der CPU hängenbleibt.

MfG
Alkan
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD
Worklog: Planetensimulation
Homepage(Under Construction): alkan96.dyndns.org
Wenn schon falsch, dann richtig falsch.
  • Zuletzt bearbeitet von Alkan am Mi, Okt 13, 2010 19:10, insgesamt einmal bearbeitet

biggicekey

BeitragMi, Okt 13, 2010 17:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Alkan hat Folgendes geschrieben:

das einzige was mich stört ist, dass ich bei 240000 Sternen nur 9 FPS kriege

Alkan hat Folgendes geschrieben:

Außerdem hab ich 240000 Sterne und nicht 24000 geschrieben.
Oder hast du mit deinem Onboard-Grafikchip wirklich 48 FPS bei 240000 Sternen?(ich habe da 86 FPS)


kann ich nicht zählen? hattest du nun 9 oder 86 FPS bei 240000????
#45 www.icekeyunlimited.de www.starcrusade.de
Gewinner BCC#17 !!! mit dotkiller
Nothing more to register - you've cleaned us out![/size]

Alkan

BeitragMi, Okt 13, 2010 19:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Alkan hat Folgendes geschrieben:

das einzige was mich stört ist, dass ich bei 240000 Sternen nur 9 FPS kriege

Alkan hat Folgendes geschrieben:

Außerdem hab ich 240000 Sterne und nicht 24000 geschrieben.
Oder hast du mit deinem Onboard-Grafikchip wirklich 48 FPS bei 240000 Sternen?(ich habe da 86 FPS)


kann ich nicht zählen? hattest du nun 9 oder 86 FPS bei 240000????

Oh das hab ich jetzt selber auch verwechselt Embarassed
Naja, vielen dank für den Hinweis biggicekey, hab es jetzt korrigiert. Wink
Hauptrechner: Win7 Ultimate x64|AMD Phenom II X4 965 BlackEdition 4x3.4GHz|4 GB DualKit DDR3-1600 Ram|1.5 TB Samsung EcoGreen|Cougar CM 700Watt|ASRock M3A790GFX/120M|Nvidia GeForce 9500GT|Ati Radeon HD3300(Onboard-Deaktiviert)
Server(früher Hauptrechner): Ubuntu 9.1 x86|Intel P4 HT 3GHz|Ati Radeon X600Pro|200 GB HDD
Worklog: Planetensimulation
Homepage(Under Construction): alkan96.dyndns.org
Wenn schon falsch, dann richtig falsch.

ozzi789

BeitragDo, Okt 14, 2010 22:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schöne Sache!
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group