2D Raytracer

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

 

Boris1993

Betreff: 2D Raytracer

BeitragFr, Nov 16, 2012 0:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ich mich gerade mit dem Thema Realtime Voxel Raytracing auseinandersetze habe ich zum Testen einen einfachen, grob gecodeten 2D Raytracer geschrieben...

Code: [AUSKLAPPEN]
SuperStrict

Framework BRL.GLMax2D
Import BRL.Random

SetGraphicsDriver GLMax2DDriver()
SeedRnd MilliSecs()

'Bildschirm-Breite/Höhe
Const w:Float = 1280
Const h:Float = 768

Graphics w, h, 0, 60
SetClsColor 255, 255, 255
SetBlend ALPHABLEND


Global eye:Float[] = [0.5, 0.5]
Global vdist:Int = 100
Global rot:Float

Global screen:Int[]
Global map:Int[41, 41]

For Local x:Byte = 0 To 40
   For Local y:Byte = 0 To 40
      If Rand(1, 100) <= 8 Then
         map[x, y] = GenARGB(255, Rand(0, 255), Rand(0, 255), Rand(0, 255))
      End If
   Next
Next




'-----Hauptschleife-----
Repeat
   Cls
   
   screen = New Int[301]
   
   If KeyDown(KEY_RIGHT) Then rot:+1
   If KeyDown(KEY_LEFT) Then rot:-1
   If KeyDown(KEY_W) Then eye[1]:+0.1
   If KeyDown(KEY_A) Then eye[0]:-0.1
   If KeyDown(KEY_S) Then eye[1]:-0.1
   If KeyDown(KEY_D) Then eye[0]:+0.1
   If rot > 360 Then rot = 0
   If rot < 0 Then rot = 360
   
   SetColor 155, 155, 155
   'vertikale Linien Zeichnen
   For Local vl:Int = 1 To w/20
      DrawLine vl*20, 0, vl*20, h
   Next
   'horizontale Linien Zeichnen
   For Local hl:Int = 1 To h/20
      DrawLine 0, hl*20, w, hl*20
   Next
   
   
   
   'Rays Zeichnen
   SetColor 255, 0, 0
   SetAlpha 0.014
   For Local x:Int = -150 To 150
      Ray(eye[0], eye[1], rot+x*0.25, vdist, x)
   Next
   SetAlpha 1
   
   'Objekte Zeichnen
   For Local x:Int = -20 To 20
      For Local y:Int = -20 To 20
         If map[x+20, y+20] <> 0 Then    
            Local a:Byte, r:Byte, g:Byte, b:Byte
            
            GetARGB(map[x+20, y+20], a, r, g, b)
            
            SetColor r, g, b
            DrawBox(x, y)
         End If
      Next
   Next
   
   'Auge Zeichnen
   SetColor 0, 0, 0
   DrawBox(Floor(eye[0]), Floor(eye[1]))
   
   'Screen Zeichnen
   SetColor 0, 0, 0
   DrawRect 0, 695, w, 30
   For Local x:Int = 0 To 300
      SetColor 255, 255, 255
      If screen[x] <> 0 Then
         Local a:Byte, r:Byte, g:Byte, b:Byte
         
         GetARGB(screen[x], a, r, g, b)
         
         SetColor r, g, b
      End If
      DrawRect 35+x*4, 700, 4, 20
   Next
   
   'Debug Text
   SetColor 0, 0, 0
   DrawText "Position: "+Int(Floor(eye[0]))+", "+Int(Floor(eye[1])), 10, 5
   DrawText "Rotation: "+Int(rot), 10, 25
   
   Flip -1
Until KeyHit(KEY_ESCAPE) Or AppTerminate()

End



Function GenARGB:Int(a:Byte, r:Byte, g:Byte, b:Byte)
   Local argb:Int
   argb = (a Shl 24) | (r Shl 16) | (g Shl 8) | b
   Return argb
End Function


Function GetARGB(argb:Int, a:Byte Var, r:Byte Var, g:Byte Var, b:Byte Var)
   a = (argb Shr 24) & $ff
   r = (argb Shr 16) & $ff
   g = (argb Shr 8) & $ff
   b = argb & $ff
End Function


Function DrawBox(x:Int, y:Int)
   DrawRect (x+32)*20, (0-y+18)*20, 20, 20
End Function


Function Ray(x0:Float, y0:Float, ang:Float, dist:Int, x:Int)
   Local sx:Int
   Local sy:Int
   Local ex:Int
   Local ey:Int
   Local x1:Float
   Local y1:Float
   Local dx:Float
   Local dy:Float
   Local tdx:Float
   Local tdy:Float
   Local stepx:Int
   Local stepy:Int
   Local maxx:Float
   Local maxy:Float
   Local reachedx:Byte
   Local reachedy:Byte
   Local steps:Float
   
   
   dx = Cos(ang)
   dy = Sin(ang)
   
   x1 = x0+dx*dist
   y1 = y0+dy*dist
   
   
   sx = Int(Floor(x0))
   sy = Int(Floor(y0))
   ex = Int(Floor(x1))
   ey = Int(Floor(y1))
   
   
   tdx = 1.0/Abs(dx)
   tdy = 1.0/Abs(dy)
   
   
   If dx < 0 Then
      maxx = (Float(sx)-x0)/dx
   Else
      maxx = (Float(sx+1)-x0)/dx
   EndIf
   If dy < 0 Then
      maxy = (Float(sy)-y0)/dy
   Else
      maxy = (Float(sy+1)-y0)/dy
   EndIf
   
   
   stepx = Sgn(dx)
   stepy = Sgn(dy)
   
   
   Repeat
      steps :+ 1
      
      drawbox(sx, sy)
      
      reachedx = False
      reachedy = False
      
      If stepx > 0 Then
         If sx >= ex Then reachedx = True
      ElseIf stepx < 0 Then
         If sx <= ex Then reachedx = True
      Else
         reachedx = True
      EndIf
      If stepy > 0 Then
         If sy >= ey Then reachedy = True
      ElseIf stepy < 0 Then
         If sy <= ey Then reachedy = True
      Else
         reachedy = True
      EndIf
      
      If reachedx And reachedy Then Exit
      
      If sx <= 20 And sy <= 20 Then
         If sx >=-20 And sy >=-20 Then
            If map[sx+20, sy+20] <> 0 Then
               Local a:Byte, r:Byte, g:Byte, b:Byte
               GetARGB(map[sx+20, sy+20], a, r, g, b)
               
               If steps < 80 Then
                  r :+ (255-r)*steps/80
                  g :+ (255-g)*steps/80
                  b :+ (255-b)*steps/80
               Else
                  r = 255
                  g = 255
                  b = 255
               EndIf
               
               screen[x+150] = GenARGB(255, r, g, b)
               Exit
            End If
         End If
      End If
      
      If maxx < maxy Then
         maxx :+ tdx
         sx :+ stepx
      Else
         maxy :+ tdy
         sy :+ stepy
      EndIf
   Forever
EndFunction

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group