home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / attrib.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  17KB  |  541 lines

  1. /* $Id: attrib.c,v 1.12 1996/04/18 14:53:32 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Log: attrib.c,v $
  26.  * Revision 1.12  1996/04/18  14:53:32  brianp
  27.  * added error checking for GL_INVALID_OPERATION
  28.  *
  29.  * Revision 1.11  1996/03/22  20:54:08  brianp
  30.  * removed CC.ClipSpans stuff
  31.  *
  32.  * Revision 1.10  1995/11/01  23:18:22  brianp
  33.  * update CC.Light.LastEnabled when poping GL_ENABLE_BIT
  34.  *
  35.  * Revision 1.9  1995/10/27  20:29:02  brianp
  36.  * added glPolygonOffsetEXT() support
  37.  *
  38.  * Revision 1.8  1995/08/31  21:32:45  brianp
  39.  * new TexGenEnabled bitfield
  40.  * introduced CC.NewState convention
  41.  *
  42.  * Revision 1.7  1995/07/24  18:58:55  brianp
  43.  * added CC.ClipSpans logic to glPopAttrib()
  44.  *
  45.  * Revision 1.6  1995/07/17  15:36:32  brianp
  46.  * fixed malloc size problem for stipples per Steve Freitag (stevef@ultranet.com)
  47.  * added missing code for popping GL_POLYGON_STIPPLE_BIT attribute
  48.  *
  49.  * Revision 1.5  1995/05/22  21:02:41  brianp
  50.  * Release 1.2
  51.  *
  52.  * Revision 1.4  1995/03/27  20:30:12  brianp
  53.  * new Texture.Enabled sheme
  54.  *
  55.  * Revision 1.3  1995/03/24  17:00:59  brianp
  56.  * added gl_update_pixel_logic
  57.  *
  58.  * Revision 1.2  1995/03/04  19:29:44  brianp
  59.  * 1.1 beta revision
  60.  *
  61.  * Revision 1.1  1995/02/24  14:16:38  brianp
  62.  * Initial revision
  63.  *
  64.  */
  65.  
  66.  
  67. #include <stdlib.h>
  68. #include <string.h>
  69. #include "context.h"
  70. #include "list.h"
  71. #include "macros.h"
  72.  
  73.  
  74. #define MALLOC_STRUCT(T)  (struct T *) malloc( sizeof(struct T) )
  75.  
  76.  
  77.  
  78. static struct gl_attrib_node *new_attrib_node( GLbitfield kind )
  79. {
  80.    struct gl_attrib_node *an;
  81.  
  82.    an = (struct gl_attrib_node *) malloc( sizeof(struct gl_attrib_node) );
  83.    if (an) {
  84.       an->kind = kind;
  85.    }
  86.    return an;
  87. }
  88.  
  89.  
  90.  
  91. void gl_push_attrib( GLbitfield mask )
  92. {
  93.    struct gl_attrib_node *newnode;
  94.    struct gl_attrib_node *head;
  95.  
  96.    if (INSIDE_BEGIN_END) {
  97.       gl_error( GL_INVALID_OPERATION, "glPushAttrib" );
  98.       return;
  99.    }
  100.  
  101.    if (CC.AttribStackDepth>=MAX_ATTRIB_STACK_DEPTH) {
  102.       gl_error( GL_STACK_OVERFLOW, "glPushAttrib" );
  103.       return;
  104.    }
  105.  
  106.    /* Build linked list of attribute nodes which save all attribute */
  107.    /* groups specified by the mask. */
  108.    head = NULL;
  109.  
  110.    if (mask & GL_ACCUM_BUFFER_BIT) {
  111.       struct gl_accum_attrib *attr;
  112.  
  113.       attr = MALLOC_STRUCT( gl_accum_attrib );
  114.       MEMCPY( attr, &CC.Accum, sizeof(struct gl_accum_attrib) );
  115.       newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
  116.       newnode->data = attr;
  117.       newnode->next = head;
  118.       head = newnode;
  119.    }
  120.  
  121.    if (mask & GL_COLOR_BUFFER_BIT) {
  122.       struct gl_colorbuffer_attrib *attr;
  123.       attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
  124.       MEMCPY( attr, &CC.Color, sizeof(struct gl_colorbuffer_attrib) );
  125.       newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
  126.       newnode->data = attr;
  127.       newnode->next = head;
  128.       head = newnode;
  129.    }
  130.  
  131.    if (mask & GL_CURRENT_BIT) {
  132.       struct gl_current_attrib *attr;
  133.       attr = MALLOC_STRUCT( gl_current_attrib );
  134.       MEMCPY( attr, &CC.Current, sizeof(struct gl_current_attrib) );
  135.       newnode = new_attrib_node( GL_CURRENT_BIT );
  136.       newnode->data = attr;
  137.       newnode->next = head;
  138.       head = newnode;
  139.    }
  140.  
  141.    if (mask & GL_DEPTH_BUFFER_BIT) {
  142.       struct gl_depthbuffer_attrib *attr;
  143.       attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
  144.       MEMCPY( attr, &CC.Depth, sizeof(struct gl_depthbuffer_attrib) );
  145.       newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
  146.       newnode->data = attr;
  147.       newnode->next = head;
  148.       head = newnode;
  149.    }
  150.  
  151.    if (mask & GL_ENABLE_BIT) {
  152.       struct gl_enable_attrib *attr;
  153.       GLuint i;
  154.       attr = MALLOC_STRUCT( gl_enable_attrib );
  155.       /* Copy enable flags from all other attributes into the enable struct. */
  156.       attr->AlphaTest = CC.Color.AlphaEnabled;
  157.       attr->AutoNormal = CC.Eval.AutoNormal;
  158.       attr->Blend = CC.Color.BlendEnabled;
  159.       for (i=0;i<MAX_CLIP_PLANES;i++) {
  160.          attr->ClipPlane[i] = CC.Transform.ClipEnabled[i];
  161.       }
  162.       attr->ColorMaterial = CC.Light.ColorMaterialEnabled;
  163.       attr->CullFace = CC.Polygon.CullFlag;
  164.       attr->DepthTest = CC.Depth.Test;
  165.       attr->Dither = CC.Color.DitherFlag;
  166.       attr->Fog = CC.Fog.Enabled;
  167.       for (i=0;i<MAX_LIGHTS;i++) {
  168.          attr->Light[i] = CC.Light.Light[i].Enabled;
  169.       }
  170.       attr->Lighting = CC.Light.Enabled;
  171.       attr->LineSmooth = CC.Line.SmoothFlag;
  172.       attr->LineStipple = CC.Line.StippleFlag;
  173.       attr->LogicOp = CC.Color.LogicOpEnabled;
  174.       attr->Map1Color4 = CC.Eval.Map1Color4;
  175.       attr->Map1Index = CC.Eval.Map1Index;
  176.       attr->Map1Normal = CC.Eval.Map1Normal;
  177.       attr->Map1TextureCoord1 = CC.Eval.Map1TextureCoord1;
  178.       attr->Map1TextureCoord2 = CC.Eval.Map1TextureCoord2;
  179.       attr->Map1TextureCoord3 = CC.Eval.Map1TextureCoord3;
  180.       attr->Map1TextureCoord4 = CC.Eval.Map1TextureCoord4;
  181.       attr->Map1Vertex3 = CC.Eval.Map1Vertex3;
  182.       attr->Map1Vertex4 = CC.Eval.Map1Vertex4;
  183.       attr->Map2Color4 = CC.Eval.Map2Color4;
  184.       attr->Map2Index = CC.Eval.Map2Index;
  185.       attr->Map2Normal = CC.Eval.Map2Normal;
  186.       attr->Map2TextureCoord1 = CC.Eval.Map2TextureCoord1;
  187.       attr->Map2TextureCoord2 = CC.Eval.Map2TextureCoord2;
  188.       attr->Map2TextureCoord3 = CC.Eval.Map2TextureCoord3;
  189.       attr->Map2TextureCoord4 = CC.Eval.Map2TextureCoord4;
  190.       attr->Map2Vertex3 = CC.Eval.Map2Vertex3;
  191.       attr->Map2Vertex4 = CC.Eval.Map2Vertex4;
  192.       attr->Normalize = CC.Transform.Normalize;
  193.       attr->PointSmooth = CC.Point.SmoothFlag;
  194.       attr->PolygonOffset = CC.Polygon.OffsetEnabled;
  195.       attr->PolygonSmooth = CC.Polygon.SmoothFlag;
  196.       attr->PolygonStipple = CC.Polygon.StippleFlag;
  197.       attr->Scissor = CC.Scissor.Enabled;
  198.       attr->Stencil = CC.Stencil.Enabled;
  199.       attr->Texture = CC.Texture.Enabled;
  200.       attr->TexGen = CC.Texture.TexGenEnabled;
  201.       newnode = new_attrib_node( GL_ENABLE_BIT );
  202.       newnode->data = attr;
  203.       newnode->next = head;
  204.       head = newnode;
  205.    }
  206.  
  207.    if (mask & GL_EVAL_BIT) {
  208.       struct gl_eval_attrib *attr;
  209.       attr = MALLOC_STRUCT( gl_eval_attrib );
  210.       MEMCPY( attr, &CC.Eval, sizeof(struct gl_eval_attrib) );
  211.       newnode = new_attrib_node( GL_EVAL_BIT );
  212.       newnode->data = attr;
  213.       newnode->next = head;
  214.       head = newnode;
  215.    }
  216.  
  217.    if (mask & GL_FOG_BIT) {
  218.       struct gl_fog_attrib *attr;
  219.       attr = MALLOC_STRUCT( gl_fog_attrib );
  220.       MEMCPY( attr, &CC.Fog, sizeof(struct gl_fog_attrib) );
  221.       newnode = new_attrib_node( GL_FOG_BIT );
  222.       newnode->data = attr;
  223.       newnode->next = head;
  224.       head = newnode;
  225.    }
  226.  
  227.    if (mask & GL_HINT_BIT) {
  228.       struct gl_hint_attrib *attr;
  229.       attr = MALLOC_STRUCT( gl_hint_attrib );
  230.       MEMCPY( attr, &CC.Hint, sizeof(struct gl_hint_attrib) );
  231.       newnode = new_attrib_node( GL_HINT_BIT );
  232.       newnode->data = attr;
  233.       newnode->next = head;
  234.       head = newnode;
  235.    }
  236.  
  237.    if (mask & GL_LIGHTING_BIT) {
  238.       struct gl_light_attrib *attr;
  239.       attr = MALLOC_STRUCT( gl_light_attrib );
  240.       MEMCPY( attr, &CC.Light, sizeof(struct gl_light_attrib) );
  241.       newnode = new_attrib_node( GL_LIGHTING_BIT );
  242.       newnode->data = attr;
  243.       newnode->next = head;
  244.       head = newnode;
  245.    }
  246.  
  247.    if (mask & GL_LINE_BIT) {
  248.       struct gl_line_attrib *attr;
  249.       attr = MALLOC_STRUCT( gl_line_attrib );
  250.       MEMCPY( attr, &CC.Line, sizeof(struct gl_line_attrib) );
  251.       newnode = new_attrib_node( GL_LINE_BIT );
  252.       newnode->data = attr;
  253.       newnode->next = head;
  254.       head = newnode;
  255.    }
  256.  
  257.    if (mask & GL_LIST_BIT) {
  258.       struct gl_list_attrib *attr;
  259.       attr = MALLOC_STRUCT( gl_list_attrib );
  260.       MEMCPY( attr, &CC.List, sizeof(struct gl_list_attrib) );
  261.       newnode = new_attrib_node( GL_LIST_BIT );
  262.       newnode->data = attr;
  263.       newnode->next = head;
  264.       head = newnode;
  265.    }
  266.  
  267.    if (mask & GL_PIXEL_MODE_BIT) {
  268.       struct gl_pixel_attrib *attr;
  269.       attr = MALLOC_STRUCT( gl_pixel_attrib );
  270.       MEMCPY( attr, &CC.Pixel, sizeof(struct gl_pixel_attrib) );
  271.       newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
  272.       newnode->data = attr;
  273.       newnode->next = head;
  274.       head = newnode;
  275.    }
  276.  
  277.    if (mask & GL_POINT_BIT) {
  278.       struct gl_point_attrib *attr;
  279.       attr = MALLOC_STRUCT( gl_point_attrib );
  280.       MEMCPY( attr, &CC.Point, sizeof(struct gl_point_attrib) );
  281.       newnode = new_attrib_node( GL_POINT_BIT );
  282.       newnode->data = attr;
  283.       newnode->next = head;
  284.       head = newnode;
  285.    }
  286.  
  287.    if (mask & GL_POLYGON_BIT) {
  288.       struct gl_polygon_attrib *attr;
  289.       attr = MALLOC_STRUCT( gl_polygon_attrib );
  290.       MEMCPY( attr, &CC.Polygon, sizeof(struct gl_polygon_attrib) );
  291.       newnode = new_attrib_node( GL_POLYGON_BIT );
  292.       newnode->data = attr;
  293.       newnode->next = head;
  294.       head = newnode;
  295.    }
  296.  
  297.    if (mask & GL_POLYGON_STIPPLE_BIT) {
  298.       GLuint *stipple;
  299.       stipple = (GLuint *) malloc( 32*sizeof(GLuint) );
  300.       MEMCPY( stipple, CC.PolygonStipple, 32*sizeof(GLuint) );
  301.       newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
  302.       newnode->data = stipple;
  303.       newnode->next = head;
  304.       head = newnode;
  305.    }
  306.  
  307.    if (mask & GL_SCISSOR_BIT) {
  308.       struct gl_scissor_attrib *attr;
  309.       attr = MALLOC_STRUCT( gl_scissor_attrib );
  310.       MEMCPY( attr, &CC.Scissor, sizeof(struct gl_scissor_attrib) );
  311.       newnode = new_attrib_node( GL_SCISSOR_BIT );
  312.       newnode->data = attr;
  313.       newnode->next = head;
  314.       head = newnode;
  315.    }
  316.  
  317.    if (mask & GL_STENCIL_BUFFER_BIT) {
  318.       struct gl_stencil_attrib *attr;
  319.       attr = MALLOC_STRUCT( gl_stencil_attrib );
  320.       MEMCPY( attr, &CC.Stencil, sizeof(struct gl_stencil_attrib) );
  321.       newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
  322.       newnode->data = attr;
  323.       newnode->next = head;
  324.       head = newnode;
  325.    }
  326.  
  327.    if (mask & GL_TEXTURE_BIT) {
  328.       struct gl_texture_attrib *attr;
  329.       attr = MALLOC_STRUCT( gl_texture_attrib );
  330.       MEMCPY( attr, &CC.Texture, sizeof(struct gl_texture_attrib) );
  331.       newnode = new_attrib_node( GL_TEXTURE_BIT );
  332.       newnode->data = attr;
  333.       newnode->next = head;
  334.       head = newnode;
  335.    }
  336.  
  337.    if (mask & GL_TRANSFORM_BIT) {
  338.       struct gl_transform_attrib *attr;
  339.       attr = MALLOC_STRUCT( gl_transform_attrib );
  340.       MEMCPY( attr, &CC.Transform, sizeof(struct gl_transform_attrib) );
  341.       newnode = new_attrib_node( GL_TRANSFORM_BIT );
  342.       newnode->data = attr;
  343.       newnode->next = head;
  344.       head = newnode;
  345.    }
  346.  
  347.    if (mask & GL_VIEWPORT_BIT) {
  348.       struct gl_viewport_attrib *attr;
  349.       attr = MALLOC_STRUCT( gl_viewport_attrib );
  350.       MEMCPY( attr, &CC.Viewport, sizeof(struct gl_viewport_attrib) );
  351.       newnode = new_attrib_node( GL_VIEWPORT_BIT );
  352.       newnode->data = attr;
  353.       newnode->next = head;
  354.       head = newnode;
  355.    }
  356.  
  357.    /* etc... */
  358.  
  359.    CC.AttribStack[CC.AttribStackDepth] = head;
  360.    CC.AttribStackDepth++;
  361. }
  362.  
  363.  
  364.  
  365. void gl_pop_attrib( void )
  366. {
  367.    struct gl_attrib_node *attr, *next;
  368.    struct gl_enable_attrib *enable;
  369.    GLuint i;
  370.  
  371.    if (INSIDE_BEGIN_END) {
  372.       gl_error( GL_INVALID_OPERATION, "glPopAttrib" );
  373.       return;
  374.    }
  375.  
  376.    if (CC.AttribStackDepth==0) {
  377.       gl_error( GL_STACK_UNDERFLOW, "glPopAttrib" );
  378.       return;
  379.    }
  380.  
  381.    CC.AttribStackDepth--;
  382.    attr = CC.AttribStack[CC.AttribStackDepth];
  383.  
  384.    while (attr) {
  385.       switch (attr->kind) {
  386.          case GL_ACCUM_BUFFER_BIT:
  387.             MEMCPY( &CC.Accum, attr->data, sizeof(struct gl_accum_attrib) );
  388.             break;
  389.          case GL_COLOR_BUFFER_BIT:
  390.             MEMCPY( &CC.Color, attr->data,
  391.             sizeof(struct gl_colorbuffer_attrib) );
  392.             break;
  393.          case GL_CURRENT_BIT:
  394.             MEMCPY( &CC.Current, attr->data,
  395.             sizeof(struct gl_current_attrib) );
  396.             break;
  397.          case GL_DEPTH_BUFFER_BIT:
  398.             MEMCPY( &CC.Depth, attr->data,
  399.             sizeof(struct gl_depthbuffer_attrib) );
  400.             break;
  401.          case GL_ENABLE_BIT:
  402.             enable = (struct gl_enable_attrib *) attr->data;
  403.             CC.Color.AlphaEnabled = enable->AlphaTest;
  404.             CC.Transform.Normalize = enable->AutoNormal;
  405.             CC.Color.BlendEnabled = enable->Blend;
  406.         for (i=0;i<MAX_CLIP_PLANES;i++) {
  407.                CC.Transform.ClipEnabled[i] = enable->ClipPlane[i];
  408.         }
  409.         CC.Light.ColorMaterialEnabled = enable->ColorMaterial;
  410.         CC.Polygon.CullFlag = enable->CullFace;
  411.         CC.Depth.Test = enable->DepthTest;
  412.         CC.Color.DitherFlag = enable->Dither;
  413.         CC.Fog.Enabled = enable->Fog;
  414.             CC.Light.LastEnabled = -1;
  415.         for (i=0;i<MAX_LIGHTS;i++) {
  416.            CC.Light.Light[i].Enabled = enable->Light[i];
  417.                if (enable->Light[i]) {
  418.                   CC.Light.LastEnabled = i;
  419.                }
  420.         }
  421.         CC.Light.Enabled = enable->Lighting;
  422.         CC.Line.SmoothFlag = enable->LineSmooth;
  423.         CC.Line.StippleFlag = enable->LineStipple;
  424.         CC.Color.LogicOpEnabled = enable->LogicOp;
  425.         CC.Eval.Map1Color4 = enable->Map1Color4;
  426.         CC.Eval.Map1Index = enable->Map1Index;
  427.         CC.Eval.Map1Normal = enable->Map1Normal;
  428.         CC.Eval.Map1TextureCoord1 = enable->Map1TextureCoord1;
  429.         CC.Eval.Map1TextureCoord2 = enable->Map1TextureCoord2;
  430.         CC.Eval.Map1TextureCoord3 = enable->Map1TextureCoord3;
  431.         CC.Eval.Map1TextureCoord4 = enable->Map1TextureCoord4;
  432.         CC.Eval.Map1Vertex3 = enable->Map1Vertex3;
  433.         CC.Eval.Map1Vertex4 = enable->Map1Vertex4;
  434.         CC.Eval.Map2Color4 = enable->Map2Color4;
  435.         CC.Eval.Map2Index = enable->Map2Index;
  436.         CC.Eval.Map2Normal = enable->Map2Normal;
  437.         CC.Eval.Map2TextureCoord1 = enable->Map2TextureCoord1;
  438.         CC.Eval.Map2TextureCoord2 = enable->Map2TextureCoord2;
  439.         CC.Eval.Map2TextureCoord3 = enable->Map2TextureCoord3;
  440.         CC.Eval.Map2TextureCoord4 = enable->Map2TextureCoord4;
  441.         CC.Eval.Map2Vertex3 = enable->Map2Vertex3;
  442.         CC.Eval.Map2Vertex4 = enable->Map2Vertex4;
  443.         CC.Transform.Normalize = enable->Normalize;
  444.         CC.Point.SmoothFlag = enable->PointSmooth;
  445.         CC.Polygon.OffsetEnabled = enable->PolygonOffset;
  446.         CC.Polygon.SmoothFlag = enable->PolygonSmooth;
  447.         CC.Polygon.StippleFlag = enable->PolygonStipple;
  448.         CC.Scissor.Enabled = enable->Scissor;
  449.         CC.Stencil.Enabled = enable->Stencil;
  450.         CC.Texture.Enabled = enable->Texture;
  451.         CC.Texture.TexGenEnabled = enable->TexGen;
  452.             break;
  453.          case GL_EVAL_BIT:
  454.             MEMCPY( &CC.Eval, attr->data, sizeof(struct gl_eval_attrib) );
  455.             break;
  456.          case GL_FOG_BIT:
  457.             MEMCPY( &CC.Fog, attr->data, sizeof(struct gl_fog_attrib) );
  458.             break;
  459.          case GL_HINT_BIT:
  460.             MEMCPY( &CC.Hint, attr->data, sizeof(struct gl_hint_attrib) );
  461.             break;
  462.          case GL_LIGHTING_BIT:
  463.             MEMCPY( &CC.Light, attr->data, sizeof(struct gl_light_attrib) );
  464.             break;
  465.          case GL_LINE_BIT:
  466.             MEMCPY( &CC.Line, attr->data, sizeof(struct gl_line_attrib) );
  467.             break;
  468.          case GL_LIST_BIT:
  469.             MEMCPY( &CC.List, attr->data, sizeof(struct gl_list_attrib) );
  470.             break;
  471.          case GL_PIXEL_MODE_BIT:
  472.             MEMCPY( &CC.Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
  473.             break;
  474.          case GL_POINT_BIT:
  475.             MEMCPY( &CC.Point, attr->data, sizeof(struct gl_point_attrib) );
  476.             break;
  477.          case GL_POLYGON_BIT:
  478.             MEMCPY( &CC.Polygon, attr->data,
  479.             sizeof(struct gl_polygon_attrib) );
  480.             break;
  481.      case GL_POLYGON_STIPPLE_BIT:
  482.         MEMCPY( CC.PolygonStipple, attr->data, 32*sizeof(GLuint) );
  483.         break;
  484.          case GL_SCISSOR_BIT:
  485.             MEMCPY( &CC.Scissor, attr->data,
  486.             sizeof(struct gl_scissor_attrib) );
  487.             break;
  488.          case GL_STENCIL_BUFFER_BIT:
  489.             MEMCPY( &CC.Stencil, attr->data,
  490.             sizeof(struct gl_stencil_attrib) );
  491.             break;
  492.          case GL_TRANSFORM_BIT:
  493.             MEMCPY( &CC.Transform, attr->data,
  494.             sizeof(struct gl_transform_attrib) );
  495.             break;
  496.          case GL_TEXTURE_BIT:
  497.             MEMCPY( &CC.Texture, attr->data,
  498.             sizeof(struct gl_texture_attrib) );
  499.             break;
  500.          case GL_VIEWPORT_BIT:
  501.             MEMCPY( &CC.Viewport, attr->data,
  502.             sizeof(struct gl_viewport_attrib) );
  503.             break;
  504.          default:
  505.             /* ERROR! */
  506.             break;
  507.       }
  508.  
  509.       next = attr->next;
  510.       free( (void *) attr->data );
  511.       free( (void *) attr );
  512.       attr = next;
  513.    }
  514.  
  515.    CC.NewState = GL_TRUE;
  516. }
  517.  
  518.  
  519.  
  520. void glPushAttrib( GLbitfield mask )
  521. {
  522.    if (CC.CompileFlag) {
  523.       gl_save_pushattrib( mask );
  524.    }
  525.    if (CC.ExecuteFlag) {
  526.       gl_push_attrib( mask );
  527.    }
  528. }
  529.  
  530.  
  531.  
  532. void glPopAttrib( void )
  533. {
  534.    if (CC.CompileFlag) {
  535.       gl_save_popattrib();
  536.    }
  537.    if (CC.ExecuteFlag) {
  538.       gl_pop_attrib();
  539.    }
  540. }
  541.