/**************************************************************************
                      sample.c is in the public domain
**************************************************************************/
 
/*  ======================================================================
    This file contains the source code for the sample program from 
    Chapter 2 of the Dore Programmer's Guide.  The generated image contains 
    a blue cylinder, a magenta box, and a wireframe magenta sphere.
    ====================================================================== */

#include <stdio.h>
#include <dore/dore.h>     /* standard Dore include */

main()
{
/* ============== select renderer =================== */

    DtRenderStyle renderstyle = DcProductionTime;

/* DtRenderStyle renderstyle = DcRealTime;            */
/* ================================================== */

    DtObject device, frame, view;
    DtObject post, base, def_group, obj_group;
    static DtPoint3
    	origin     = {  0.0,  0.0,  0.0 },
    	eye_point  = { 10.0, 10.0, 10.0 },
    	light      = {  1.0,  1.0,  0.5 };
    static DtVector3
    	up         = {  0.0,  1.0,  0.0 };
    static DtReal
    	magenta[]  = {  1.0,  0.0,  1.0 },   /* R,G,B */
    	grey[]     = {  0.4,  0.4,  0.4 },
    	sky_blue[] = {  0.3,  0.3,  1.0 },
    	sds[]      = { 28.0 };  /* for DoSubDivSpec */

    /* initialize Dore */
    DsInitialize(0);                

/* ================= create device ================== */
 /*  device = DoDevice("stdx11", "-singlebuffered "); */
 /*  device = DoDevice("ps", " ");                    */

    device = DoDevice("rasterfile", " ");

/* ================================================== */

    /* create frame and add to the device */
    frame = DoFrame();
    DdSetFrame(device, frame);

    /* create view and add to frame */
    view = DoView();
    DvSetRendStyle(view, renderstyle);
    DvSetBackgroundColor(view, DcRGB, grey);
    DgAddObjToGroup(DfInqViewGroup(frame), view);

    /* use degrees for all angles */

    DsSetAngleUnits(DcAngleDegrees);

    /* create group with a parallel camera and a light */
    def_group = DoGroup(DcTrue);
    	DgAddObj(DoParallel(10.0, -0.1, -20.0));
    	DgAddObj(DoPushMatrix());
    	    DgAddObj(DoLookAtFrom(origin, eye_point, up));
    	    DgAddObj(DoCamera());
    	DgAddObj(DoPopMatrix());
    	DgAddObj(DoPushMatrix());
    	    DgAddObj(DoLookAtFrom(origin, light, up));
    	    DgAddObj(DoLightIntens(1.0));
    	    DgAddObj(DoLight());
    	DgAddObj(DoPopMatrix());
    DgClose();

    /* define post group */
    post = DoGroup(DcTrue);
    	DgAddObj(DoDiffuseColor(DcRGB, sky_blue));
    	DgAddObj(DoTranslate(0.0, 1.5, 0.0));
    	DgAddObj(DoRotate(DcXAxis, 90.));
    	DgAddObj(DoScale(1.2, 1.2, 2.4));
    	DgAddObj(DoPrimSurf(DcCylinder));
    DgClose();

    /* define base group */
    base = DoGroup(DcTrue);
    	DgAddObj(DoTranslate(0.0, -2.2, 0.0));
    	DgAddObj(DoScale(2.5, 2.5, 2.5));
    	DgAddObj(DoTranslate(-0.5, -0.5, -0.5));
    	DgAddObj(DoPrimSurf(DcBox));
    DgClose();

    /* obj_group includes post & base groups, and sphere */
    obj_group = DoGroup(DcTrue);
    	DgAddObj(DoRepType(DcSurface));
    	DgAddObj(DoSubDivSpec(DcSubDivSegments, sds));
    	DgAddObj(DoDiffuseColor(DcRGB, magenta));
    	DgAddObj(post);
    	DgAddObj(base);
    	DgAddObj(DoTranslate(0.0, 3.2, 0.0));
    	DgAddObj(DoScale(1.5, 1.5, 1.5));
    	DgAddObj(DoRepType(DcWireframe));
    	DgAddObj(DoPrimSurf(DcSphere));
    DgClose();

    /* add objects to view */
    DgAddObjToGroup(DvInqDefinitionGroup(view), def_group);
    DgAddObjToGroup(DvInqDisplayGroup(view), obj_group);

    /* render the image */
    DdUpdate(device);

    printf("Hit return to continue.");
    getchar();
     
    /* clean up */
    DsReleaseObj(device); 

    /* shut down */
    DsTerminate();
}
