home *** CD-ROM | disk | FTP | other *** search
- /* context.c */
-
- /*
- * Mesa 3-D graphics library
- * Version: 1.2
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- $Id: context.c,v 1.32 1995/11/22 13:35:00 brianp Exp $
-
- $Log: context.c,v $
- * Revision 1.32 1995/11/22 13:35:00 brianp
- * added MutableColors flag, test for RGBA mode before setting GAMMA_BIT
- *
- * Revision 1.31 1995/11/08 22:09:05 brianp
- * changed GL<type> assertions from == to >=
- *
- * Revision 1.30 1995/11/03 17:41:05 brianp
- * removed unused variables
- *
- * Revision 1.29 1995/11/01 21:44:15 brianp
- * added CC.Light.LastEnabled
- *
- * Revision 1.28 1995/10/27 20:28:27 brianp
- * added glPolygonOffsetEXT() support
- *
- * Revision 1.27 1995/10/19 15:45:20 brianp
- * added gamma support
- * new arguments to gl_new_context()
- *
- * Revision 1.26 1995/10/14 16:26:13 brianp
- * enable dithering by default
- * added SWmasking code
- *
- * Revision 1.25 1995/09/25 16:31:54 brianp
- * reorganized front and back material indexing
- *
- * Revision 1.24 1995/09/15 18:47:32 brianp
- * introduced CC.NewState convention
- * use bitmask flag for CC.Texture.TexGenEnabled
- *
- * Revision 1.23 1995/07/25 16:41:54 brianp
- * made changes for using CC.VertexFunc pointer
- *
- * Revision 1.22 1995/07/24 20:34:16 brianp
- * replaced memset() with MEMSET() and memcpy() with MEMCPY()
- *
- * Revision 1.21 1995/06/19 14:52:37 brianp
- * initialize current texture coordinate, per Asif Khan
- *
- * Revision 1.20 1995/06/05 20:26:24 brianp
- * added Unfilled field to gl_polygon struct
- *
- * Revision 1.19 1995/05/22 21:02:41 brianp
- * Release 1.2
- *
- * Revision 1.18 1995/05/17 13:52:37 brianp
- * implemented glIndexMask(0) and glColorMask(0,0,0,0)
- *
- * Revision 1.17 1995/05/17 13:17:22 brianp
- * changed default CC.Mode value to allow use of real OpenGL headers
- * removed need for CC.MajorMode variable
- *
- * Revision 1.16 1995/05/15 16:07:01 brianp
- * implemented shared/nonshared display lists
- *
- * Revision 1.15 1995/05/12 16:30:14 brianp
- * Texture images stored as bytes, not floats
- *
- * Revision 1.14 1995/04/17 13:51:19 brianp
- * added gl_copy_context() function
- *
- * Revision 1.13 1995/03/27 20:31:26 brianp
- * new Texture.Enabled scheme
- *
- * Revision 1.12 1995/03/24 16:59:56 brianp
- * added gl_update_pixel_logic
- *
- * Revision 1.11 1995/03/24 16:11:41 brianp
- * fixed logicop bug in gl_update_rasterflags
- *
- * Revision 1.10 1995/03/16 20:36:38 brianp
- * added call to gl_update_rasterflags in gl_set_context
- *
- * Revision 1.9 1995/03/10 16:26:43 brianp
- * updated for bleding extensions
- *
- * Revision 1.8 1995/03/09 21:40:14 brianp
- * added ModelViewInvValid initializer
- * added ComputePlane test to gl_update_rasterflags
- *
- * Revision 1.7 1995/03/09 19:07:16 brianp
- * added MESA_DEBUG env var support
- *
- * Revision 1.6 1995/03/08 15:10:02 brianp
- * added support for dd_logicop
- *
- * Revision 1.5 1995/03/04 19:29:44 brianp
- * 1.1 beta revision
- *
- * Revision 1.4 1995/03/02 19:17:54 brianp
- * new RasterMask logic, fixed some comments
- *
- * Revision 1.3 1995/02/27 22:48:28 brianp
- * modified for PB
- *
- * Revision 1.2 1995/02/24 15:19:23 brianp
- * *** empty log message ***
- *
- * Revision 1.1 1995/02/24 14:18:45 brianp
- * Initial revision
- *
- */
-
-
- /*
- * The gl_context structure holds the current state of the library.
- * Typically, there will be a gl_context structure associated with each
- * window into which we're rendering:
- * When we open a new rendering window we need a new gl_context.
- * When we close a rendering window we destroy its gl_context.
- * When we switch rendering to a different window we change gl_context.
- *
- * Throughout this implementation, references are made to CC which is
- * the Current Context. Some information is shared among all contexts:
- * Texture Images (incorrect?)
- * Display Lists (incorrect)
- * Evaluator definitions (incorrect?)
- */
-
-
-
- #include <assert.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "context.h"
- #include "dd.h"
- #include "draw.h"
- #include "eval.h"
- #include "lines.h"
- #include "list.h"
- #include "macros.h"
- #include "pb.h"
- #include "points.h"
- #include "polygons.h"
- #include "vb.h"
-
-
-
- /* Copy of Current Context (PUBLIC) */
- struct gl_context CC;
-
- /* Pointer to Current Context (PRIVATE) */
- static struct gl_context *CCptr = NULL;
-
-
-
-
- /*
- * Allocate and initialize a display list group.
- */
- static struct gl_list_group *alloc_display_list_group( void )
- {
- struct gl_list_group *lg;
- GLuint i;
-
- lg = (struct gl_list_group*) malloc( sizeof(struct gl_list_group) );
- for (i=0;i<MAX_DISPLAYLISTS;i++) {
- lg->List[i] = NULL;
- lg->Reserved[i] = GL_FALSE;
- }
- lg->RefCount = 0;
- return lg;
- }
-
-
-
- /*
- * Initialize the nth light. Note that the defaults for light 0 are
- * different than the other lights.
- */
- static void init_light( struct gl_light *l, GLuint n )
- {
- ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
- if (n==0) {
- ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
- ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
- }
- else {
- ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
- ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
- }
- ASSIGN_4V( l->Position, 0.0, 0.0, 1.0, 0.0 );
- ASSIGN_3V( l->NormPosition, 0.0, 0.0, 1.0 );
- ASSIGN_3V( l->Direction, 0.0, 0.0, -1.0 );
- l->SpotExponent = 0.0;
- l->SpotCutoff = 180.0;
- l->ConstantAttenuation = 1.0;
- l->LinearAttenuation = 0.0;
- l->QuadraticAttenuation = 0.0;
- l->Enabled = GL_FALSE;
- }
-
-
-
- static void init_lightmodel( struct gl_lightmodel *lm )
- {
- ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 );
- lm->LocalViewer = GL_FALSE;
- lm->TwoSide = GL_FALSE;
- }
-
-
- static void init_material( struct gl_material *m )
- {
- ASSIGN_4V( m->Ambient, 0.2, 0.2, 0.2, 1.0 );
- ASSIGN_4V( m->Diffuse, 0.8, 0.8, 0.8, 1.0 );
- ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 );
- ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 );
- m->Shininess = 0.0;
- m->AmbientIndex = 0;
- m->DiffuseIndex = 1;
- m->SpecularIndex = 1;
- }
-
-
-
- /*
- * Setup the gamma lookup tables for the given context by examining the
- * MESA_GAMMA environment variable.
- */
- static void init_gamma_tables( struct gl_context *c )
- {
- char *gamma;
- GLint i, n;
- GLdouble g;
-
- if (!c->RGBAflag) {
- return;
- }
-
- gamma = getenv("MESA_GAMMA");
- if (gamma) {
- sscanf( gamma, "%f %f %f", &c->RedGamma, &c->GreenGamma, &c->BlueGamma );
- if (c->RedGamma==0.0) c->RedGamma = 1.0;
- if (c->GreenGamma==0.0) c->GreenGamma = c->RedGamma;
- if (c->BlueGamma==0.0) c->BlueGamma = c->RedGamma;
- }
- else {
- c->RedGamma = c->GreenGamma = c->BlueGamma = 1.0;
- }
-
- /* red */
- n = (GLint) c->RedScale;
- g = 1.0 / c->RedGamma;
- for (i=0;i<=n;i++) {
- double x = (double) i / c->RedScale;
- c->RedRamp[i] = c->RedScale * pow(x,g) + 0.5;
- }
-
- /* green */
- n = (GLint) c->GreenScale;
- g = 1.0 / c->GreenGamma;
- for (i=0;i<=n;i++) {
- double x = (double) i / c->GreenScale;
- c->GreenRamp[i] = c->GreenScale * pow(x,g) + 0.5;
- }
-
- /* blue */
- n = (GLint) c->BlueScale;
- g = 1.0 / c->BlueGamma;
- for (i=0;i<=n;i++) {
- double x = (double) i / c->BlueScale;
- c->BlueRamp[i] = c->BlueScale * pow(x,g) + 0.5;
- }
- }
-
-
-
- /*
- * Initialize a gl_context structure to default values.
- */
- void gl_initialize_context( struct gl_context *c )
- {
- static GLfloat identity[16] = {
- 1.0, 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0
- };
- GLuint i;
-
- if (c) {
- ASSIGN_4V( c->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
-
- c->Color.IndexMask = 0xffffffff;
- c->Color.ColorMask = 0xf;
- c->Color.SWmasking = GL_FALSE;
- c->Color.ClearIndex = 0;
- ASSIGN_4V( c->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
- c->Color.DrawBuffer = GL_FRONT;
- c->Color.AlphaEnabled = GL_FALSE;
- c->Color.AlphaFunc = GL_ALWAYS;
- c->Color.AlphaRef = 0.0;
- c->Color.BlendEnabled = GL_FALSE;
- c->Color.BlendSrc = GL_ONE;
- c->Color.BlendDst = GL_ZERO;
- c->Color.BlendEquation = GL_FUNC_ADD_EXT;
- ASSIGN_4V( c->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
- c->Color.LogicOpEnabled = GL_FALSE;
- c->Color.SWLogicOpEnabled = GL_FALSE;
- c->Color.LogicOp = GL_COPY;
- c->Color.DitherFlag = GL_TRUE;
-
- c->Current.Index = 1;
- ASSIGN_3V( c->Current.Normal, 0.0, 0.0, 1.0 );
- ASSIGN_4V( c->Current.Color, 1.0, 1.0, 1.0, 1.0 );
- ASSIGN_4V( c->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
- c->Current.RasterPosValid = GL_TRUE;
- c->Current.RasterIndex = 1;
- ASSIGN_4V( c->Current.TexCoord, 0.0, 0.0, 0.0, 1.0 );
- ASSIGN_4V( c->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
- c->Current.EdgeFlag = GL_TRUE;
-
- c->Depth.Test = GL_FALSE;
- c->Depth.Clear = 1.0;
- c->Depth.Func = GL_LESS;
- c->Depth.Mask = GL_TRUE;
-
- c->Eval.Map1Color4 = GL_FALSE;
- c->Eval.Map1Index = GL_FALSE;
- c->Eval.Map1Normal = GL_FALSE;
- c->Eval.Map1TextureCoord1 = GL_FALSE;
- c->Eval.Map1TextureCoord2 = GL_FALSE;
- c->Eval.Map1TextureCoord3 = GL_FALSE;
- c->Eval.Map1TextureCoord4 = GL_FALSE;
- c->Eval.Map1Vertex3 = GL_FALSE;
- c->Eval.Map1Vertex4 = GL_FALSE;
- c->Eval.Map2Color4 = GL_FALSE;
- c->Eval.Map2Index = GL_FALSE;
- c->Eval.Map2Normal = GL_FALSE;
- c->Eval.Map2TextureCoord1 = GL_FALSE;
- c->Eval.Map2TextureCoord2 = GL_FALSE;
- c->Eval.Map2TextureCoord3 = GL_FALSE;
- c->Eval.Map2TextureCoord4 = GL_FALSE;
- c->Eval.Map2Vertex3 = GL_FALSE;
- c->Eval.Map2Vertex4 = GL_FALSE;
- c->Eval.AutoNormal = GL_FALSE;
- c->Eval.MapGrid1un = 1;
- c->Eval.MapGrid1u1 = 0.0;
- c->Eval.MapGrid1u2 = 1.0;
- c->Eval.MapGrid2un = 1;
- c->Eval.MapGrid2vn = 1;
- c->Eval.MapGrid2u1 = 0.0;
- c->Eval.MapGrid2u2 = 1.0;
- c->Eval.MapGrid2v1 = 0.0;
- c->Eval.MapGrid2v2 = 1.0;
-
- c->Fog.Enabled = GL_FALSE;
- c->Fog.Mode = GL_EXP;
- ASSIGN_4V( c->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
- c->Fog.Index = 0.0;
- c->Fog.Density = 1.0;
- c->Fog.Start = 0.0;
- c->Fog.End = 1.0;
-
- c->Hint.PerspectiveCorrection = GL_DONT_CARE;
- c->Hint.PointSmooth = GL_DONT_CARE;
- c->Hint.LineSmooth = GL_DONT_CARE;
- c->Hint.PolygonSmooth = GL_DONT_CARE;
- c->Hint.Fog = GL_DONT_CARE;
-
- for (i=0;i<MAX_LIGHTS;i++) {
- init_light( &c->Light.Light[i], i );
- }
- init_lightmodel( &c->Light.Model );
- init_material( &c->Light.Material[0] );
- init_material( &c->Light.Material[1] );
- c->Light.ShadeModel = GL_SMOOTH;
- c->Light.Enabled = GL_FALSE;
- c->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
- c->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
- c->Light.ColorMaterialEnabled = GL_FALSE;
- c->Light.LastEnabled = -1;
-
- c->Line.SmoothFlag = GL_FALSE;
- c->Line.StippleFlag = GL_FALSE;
- c->Line.Width = 1.0;
- c->Line.StipplePattern = 0xffff;
- c->Line.StippleFactor = 1;
-
- c->List.ListBase = 0;
-
- c->Pixel.RedBias = 0.0;
- c->Pixel.RedScale = 1.0;
- c->Pixel.GreenBias = 0.0;
- c->Pixel.GreenScale = 1.0;
- c->Pixel.BlueBias = 0.0;
- c->Pixel.BlueScale = 1.0;
- c->Pixel.AlphaBias = 0.0;
- c->Pixel.AlphaScale = 1.0;
- c->Pixel.DepthBias = 0.0;
- c->Pixel.DepthScale = 1.0;
- c->Pixel.IndexOffset = 0;
- c->Pixel.IndexShift = 0;
- c->Pixel.ZoomX = 1.0;
- c->Pixel.ZoomY = 1.0;
- c->Pixel.MapColorFlag = GL_FALSE;
- c->Pixel.MapStencilFlag = GL_FALSE;
- c->Pixel.MapStoSsize = 1;
- c->Pixel.MapItoIsize = 1;
- c->Pixel.MapItoRsize = 1;
- c->Pixel.MapItoGsize = 1;
- c->Pixel.MapItoBsize = 1;
- c->Pixel.MapItoAsize = 1;
- c->Pixel.MapRtoRsize = 1;
- c->Pixel.MapGtoGsize = 1;
- c->Pixel.MapBtoBsize = 1;
- c->Pixel.MapAtoAsize = 1;
- c->Pixel.MapStoS[0] = 0;
- c->Pixel.MapItoI[0] = 0;
- c->Pixel.MapItoR[0] = 0.0;
- c->Pixel.MapItoG[0] = 0.0;
- c->Pixel.MapItoB[0] = 0.0;
- c->Pixel.MapItoA[0] = 0.0;
- c->Pixel.MapRtoR[0] = 0.0;
- c->Pixel.MapGtoG[0] = 0.0;
- c->Pixel.MapBtoB[0] = 0.0;
- c->Pixel.MapAtoA[0] = 0.0;
-
- c->Point.SmoothFlag = GL_FALSE;
- c->Point.Size = 1.0;
-
- c->Polygon.CullFlag = GL_FALSE;
- c->Polygon.CullFaceMode = GL_BACK;
- c->Polygon.FrontFace = GL_CCW;
- c->Polygon.FrontMode = GL_FILL;
- c->Polygon.BackMode = GL_FILL;
- c->Polygon.Unfilled = GL_FALSE;
- c->Polygon.SmoothFlag = GL_FALSE;
- c->Polygon.StippleFlag = GL_FALSE;
- c->Polygon.OffsetFactor = 0.0;
- c->Polygon.OffsetBias = 0.0;
- c->Polygon.OffsetEnabled = GL_FALSE;
-
- MEMSET( c->PolygonStipple, 0xff, 32*sizeof(GLuint) );
-
- c->Scissor.Enabled = GL_FALSE;
- c->Scissor.X = 0;
- c->Scissor.Y = 0;
- c->Scissor.Width = 0;
- c->Scissor.Height = 0;
-
- c->Stencil.Enabled = GL_FALSE;
- c->Stencil.Function = GL_ALWAYS;
- c->Stencil.Ref = 0;
- c->Stencil.ValueMask = 0xffffffff;
- c->Stencil.FailFunc = GL_KEEP;
- c->Stencil.ZPassFunc = GL_KEEP;
- c->Stencil.ZFailFunc = GL_KEEP;
- c->Stencil.Clear = 0;
- c->Stencil.WriteMask = 0xffffffff;
-
- c->Texture.Enabled = 0;
- c->Texture.EnvMode = GL_MODULATE;
- ASSIGN_4V( c->Texture.EnvColor, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.BorderColor, 0.0, 0.0, 0.0, 0.0 );
- c->Texture.TexGenEnabled = 0;
- c->Texture.GenModeS = GL_EYE_LINEAR;
- c->Texture.GenModeT = GL_EYE_LINEAR;
- c->Texture.GenModeR = GL_EYE_LINEAR;
- c->Texture.GenModeQ = GL_EYE_LINEAR;
- ASSIGN_4V( c->Texture.ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( c->Texture.EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
- c->Texture.WrapS1D = GL_REPEAT;
- c->Texture.WrapT1D = GL_REPEAT;
- c->Texture.WrapS2D = GL_REPEAT;
- c->Texture.WrapT2D = GL_REPEAT;
- c->Texture.MinFilter1D = GL_NEAREST_MIPMAP_LINEAR;
- c->Texture.MagFilter1D = GL_LINEAR;
- c->Texture.MinFilter2D = GL_NEAREST_MIPMAP_LINEAR;
- c->Texture.MagFilter2D = GL_LINEAR;
-
- c->Transform.MatrixMode = GL_MODELVIEW;
- c->Transform.Normalize = GL_TRUE;
- for (i=0;i<MAX_CLIP_PLANES;i++) {
- c->Transform.ClipEnabled[i] = GL_FALSE;
- ASSIGN_4V( c->Transform.ClipEquation[i], 0.0, 0.0, 0.0, 0.0 );
- }
- c->Transform.AnyClip = GL_FALSE;
-
- c->Viewport.X = 0;
- c->Viewport.Y = 0;
- c->Viewport.Width = 0;
- c->Viewport.Height = 0;
- c->Viewport.Near = 0.0;
- c->Viewport.Far = 1.0;
- c->Viewport.Sx = 0.0; /* Sx, Tx, Sy, Ty are computed later */
- c->Viewport.Tx = 0.0;
- c->Viewport.Sy = 0.0;
- c->Viewport.Ty = 0.0;
- c->Viewport.Sz = 0.5;
- c->Viewport.Tz = 0.5;
-
- c->PackAlignment = 4;
- c->PackRowLength = 0;
- c->PackSkipPixels = 0;
- c->PackSkipRows = 0;
- c->PackSwapBytes = GL_FALSE;
- c->PackLSBFirst = GL_FALSE;
- c->UnpackAlignment = 4;
- c->UnpackRowLength = 0;
- c->UnpackSkipPixels = 0;
- c->UnpackSkipRows = 0;
- c->UnpackSwapBytes = GL_FALSE;
- c->UnpackLSBFirst = GL_FALSE;
- c->RenderMode = GL_RENDER;
-
- c->FeedbackType = GL_2D; /* TODO: verify */
- c->FeedbackBuffer = NULL;
- c->FeedbackBufferSize = 0;
- c->FeedbackCount = 0;
-
- c->SelectBuffer = NULL;
- c->SelectBufferSize = 0;
- c->SelectBufferCount = 0;
- c->SelectHits = 0;
- c->NameStackDepth = 0;
-
- c->AttribStackDepth = 0;
-
- c->NewState = GL_TRUE;
- c->Mode = GL_BITMAP;
-
- c->NeedNormals = GL_FALSE;
- c->FastDrawPixels = GL_TRUE;
-
- c->ModelViewStackDepth = 0;
- MEMCPY( c->ModelViewMatrix, identity, 16*sizeof(GLfloat) );
- MEMCPY( c->ModelViewInv, identity, 16*sizeof(GLfloat) );
- c->ModelViewInvValid = GL_TRUE;
-
- c->ProjectionStackDepth = 0;
- MEMCPY( c->ProjectionMatrix, identity, 16*sizeof(GLfloat) );
-
- c->TextureStackDepth = 0;
- MEMCPY( c->TextureMatrix, identity, 16*sizeof(GLfloat) );
- c->IdentityTexMat = GL_TRUE;
-
- for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
- c->TextureComponents1D[i] = 0;
- c->TextureWidth1D[i] = 0;
- c->TextureBorder1D[i] = 0;
- c->TextureImage1D[i] = NULL;
- c->TextureImage1DDeleteFlag[i] = GL_FALSE;
- c->TextureComponents2D[i] = 0;
- c->TextureWidth2D[i] = 0;
- c->TextureHeight2D[i] = 0;
- c->TextureBorder2D[i] = 0;
- c->TextureImage2D[i] = NULL;
- c->TextureImage2DDeleteFlag[i] = GL_FALSE;
- }
-
- c->VertexFunc = gl_execute_vertex;
- c->PointsFunc = NULL;
- c->LineFunc = NULL;
- c->PolygonFunc = NULL;
- c->AuxPolygonFunc = NULL;
-
- c->CallDepth = 0;
- c->ExecuteFlag = GL_TRUE;
- c->CompileFlag = GL_FALSE;
-
- c->BufferWidth = 0;
- c->BufferHeight = 0;
- c->DepthBuffer = NULL;
- c->AccumBuffer = NULL;
- c->StencilBuffer = NULL;
-
- c->ErrorValue = GL_NO_ERROR;
- }
- }
-
-
-
- /*
- * Allocate and initialize a gl_context structure.
- * Input: rgb_flag - GL_TRUE or GL_FALSE to indicate if using RGB mode
- * redscale, greenscale, bluescale, alphascale - if in RGB mode
- * these values are used to scale floating point color values
- * in [0,1] to integers in [0,scale]
- * db_flag - GL_TRUE or GL_FALSE to indicate if using double buffering
- * sharelist - another context to share display lists with or NULL
- */
- struct gl_context *gl_new_context( GLboolean rgb_flag,
- GLfloat redscale,
- GLfloat greenscale,
- GLfloat bluescale,
- GLfloat alphascale,
- GLboolean db_flag,
- struct gl_context *shareList )
- {
- struct gl_context *c;
-
- /* do some implementation tests */
- assert( sizeof(GLbyte) >= 1 );
- assert( sizeof(GLshort) >= 2 );
- assert( sizeof(GLint) >= 4 );
- assert( sizeof(GLubyte) >= 1 );
- assert( sizeof(GLushort) >= 2 );
- assert( sizeof(GLuint) >= 4 );
-
- gl_init_lists();
- gl_init_eval();
- gl_init_vb();
-
- c = (struct gl_context *) malloc( sizeof(struct gl_context) );
- if (c) {
- gl_initialize_context( c );
- c->RGBAflag = rgb_flag;
- c->RedScale = redscale;
- c->GreenScale = greenscale;
- c->BlueScale = bluescale;
- c->AlphaScale = alphascale;
- if (db_flag) {
- c->DBflag = GL_TRUE;
- c->Color.DrawBuffer = GL_BACK;
- c->Pixel.ReadBuffer = GL_BACK;
- }
- else {
- c->DBflag = GL_FALSE;
- c->Color.DrawBuffer = GL_FRONT;
- c->Pixel.ReadBuffer = GL_FRONT;
- }
- init_gamma_tables( c );
-
- if (shareList) {
- /* share the group of display lists of another context */
- c->ListGroup = shareList->ListGroup;
- c->ListGroup->RefCount++;
- }
- else {
- /* allocate new group of display lists */
- c->ListGroup = alloc_display_list_group();
- }
- }
- return c;
- }
-
-
-
- /*
- * Destroy a gl_context structure.
- */
- void gl_destroy_context( struct gl_context *c )
- {
- if (c) {
- if (c->DepthBuffer)
- free(c->DepthBuffer);
- if (c->AccumBuffer)
- free(c->AccumBuffer);
- c->ListGroup->RefCount--;
- if (c->ListGroup->RefCount==0) {
- /* free display list group */
- free( c->ListGroup );
- }
- free( (void *) c );
- if (c==CCptr) {
- CCptr = NULL;
- }
- }
- }
-
-
-
- /*
- * Set the current context.
- */
- void gl_set_context( struct gl_context *c )
- {
- if (c) {
- /* "write back" current context */
- if (CCptr) {
- MEMCPY( CCptr, &CC, sizeof(struct gl_context) );
- }
- /* "load" new context */
- CCptr = c;
- MEMCPY( &CC, c, sizeof(struct gl_context) );
- }
- gl_init_pb( GL_BITMAP );
- CC.NewState = GL_TRUE;
- }
-
-
-
- /*
- * Copy attribute groups from one context to another.
- * Input: src - source context
- * dst - destination context
- * mask - bitwise OR of GL_*_BIT flags
- */
- void gl_copy_context( struct gl_context *src, struct gl_context *dst,
- GLuint mask )
- {
- if (src==CCptr) {
- src = &CC;
- }
- else if (dst==CCptr) {
- dst = &CC;
- }
-
- if (mask & GL_ACCUM_BUFFER_BIT) {
- MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
- }
- if (mask & GL_COLOR_BUFFER_BIT) {
- MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
- }
- if (mask & GL_CURRENT_BIT) {
- MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
- }
- if (mask & GL_DEPTH_BUFFER_BIT) {
- MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
- }
- if (mask & GL_ENABLE_BIT) {
- /* no op */
- }
- if (mask & GL_EVAL_BIT) {
- MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
- }
- if (mask & GL_FOG_BIT) {
- MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
- }
- if (mask & GL_HINT_BIT) {
- MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
- }
- if (mask & GL_LIGHTING_BIT) {
- MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
- }
- if (mask & GL_LINE_BIT) {
- MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
- }
- if (mask & GL_LIST_BIT) {
- MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
- }
- if (mask & GL_PIXEL_MODE_BIT) {
- MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
- }
- if (mask & GL_POINT_BIT) {
- MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
- }
- if (mask & GL_POLYGON_BIT) {
- MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
- }
- if (mask & GL_POLYGON_STIPPLE_BIT) {
- MEMCPY( &dst->PolygonStipple, &src->PolygonStipple, 32*sizeof(GLuint) );
- }
- if (mask & GL_SCISSOR_BIT) {
- MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
- }
- if (mask & GL_STENCIL_BUFFER_BIT) {
- MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
- }
- if (mask & GL_TEXTURE_BIT) {
- MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
- }
- if (mask & GL_TRANSFORM_BIT) {
- MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
- }
- if (mask & GL_VIEWPORT_BIT) {
- MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
- }
- }
-
-
-
- /*
- * This is Mesa's error handler. Normally, all that's done is the updating
- * of the current error value. If Mesa is compiled with -DDEBUG or if the
- * environment variable "MESA_DEBUG" is defined then a real error message
- * is printed to stderr.
- * Input: error - the error value
- * s - a diagnostic string
- */
- void gl_error( GLenum error, char *s )
- {
- GLboolean debug;
-
- #ifdef DEBUG
- debug = GL_TRUE;
- #else
- if (getenv("MESA_DEBUG")) {
- debug = GL_TRUE;
- }
- else {
- debug = GL_FALSE;
- }
- #endif
-
- if (debug) {
- char errstr[1000];
-
- switch (error) {
- case GL_NO_ERROR:
- strcpy( errstr, "GL_NO_ERROR" );
- break;
- case GL_INVALID_VALUE:
- strcpy( errstr, "GL_INVALID_VALUE" );
- break;
- case GL_INVALID_ENUM:
- strcpy( errstr, "GL_INVALID_ENUM" );
- break;
- case GL_INVALID_OPERATION:
- strcpy( errstr, "GL_INVALID_OPERATION" );
- break;
- case GL_STACK_OVERFLOW:
- strcpy( errstr, "GL_STACK_OVERFLOW" );
- break;
- case GL_STACK_UNDERFLOW:
- strcpy( errstr, "GL_STACK_UNDERFLOW" );
- break;
- case GL_OUT_OF_MEMORY:
- strcpy( errstr, "GL_OUT_OF_MEMORY" );
- break;
- default:
- strcpy( errstr, "unknown" );
- break;
- }
- fprintf( stderr, "Mesa Error (%s): %s\n", errstr, s );
- }
-
- if (CC.ErrorValue==GL_NO_ERROR) {
- CC.ErrorValue = error;
- }
- }
-
-
-
- GLenum glGetError( void )
- {
- GLenum e;
-
- if (!CCptr) {
- /* No current context */
- return GL_NO_ERROR;
- }
-
- if (INSIDE_BEGIN_END) {
- gl_error( GL_INVALID_OPERATION, "glGetError" );
- return GL_INVALID_OPERATION;
- }
-
- e = CC.ErrorValue;
- CC.ErrorValue = GL_NO_ERROR;
- return e;
- }
-
-
-
- /*
- * Since the device driver may or may not support pixel logic ops we
- * have to make some extensive tests whenever glLogicOp, glBlendFunc,
- * glBlendEquation, glEn/Disable( GL_LOGIC_OP ), glEn/Disable( GL_BLEND ),
- * or glPopAttrib is called.
- */
- static void update_pixel_logic( void )
- {
- if (CC.RGBAflag) {
- /* RGBA mode blending w/ Logic Op */
- if (CC.Color.BlendEnabled && CC.Color.BlendEquation==GL_LOGIC_OP) {
- if ((*DD.logicop)( CC.Color.LogicOp )) {
- /* Device driver can do logic, don't have to do it in software */
- CC.Color.SWLogicOpEnabled = GL_FALSE;
- }
- else {
- /* Device driver can't do logic op so we do it in software */
- CC.Color.SWLogicOpEnabled = GL_TRUE;
- }
- }
- else {
- /* no logic op */
- (void) (*DD.logicop)( GL_COPY );
- CC.Color.SWLogicOpEnabled = GL_FALSE;
- }
- }
- else {
- /* CI mode Logic Op */
- if (CC.Color.LogicOpEnabled) {
- if ((*DD.logicop)( CC.Color.LogicOp )) {
- /* Device driver can do logic, don't have to do it in software */
- CC.Color.SWLogicOpEnabled = GL_FALSE;
- }
- else {
- /* Device driver can't do logic op so we do it in software */
- CC.Color.SWLogicOpEnabled = GL_TRUE;
- }
- }
- else {
- /* no logic op */
- (void) (*DD.logicop)( GL_COPY );
- CC.Color.SWLogicOpEnabled = GL_FALSE;
- }
- }
- }
-
-
-
- /*
- * Check if software implemented RGBA or Color Index masking is needed.
- */
- static void update_pixel_masking( void )
- {
- if (CC.RGBAflag) {
- if (CC.Color.ColorMask==0xf) {
- /* disable masking */
- (void) (*DD.color_mask)( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
- CC.Color.SWmasking = GL_FALSE;
- }
- else {
- /* Ask DD to do color masking, if it can't we'll do it in software */
- GLboolean red = (CC.Color.ColorMask & 8) ? GL_TRUE : GL_FALSE;
- GLboolean green = (CC.Color.ColorMask & 4) ? GL_TRUE : GL_FALSE;
- GLboolean blue = (CC.Color.ColorMask & 2) ? GL_TRUE : GL_FALSE;
- GLboolean alpha = (CC.Color.ColorMask & 1) ? GL_TRUE : GL_FALSE;
- if ((*DD.color_mask)( red, green, blue, alpha )) {
- CC.Color.SWmasking = GL_FALSE;
- }
- else {
- CC.Color.SWmasking = GL_TRUE;
- }
- }
- }
- else {
- if (CC.Color.IndexMask==0xffffffff) {
- /* disable masking */
- (void) (*DD.index_mask)( 0xffffffff );
- CC.Color.SWmasking = GL_FALSE;
- }
- else {
- /* Ask DD to do index masking, if it can't we'll do it in software */
- if ((*DD.index_mask)( CC.Color.IndexMask )) {
- CC.Color.SWmasking = GL_FALSE;
- }
- else {
- CC.Color.SWmasking = GL_TRUE;
- }
- }
- }
- }
-
-
-
- /*
- * Recompute the value of CC.RasterMask, CC.ClipMask, etc. according to
- * the current context.
- */
- static void update_rasterflags( void )
- {
- CC.RasterMask = 0;
-
- if (CC.Color.AlphaEnabled) CC.RasterMask |= ALPHA_BIT;
- if (CC.Color.BlendEnabled) CC.RasterMask |= BLEND_BIT;
- if (CC.Depth.Test) CC.RasterMask |= DEPTH_BIT;
- if (CC.Fog.Enabled) CC.RasterMask |= FOG_BIT;
- if (CC.Color.SWLogicOpEnabled) CC.RasterMask |= LOGIC_OP_BIT;
- if (CC.Scissor.Enabled) CC.RasterMask |= SCISSOR_BIT;
- if (CC.Stencil.Enabled) CC.RasterMask |= STENCIL_BIT;
- if (CC.Color.SWmasking) CC.RasterMask |= MASKING_BIT;
- if (CC.RGBAflag &&
- (CC.RedGamma!=1.0 ||
- CC.GreenGamma!=1.0 ||
- CC.BlueGamma!=1.0)) CC.RasterMask |= GAMMA_BIT;
-
- /* Recompute ClipMask (what has to be interpolated when clipping) */
- CC.ClipMask = 0;
- if (CC.Texture.Enabled) {
- CC.ClipMask |= CLIP_TEXTURE_BIT;
- }
- if (CC.Light.ShadeModel==GL_SMOOTH) {
- if (CC.RGBAflag) {
- CC.ClipMask |= CLIP_FCOLOR_BIT;
- if (CC.Light.Model.TwoSide) {
- CC.ClipMask |= CLIP_BCOLOR_BIT;
- }
- }
- else {
- CC.ClipMask |= CLIP_FINDEX_BIT;
- if (CC.Light.Model.TwoSide) {
- CC.ClipMask |= CLIP_BINDEX_BIT;
- }
- }
- }
-
-
- /* Check if the equation of the plane for polygons has to be computed. */
- CC.ComputePlane = CC.Depth.Test || CC.Polygon.CullFlag
- || CC.Light.Model.TwoSide || CC.Texture.Enabled
- || CC.Polygon.OffsetEnabled;
- }
-
-
-
- /*
- * If CC.NewState==GL_TRUE then this function MUST be called before
- * rendering any primitive. Basically, function pointers and miscellaneous
- * flags are updated to reflect the current state of the state machine.
- */
- void gl_update_state( void )
- {
- update_pixel_logic();
- update_pixel_masking();
- update_rasterflags();
-
- /* Check if normal vectors are needed */
- if (CC.Light.Enabled
- || (CC.Texture.GenModeS==GL_SPHERE_MAP
- && (CC.Texture.TexGenEnabled & S_BIT))
- || (CC.Texture.GenModeT==GL_SPHERE_MAP
- && (CC.Texture.TexGenEnabled & T_BIT))) {
- CC.NeedNormals = GL_TRUE;
- }
- else {
- CC.NeedNormals = GL_FALSE;
- }
-
- /* Check if incoming colors can be modified by rasterization */
- if ( CC.Color.BlendEnabled || (CC.RasterMask & GAMMA_BIT)
- || CC.Color.SWmasking) {
- CC.MutableColors = GL_TRUE;
- }
- else {
- CC.MutableColors = GL_FALSE;
- }
-
- gl_set_point_function();
- gl_set_line_function();
- gl_set_polygon_function();
-
- CC.NewState = GL_FALSE;
- }
-
-