MODULE srRayEngine;
IMPORT srBase, Raster, Objects;
CONST
X=srBase.TILESIZE;
LX=srBase.LTILESIZE;
TYPE Tile=OBJECT
VAR
G,H,I,J,i,j: INTEGER;
GO: BOOLEAN;
large: BOOLEAN;
PROCEDURE & init*(i,j,g,h: INTEGER; l: BOOLEAN);
BEGIN
I:=i; J:=j; G:=g; H:=h; large:=l;
END init;
PROCEDURE go;
BEGIN{EXCLUSIVE}
GO:=TRUE;
END go;
PROCEDURE slow;
BEGIN
FOR i := G TO G+X-1 DO
FOR j := H TO H+X-1 DO
block.Shade(srBase.rays[i,j]);
srBase.image[i,j].red := srBase.rays[i,j].r;
srBase.image[i,j].green := srBase.rays[i,j].g;
srBase.image[i,j].blue := srBase.rays[i,j].b;
srBase.clampColor(srBase.image[i,j]);
END
END
END slow;
PROCEDURE lslow;
BEGIN
FOR i := G TO G+LX-1 DO
FOR j := H TO H+LX-1 DO
block.Shade(srBase.lrays[i,j]);
srBase.limage[i,j].red := srBase.lrays[i,j].r;
srBase.limage[i,j].green := srBase.lrays[i,j].g;
srBase.limage[i,j].blue := srBase.lrays[i,j].b;
srBase.limage[i,j].alpha := srBase.lrays[i,j].ra;
srBase.clampColor(srBase.limage[i,j]);
END
END
END lslow;
PROCEDURE lfast;
BEGIN
FOR i := G TO G+LX-1 BY 2 DO
FOR j := H TO H+LX-1 BY 2 DO
block.Shade(srBase.lrays[i,j]);
srBase.limage[i,j].red := srBase.lrays[i,j].r;
srBase.limage[i,j].green := srBase.lrays[i,j].g;
srBase.limage[i,j].blue := srBase.lrays[i,j].b;
srBase.clampColor(srBase.limage[i,j]);
END
END
END lfast;
BEGIN{ACTIVE, PRIORITY(Objects.Normal)}
REPEAT
BEGIN{EXCLUSIVE}
AWAIT(GO);
GO:=FALSE;
incTD;
END;
IF large THEN
IF ~fast THEN lslow ELSE lfast END
ELSE slow END;
UNTIL FALSE;
END Tile;
VAR
block: srBase.Voxel;
image: Raster.Image;
tiles, ltiles: ARRAY srBase.TILEi, srBase.TILEj OF Tile;
i,j,G,H,LG,LH: INTEGER;
tilesdone:INTEGER;
mode: Raster.Mode;
fast*: BOOLEAN;
PROCEDURE incTD;
BEGIN{EXCLUSIVE}
INC(tilesdone);
END incTD;
PROCEDURE zeroTD;
BEGIN{EXCLUSIVE}
tilesdone:=0;
END zeroTD;
PROCEDURE goyethreads;
VAR
i,j: INTEGER;
BEGIN{EXCLUSIVE}
FOR i:= 0 TO srBase.TILEi-1 DO
FOR j:= 0 TO srBase.TILEj-1 DO
tiles[i,j].go;
END
END
END goyethreads;
PROCEDURE lgoyethreads;
VAR
i,j: INTEGER;
BEGIN{EXCLUSIVE}
FOR i:= 0 TO srBase.TILEi-1 DO
FOR j:= 0 TO srBase.TILEj-1 DO
ltiles[i,j].go;
END
END
END lgoyethreads;
PROCEDURE setBlock*(b:srBase.Voxel);
BEGIN
block := b;
END setBlock;
PROCEDURE setImage*(img: Raster.Image);
BEGIN
image:=img
END setImage;
PROCEDURE go*;
BEGIN
zeroTD;
goyethreads;
BEGIN{EXCLUSIVE}
AWAIT(tilesdone=srBase.TILES)
END
END go;
PROCEDURE lgo*;
BEGIN
zeroTD;
lgoyethreads;
BEGIN{EXCLUSIVE}
AWAIT(tilesdone=srBase.TILES)
END
END lgo;
BEGIN
FOR i:= 0 TO srBase.TILEi-1 DO
G:=i*srBase.TILESIZE;
LG:=i*srBase.LTILESIZE;
FOR j:= 0 TO srBase.TILEj-1 DO
H:=j*srBase.TILESIZE;
LH:=j*srBase.LTILESIZE;
NEW(tiles[i,j],i,j,G,H,FALSE);
NEW(ltiles[i,j],i,j,LG,LH,TRUE);
END
END;
Raster.InitMode(mode, Raster.srcCopy)
END srRayEngine.