Again: 2 lights+lmodels in 1 scene

New Message Reply Date view Thread view Subject view Author view

Klaus Otto (kotto++at++cae-gmbh.de)
Thu, 6 Nov 1997 17:05:01 +0100


Hi all,

I thought i had the solution for my problem with the 2
lights in the scene, but i do not get this sorted out.

I want to have 2 main parts in the scene that i want to
have lit by one of two different lighting models.
(Part 1 lit by light 1, Part 2 lit by light 2)
The databases are made with MultiGen 14.2 (with normals).

So my first approach was to set up the pfBldrState
(pfdDefaultGState) to have a movable light and a local LModel
before loading one portion.
Then change the pfdDefaultState to a global light with an
infinite LModel. For some reason the default state was not
propagated to the final geosets, because the database seemed
to be unlighted or lit globally.

Failing to initially set the gstate i tried to change it in a
postload traversal. The result wasn't satisfying either.
(see posting: Problem with 2 Lights/Lmodels in one scene, 3.Nov)

Now is there anybody out there who can give me a general primer?
(Best a (pseudo)code fragment how-to)

For those who want to read on I will attach code fragments of the two
a.m. schemes.

Thanks in advance for any help,

  Klaus

 ------------------------------------------------------
| Klaus Otto | |
| CAE Elektronik GmbH | Email: kotto++at++cae-gmbh.de |
| Abt. Systemtechnik | |
| Steinfurt 11 | Tel. : +49-2402-106-456 |
| D-52222 Stolberg | Fax : +49-2402-106-270 |
| Germany | |
 ------------------------------------------------------

   pfdConverterMode_flt (PFFLT_COMPUTENORMALS, FALSE); /* */
   pfdConverterAttr_flt ( PFFLT_REGISTER_NODE, hFunc );
   pfdMesherMode (PFDMESH_RETESSELLATE, FALSE); /* */
   pfdMesherMode (PFDMESH_LOCAL_LIGHTING, TRUE); /* */

   pLocalState = pfNewGState (arena); /* */
   pfGStateAttr (pLocalState,
                 PFSTATE_FRONTMTL, ViewState->pLocalMaterial); /* */
   pfGStateAttr (pLocalState,
                 PFSTATE_LIGHTMODEL, ViewState->pLocalLightModel); /* */
   pfGStateAttr (pLocalState,
                 PFSTATE_LIGHTS, ViewState->pLocalLights); /* */

   pfGStateMode (pLocalState, PFSTATE_ENLIGHTING, PF_ON); /* */
   pfdDefaultGState (pLocalState); /* */

   pBranch1 = pfdLoadFile("file1");

   pGlobalState = pfNewGState (arena); /* */
   pfGStateAttr (pGlobalState,
                 PFSTATE_FRONTMTL, ViewState->pGlobalMaterial); /* */
   pfGStateAttr (pGlobalState,
                 PFSTATE_LIGHTMODEL, ViewState->pGlobalLightModel); /* */
   pfGStateAttr (pGlobalState,
                 PFSTATE_LIGHTS, ViewState->pGlobalLights); /* */

   pfGStateMode (pGlobalState, PFSTATE_ENLIGHTING, PF_ON); /* */
   pfdDefaultGState (pGlobalState); /* */

   pBranch2 = pfdLoadFile("file2");
    
   .
   .

Add branches to scene
   .
   .
   .
Simloop

********************************************************

typedef struct _GStateAttr
{
   int iDatabase;
   pfLightModel *pLightModel;
   pfMaterial *pMaterial;
   pfLight **pLights; /* array of PFMAX_LIGHTS pfLights !*/
} GStateAttr;

void
main (void)
{
   GStateAttr Change;

   .
   .

   pfdConverterMode_flt (PFFLT_COMPUTENORMALS, FALSE);
   pfdConverterAttr_flt ( PFFLT_REGISTER_NODE, hFunc );

   pfdMesherMode (PFDMESH_RETESSELLATE, FALSE);
   pfdMesherMode (PFDMESH_LOCAL_LIGHTING, TRUE);

   for (i = 0; i < NumFiles; i++)
   {
      /* Load the database. create a hierarchy under node "root" */
      root = pfdLoadFile(DatabaseFiles[i]);
   }

   vInitLightScene (); /* init local+global lights */
   .
   .
load the databases
   .
   .

   Change.iDatabase = GLOBAL_DATABASE;
   Change.pLightModel = ViewState->pGlobalLightModel;
   Change.pMaterial = ViewState->pGlobalMaterial;
   Change.pLights = ViewState->pGlobalLights;
   vTravChangeGStateAttr ((pfNode *) ViewState->pGlobalGroup, &Change);

   Change.iDatabase = LOCAL_DATABASE;
   Change.pLightModel = ViewState->pLocalLightModel;
   Change.pMaterial = ViewState->pLocalMaterial;
   Change.pLights = ViewState->pLocalLights;
   vTravChangeGStateAttr ((pfNode *) ViewState->pLocalGroup, &Change);

   .
   .
 simloop
}

void
vInitLightScene (void)

{
   register int ii;

   arena = pfGetSharedArena ();

   /* create global light */
   ViewState->pGlobalLight = pfNewLight (arena);
   pfLightColor (ViewState->pGlobalLight, PFLT_DIFFUSE, .. .etc.

   pfLightOn (ViewState->pGlobalLight);

   /* create global light model /*
   ViewState->pGlobalLightModel = pfNewLModel (arena);
   pfLModelLocal (ViewState->pGlobalLightModel, PF_OFF);
   pfLModelAmbient (ViewState->pGlobalLightModel, 1.0f, 1.0f, 1.0f);

   /* create global material */
   ViewState->GlobalMaterial = pfNewMtl (arena);
   pfMtlColor (ViewState->GlobalMaterial, PFMTL_AMBIENT, .. .etc.

   /* allocate memory for global light array */
   ViewState->pGlobalLights = (pfLight **) pfMalloc (PF_MAX_LIGHTS * sizeof
                                                          (pfLight *), arena);
   /* init global light array */
   for (ii=0; ii < PF_MAX_LIGHTS; ii++)
   {
     ViewState->pGlobalLights[ii] = NULL;
   }

   /* write global light into global light array */
   ViewState->pGlobalLights[0] = ViewState->pGlobalLight;

   /* ******************** */
   /* create local light */
   ViewState->pLocalLight = pfNewLight (arena);
   pfLightColor (ViewState->pLocalLight, PFLT_DIFFUSE, .. .etc.

   pfLightOn (ViewState->pLocalLight);

   /* create local light model
   /*
   ViewState->pLocalLightModel = pfNewLModel (arena);
   pfLModelLocal (ViewState->pLocalLightModel, PF_ON);
   pfLModelAmbient (ViewState->pLocalLightModel, 0.0f, 0.0f, 0.0f);

   /* create local material for
   */
   ViewState->pLocalMaterial = pfNewMtl (arena);
   pfMtlColor (ViewState->pLocalMaterial, PFMTL_AMBIENT, .. .etc.

   /* allocate memory for local light array
   */
   ViewState->pLocalLights = (pfLight **) pfMalloc (PF_MAX_LIGHTS * sizeof
                                                          (pfLight *), arena);
   /* initialize local light array */
   for (ii=0; ii < PF_MAX_LIGHTS; ii++)
   {
     ViewState->pLocalLights[ii] = NULL;
   }

   /* write local light into local light array
   */
   ViewState->pLocalLights[0] = ViewState->pLocalLight;

   pfEnable (PFEN_LIGHTING);

   return;
}

void
vTravChangeGStateAttr (pfNode *node, GStateAttr *pData)

{
   pfuTraverser trav; /* Traverserstructure */

   pfuInitTraverser (&trav);

   trav.postFunc = (pfuTravFuncType) NULL;
   trav.preFunc = (pfuTravFuncType) slcbGStateAttr;
   trav.mstack = pfNewMStack (32, arena);

   trav.data = pData;
   trav.mode = PFUTRAV_SW_ALL | PFUTRAV_LOD_ALL | PFUTRAV_SEQ_ALL;

   pfuTraverse (node, &trav);

   pfDelete (trav.mstack);
}

static long
slcbGStateAttr (pfuTraverser * trav)

{
   pfGeoState *pCurrentGState;

   pfLightModel *pCurrentGStateLightModel;
   pfMaterial *pCurrentGStateMaterial;
   pfLight **pCurrentGStateLights;

   pfGeoState **pNewGState;
   static int siIndexNewGState = 0;

   pfGeoSet *pGeoSet;
   int iNumGSets;
   register int ii;
   register int ij;

   if (pfIsOfType(trav->node, pfGetGeodeClassType()))
   {
      iNumGSets = pfGetNumGSets ((pfGeode *) trav->node);

      for (ii=0; ii<iNumGSets; ii++)
      {
         pGeoSet = pfGetGSet ((pfGeode *) trav->node, ii);
         pCurrentGState = pfGetGSetGState (pGeoSet);

         pCurrentGStateLightModel = pfGetGStateAttr (pCurrentGState,
                                                     PFSTATE_LIGHTMODEL);
         pCurrentGStateMaterial = pfGetGStateAttr (pCurrentGState, PFSTATE_FRONTMTL);
         pCurrentGStateLights = pfGetGStateAttr (pCurrentGState, PFSTATE_LIGHTS);

         if ((((GStateAttr *) trav->data)->iDatabase == LOCAL_DATABASE) &&
             pfCompare (pCurrentGStateLightModel,
             ViewState->pLightModelGlobal))
         {
            if (!siIndexNewGState)
            {
               pNewGState = (pfGeoState **) pfMalloc (sizeof (pfGeoState *), arena);
               pNewGState[siIndexNewGState] = pfNewGState (arena);
               pfCopy (pNewGState[siIndexNewGState], pCurrentGState);
               pCurrentGState = pNewGState[siIndexNewGState];
               siIndexNewGState++;
            }
            else
            {
               for (ij=0; ij<siIndexNewGState; ij++)
               {
                  if (pCurrentGState == pNewGState[ij])
                  {
                     pNewGState = (pfGeoState**) pfRealloc (pNewGState,
                                       sizeof (pfGeoState*)
                                       *siIndexNewGState+1);

                     pNewGState[siIndexNewGState] = pfNewGState (arena);
                     bcopy (pCurrentGState, pNewGState[siIndexNewGState],
                                                  sizeof(pfGeoState*));
                     pCurrentGState = pNewGState[siIndexNewGState];
                     siIndexNewGState++;
                     break;
                  }
               }
            }
         }

         pfGStateAttr (pCurrentGState, PFSTATE_FRONTMTL,
                       (pfMaterial *) (((GStateAttr *)trav->data)->pMaterial));

         pfGStateAttr ( pCurrentGState, PFSTATE_LIGHTMODEL,
                     (pfLightModel *) (((GStateAttr *)trav->data)->pLightModel));

         pfGStateAttr (pCurrentGState, PFSTATE_LIGHTS,
                       (pfLight **) (((GStateAttr *)trav->data)->pLights));

         pfGSetGState (pGeoSet, pCurrentGState);
      }
   }

   return PFTRAV_CONT;
}

=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
            Submissions: info-performer++at++sgi.com
        Admin. requests: info-performer-request++at++sgi.com


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:56:13 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.