Render3dSceneImpl.mesa
Last Edited by: Crow, August 11, 1986 10:55:19 am PDT
DIRECTORY
Rope USING [ Cat, ROPE, Substr, Index ],
Convert USING [ RopeFromReal, RopeFromInt, TimeFromRope ],
BasicTime USING [ GetClockPulses, PulsesToSeconds, Period, Now, GMT ],
IO USING [ UnsafePutBlock ],
Terminal USING [ Current ],
ColorDisplay USING [ GetColorDisplayStatus, SetColorDisplayStatus ],
WindowManager USING [ StopColorViewers ],
Real USING [ Fix, RoundI, Float ],
ComputeServerServer USING [ Register ],
Commander USING [ CommandProc, Register ],
Args USING [ Arg, ArgsGet ],
Pixels USING [ GetScanSeg, GetFromTerminal, PixelBuffer, SampleSetSequence ],
SampleMapOps USING [ GetPointer ],
ThreeDMisc USING [ AddShapeAt, MakeFrameFromFile, MakeFrame,
SetSmoothColor, SetFacetedColor ],
ThreeDScenes USING [ Error, Create, ReadScene, SetEyeSpace,
SetLight, SetView, SetViewPort, SetWindow,
WindowFromViewPort ],
ThreeDBasics USING [ Context ];
Render3dSceneImpl:
CEDAR
PROGRAM
IMPORTS Args, BasicTime, ColorDisplay, Commander, ComputeServerServer, Convert, IO, Pixels, Real, Rope, SampleMapOps, Terminal, ThreeDMisc, ThreeDScenes, WindowManager
~ BEGIN
Ceiling:
PROC[ in:
REAL ]
RETURNS[ out:
INTEGER ] ~ {
out ← Real.RoundI[in];
IF Real.Float[out] < in THEN out ← out + 1;
};
ElapsedTime:
PROC[startTime:
REAL]
RETURNS[Rope.
ROPE] ~ {
timeX100: REAL ← 100.0 * (BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[]] - startTime);
RETURN[ Rope.Cat[ Convert.RopeFromReal[ Real.Fix[timeX100] / 100.0 ], " s. " ] ];
};
CurrentTime:
PROC[]
RETURNS[
REAL] ~ {
RETURN[ BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[]] ];
};
GetContext:
PROC[]
RETURNS[
REF ThreeDBasics.Context] ~ {
context: REF ThreeDBasics.Context;
renderMode: ATOM;
display: Pixels.PixelBuffer;
on, onLeft, gray: BOOLEAN;
bpp, bppB: CARDINAL;
monitorType: Rope.ROPE;
[on, onLeft, gray, bpp, bppB, monitorType] ← ColorDisplay.GetColorDisplayStatus[];
IF on THEN WindowManager.StopColorViewers[]; -- get rid of conflicting users of color display
IF bpp < 8 THEN bpp ← 8;
ColorDisplay.SetColorDisplayStatus[
on: TRUE, onLeft: onLeft, gray: FALSE, bpp: bpp, monitorType: monitorType
];
display ← Pixels.GetFromTerminal[vt: Terminal.Current[], alpha: FALSE, depth: TRUE];
SELECT display.samplesPerPixel
FROM
2 => renderMode ← $PseudoClr;
4 => renderMode ← $Dorado24;
ENDCASE => ThreeDScenes.Error[[$MisMatch, "Strange Error??"]];
context ← ThreeDScenes.Create[ width: 0, height: 0, renderMode: renderMode,
alpha: FALSE, depth: TRUE ];
context.display ← display;
ThreeDScenes.SetViewPort[context, [0.0, 0.0, context.display.width, context.display.height] ];
ThreeDScenes.SetWindow[context, ThreeDScenes.WindowFromViewPort[context.viewPort] ];
[] ← ThreeDScenes.SetLight[context, "Initial", [-100., -200., 50.] ];
ThreeDScenes.SetView[ context, [0.0, -10.0, 3.0], [0.0, 0.0, 0.0] ];
RETURN[context];
Render3dScene
Proc: Commander.CommandProc ~ {
Renders scene described by file name on command line, displays on available display
context: REF ThreeDBasics.Context ← GetContext[ ! ThreeDScenes.Error => GO TO GiveUp ];
fileName: Rope.
ROPE ← Rope.Substr[
base: cmd.commandLine,
start: 1,
len: Rope.Index[cmd.commandLine, 0, "\n"] - 1
];
ThreeDMisc.MakeFrameFromFile[context, fileName];
EXITS GiveUp => NULL
};
Render3dShape
Proc: Commander.CommandProc ~ {
Renders shape described file name on command line, displays on available display
context: REF ThreeDBasics.Context ← GetContext[];
ok: BOOL;
shapeFile, x, y, z, fr, fg, fb, sr, sg, sb: Args.Arg;
[ok, shapeFile, x, y, z, fr, fg, fb, sr, sg, sb] ← Args.ArgsGet[cmd,
"%s-from%rrr-faceted%rrr-smooth%rr"];
IF NOT ok THEN SIGNAL ThreeDScenes.Error[[$MisMatch, "command line bad"]];
IF NOT shapeFile.ok THEN SIGNAL ThreeDScenes.Error[[$MisMatch, "no shape to render"]];
IF x.ok
AND y.ok
AND z.ok
THEN ThreeDScenes.SetView[context, [x.real, y.real, z.real], [0.0, 0.0, 0.0] ];
ThreeDMisc.AddShapeAt[context, "Shape", shapeFile.rope, [0.,0.,0.]];
IF fr.ok
AND fg.ok
AND fb.ok
THEN ThreeDMisc.SetFacetedColor[ context, "Shape", [fr.real, fg.real, fb.real] ]
ELSE IF sr.ok
AND sg.ok
AND sb.ok
THEN ThreeDMisc.SetSmoothColor[ context, "Shape", [sr.real, sg.real, sb.real] ]
ELSE ThreeDMisc.SetSmoothColor[ context, "Shape", [1.0, 0.8, 0.2] ];
ThreeDMisc.MakeFrame[context];
};
RenderFromStream
Proc: Commander.CommandProc ~ {
CommandProc: TYPE = PROC [cmd: Handle] RETURNS [result: REF ← NIL, msg: ROPE ← NIL];
Renders scene described on input stream, passes pixels back on output stream
startTime, lastTime: REAL ← CurrentTime[];
procTime: BasicTime.GMT ← BasicTime.Now[];
scanSeg: REF Pixels.SampleSetSequence;
displaycontext: REF ThreeDBasics.Context;
context: REF ThreeDBasics.Context ← ThreeDScenes.Create[ 0, 0, $FullClr, TRUE];
serverDelay: INT ← BasicTime.Period[ Convert.TimeFromRope[cmd.commandLine], procTime ];
IF serverDelay > 0
AND serverDelay < 3600
THEN msg ← Rope.Cat[" delay: ", Convert.RopeFromInt[ serverDelay], " s. " ];
ThreeDScenes.ReadScene[context, cmd.in];
displaycontext ← ThreeDScenes.Create[
-- get display bits of proper size
width: Ceiling[context.viewPort.w],
height: Ceiling[context.viewPort.h],
renderMode: $FullClr,
alpha: TRUE
];
context.display ← displaycontext.display; -- give display bits to context
ThreeDScenes.SetEyeSpace[context]; -- update for actual display size
msg ← Rope.Cat[msg, " set-up: ", ElapsedTime[startTime] ]; lastTime ← CurrentTime[];
ThreeDMisc.MakeFrame[context]; -- render image
msg ← Rope.Cat[msg, " rendering: ", ElapsedTime[lastTime] ]; lastTime ← CurrentTime[];
Write pixels back on output stream
FOR y:
NAT
IN [0 .. Ceiling[context.viewPort.h] )
DO
scanSeg ← Pixels.GetScanSeg[context.display, 0, y, Ceiling[context.viewPort.w], scanSeg];
FOR i:
NAT
IN [0.. context.display.samplesPerPixel)
DO
TRUSTED {
IO.UnsafePutBlock[
-- uses 16 bits per byte (wasting net bandwidth)
self: cmd.out,
block: [ base: LOOPHOLE[SampleMapOps.GetPointer[scanSeg[i], 0, scanSeg[i].length]],
count: 2*scanSeg[i].length ]
];
};
ENDLOOP;
ENDLOOP;
msg ← Rope.Cat[msg, " output: ", ElapsedTime[lastTime], " total: ", ElapsedTime[startTime] ];
context ← displaycontext ← NIL; -- kill off everything, no state saved
};
Init:
PROC ~ {
ComputeServerServer.Register[
key: "Render3dFromStream",
proc: RenderFromStreamProc
];
Commander.Register[
key: "RenderFromStream",
proc: RenderFromStreamProc
];
Commander.Register[
key: "Render3dScene",
proc: Render3dSceneProc
];
Commander.Register[
key: "Render3dShape",
proc: Render3dShapeProc
];
};