Листинг программы:
Демонстрация работы программы:
Код: Выделить всё
//
// Demonstration of how to calculate lighting effects
// An improvement to this meathod would be to use a
// per vertex lighting algorithm
//
// Adapted from PS2 version of Yabasic for Galileo 2014/09
DEBUG = FALSE
label Init
clear screen
open window 640, 512
window origin "cc"
backcolor 0,0,255
label Vertices
read verts
dim px(verts), py(verts), pz(verts)
dim nx(verts), ny(verts), nz(verts)
dim tx(verts), ty(verts)
for i = 0 to verts
read px(i), py(i), pz(i)
next i
label Polygons
read polys
dim p1(polys), p2(polys), p3(polys), p4(polys)
for i = 0 to polys
read p1(i), p2(i), p3(i), p4(i)
next i
label Colours
dim r1(polys), g1(polys), b1(polys)
dim r2(polys), g2(polys), b2(polys)
dim r3(polys), g3(polys), b3(polys)
dim r4(polys), g4(polys), b4(polys)
for i = 0 to polys
read r1(i), g1(i), b1(i)
read r2(i), g2(i), b2(i)
read r3(i), g3(i), b3(i)
read r4(i), g4(i), b4(i)
next i
label Lighting
litX = -64.0
litY = -64.0
litZ = -64.0
Ambient = 0.1
label Camera
camX = 0.0000
camY = 0.0000
camZ = -256.0
Aspect = 512.0
do
c$ = inkey$(0.1)
if c$="up" litY = litY - 1.0
if c$="right" litX = litX + 1.0
if c$="down" litY = litY + 1.0
if c$="left" litX = litX - 1.0
if c$="z" litZ = litZ + 1.0
if c$="x" litZ = litZ - 1.0
rotX = rotX + 0.0100
rotY = rotY + 0.0020
rotZ = rotZ + 0.0003
Rotate(rotX, rotY, rotZ, -camX,-camY,-camZ)
Render()
loop
sub Rotate(rx,ry,rz, ox,oy,oz)
local cx,cy,cz, sx,sy,sz, px,py,pz, nx,ny,nz, tx,ty,tz
cx = cos(rx)
sx = sin(rx)
cy = cos(ry)
sy = sin(ry)
cz = cos(rz)
sz = sin(rz)
for i = 0 to verts
px = px(i)
py = py(i)
pz = pz(i)
nx = cz*px + sz*py
ny = cz*py - sz*px
nz = cy*pz + sy*nx
tx = cy*nx - sy*pz
ty = cx*ny + sx*nz
tz = cx*nz - sx*ny
nx(i) = tx
ny(i) = ty
nz(i) = tz
tz = Aspect/(tz+oz)
tx(i) = (tx+ox)*tz
ty(i) = (ty+oy)*tz
next i
end sub
sub Render()
clear window
// Draw a white circle for the light
if (litZ >= 0.0) then
color 255, 255, 255
lz = Aspect/(litZ-camZ)
lx = litX*lz
ly = litY*lz
fill circle lx, ly, 10
endif
for i = 0 to polys
x1 = tx(p1(i))
y1 = ty(p1(i))
x2 = tx(p2(i))
y2 = ty(p2(i))
x3 = tx(p3(i))
y3 = ty(p3(i))
x4 = tx(p4(i))
y4 = ty(p4(i))
cp = (x1-x2)*(y3-y2) - (x3-x2)*(y1-y2)
if (cp > 0) then
nx1 = nx(p1(i))
ny1 = ny(p1(i))
nz1 = nz(p1(i))
nx2 = nx(p2(i))
ny2 = ny(p2(i))
nz2 = nz(p2(i))
nx3 = nx(p3(i))
ny3 = ny(p3(i))
nz3 = nz(p3(i))
nx4 = nx(p4(i))
ny4 = ny(p4(i))
nz4 = nz(p4(i))
//
// Calculate the midpoint of polygon
cx = (nx1+nx2+nx3+nx4)*0.25
cy = (ny1+ny2+ny3+ny4)*0.25
cz = (nz1+nz2+nz3+nz4)*0.25
//
// Calculate the normal vector using cross-product
nx = (nz1-nz2)*(ny3-ny2) - (ny1-ny2)*(nz3-nz2)
ny = (nx1-nx2)*(nz3-nz2) - (nz1-nz2)*(nx3-nx2)
nz = (ny1-ny2)*(nx3-nx2) - (nx1-nx2)*(ny3-ny2)
//
// Calculate the lighting vector
lx = litX - cx
ly = litY - cy
lz = litZ - cz
//
// Calculate length of the normal & lighting vectors
n = 1.0/sqrt(nx*nx + ny*ny + nz*nz)
l = 1.0/sqrt(lx*lx + ly*ly + lz*lz)
//
// Normalise the normal & lighting vectors
nx = n*nx
ny = n*ny
nz = n*nz
lx = l*lx
ly = l*ly
lz = l*lz
//
// Calculate dot-product of normal & lighting vectors
dp = max(Ambient, nx*lx + ny*ly + nz*lz + Ambient)
//
// Scale colour channels by dot-product
color min(abs(r1(i)*dp),255), min(abs(g1(i)*dp),255), min(abs(b1(i)*dp),255)
fill triangle x1, y1 to x2, y2 to x3, y3
fill triangle x1, y1 to x4, y4 to x3, y3
//
// Debug view of surface normals & midpoints
if (DEBUG = TRUE) then
pz = Aspect/(nz*60-camZ)
py = ny*pz*60
px = nx*pz*60
cz = Aspect/(cz-camZ)
cy = cy*cz
cx = cx*cz
color 255, 255, 000
line cx, cy to px, py
line x1, y1 to px, py
line x2, y2 to px, py
line x3, y3 to px, py
line x4, y4 to px, py
line x1, y1 to cx, cy
line x2, y2 to cx, cy
line x3, y3 to cx, cy
line x4, y4 to cx, cy
line x1, y1 to x2, y2
line x2, y2 to x3, y3
line x3, y3 to x4, y4
line x4, y4 to x1, y1
endif
endif
next i
//
// Draw a white circle for the light
if (litZ < 0.0) then
color 255, 255, 255
lz = Aspect/(litZ-camZ)
lx = litX*lz
ly = litY*lz
fill circle lx, ly, 10
endif
//
// Display data
color 255, 255, 255
text -300,-240, "ROTX : " + str$(rotX)
text -300,-220, "ROTY : " + str$(rotY)
text -300,-200, "ROTZ : " + str$(rotZ)
text -300,-180, "LITX : " + str$(litX)
text -300,-160, "LITY : " + str$(litY)
text -300,-140, "LITZ : " + str$(litZ)
end sub
label Model
data 7 // verts
data -30.0,30.00,30.00
data -30.0,-30.0,30.00
data -30.0,30.00,-30.0
data -30.0,-30.0,-30.0
data 30.00,30.00,30.00
data 30.00,-30.0,30.00
data 30.00,30.00,-30.0
data 30.00,-30.0,-30.0
data 5 // polys
data 2,0,4,6
data 7,5,1,3
data 3,1,0,2
data 6,4,5,7
data 0,1,5,4
data 3,2,6,7
data 000,255,000, 255,000,000, 000,000,255, 200,200,200
data 063,063,063, 255,000,255, 255,255,000, 000,255,255
data 000,255,255, 255,255,000, 255,000,000, 000,255,000
data 200,200,200, 000,000,255, 255,000,255, 063,063,063
data 255,000,000, 255,255,000, 255,000,255, 000,000,255
data 000,255,255, 000,255,000, 200,200,200, 063,063,063