RenderWithStreamImpl.mesa
Last Edited by: Crow, February 20, 1987 5:58:01 pm PST
DIRECTORY
Atom USING [ GetPropFromList, PutPropOnList ],
Rope USING [ Cat, ROPE ],
Convert USING [ RealFromRope, RopeFromReal ],
BasicTime USING [ GetClockPulses, PulsesToSeconds ],
IO USING [ PutRope, RopeFromROS, ROS, STREAM, UnsafePutBlock ],
Real USING [ Fix, RoundI, Float ],
Commander USING [ CommandProc ],
ComputeServerServer USING [ Register ],
Pixels USING [ GetScanSeg, SampleSetSequence ],
SampleMapOps USING [ GetPointer ],
SceneUtilities USING [ ReadScene ],
ThreeDBasics USING [ Context, ContextClass, Create, GetDisplayType, RegisterDisplayType ];
RenderWithStreamImpl:
CEDAR
PROGRAM
IMPORTS Atom, BasicTime, ComputeServerServer, Convert, IO, Pixels, Real, Rope, SampleMapOps, SceneUtilities, ThreeDBasics
~ BEGIN
Context: TYPE ~ ThreeDBasics.Context;
ContextClass: TYPE ~ ThreeDBasics.ContextClass;
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 * (CurrentTime[] - startTime);
RETURN[ Rope.Cat[ Convert.RopeFromReal[ Real.Fix[timeX100] / 100.0 ], "s," ] ];
};
CurrentTime:
PROC[]
RETURNS[
REAL] ~ {
RETURN[ BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[]] ];
renderFullClrProc: PROC[context: REF Context];
renderPseudoClrProc: PROC[context: REF Context];
renderGreyProc: PROC[context: REF Context];
MakeFrame:
PROC[context:
REF Context] ~ {
Makes image, sends pixels and log back on output stream.
lastTime: REAL ← CurrentTime[];
scanSeg: REF Pixels.SampleSetSequence;
startTime: REAL ← NARROW[Atom.GetPropFromList[context.props, $StartTime], REF REAL]^;
log: IO.STREAM ← NARROW[Atom.GetPropFromList[context.props, $Log]];
output: IO.STREAM ← NARROW[ Atom.GetPropFromList[context.props, $Output] ];
SELECT context.class.displayType
FROM
$FullColor, $Dorado24 => renderFullClrProc[context];
$PseudoColor => renderPseudoClrProc[context];
$Grey => renderGreyProc[context];
ENDCASE => log.PutRope[ " \n No frame: unknown displayType \n " ];
Write pixels back on output stream
lastTime ← CurrentTime[];
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: output,
block: [ base: LOOPHOLE[SampleMapOps.GetPointer[scanSeg[i], 0, scanSeg[i].length]],
count: 2*scanSeg[i].length ]
];
};
ENDLOOP;
ENDLOOP;
log.PutRope[ Rope.Cat[
" output: ", ElapsedTime[lastTime], " total: ", ElapsedTime[startTime]
] ];
};
RenderWithStream
Proc: Commander.CommandProc ~ {
CommandProc: TYPE = PROC [cmd: Handle] RETURNS [result: REF ← NIL, msg: ROPE ← NIL];
Reads scene described on input stream, passes pixels back on output stream
startTime: REAL ← Convert.RealFromRope[cmd.commandLine];
context: REF ThreeDBasics.Context ← ThreeDBasics.Create[];
log: IO.STREAM ← IO.ROS[]; -- use Rope Output Stream
log.PutRope[ Rope.Cat[" delay: ", ElapsedTime[startTime] ] ];
context.props ← Atom.PutPropOnList[context.props, $StartTime, NEW[REAL ← CurrentTime[]] ];
context.props ← Atom.PutPropOnList[context.props, $Log, log ];
context.props ← Atom.PutPropOnList[context.props, $Output, cmd.out]; -- output pixel stream
SceneUtilities.ReadScene[context, cmd.in]; -- read from stream until termination
msg ← Rope.Cat[ msg, IO.RopeFromROS[log] ]; -- add log to end of stream for feedback
msg ← Rope.Cat[ msg, " remote end at: ", ElapsedTime[startTime] ];
context ← NIL; -- kill off everything, no state saved
};
Init:
PROC ~ {
Get previously registered classes and modify them to call MakeFrame for rendering
contextClass: ContextClass ← ThreeDBasics.GetDisplayType[$FullColor];
renderFullClrProc ← contextClass.render; -- ambush render procedure
contextClass.render ← MakeFrame; -- and insert local proc before call
ThreeDBasics.RegisterDisplayType[contextClass];
contextClass.displayType ← $Dorado24; -- catch $Dorado24 and treat as $FullColor
ThreeDBasics.RegisterDisplayType[contextClass];
contextClass ← ThreeDBasics.GetDisplayType[$PseudoColor];
renderPseudoClrProc ← contextClass.render; -- ambush render procedure
contextClass.render ← MakeFrame; -- and insert local proc before call
ThreeDBasics.RegisterDisplayType[contextClass];
contextClass ← ThreeDBasics.GetDisplayType[$Grey];
renderGreyProc ← contextClass.render; -- ambush render procedure
contextClass.render ← MakeFrame; -- and insert local proc before call
ThreeDBasics.RegisterDisplayType[contextClass];
ComputeServerServer.Register[
-- register control procedure with compute server
key: "3dRenderWithStream",
proc: RenderWithStreamProc
];
};
Init[];
END.