From: Benedikt Kessler (bjk++at++munich.sgi.com)
Date: 09/07/2001 00:40:23
Hi!
You probably want to specify a (asymetric) viewing frustum that
represents a subvolume of the original frustum filling just a small
rectangle of your full image; this function might be usefull (you
probably have to modyfy a few things: the original size and offsets of
the (full) viewport wre stored in a structure called IBRchanData; x, y
sx, sy are the offsets and size of the subviewport):
it will update chan or frust.
void
calcChanSubFrust(pfChannel *chan, pfFrustum *frust, float fovHoriz,
float fovVert, int x, int y, int sx, int sy)
{
int cxs, cys, xcenter, ycenter;
float near, far, scalex, scaley, snear;
IBRchanData *cs = BGGETCHANDATA(chan);
pfGetChanNearFar(chan, &near, &far);
// fprintf(stderr, "fovHoriz, fovVert, x, y, sx, sy: %f %f %d %d %d
%d\n",
// fovHoriz, fovVert, x, y, sx, sy);
cxs=cs->chanCompSizeX; // size of an (symmetric )viewport
cys=cs->chanCompSizeY; // that was used to calculate the symmetric
fristum
// what would be the near value, given the fovh and the comp xsize
snear = (cxs*0.5f)/pfTan(fovHoriz * .5f);
scalex = near / snear;
if (fovVert <= 0.0f || fovVert >= 180.0f)
fovVert = 2.0f * pfArcTan2(cys*0.5f, snear);
fovVert = cs->fovVert;
// bjkhack
scaley = near / ((cys*0.5f)/pfTan(fovVert * .5f));
xcenter = cxs/2;
ycenter = cys/2;
// update chan only if we did not provide a frustum
if (frust)
{
pfMakePerspFrust(frust, scalex*(x-xcenter), scalex*(x+sx-xcenter),
scaley*(y-ycenter), scaley*(y+sy-ycenter));
// I have split my scene into two viewports
// one for the upper half (skyFrust)
// one for the lower half (optFrust)
if (frust == cs->optFrust)
{
cs->optVPleft = (float)(cs->chanCompOrigX+x) /cs->winSizeX;
cs->optVPright = (float)(cs->chanCompOrigX+x+sx)/cs->winSizeX;
cs->optVPbot = (float)(cs->chanCompOrigY+y) /cs->winSizeY;
cs->optVPtop = (float)(cs->chanCompOrigY+y+sy)/cs->winSizeY;
}
else if (frust == cs->skyFrust)
{
cs->skyVPleft = (float)(cs->chanCompOrigX+x) /cs->winSizeX;
cs->skyVPright = (float)(cs->chanCompOrigX+x+sx)/cs->winSizeX;
cs->skyVPbot = (float)(cs->chanCompOrigY+y) /cs->winSizeY;
cs->skyVPtop = (float)(cs->chanCompOrigY+y+sy)/cs->winSizeY;
}
}
else
{
pfChanViewport(chan, (float)(cs->chanCompOrigX+x) /cs->winSizeX,
(float)(cs->chanCompOrigX+x+sx)/cs->winSizeX,
(float)(cs->chanCompOrigY+y) /cs->winSizeY,
(float)(cs->chanCompOrigY+y+sy)/cs->winSizeY);
pfMakePerspChan(chan, scalex*(x-xcenter), scalex*(x+sx-xcenter),
scaley*(y-ycenter), scaley*(y+sy-ycenter));
pfGetChanBaseFrust(chan, cs->chanFrust);
}
}
Bye! Benedikt
Mark Evans wrote:
>
> What is the best way to render in a subwindow of a
> Performer window?
> What I need is to render only in one rectangular
> subwindow of my application (say a rectangle at 200
> pixels up and 200 pixels to the right of the bottom
> left corner of the main window, and which is, say
> 200x200 pixels wide. I would need that everything that
> is out of this subwindow to be culled, since my
> application is Transform limited. I need to do this no
> matter the azimuth, pitch and roll of the viewpoint.
> Of course, if I change the parameters of the subwindow
> to make it adiacent to the first one, the generated
> images should collate perfectly.
>
-- +---------------------------------+----------------------------------+ |Benedikt J. Kessler | Silicon Graphics GmbH | |Professional Services | Am Hochacker 3 - Technopark | |SGI | 85630 Grasbrunn-Neukeferloh, FRG | | --- __o ,__o | | | ------_ \<,_ _-\_<, | Phone: (+49) 89 46108-366 or -0 | |----- (*)/ (*) (*)/'(*) | Fax: (+49) 89 46107-366 | +---------------------------------+----------------------------------+ |E-Mail: bjk++at++sgi.com Web (private): http://reality.sgi.com/bjk | | Web: http://www.sgi.de/dienstleistungen/ | +--------------------------------------------------------------------+
This archive was generated by hypermail 2b29 : Fri Sep 07 2001 - 00:41:37 PDT