Sophie

Sophie

distrib > Mandriva > 2007.0 > i586 > media > contrib-release > by-pkgid > 8079d983ecf371717db799dd75bd56c2 > files > 69

libopenrm1-1.5.2-2mdv2007.0.i586.rpm

/*
 * Copyright (C) 2000, R3vis Corporation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA,
 * or visit http://www.gnu.org/copyleft/gpl.html.
 *
 * Contributor(s):
 *   Wes Bethel, R3vis Corporation, Marin County, California
 *
 * The OpenRM project is located at http://openrm.sourceforge.net/.
 */
/*
 * $Id: jack.c,v 1.5 2004/01/19 20:37:26 wes Exp $
 * $Revision: 1.5 $
 * $Name: OpenRM-1-5-2-RC1 $
 * $Log: jack.c,v $
 * Revision 1.5  2004/01/19 20:37:26  wes
 * Updated call that sets the context - was rmxPipeSetContext, is now
 * rmPipeSetContext.
 *
 * Set RM's frame rate to 60fps. You can now actually interact with these
 * programs on fast hardware.
 *
 * Revision 1.4  2003/08/06 19:04:01  wes
 * Updates for API changes present in OpenRM 1.5.0.
 *
 * Revision 1.3  2003/01/16 23:00:22  wes
 * Updated sources to reflect new organization of header files in OpenRM 1.5.0.
 *
 * Revision 1.2  2000/12/05 02:20:25  wes
 * Use OpenRM v1.4.0-alpha-1 API.
 *
 * Revision 1.1.1.1  2000/09/02 17:23:53  wes
 * Initial entry.
 *
 *
 */

/*
 * usage: jack [CAVE args]
 *
 * this demo program creates a single "jack" object that is placed
 * in the center of the CAVE. on each frame, it rotates by a
 * small amount about it's vertical axis. the purpose of this demo
 * program is to show how OpenRM can be used as a rendering and
 * data management infrastructure in CAVE applications.
 *
 * for more information about the CAVE library, visit the VRCO
 * website at http://www.vrco.com/.
 */

#include <stdio.h>
#include <unistd.h>
#include <rm/rm.h>   
#include <rm/rmaux.h>

#include <cave_ogl.h>

static RMnode *MyRoot;
static RMpipe *myPipe;
static int frameRate=60; /* could use a command line arg to set frame rate*/

void
my_sphere(RMnode *addto,
	  float cx,
	  float cy,
	  float cz,
	  float radius,
	  RMcolor3D *color)
{
    RMprimitive *sprim;
    RMvertex3D v;

    v.x = cx;
    v.y = cy;
    v.z = cz;
    
    sprim = rmPrimitiveNew(RM_SPHERES);
    rmPrimitiveSetVertex3D(sprim,1,&v,RM_COPY_DATA,NULL);

    rmPrimitiveSetRadii(sprim, 1, &radius, RM_COPY_DATA, NULL);

    if (color != NULL)
	rmPrimitiveSetColor3D(sprim, 1, color, RM_COPY_DATA, NULL);

    rmPrimitiveSetModelFlag(sprim,RM_SPHERES_32);
    
    rmNodeAddPrimitive(addto, sprim);
}

void
my_cylinder(RMnode *addto,
	    float p1x,
	    float p1y,
	    float p1z,
	    float p2x,
	    float p2y,
	    float p2z,
	    float radius)
{
    RMvertex3D v[2];
    RMprimitive *cprim;

    v[0].x = p1x;
    v[0].y = p1y;
    v[0].z = p1z;
    
    v[1].x = p2x;
    v[1].y = p2y;
    v[1].z = p2z;

    cprim = rmPrimitiveNew(RM_CYLINDERS);
    rmPrimitiveSetVertex3D(cprim,2,v,RM_COPY_DATA,NULL);

    rmPrimitiveSetRadii(cprim, 1, &radius, RM_COPY_DATA, NULL);
    
    rmNodeAddPrimitive(addto, cprim);
}

void
my_cone(RMnode *addto,
	float p1x,
	float p1y,
	float p1z,
	float p2x,
	float p2y,
	float p2z,
	float radius,
	RMcolor3D *color)
{
    RMprimitive *cprim;
    RMvertex3D v[2];
    
    v[0].x = p1x;
    v[0].y = p1y;
    v[0].z = p1z;
    v[1].x = p2x;
    v[1].y = p2y;
    v[1].z = p2z;
    
    cprim = rmPrimitiveNew(RM_CONES);
    rmPrimitiveSetVertex3D(cprim,2,v,RM_COPY_DATA,NULL);

    rmPrimitiveSetRadii(cprim, 1, &radius, RM_COPY_DATA, NULL);

    if (color != NULL)
	rmPrimitiveSetColor3D(cprim, 1, color, RM_COPY_DATA, NULL);

    rmNodeAddPrimitive(addto, cprim);
		       
}

void
buildInitialSceneGraph(void)
{
    RMcolor3D color;

    /* from the cones.c in the x-demos distribution*/

    MyRoot = rmNodeNew("MyRoot",RM_RENDERPASS_3D, RM_RENDERPASS_OPAQUE);

    {
	RMcolor4D c={0.2, 0.2, 0.3, 1.0};
	float one = 1.0F;

	rmNodeSetSceneBackgroundColor(MyRoot, &c);
	rmNodeSetSceneDepthValue(MyRoot, &one);

    }
    rmNodeAddChild(rmRootNode(), MyRoot);
    rmDefaultLighting(rmRootNode());


    /* build the jack */

    /* the center sphere should be red. */
    color.r = 1.0;
    color.g = color.b = 0.0;
    my_sphere(MyRoot,0.0F, 0.0F, 0.0F, 1.0F,&color);

    /* a blue sphere at (5,0,0) */
    color.r = color.g = 0.0;
    color.b = 1.0;
    my_sphere(MyRoot,5.0F, 0.0F, 0.0F, 1.0F,&color); 

    /* a white sphere opposite blue sphere at (-5, 0, 0) */
    my_sphere(MyRoot,-5.0F, 0.0F, 0.0F, 1.0F,NULL);

    /* a green sphere at (0,0,5) */
    color.r = color.b = 0.0;
    color.g = 1.0;
    my_sphere(MyRoot,0.0F, 0.0F, 5.0F, 1.0F,&color);

    /* a white sphere opposite the green sphere at (0,0,-5) */
    my_sphere(MyRoot,0.0F, 0.0F, -5.0F, 1.0F,NULL);

    my_cylinder(MyRoot,0.0F, 0.0F, 0.0F, 5.0F, 0.0F, 0.0F, 0.3F);
    my_cylinder(MyRoot,0.0F, 0.0F, 0.0F, -5.0F, 0.0F, 0.0F, 0.3F);
    my_cylinder(MyRoot,0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 5.0F, 0.3F);
    my_cylinder(MyRoot,0.0F, 0.0F, 0.0F, 0.0F, 0.0F, -5.0F, 0.3F);

    {
	RMcolor3D red={1.0,0.0,0.0};
	/* one cone is red, one is white (default color) */
	my_cone(MyRoot,0.0F,0.0F,0.0F,0.0F,6.0F,0.0F,0.5F,NULL);  
	my_cone(MyRoot,0.0F,0.0F,0.0F,0.0F,-6.0F,0.0F,0.5F,&red); 
    }

/*    rmNodeComputeBoundingBox(MyRoot); */
    /*
     * add "my root" to RM's root node. this is necessary since we're
     * doing an rmFrame() to render everything inside of rmauxUI();
     */
#if 0
    rmNodeUnionAllBoxes(rmRootNode()); 
    rmNodeComputeCenterFromBoundingBox(rmRootNode());
    rmNodeSetPolygonDrawMode(MyRoot,RM_FRONT_AND_BACK,RM_LINE);
#endif


    /*
     * probably want to grab rmRootNode's bbox info to build a
     * xform matrix for use with the cave - sort of an equivalent
     * of "compute view from geometry."
     */
    {
	RMmatrix m;
	RMvertex3D v;

	rmMatrixIdentity(&m);
	m.m[0][0] = m.m[1][1] = m.m[2][2] = 0.5;
	rmNodeSetScaleMatrix(MyRoot,&m); 

	v.x = 0.0;
	v.y = 5.0;
	v.z = 0.0;
	rmNodeSetTranslateVector(MyRoot, &v);
    }

    rmNodeSetSceneViewport(rmRootNode(), NULL);
}

void
mySpinFunc()
{
    RMmatrix m,old;
    double d,c,s;

    rmMatrixIdentity(&m);
    d = RM_DEGREES_TO_RADIANS(1.0);
    c = cos(d);
    s = sin(d);
    m.m[0][0] = m.m[2][2] = c;
    m.m[0][2] = -s;
    m.m[2][0] = s;
    
    if (rmNodeGetRotateMatrix(MyRoot,&old) == RM_WHACKED)
	rmMatrixIdentity(&old);
    rmMatrixMultiply(&old,&m,&old);
    
    rmNodeSetRotateMatrix(MyRoot,&old); 
}


void
appInitGL(void)
{
    int myWidth, myHeight, myOriginX, myOriginY;

    rmInit();

    myPipe = rmPipeNew(RM_PIPE_GLX);

    /*
     * we have to manually assign needed parameters to the Pipe
     * using the values set up by CAVElib.
     */

    /* want a channel format that doesn't blow the matrix stack
     upon entry. */
    rmPipeSetChannelFormat(myPipe, RM_MONO_CHANNEL);
    rmPipeSetInitMatrixStackMode(myPipe, RM_FALSE);
    rmPipeSetFrameRate(myPipe, frameRate);

    /* turn off swapbuffers - CAVElib handles that. */
    rmPipeSetSwapBuffersFunc(myPipe, NULL);

    /* obtain the OpenGL context from CAVElib, assign that to the pipe */
    rmPipeSetContext(myPipe, CAVEGLXContext());
    rmxPipeSetDisplay(myPipe, CAVEXDisplay());

    /* obtain and assign window geometry */
    CAVEGetWindowGeometry(&myOriginX, &myOriginY, &myWidth, &myHeight);
    rmPipeSetWindow(myPipe, CAVEXWindow(), myWidth, myHeight);
	
    rmPipeMakeCurrent(myPipe);	

    /*  */
    buildInitialSceneGraph();
}

void
appDrawFunc(void)
{
    rmFrame(myPipe, rmRootNode());
}

int
main(int argc,
     char *argv[])
{
    int numPipes;
    extern void caveDrawFunc(void);
    
    CAVEConfigure(&argc, argv, NULL);
    
    numPipes = CAVENumPipes();

    CAVEInit();			/* app goes parallel here */
 
    CAVEInitApplication(appInitGL, 0); /* each CAVE pipe or channel has
					  some gfx initialization code. */

    CAVEDisplay(appDrawFunc, 0);	/* parallel draw */

    CAVEFrameFunction(mySpinFunc, 0);

    while (!CAVEgetbutton(CAVE_ESCKEY))
	usleep(1000);		/* sleep 1000 microseconds (1msec) */
    
    CAVEExit();
    return(0);
}