1 /*
2  * Copyright (C) 1997-2005, R3vis Corporation.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18  *
19  * Original Contributor:
20  *   Wes Bethel, R3vis Corporation, Marin County, California
21  * Additional Contributor(s):
22  *
23  * The OpenRM project is located at http://openrm.sourceforge.net/.
24  */
25 /*
26  * $Id: rmrstate.c,v 1.7 2005/06/26 19:01:36 wes Exp $
27  * Version: $Name: OpenRM-1-6-0-2-RC2 $
28  * $Revision: 1.7 $
29  * $Log: rmrstate.c,v $
30  * Revision 1.7  2005/06/26 19:01:36  wes
31  * Use new routine to compute viewport matrix.
32  *
33  * Revision 1.6  2005/02/19 16:28:54  wes
34  * Distro sync and consolidation.
35  * Fixes for a number of state tracking buglets.
36  *
37  * Revision 1.5  2004/12/11 16:19:14  wes
38  * Fixed bug in how RMstate->aspect_ratio was computed.
39  *
40  * Revision 1.4  2004/01/16 16:48:35  wes
41  * Updated copyright line for 2004.
42  *
43  * Revision 1.3  2003/06/14 16:24:20  wes
44  * Minor documentation tweaks.
45  *
46  * Revision 1.2  2003/02/02 02:07:15  wes
47  * Updated copyright to 2003.
48  *
49  * Revision 1.1.1.1  2003/01/28 02:15:23  wes
50  * Manual rebuild of rm150 repository.
51  *
52  * Revision 1.9  2003/01/16 22:21:17  wes
53  * Updated all source files to reflect new organization of header files:
54  * all header files formerly located in include/rmaux, include/rmi, include/rmv
55  * are now located in include/rm.
56  *
57  * Revision 1.8  2002/06/17 01:02:37  wes
58  * Added back in code that syncs the lighting state between the render
59  * state cache and the RMrstate used during rendering.
60  *
61  * Revision 1.7  2002/06/02 15:16:27  wes
62  * Added RMstateCache code to help eliminate the number of state changes
63  * made during the render traversal. The RMstateCache tracks
64  * the actual OpenGL rendering state w/o the need for querying OpenGL
65  * directly, and  is queried by draw code that then decides if any
66  * real state changes are required given the configuration of data
67  * within an RMprimitive.
68  *
69  * Revision 1.6  2002/04/30 19:33:26  wes
70  * Updated copyright dates.
71  *
72  * Revision 1.5  2001/03/31 17:12:39  wes
73  * v1.4.0-alpha-2 checkin.
74  *
75  * Revision 1.4  2000/08/23 23:28:50  wes
76  * Assertions added to some routines.
77  *
78  * Revision 1.3  2000/05/14 23:37:11  wes
79  * Added control via RMpipe attribute to how OpenGL matrix stack
80  * is initialized or used during rendering.
81  *
82  * Revision 1.2  2000/04/20 16:29:47  wes
83  * Documentation additions/enhancements, some code rearragement.
84  *
85  * Revision 1.1.1.1  2000/02/28 21:29:40  wes
86  * OpenRM 1.2 Checkin
87  *
88  * Revision 1.1.1.1  2000/02/28 17:18:48  wes
89  * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
90  *
91  */
92 
93 /* documentation of public routines is incomplete in this file. */
94 
95 
96 #include <rm/rm.h>
97 #include "rmprivat.h"
98 
99 
100 /*
101  * ----------------------------------------------------
102  * @Name rmStateNew
103  @pstart
104  RMstate *rmStateNew (void)
105  @pend
106 
107  @astart
108  No arguments.
109  @aend
110 
111  @dstart
112 
113  Create and initialize an RMstate object, meaning that all RMstate
114  matrices are set to the identity.  Upon success, a handle to the new
115  RMstate is returned to the caller.  Otherwise, a NULL pointer is
116  returned to the caller.
117 
118  @dend
119  * ----------------------------------------------------
120  */
121 RMstate *
rmStateNew(void)122 rmStateNew (void)
123 {
124     RMstate *t = (RMstate *)malloc(sizeof(RMstate));
125 
126     if (RM_ASSERT(t, "rmStateNew() malloc failure") == RM_WHACKED)
127 	return(NULL);
128 
129     memset(t, 0, sizeof(RMstate));
130 
131     /* initialize everything the right way, set matrices to I */
132     rmMatrixIdentity(&(t->model));
133     rmMatrixIdentity(&(t->view));
134     rmMatrixIdentity(&(t->modelView));
135     rmMatrixIdentity(&(t->composite));
136     rmMatrixIdentity(&(t->pick));
137     rmMatrixIdentity(&(t->projection));
138     rmMatrixIdentity(&(t->projection_inverse));
139     rmMatrixIdentity(&(t->textureMatrix));
140 
141     return(t);
142 }
143 
144 
145 /*
146  * ----------------------------------------------------
147  * @Name rmStateDelete
148  @pstart
149  void rmStateDelete (RMstate *s)
150  @pend
151 
152  @astart
153  RMstate *s - a handle to the RMstate object to delete (modified).
154  @aend
155 
156  @dstart
157 
158  Frees the resources for an RMstate object.  No error checking is
159  performed, so the result of deleting a non-object will be
160  system-dependent (generllay this is something to avoid).
161 
162  No status is returned.
163 
164  @dend
165  * ----------------------------------------------------
166  */
167 void
rmStateDelete(RMstate * s)168 rmStateDelete (RMstate *s)
169 {
170     if (RM_ASSERT(s,"rmStateDelete() error: the input RMstate object is NULL.") == RM_WHACKED)
171 	return;
172     free((void *)s);
173 }
174 
175 
176 /*
177  * ----------------------------------------------------
178  * @Name rmStateCopy
179  @pstart
180  void rmStateCopy (const RMstate *s,
181                    RMstate *d)
182  @pend
183 
184  @astart
185  const RMstate *s - a handle to the source RMstate (input).
186 
187  RMstate *d - a handle to the destination RMstate (modified).
188  @aend
189 
190  @dstart
191 
192  Copies the RMstate object s to the RMstate object d.  No error
193  checking is performed, so the copy is only valid if s and d are valid
194  RMstate objects.
195 
196  No status is returned.
197 
198  @dend
199  * ----------------------------------------------------
200  */
201 void
rmStateCopy(const RMstate * s,RMstate * d)202 rmStateCopy (const RMstate *s,
203 	     RMstate *d)
204 {
205     if ((RM_ASSERT(s,"rmStateCopy() error: the input RMstate object is NULL") == RM_WHACKED) ||
206 	(RM_ASSERT(d,"rmStateCopy() error: the destination RMstate object is NULL") == RM_WHACKED))
207 	return;
208 
209     memcpy((void *)d, (void *)s, sizeof(RMstate));
210 }
211 
212 
213 /*
214  * ----------------------------------------------------
215  * @Name rmStateGetModelViewMatrix
216  @pstart
217  const RMmatrix *rmStateGetModelViewMatrix (const RMstate *toQuery)
218  @pend
219 
220  @astart
221  const RMstate *toQuery - a handle to an RMstate object (input).
222  @aend
223 
224  @dstart
225 
226  During a render-time traversal, the RMstate object reflects the
227  current state of many rendering parameters as affected by nodes in
228  the scene graph. The RMstate object is provided to node callback
229  functions as a parameter. The rmStateGet*() family of routines can be
230  used by developers to obtain current render state parameters.
231 
232  This routine is used to obtain a handle to the OpenGL "model-view"
233  matrix.  The modelView matrix is the concatenation of model
234  transformations with the view transformation defined by the current
235  camera.
236 
237  The RMmatrix handle that is returned is "read only." NULL is returned
238  if the input RMstate object is NULL.
239 
240  @dend
241  * ----------------------------------------------------
242  */
243 const RMmatrix *
rmStateGetModelViewMatrix(const RMstate * s)244 rmStateGetModelViewMatrix (const RMstate *s)
245 {
246     if (RM_ASSERT(s, "rmStateGetModelViewMatrix() error: the input RMstate object is NULL.\n") == RM_WHACKED)
247 	return(NULL);
248 
249     return(&(s->modelView));
250 }
251 
252 
253 /*
254  * ----------------------------------------------------
255  * @Name rmStateGetProjectionMatrix
256  @pstart
257  const RMmatrix *rmStateGetProjectionMatrix (const RMstate *toQuery)
258  @pend
259 
260  @astart
261  const RMstate *toQuery - a handle to an RMstate object (input).
262  @aend
263 
264  @dstart
265 
266  During a render-time traversal, the RMstate object reflects the
267  current state of many rendering parameters as affected by nodes in
268  the scene graph. The RMstate object is provided to node callback
269  functions as a parameter. The rmStateGet*() family of routines can be
270  used by developers to obtain current render state parameters.
271 
272  This routine is used to obtain a handle to the OpenGL "projection"
273  matrix.  The projection matrix represents the transformation from eye
274  coordinates to clip coordinates, typically defined only by 3D
275  cameras.
276 
277  The RMmatrix handle that is returned is "read only." NULL is returned
278  if the input RMstate object is NULL.
279 
280  @dend
281  * ----------------------------------------------------
282  */
283 const RMmatrix *
rmStateGetProjectionMatrix(const RMstate * s)284 rmStateGetProjectionMatrix (const RMstate *s)
285 {
286     if (RM_ASSERT(s, "rmStateGetModelViewMatrix() error: the input RMstate object is NULL.\n") == RM_WHACKED)
287 	return(NULL);
288 
289     return(&(s->projection));
290 }
291 
292 /*
293  * ----------------------------------------------------
294  * @Name rmStateGetShader
295  @pstart
296  RMenum rmStateGetShader(const RMstate *toQuery)
297  @pend
298 
299  @astart
300  const RMstate *toQuery - a handle to an RMstate object (input).
301  @aend
302 
303  @dstart
304  Use this routine to obtain the shader attribute of an RMstate object.
305  Upon success, one of the RM shade model enumerators is returned to the
306  caller (RM_SHADER_SMOOTH, RM_SHADER_FLAT or RM_SHADER_NOLIGHT). Otherwise,
307  RM_WHACKED is returned.
308 
309  This routine is intended to be used from inside application callback
310  code, either node callbacks or application-defined RMprimitive draw
311  routines.
312  @dend
313  * ----------------------------------------------------
314  */
315 RMenum
rmStateGetShader(const RMstate * s)316 rmStateGetShader(const RMstate *s)
317 {
318     if (RM_ASSERT(s,"rmStateGetShader() error: the input RMstate object is NULL") == RM_WHACKED)
319 	return(RM_WHACKED);
320 
321     return(s->shademodel);
322 }
323 
324 /*
325  * ----------------------------------------------------
326  * @Name rmStateGetPolygonDrawMode
327  @pstart
328  RMenum rmStateGetPolygonDrawMode(const RMstate *toQuery,
329 		                  RMenum *whichFaceReturn,
330 				  RMenum *drawModeReturn)
331  @pend
332 
333  @astart
334  const RMstate *toQuery - a handle to an RMnode (input).
335  RMenum *whichFaceReturn, *drawModeReturn - handles to caller-supplied
336     RMenum's (result). A value of NULL is acceptable.
337  @aend
338 
339  @dstart
340  Use this routine to query the render-time values for the polygon draw
341  mode. See rmNodeSetPolygonDrawMode() for more details about these parameters.
342  This routine is intended to be used from inside an application callback
343  that would be attached to an RMnode, to be invoked during a render-time
344  traversal of the scene graph.
345 
346  If the caller specifies NULL for one of the return parameters, that
347  value will not be queried.
348 
349  RM_CHILL is returned upon success. Upon failure, RM_WHACKED is returned,
350  and caller supplied memory remains unmodified.
351  @dend
352  * ----------------------------------------------------
353  */
354 RMenum
rmStateGetPolygonDrawMode(const RMstate * s,RMenum * whichFaceReturn,RMenum * drawModeReturn)355 rmStateGetPolygonDrawMode(const RMstate *s,
356 			  RMenum *whichFaceReturn,
357 			  RMenum *drawModeReturn)
358 {
359     if (RM_ASSERT(s,"rmStateGetPolygonDrawMode() error: the input RMstate object is NULL") == RM_WHACKED)
360 	return(RM_WHACKED);
361 
362     if (whichFaceReturn != NULL)
363 	*whichFaceReturn = s->poly_mode_face;
364 
365     if (drawModeReturn != NULL)
366 	*drawModeReturn = s->poly_mode_drawstyle;
367 
368     return(RM_CHILL);
369 }
370 
371 
372 /*
373  * ----------------------------------------------------
374  * @Name rmStateGetPolygonCullMode
375  @pstart
376  RMenum rmStateGetPolygonCullMode(const RMstate *toQuery,
377 				  RMenum *cullModeReturn)
378  @pend
379 
380  @astart
381  const RMstate *toQuery - a handle to an RMnode (input).
382  RMenum *cullModeReturn - handles to caller-supplied
383     RMenum's (result). A value of NULL is acceptable.
384  @aend
385 
386  @dstart
387  Use this routine to query the render-time values for the polygon cull
388  mode. See rmNodeSetPolygonCullMode() for more details about this parameter.
389  This routine is intended to be used from inside an application callback
390  that would be attached to an RMnode, to be invoked during a render-time
391  traversal of the scene graph.
392 
393  If the caller specifies NULL for the return parameter, the polygon
394  cull mode from the RMstate object will not be copied into caller-supplied
395  memory.
396 
397  RM_CHILL is returned upon success. Upon failure, RM_WHACKED is returned,
398  and caller supplied memory remains unmodified.
399  @dend
400  * ----------------------------------------------------
401  */
402 RMenum
rmStateGetPolygonCullMode(const RMstate * s,RMenum * cullModeReturn)403 rmStateGetPolygonCullMode(const RMstate *s,
404 			  RMenum *cullModeReturn)
405 {
406     if (RM_ASSERT(s,"rmStateGetPolygonCullMode() error: the input RMstate object is NULL") == RM_WHACKED)
407 	return(RM_WHACKED);
408 
409     if (cullModeReturn != NULL)
410 	*cullModeReturn = s->cull_mode;
411 
412     return(RM_CHILL);
413 }
414 
415 /*
416  * ----------------------------------------------------
417  * @Name rmStateGetFrontFace
418  @pstart
419  RMenum rmStateGetFrontFace(const RMstate *toQuery,
420 		            RMenum *frontFaceReturn)
421  @pend
422 
423  @astart
424  const RMstate *toQuery - a handle to an RMnode (input).
425  RMenum *frontFaceReturn - a handle to a caller-supplied RMenum (result).
426  @aend
427 
428  @dstart
429  Use this routine to query the render-time values for the polygon front
430  face attribute. See rmNodeSetFrontFace() for more details about this
431  parameter.  This routine is intended to be used from inside an
432  application callback that would be attached to an RMnode, to be
433  invoked during a render-time traversal of the scene graph.
434 
435  If the caller specifies NULL for the return parameter, the polygon
436  front face mode from the RMstate object will not be copied into
437  caller-supplied memory.
438 
439  RM_CHILL is returned upon success. Upon failure, RM_WHACKED is returned,
440  and caller supplied memory remains unmodified.
441  @dend
442  * ----------------------------------------------------
443  */
444 RMenum
rmStateGetFrontFace(const RMstate * s,RMenum * frontFaceReturn)445 rmStateGetFrontFace(const RMstate *s,
446 		    RMenum *frontFaceReturn)
447 {
448     if (RM_ASSERT(s,"rmStateGetFrontFace() error: the input RMstate object is NULL") == RM_WHACKED)
449 	return(RM_WHACKED);
450 
451     if (frontFaceReturn != NULL)
452 	*frontFaceReturn = s->front_face;
453 
454     return(RM_CHILL);
455 }
456 
457 /*
458  * ----------------------------------------------------
459  * @Name rmStateGetLineWidth
460  @pstart
461  RMenum rmStateGetLineWidth(const RMstate *toQuery,
462 		            RMenum *lineWidthReturn)
463  @pend
464 
465  @astart
466  const RMstate *toQuery - a handle to an RMnode (input).
467  RMenum *lineStyleReturn - a handle to a caller-supplied RMenum (result).
468  @aend
469 
470  @dstart
471  Use this routine to query the render-time values for the current
472  line style attribute. See rmNodeSetLineWidth() for more details about this
473  parameter.  This routine is intended to be used from inside an
474  application callback that would be attached to an RMnode, to be
475  invoked during a render-time traversal of the scene graph.
476 
477  Note that an RM line width enumerator is returned, not the actual pixel
478  width of the lines.
479 
480  If the caller specifies NULL for the return parameter, the line style
481  attribute from the RMstate object will not be copied into
482  caller-supplied memory.
483 
484  RM_CHILL is returned upon success. Upon failure, RM_WHACKED is returned,
485  and caller supplied memory remains unmodified.
486  @dend
487  * ----------------------------------------------------
488  */
489 
490 RMenum
rmStateGetLineWidth(const RMstate * s,RMenum * lineWidthReturn)491 rmStateGetLineWidth(const RMstate *s,
492 		    RMenum *lineWidthReturn)
493 {
494     if (RM_ASSERT(s,"rmStateGetLineWidth() error: the input RMstate object is NULL") == RM_WHACKED)
495 	return(RM_WHACKED);
496 
497     if (lineWidthReturn != NULL)
498 	*lineWidthReturn = s->linewidth;
499 
500     return(RM_CHILL);
501 }
502 
503 
504 /*
505  * ----------------------------------------------------
506  * @Name rmStateGetLineStyle
507  @pstart
508  RMenum rmStateGetLineStyle(const RMstate *toQuery,
509 		            RMenum *lineStyleReturn)
510  @pend
511 
512  @astart
513  const RMstate *toQuery - a handle to an RMnode (input).
514  RMenum *lineStyleReturn - a handle to a caller-supplied RMenum (result).
515  @aend
516 
517  @dstart
518  Use this routine to query the render-time values for the current
519  line style attribute. See rmNodeSetLineStyle() for more details about this
520  parameter.  This routine is intended to be used from inside an
521  application callback that would be attached to an RMnode, to be
522  invoked during a render-time traversal of the scene graph.
523 
524  If the caller specifies NULL for the return parameter, the line style
525  attribute from the RMstate object will not be copied into
526  caller-supplied memory.
527 
528  RM_CHILL is returned upon success. Upon failure, RM_WHACKED is returned,
529  and caller supplied memory remains unmodified.
530  @dend
531  * ----------------------------------------------------
532  */
533 RMenum
rmStateGetLineStyle(const RMstate * s,RMenum * lineStyleReturn)534 rmStateGetLineStyle(const RMstate *s,
535 		    RMenum *lineStyleReturn)
536 {
537     if (RM_ASSERT(s,"rmStateGetLineStyle() error: the input RMstate object is NULL") == RM_WHACKED)
538 	return(RM_WHACKED);
539 
540     if (lineStyleReturn != NULL)
541 	*lineStyleReturn = s->linestyle;
542 
543     return(RM_CHILL);
544 }
545 
546 /*
547  * ----------------------------------------------------
548  * @Name rmStateGetPointSize
549  @pstart
550  RMenum rmStateGetPointSize(const RMstate *toQuery,
551 		            float *sizeReturn)
552  @pend
553 
554  @astart
555  const RMstate *toQuery - a handle to an RMnode (input).
556  float *sizeReturn - a handle to a caller-supplied float (result).
557  @aend
558 
559  @dstart
560  Use this routine to query the render-time values for the current
561  point size attribute. See rmNodeSetPointSize() for more details about this
562  parameter.  This routine is intended to be used from inside an
563  application callback that would be attached to an RMnode, to be
564  invoked during a render-time traversal of the scene graph.
565 
566  If the caller specifies NULL for the return parameter, the point size
567  attribute from the RMstate object will not be copied into
568  caller-supplied memory.
569 
570  RM_CHILL is returned upon success. Upon failure, RM_WHACKED is returned,
571  and caller supplied memory remains unmodified.
572  @dend
573  * ----------------------------------------------------
574  */
575 RMenum
rmStateGetPointSize(const RMstate * s,float * sizeReturn)576 rmStateGetPointSize(const RMstate *s,
577 		    float *sizeReturn)
578 {
579     if (RM_ASSERT(s,"rmStateGetPointSize() error: the input RMstate object is NULL") == RM_WHACKED)
580 	return(RM_WHACKED);
581 
582     if (sizeReturn != NULL)
583 	*sizeReturn = s->pointsize;
584 
585     return(RM_CHILL);
586 }
587 
588 /*
589  * ----------------------------------------------------
590  * @Name rmStateGetFrameNumber
591  @pstart
592  int rmStateGetFrameNumber(const RMstate *toQuery)
593  @pend
594 
595  @astart
596  const RMstate *toQuery - a handle to an RMstate object.
597  @aend
598 
599  @dstart
600  Use this routine to query the render-time frame number from the RMstate
601  object "toQuery." This routine is intended to be used by application-
602  supplied render- or view-traversal callback routines in order to
603  implement operations that are a function of the current frame number.
604  @dend
605  * ----------------------------------------------------
606  */
607 int
rmStateGetFrameNumber(const RMstate * toQuery)608 rmStateGetFrameNumber(const RMstate *toQuery)
609 {
610     if (RM_ASSERT(toQuery, "rmStateGetFrameNumber error(): the input RMstate object is NULL. The returned frame number is invalid. ") == RM_WHACKED)
611 	return(0);
612     else
613 	return(toQuery->frameNumber);
614 }
615 
616 
617 /* PRIVATE */
618 void
private_rmStateInit(const RMpipe * p,RMstate * s,RMenum rendermode,RMmatrix * model,RMmatrix * view,RMmatrix * proj,RMmatrix * texture)619 private_rmStateInit (const RMpipe *p,
620 		     RMstate *s,
621 		     RMenum rendermode,
622 		     RMmatrix *model,
623 		     RMmatrix *view,
624 		     RMmatrix *proj,
625 		     RMmatrix *texture)
626 {
627     memset(s, 0, sizeof(RMstate));
628 
629     if (view != NULL)
630 	rmMatrixCopy(&(s->view), view);
631     else
632 	rmMatrixIdentity(&(s->view));
633 
634     if (model != NULL)
635 	rmMatrixCopy(&(s->model), model);
636     else
637 	rmMatrixIdentity(&(s->model));
638 
639     if (proj != NULL)
640 	rmMatrixCopy(&(s->projection), proj);
641     else
642 	rmMatrixIdentity(&(s->projection));
643 
644     if (texture != NULL)
645 	rmMatrixCopy(&(s->textureMatrix), texture);
646     else
647 	rmMatrixIdentity(&(s->textureMatrix));
648 
649 
650     rmMatrixIdentity(&(s->pick));
651 
652     rmMatrixInverse(&(s->projection), &(s->projection_inverse));
653     rmMatrixMultiply(&(s->model), &(s->view), &(s->modelView));
654     rmMatrixMultiply(&(s->modelView), &(s->projection), &(s->composite));
655 
656     if (p != NULL)
657     {
658 	float fw, fh;
659 
660 	rmPipeGetWindowSize(p, &(s->w), &(s->h));
661 
662 	/*
663 	 * in the RMstate structure, viewport settings are in pixel,
664 	 * not NDC coordinates.
665 	 */
666 
667 	/*
668 	 * we assign the default viewport to take up the entire screen.
669 	 * eventually, we want to be able to take into account any
670 	 * existing viewport value that might be set.
671 	 */
672 
673 	fw = (float)s->w;
674 	fh = (float)s->h;
675 
676 	s->vp[0] = s->vp[1] = 0.0F;
677 	s->vp[2] = fw;
678 	s->vp[3] = fh;
679 
680 	/* set the viewport matrix */
681 	private_rmComputeViewportMatrix(s->vp, fw, fh, &(s->vpm));
682 
683 	s->aspect_ratio = fw/fh;
684 
685 	s->frameNumber = p->frameNumber;
686     }
687 
688     s->rendermode = rendermode;
689 #if 0
690     /* is this necessary/correct here? */
691     s->colorMaterialActive = RM_FALSE;
692     s->lightingActive = RM_FALSE;
693 #endif
694 }
695 
696 RMstateCache *
private_rmStateCacheNew(void)697 private_rmStateCacheNew (void)
698 {
699     RMstateCache *t = malloc(sizeof(RMstateCache));
700     t->colorMaterialActive = RM_FALSE;
701     t->lightingActive = RM_FALSE;
702     t->texturingActive = RM_FALSE;
703     return(t);
704 }
705 
706 void
private_rmStateCacheDelete(RMstateCache * t)707 private_rmStateCacheDelete(RMstateCache *t)
708 {
709     free((void *)t);
710 }
711 
712 void
private_rmStateCacheSync(const RMstate * s,RMstateCache * rsc)713 private_rmStateCacheSync(const RMstate *s,
714 			 RMstateCache *rsc)
715 {
716     /* check texturing */
717     if ((s->texture_mode != 0) && (rsc->texturingActive == RM_FALSE))
718 	rsc->texturingActive = RM_TRUE;
719     else if ((s->texture_mode == 0) && (rsc->texturingActive == RM_TRUE))
720 	rsc->texturingActive = RM_FALSE;
721 
722     /* check lighting */
723     if ((s->lightingActive == RM_TRUE) && (rsc->lightingActive == RM_FALSE))
724 	rsc->lightingActive = RM_TRUE;
725     else if ((s->lightingActive == RM_FALSE) && (rsc->lightingActive == RM_TRUE))
726 	rsc->lightingActive = RM_FALSE;
727 
728     /* check color material state */
729     if ((s->colorMaterialActive == RM_TRUE) && (rsc->colorMaterialActive == RM_FALSE))
730 	rsc->colorMaterialActive = RM_TRUE;
731     else if ((s->colorMaterialActive == RM_FALSE) && (rsc->colorMaterialActive == RM_TRUE))
732 	rsc->colorMaterialActive = RM_FALSE;
733 
734 }
735 
736 void
private_rmSyncStateToCache(RMstateCache * rsc,RMstate * s)737 private_rmSyncStateToCache(RMstateCache *rsc,
738 			   RMstate *s)
739 {
740     /* sync the RMstate to the values indicated in the rsc */
741 #if 0
742     /* check texturing */
743     if ((s->texture_mode != 0) && (rsc->texturingActive == RM_FALSE))
744 	s->texturingActive = RM_TRUE;
745     else if ((s->texture_mode == 0) && (rsc->texturingActive == RM_TRUE))
746 	rsc->texturingActive = RM_FALSE;
747 #endif
748     /* check lighting */
749     if ((s->lightingActive == RM_TRUE) && (rsc->lightingActive == RM_FALSE))
750 	s->lightingActive = RM_FALSE;
751     else if ((s->lightingActive == RM_FALSE) && (rsc->lightingActive == RM_TRUE))
752 	s->lightingActive = RM_TRUE;
753 
754     /* check color material state */
755     if ((s->colorMaterialActive == RM_TRUE) && (rsc->colorMaterialActive == RM_FALSE))
756 	s->colorMaterialActive = RM_FALSE;
757     else if ((s->colorMaterialActive == RM_FALSE) && (rsc->colorMaterialActive == RM_TRUE))
758 	s->colorMaterialActive = RM_TRUE;
759 
760 }
761 /* EOF */
762