From: Brian Furtaw (brian++at++sgi.com)
Date: 02/04/2000 05:48:51
Bo,
Here is simple.C with some modifications to capture several channels
worth images. I am actually trying to capture a very large image so four
channels one for each fourth of the image. I recombine the four image
tiles using an imgtcl script.
Brian
Bo Staahle wrote:
>
> Hello
>
> I would like to know, how I can grap an image from the frame buffer in
> a multi channel environment.
>
> I am using pfuSaveImage and I have looked at the source in
> /usr/share/Performer/src/lib/libpfutil/snapwin.c
> but I didn't get any further.
>
> I would like to grap an image for each of the channels.
> If I have four channels, then I would like to save four images,
> each showing whats in the specific channel.
>
> Is this possible ?
> If so how could I do it?
> Does anybody have any small working examples?
>
> --
> Bo Sixten Staahle
> mailto:c960355++at++student.dtu.dk,
> mailto:Bo.Sixten.Staahle++at++uni-c.dk
> -----------------------------------------------------------------------
> List Archives, FAQ, FTP: http://www.sgi.com/software/performer/
> Submissions: info-performer++at++sgi.com
> Admin. requests: info-performer-request++at++sgi.com
--
----oOOo---- ----oOOo---- ----oOOo---- ----oOOo----
Brian Furtaw (brian++at++sgi.com)
Graphics Guru Office:(301)572-3293 Fax: (301)572-3280
12200-G Plum Orchard Drive OpenGL/Performer/OpenInventor/ImageVision
Silver Spring, Maryland 20904 Optimizer/React/PCI Device Drivers
// // Copyright 1995, Silicon Graphics, Inc. // ALL RIGHTS RESERVED // // UNPUBLISHED -- Rights reserved under the copyright laws of the United // States. Use of a copyright notice is precautionary only and does not // imply publication or disclosure. // // U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: // Use, duplication or disclosure by the Government is subject to restrictions // as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights // in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or // in similar or successor clauses in the FAR, or the DOD or NASA FAR // Supplement. Contractor/manufacturer is Silicon Graphics, Inc., // 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. // // Permission to use, copy, modify, distribute, and sell this software // and its documentation for any purpose is hereby granted without // fee, provided that (i) the above copyright notices and this // permission notice appear in all copies of the software and related // documentation, and (ii) the name of Silicon Graphics may not be // used in any advertising or publicity relating to the software // without the specific, prior written permission of Silicon Graphics. // // THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, // EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY // WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. // // IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, // INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, // WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY // THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE // OR PERFORMANCE OF THIS SOFTWARE. // // // simpleC.C: simple Performer program for programmer's guide // // $Revision: 1.10 $ // $Date: 1995/11/22 14:35:21 $ //
#include <stdlib.h>
#include <Performer/pf/pfChannel.h> #include <Performer/pf/pfLightSource.h> #include <Performer/pf/pfNode.h> #include <Performer/pf/pfScene.h>
#include <Performer/image.h> #include <Performer/pfutil.h> #include <Performer/pfdu.h> #include <Performer/pr.h>
enum { topLeft, topRight, bottomLeft, bottomRight };
void pfuCpackToRGB(unsigned long *l, unsigned short *r, unsigned short *g, unsigned short *b, int n) { while (n >= 8) { PFU_CPACKTORGB(l[0], r[0], g[0], b[0]); PFU_CPACKTORGB(l[1], r[1], g[1], b[1]); PFU_CPACKTORGB(l[2], r[2], g[2], b[2]); PFU_CPACKTORGB(l[3], r[3], g[3], b[3]); PFU_CPACKTORGB(l[4], r[4], g[4], b[4]); PFU_CPACKTORGB(l[5], r[5], g[5], b[5]); PFU_CPACKTORGB(l[6], r[6], g[6], b[6]); PFU_CPACKTORGB(l[7], r[7], g[7], b[7]); l += 8; r += 8; g += 8; b += 8; n -= 8; }
while (n--) { PFU_CPACKTORGB(l[0], r[0], g[0], b[0]); l++; r++; g++; b++; } }
void pfuCpackToRGBA(unsigned long *l, unsigned short *r, unsigned short *g, unsigned short *b, unsigned short *a, int n) { while (n >= 8) { PFU_CPACKTORGBA(l[0], r[0], g[0], b[0], a[0]); PFU_CPACKTORGBA(l[1], r[1], g[1], b[1], a[1]); PFU_CPACKTORGBA(l[2], r[2], g[2], b[2], a[2]); PFU_CPACKTORGBA(l[3], r[3], g[3], b[3], a[3]); PFU_CPACKTORGBA(l[4], r[4], g[4], b[4], a[4]); PFU_CPACKTORGBA(l[5], r[5], g[5], b[5], a[5]); PFU_CPACKTORGBA(l[6], r[6], g[6], b[6], a[6]); PFU_CPACKTORGBA(l[7], r[7], g[7], b[7], a[7]); l += 8; r += 8; g += 8; b += 8; a += 8; n -= 8; }
while (n--) { PFU_CPACKTORGBA(l[0], r[0], g[0], b[0], a[0]); l++; r++; g++; b++; a++; } }
/* the standard error handler calls exit(). we don't want to quit out of * the application */ void my_iopenerror(char *str) { pfNotify(PFNFY_WARN, PFNFY_RESOURCE, "pfuSaveImage: %s", str); }
//extern void i_seterror(void (*)(char *)); /* from libimage.a */
int SaveImage(char *name, int xorg, int yorg, int xsize, int ysize, int alpha) { IMAGE *oimage; int writeerr, y; unsigned long *scrbuf, *ss; unsigned short *rs, *gs, *bs, *as;
// i_seterror(my_iopenerror); /* open the image file */ oimage = iopen(name, "w", RLE(1), 3, xsize, ysize, alpha ? 4 : 3);
if (!oimage) { return -1; }
writeerr = 0; /* malloc buffers */ rs = (unsigned short *)pfMalloc((unsigned int)(xsize*sizeof(short)), NULL); gs = (unsigned short *)pfMalloc((unsigned int)(xsize*sizeof(short)), NULL); bs = (unsigned short *)pfMalloc((unsigned int)(xsize*sizeof(short)), NULL); if (alpha) as = (unsigned short *)pfMalloc((unsigned int)(xsize*sizeof(short)), NULL);
scrbuf = (unsigned long *)pfMalloc((unsigned int)(xsize*ysize*sizeof(long)), NULL);
/* read from BACK-buffer to get channel stats info */ #ifdef IRISGL readsource(SRC_BACK); #else /* OPENGL */ glReadBuffer(GL_BACK); #endif /* GL type */ /* read the display */ #ifdef IRISGL lrectread((short)xorg, (short)yorg, (short)(xorg+xsize-1), (short)(yorg+ysize-1), scrbuf); #else /* OPENGL */ glReadPixels((short)xorg, (short)yorg, (short)xsize, (short)ysize, GL_RGBA, GL_UNSIGNED_BYTE, scrbuf); #endif /* GL type */
/* write the data to the image file */ if (alpha == 0) { ss = scrbuf; for (y=0; y<ysize; y++) { pfuCpackToRGB(ss, rs, gs, bs, xsize);
if(putrow(oimage, rs, (unsigned int)y, 0)!=xsize) writeerr = 1; if(putrow(oimage, gs, (unsigned int)y, 1)!=xsize) writeerr = 1; if(putrow(oimage, bs, (unsigned int)y, 2)!=xsize) writeerr = 1;
ss += xsize; } } else { ss = scrbuf; for (y=0; y<ysize; y++) { pfuCpackToRGBA(ss, rs, gs, bs, as, xsize);
if(putrow(oimage, rs, (unsigned int)y, 0)!=xsize) writeerr = 1; if(putrow(oimage, gs, (unsigned int)y, 1)!=xsize) writeerr = 1; if(putrow(oimage, bs, (unsigned int)y, 2)!=xsize) writeerr = 1; if(putrow(oimage, as, (unsigned int)y, 3)!=xsize) writeerr = 1;
ss += xsize; } } /* free buffers */ pfFree(rs); pfFree(gs); pfFree(bs); if (alpha) pfFree(as); pfFree(scrbuf); /* close the image file */ if(iclose(oimage)<0 || writeerr) return(-1); else return(0); }
// // create an asymetric viewing frustum each // quadrant of the the view frustum.
void setQuad(pfChannel *src, pfChannel *target, int quad ) { #if 0 /* * Make two off-axis projections which together provide * horizontal and vertical FOVs of 90 and 45 degrees. */ t = pfTan(22.5f);
left->setNearFar( 1.0f, 1000.0f); left->makePersp(-1.0f, 0.0f, -t, t);
right->setNearFar(1.0f, 1000.0f); right->makePersp(0.0f, 1.0f, -t, t); #endif float hov, vov; float thov, tvov; src->getFOV(&hov, &vov); thov = pfTan(hov/2.0f); tvov = pfTan(vov/2.0f); switch(quad) { // find the clip plane corners and set the Ptope case topLeft: target->makePersp(-thov, 0.0f, 0.0f, tvov); break; case topRight: target->makePersp(0.0f, thov, 0.0f, tvov); break; case bottomLeft: target->makePersp(-thov, 0.0f, -tvov, 0.0f); break; case bottomRight: target->makePersp(0.0f, thov, -tvov, 0.0f); break; } }
static void DrawChannel (pfChannel *channel, void *data) { int quad = (int) data; char fileName[64]; switch(quad) { case topLeft: sprintf(fileName, "topLeft.rgb");; break; case topRight: sprintf(fileName, "topRight.rgb");; break; case bottomLeft: sprintf(fileName, "bottomLeft.rgb");; break; case bottomRight: sprintf(fileName, "bottomRight.rgb");; break; default: pfNotify(PFNFY_WARN, PFNFY_WARN, "No filename selected for quad %d", quad); } /* erase framebuffer and draw Earth-Sky model */ channel->clear();
/* invoke Performer draw-processing for this frame */ pfDraw(); SaveImage(fileName, 0, 0, 1024 , 1024, 0); glReadBuffer(GL_FRONT);
/* draw Performer throughput statistics */ #if 0 if (drawStats) pfDrawChanStats(channel); #endif }
// // Usage() -- print usage advice and exit. This // procedure is executed in the application process. // static void Usage (void) { pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Usage: simpleC file.ext ...\n"); exit(1); }
int main (int argc, char *argv[]) { float t = 0.0f; if (argc < 2) Usage(); // Initialize Performer pfInit(); // Use default multiprocessing mode based on number of // processors. // pfMultiprocess( PFMP_DEFAULT ); // Load all loader DSO's before pfConfig() forks pfdInitConverter(argv[1]);
// initiate multi-processing mode set in pfMultiprocess call // FORKs for Performer processes, CULL and DRAW, etc. happen here. // pfConfig(); // Append to Performer search path, PFPATH, files in // /usr/share/Performer/data */ pfFilePath(".:/usr/share/Performer/data"); pfNode *root = pfdLoadFile(argv[1]); if (root == NULL) { pfExit(); exit(-1); } // Attach loaded file to a new pfScene pfScene *scene = new pfScene; scene->addChild(root); // Create a pfLightSource and attach it to scene scene->addChild(new pfLightSource); // Configure and open GL window pfPipe *p = pfGetPipe(0); pfPipeWindow *pw = new pfPipeWindow(p); pw->setWinType(PFPWIN_TYPE_X); pw->setName("IRIS Performer"); pw->setOriginSize(0,0,1024,1024); pw->open(); // Create and configure a pfChannel. pfChannel *chan = new pfChannel(p); //chan->setScene(scene); chan->setFOV(45.0f, 0.0f); pfChannel *achan[4]; // determine extent of scene's geometry pfSphere bsphere; root->getBound(&bsphere); chan->setNearFar(1.0f, 10.0f * bsphere.radius);
achan[topLeft] = new pfChannel(p); achan[topLeft]->setScene(scene); achan[topLeft]->allocChanData(sizeof(int)); achan[topLeft]->setChanData((void *)topLeft, sizeof(int)); achan[topLeft]->passChanData(); achan[topLeft]->setTravFunc(PFTRAV_DRAW, DrawChannel); achan[topLeft]->setNearFar(1.0f, 10.0f * bsphere.radius); #ifdef WHITE achan[topLeft]->setFOV(45.0f, 0.0f); #else setQuad(chan, achan[topLeft], topLeft); #endif //achan[topLeft]->setViewport(0.0f, 0.5f, 0.5f, 1.0f); achan[topRight] = new pfChannel(p); achan[topRight]->setScene(scene); achan[topRight]->allocChanData(sizeof(int)); achan[topRight]->setChanData((void *)topRight, sizeof(int)); achan[topRight]->passChanData(); achan[topRight]->setTravFunc(PFTRAV_DRAW, DrawChannel); achan[topRight]->setNearFar(1.0f, 10.0f * bsphere.radius); #ifdef BLACK achan[topRight]->setFOV(45.0f, 0.0f); #else setQuad(chan, achan[topRight], topRight); #endif //achan[topRight]->setViewport(0.5f, 1.0f, 0.5f, 1.0f); achan[bottomLeft] = new pfChannel(p); achan[bottomLeft]->setScene(scene); achan[bottomLeft]->allocChanData(sizeof(int)); achan[bottomLeft]->setChanData((void *)bottomLeft, sizeof(int)); achan[bottomLeft]->passChanData(); achan[bottomLeft]->setTravFunc(PFTRAV_DRAW, DrawChannel); achan[bottomLeft]->setNearFar(1.0f, 10.0f * bsphere.radius); #ifdef BLACK achan[bottomLeft]->setFOV(45.0f, 0.0f); #else setQuad(chan, achan[bottomLeft], bottomLeft); #endif //achan[bottomLeft]->setViewport(0.0f, 0.5f, 0.0f, 0.5f); achan[bottomRight] = new pfChannel(p); achan[bottomRight]->setScene(scene); achan[bottomRight]->allocChanData(sizeof(int)); achan[bottomRight]->setChanData((void *)bottomRight, sizeof(int)); achan[bottomRight]->passChanData(); achan[bottomRight]->setTravFunc(PFTRAV_DRAW, DrawChannel); achan[bottomRight]->setNearFar(1.0f, 10.0f * bsphere.radius); #ifdef WHITE achan[bottomRight]->setFOV(45.0f, 0.0f); #else setQuad(chan, achan[bottomRight], bottomRight); #endif //achan[bottomRight]->setViewport(0.5f, 1.0f, 0.0f, 0.5f); // Simulate for twenty seconds. while (t < 20.0f) { pfCoord view; float s, c; // Go to sleep until next frame time. pfSync(); // Initiate cull/draw for this frame. pfFrame(); // Compute new view position. t = pfGetTime(); pfSinCos(45.0f*t, &s, &c); view.hpr.set(45.0f*t, -10.0f, 0); view.xyz.set(2.0f * bsphere.radius * s, -2.0f * bsphere.radius *c, 0.5f * bsphere.radius); achan[topLeft]->setView(view.xyz, view.hpr); achan[topRight]->setView(view.xyz, view.hpr); achan[bottomLeft]->setView(view.xyz, view.hpr); achan[bottomRight]->setView(view.xyz, view.hpr); } // Terminate parallel processes and exit pfExit(); return 0; }
This archive was generated by hypermail 2b29 : Fri Feb 04 2000 - 06:16:07 PST