Kirjautuminen

Haku

Tehtävät

Koodit: QB: Raytracer

Kirjoittaja: Hipo

Kirjoitettu: 10.09.2002 – 10.09.2002

Tagit: grafiikka, koodi näytille, vinkki

Aika pitkä koodi mut joop... Melko selkeä vielä mielestäni. Eli treissaa avaruudessa pari palloa ja tason. Yksi valonlähde, joka heittää varjot.

TYPE object
 obj AS INTEGER ' type
 x AS SINGLE
 y AS SINGLE
 z AS SINGLE
 radius AS SINGLE ' jos se on pallo
 r AS SINGLE
 g AS SINGLE
 b AS SINGLE
END TYPE

TYPE vector
 x AS SINGLE
 y AS SINGLE
 z AS SINGLE
END TYPE

DIM inv AS SINGLE ' Jokin käänteisluku

Ball = 0
Plane = 1

objects = 4

DIM object(objects) AS object

object(1).obj = Ball
object(1).x = 8
object(1).y = 2
object(1).z = 15
object(1).radius = 6
object(1).r = 1
object(1).g = 1
object(1).b = .5

object(2).obj = Ball
object(2).x = -6
object(2).y = 6
object(2).z = 18
object(2).radius = 7
object(2).r = 1
object(2).g = .5
object(2).b = .5

object(3).obj = Ball
object(3).x = 0
object(3).y = 7
object(3).z = 18
object(3).radius = 4
object(3).r = .7
object(3).g = .7
object(3).b = 1

object(4).obj = Plane
object(4).x = 0
object(4).y = -7
object(4).z = 0
object(4).r = 1
object(4).g = 1
object(4).b = 1

CLS

INPUT "Leveys, korkeus (reso on 320,400): ", w, h
uudestaan:
INPUT "1) 332 paletti 2) Se toinen, värit vierekkäin: ", v
IF NOT (v = 1 OR v = 2) THEN GOTO uudestaan
IF v = 2 THEN h = h / 3

DIM ray AS vector
DIM light AS vector
DIM lightn AS vector
DIM hitpos AS vector

DEF SEG = &HA000

SCREEN 13

OUT &H3D4, 9
OUT &H3D5, &H40

OUT &H3D4, 20
OUT &H3D5, 0

OUT &H3D4, 23
OUT &H3D5, &HE3

OUT &H3C4, 4
OUT &H3C5, &H6

CLS

OUT &H3C4, 2
OUT &H3C5, 1

IF v = 1 THEN
 OUT &H3C8, 0
 FOR r = 0 TO 7
  FOR g = 0 TO 7
   FOR b = 0 TO 3
    OUT &H3C9, r / 7 * 63
    OUT &H3C9, g / 7 * 63
    OUT &H3C9, b / 3 * 63
   NEXT b
  NEXT g
 NEXT r
END IF

IF v = 2 THEN
 OUT &H3C8, 0
 FOR i = 0 TO 63
  OUT &H3C9, i: OUT &H3C9, 0: OUT &H3C9, 0
 NEXT i
 FOR i = 0 TO 63
  OUT &H3C9, 0: OUT &H3C9, i: OUT &H3C9, 0
 NEXT i
 FOR i = 0 TO 63
  OUT &H3C9, 0: OUT &H3C9, 0: OUT &H3C9, i
 NEXT i
END IF

light.x = 50
light.y = 50
light.z = -20

FOR py = 0 TO h - 1
 FOR px = 0 TO w - 1
  ray.x = (px - (w / 2)) / (w / 2)
  ray.y = ((h - py) - (h / 2)) / (h / 2)
  ray.z = .8
  invl = 1 / SQR(ray.x * ray.x + ray.y * ray.y + ray.z * ray.z)
  ray.x = ray.x * invl
  ray.y = ray.y * invl
  ray.z = ray.z * invl

  cx = 0
  cy = 0
  cz = 0
  GOSUB rt

  IF NOT no = -1 THEN
   normal2.x = nx
   normal2.y = ny
   normal2.z = nz

' Törmäyskohta
   hitpos.x = nt * ray.x + cx
   hitpos.y = nt * ray.y + cy
   hitpos.z = nt * ray.z + cz

' Varjossa?
   lightn.x = light.x - hitpos.x
   lightn.y = light.y - hitpos.y
   lightn.z = light.z - hitpos.z
   inv = 1 / SQR(lightn.x * lightn.x + lightn.y * lightn.y + lightn.z * lightn.z)
   lightn.x = lightn.x * inv
   lightn.y = lightn.y * inv
   lightn.z = lightn.z * inv

   ray.x = -lightn.x
   ray.y = -lightn.y
   ray.z = -lightn.z
   cx = light.x
   cy = light.y
   cz = light.z
   noo = no
   GOSUB rt
   valo = 1
   IF NOT no = -1 AND nt < (length - .1) THEN valo = 0 ' Varjo
   no = noo

' Valon määrä pistetulolla eli vektorien välisellä kulmalla
   st = normal2.x * lightn.x + normal2.y * lightn.y + normal2.z * lightn.z
   st = st * valo
   IF st < 0 THEN st = 0
   IF st > 1 THEN st = 1

' Jutskataan väriä
  r = st * object(no).r
  g = st * object(no).g
  b = st * object(no).b

' Valmistellaan pixelin tökkimistä
   OUT &H3C4, 2
   p = px AND 3
   IF p = 0 THEN OUT &H3C5, 1 ' Oikea pagetus
   IF p = 1 THEN OUT &H3C5, 2
   IF p = 2 THEN OUT &H3C5, 4
   IF p = 3 THEN OUT &H3C5, 8

   IF v = 1 THEN POKE py * 80 + px \ 4, INT(r * 7) * 32 + INT(g * 7) * 4 + INT(b * 3)

   IF v = 2 THEN
    POKE (py * 3) * 80 + px \ 4, r * 63
    POKE (py * 3 + 1) * 80 + px \ 4, g * 63 + 64
    POKE (py * 3 + 2) * 80 + px \ 4, b * 63 + 128
   END IF

  END IF
 NEXT px
NEXT py

END

rt:
 nt = 10000
 no = -1
 FOR i = 1 TO objects
  x = cx - object(i).x
  y = cy - object(i).y
  z = cz - object(i).z

  SELECT CASE object(i).obj
   CASE Ball
    radius = object(i).radius
    GOSUB rtBall
   CASE Plane
    GOSUB rtPlane
  END SELECT

  IF t < nt AND t > 0 THEN
   nt = t
   no = i
   nx = normal.x
   ny = normal.y
   nz = normal.z
  END IF
NEXT i
RETURN

rtBall:
 b = (x * ray.x) + (y * ray.y) + (z * ray.z)
 D = (b * b) - ((x * x) + (y * y) + (z * z) - (radius * radius))
 IF D <= 0 THEN t = -1: RETURN
 t = (-b - SQR(D))
 inv = 1 / radius
 normal.x = (ray.x * t + x) * inv
 normal.y = (ray.y * t + y) * inv
 normal.z = (ray.z * t + z) * inv
RETURN

rtPlane:
 IF ray.y = 0 THEN ray.y = .0001
 t = -y / ray.y
 normal.x = 0
 normal.y = 1
 normal.z = 0
RETURN

Kommentit

snakari [12.09.2002 14:26:37]

#

niinkun tuli jo sanottua, jätkä on kone!

Pekkuli [12.09.2002 20:16:05]

#

Aikamoisia koodeja Hipo väänteleekin.
Tosin nopsempi kieli ei olisi pahitteeksi...

TH [13.09.2002 08:03:48]

#

Wow!

thefox [28.12.2002 11:34:48]

#

Heitetään nyt vaikka sellaista kommentia että pixelplöttingiin saisi vähän vauhtia jos tsekkaisi pagetuksessa "IF p <> CurrPage THEN" ja silloin vasta vaihtaisi pageja, sekä tietysti korvasi CurrPage:n p:llä.
Tosin minä en tiedä miten nopeaa pagetus tässä tapauksessa on että olisiko tuosta edes hyötyä.. :)
Tuo taitaa olla Xtended Mode mitä käytetään?

toodles [10.09.2003 21:17:32]

#

Oon alottelija qb:ssä... mutta toi ei toimi mulla, paletin valinnan jälkee vaa starttaa ja sammuu

tejeez [04.10.2003 13:55:22]

#

Miten QB:llä saa ton 320x400 tilan?

Fisher [02.05.2004 20:57:15]

#

screen 13

tejeez [23.09.2004 12:39:10]

#

jännää.
fisher: screen 13 on 320x200 :)

Dude [31.08.2007 18:01:27]

#

Tuohan vaan piirtää näytölle hhiittaaaasstti kuvan ja sitte ei tee mitää.

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta