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
RETURNniinkun tuli jo sanottua, jätkä on kone!
Aikamoisia koodeja Hipo väänteleekin.
Tosin nopsempi kieli ei olisi pahitteeksi...
Wow!
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?
Oon alottelija qb:ssä... mutta toi ei toimi mulla, paletin valinnan jälkee vaa starttaa ja sammuu
Miten QB:llä saa ton 320x400 tilan?
screen 13
jännää.
fisher: screen 13 on 320x200 :)
Tuohan vaan piirtää näytölle hhiittaaaasstti kuvan ja sitte ei tee mitää.