/*
 * 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.
 *
 * simple.c: simple Performer program for programmer's guide
 *
 * $Revision: 1.47 $ $Date: 1995/11/22 14:36:13 $ 
 *
 */

/* 
cc -o subload subload.c -n32 -lm -lc -lfpe  -lpfdu_ogl -lpfutil_ogl -lpf_ogl  -limage -lGL -lGLU -lXmu -lXext -lXt -lX11
*/
#include <stdlib.h>
#include <Performer/pf.h>
#include <Performer/pfutil.h>
#include <Performer/pfdu.h>

void drawHUD(pfChannel *chan, void *data)
{
  static int   first   = TRUE;

  int     xsize,ysize;
  
  static pfTexture *texture = NULL;
  static unsigned int *image = NULL;
  static int sizeTex = 1024; /* power of two */
  static int texFileCount = 0;
  
  char str[64];
  
  if (first)
  {
      texture = pfNewTex(pfGetSharedArena());
      image = (unsigned int *)pfMalloc(sizeof(unsigned long)*sizeTex*sizeTex, pfGetSharedArena());
      
    pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
    pfEnable(PFEN_TEXTURE);
    pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
    pfEnable(PFEN_TEXTURE);

    pfApplyTEnv( pfNewTEnv( pfGetSharedArena() ) );

    pfTexLoadMode(texture, PFTEX_LOAD_SOURCE, PFTEX_SOURCE_FRAMEBUFFER);

    pfTexFormat(texture, PFTEX_EXTERNAL_FORMAT, PFTEX_PACK_8); //PFTEX_PACK_8
    pfTexFormat(texture, PFTEX_INTERNAL_FORMAT, PFTEX_RGBA); //PFTEX_RGBA_8
    pfTexFormat(texture, PFTEX_IMAGE_FORMAT, PFTEX_RGBA); //PFTEX_RGBA
     
    pfTexName(texture, "Frame Buffer Texture");
    pfTexImage(texture, image, 4, sizeTex, sizeTex, 1);

    pfTexLoadOrigin(texture, PFTEX_ORIGIN_SOURCE, 0, 0);
    pfTexLoadOrigin(texture, PFTEX_ORIGIN_DEST, 0, 0);
    pfTexLoadSize(texture, sizeTex, sizeTex);
    
    pfTexFormat(texture, PFTEX_SUBLOAD_FORMAT, PF_ON);
    pfTexFilter(texture, PFTEX_MINFILTER, PFTEX_BILINEAR);
    pfTexFilter(texture, PFTEX_MAGFILTER, PFTEX_BILINEAR);

    pfApplyTex(texture);

    pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
    pfEnable(PFEN_TEXTURE);
    pfOverride(PFSTATE_ENTEXTURE, PF_OFF);
    pfEnable(PFEN_TEXTURE);
    
    
    first = 0;
    
  } /* if first */
  
  
    pfClearChan(chan);
    pfDraw();
    
    
  
    pfGetChanSize(chan, &xsize, &ysize);

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    
    glMatrixMode(GL_TEXTURE);
    glPushMatrix(); /* 4 */
    glLoadIdentity();

	glMatrixMode(GL_PROJECTION);
    glPushMatrix(); /* 3 */
    glLoadIdentity();
    gluOrtho2D(0,xsize, 0,ysize);
  
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix(); /* 2 */
    glLoadIdentity();

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glDisable(GL_FOG);
    glDisable(GL_TEXTURE_1D);
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_TEXTURE_3D_EXT);
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_CULL_FACE);
  

    pfLoadTex(texture);

	if (texFileCount < 54)
	{
		texFileCount++;

		if (texFileCount > 50)
		{
			glFlush();
			sprintf(str, "TexGrab%04d.rgb", texFileCount);
			pfSaveTexFile(texture, str);
		}
	}

    glColor3f(1.0f, 1.0f, 1.0f);

    glBegin(GL_QUADS);
      glVertex2f(xsize/2.0f, ysize/2.0f); 	         
      glTexCoord2f(0.0f,0.0f);
      
      glVertex2f(xsize,ysize/2.0f); 	 
      glTexCoord2f(0.0f,1.0f);
      
      glVertex2f(xsize,ysize); 
      glTexCoord2f(1.0f,1.0f);
      
      glVertex2f(xsize/2.0f,ysize);      
      glTexCoord2f(1.0f,0.0f);

    glEnd();

    glPopMatrix();  /* 2 */
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();  /* 3 */

    glMatrixMode(GL_TEXTURE);
    glPopMatrix(); /* 4 */

    glPopAttrib();
}


/*
 *	Usage() -- print usage advice and exit. This
 *      procedure is executed in the application process.
 */
static void
Usage (void)
{
    pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Usage: simple file.ext ...\n");
    exit(1);
}


int main (int argc, char *argv[])
{
    float	    t = 0.0f;
    pfScene	    *scene;
    pfNode	    *root;
    pfPipe	    *p;
    pfPipeWindow    *pw;
    pfChannel	    *chan;
    pfSphere	    bsphere;

    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");

    /* Read a single file, of any known type. */
    if ((root = pfdLoadFile(argv[1])) == NULL) 
    {
	pfExit();
	exit(-1);
    }

    /* Attach loaded file to a new pfScene. */
    scene = pfNewScene();
    pfAddChild(scene, root);
    /* Create a pfLightSource and attach it to scene. */
    pfAddChild(scene, pfNewLSource());
    
    /* Configure and open GL window */
    p = pfGetPipe(0);
    pw = pfNewPWin(p);
    pfPWinType(pw, PFPWIN_TYPE_X);
    pfPWinName(pw, "IRIS Performer");
    pfPWinOriginSize(pw, 0, 0, 500, 500);
    /* Open and configure the GL window. */
    pfOpenPWin(pw);
    
    /* Create and configure a pfChannel. */
    chan = pfNewChan(p);	
    pfChanScene(chan, scene);
    pfChanFOV(chan, 45.0f, 0.0f);

    /* determine extent of scene's geometry */
    pfGetNodeBSphere (root, &bsphere);
    pfChanNearFar(chan, 1.0f, 10.0f * bsphere.radius);
    
      pfChanTravFunc(chan, PFTRAV_DRAW, drawHUD);
      
    
    /* 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);
	pfSetVec3(view.hpr, 45.0f*t, -10.0f, 0);
	pfSetVec3(view.xyz, 2.0f * bsphere.radius * s, 
		-2.0f * bsphere.radius *c, 
		 0.5f * bsphere.radius);
	pfChanView(chan, view.xyz, view.hpr);
    }

    /* Terminate parallel processes and exit. */
    pfExit();
}

