1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the "Software"),
8848b8605Smrg * to deal in the Software without restriction, including without limitation
9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
11848b8605Smrg * Software is furnished to do so, subject to the following conditions:
12848b8605Smrg *
13848b8605Smrg * The above copyright notice and this permission notice shall be included
14848b8605Smrg * in all copies or substantial portions of the Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
23848b8605Smrg */
24848b8605Smrg
25848b8605Smrg
26848b8605Smrg#include "glheader.h"
27848b8605Smrg#include "context.h"
28848b8605Smrg#include "fog.h"
29848b8605Smrg#include "macros.h"
30848b8605Smrg#include "mtypes.h"
31848b8605Smrg
32848b8605Smrg
33848b8605Smrg
34848b8605Smrgvoid GLAPIENTRY
35848b8605Smrg_mesa_Fogf(GLenum pname, GLfloat param)
36848b8605Smrg{
37848b8605Smrg   GLfloat fparam[4];
38848b8605Smrg   fparam[0] = param;
39848b8605Smrg   fparam[1] = fparam[2] = fparam[3] = 0.0F;
40848b8605Smrg   _mesa_Fogfv(pname, fparam);
41848b8605Smrg}
42848b8605Smrg
43848b8605Smrg
44848b8605Smrgvoid GLAPIENTRY
45848b8605Smrg_mesa_Fogi(GLenum pname, GLint param )
46848b8605Smrg{
47848b8605Smrg   GLfloat fparam[4];
48848b8605Smrg   fparam[0] = (GLfloat) param;
49848b8605Smrg   fparam[1] = fparam[2] = fparam[3] = 0.0F;
50848b8605Smrg   _mesa_Fogfv(pname, fparam);
51848b8605Smrg}
52848b8605Smrg
53848b8605Smrg
54848b8605Smrgvoid GLAPIENTRY
55848b8605Smrg_mesa_Fogiv(GLenum pname, const GLint *params )
56848b8605Smrg{
57848b8605Smrg   GLfloat p[4];
58848b8605Smrg   switch (pname) {
59848b8605Smrg      case GL_FOG_MODE:
60848b8605Smrg      case GL_FOG_DENSITY:
61848b8605Smrg      case GL_FOG_START:
62848b8605Smrg      case GL_FOG_END:
63848b8605Smrg      case GL_FOG_INDEX:
64848b8605Smrg      case GL_FOG_COORDINATE_SOURCE_EXT:
65b8e80941Smrg      case GL_FOG_DISTANCE_MODE_NV:
66848b8605Smrg	 p[0] = (GLfloat) *params;
67848b8605Smrg	 break;
68848b8605Smrg      case GL_FOG_COLOR:
69848b8605Smrg	 p[0] = INT_TO_FLOAT( params[0] );
70848b8605Smrg	 p[1] = INT_TO_FLOAT( params[1] );
71848b8605Smrg	 p[2] = INT_TO_FLOAT( params[2] );
72848b8605Smrg	 p[3] = INT_TO_FLOAT( params[3] );
73848b8605Smrg	 break;
74848b8605Smrg      default:
75848b8605Smrg         /* Error will be caught later in _mesa_Fogfv */
76848b8605Smrg         ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
77848b8605Smrg   }
78848b8605Smrg   _mesa_Fogfv(pname, p);
79848b8605Smrg}
80848b8605Smrg
81848b8605Smrg
82848b8605Smrgvoid GLAPIENTRY
83848b8605Smrg_mesa_Fogfv( GLenum pname, const GLfloat *params )
84848b8605Smrg{
85848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
86848b8605Smrg   GLenum m;
87848b8605Smrg
88848b8605Smrg   switch (pname) {
89848b8605Smrg      case GL_FOG_MODE:
90848b8605Smrg         m = (GLenum) (GLint) *params;
91848b8605Smrg	 switch (m) {
92848b8605Smrg	 case GL_LINEAR:
93b8e80941Smrg	    ctx->Fog._PackedMode = FOG_LINEAR;
94b8e80941Smrg	    break;
95848b8605Smrg	 case GL_EXP:
96b8e80941Smrg	    ctx->Fog._PackedMode = FOG_EXP;
97b8e80941Smrg	    break;
98848b8605Smrg	 case GL_EXP2:
99b8e80941Smrg	    ctx->Fog._PackedMode = FOG_EXP2;
100848b8605Smrg	    break;
101848b8605Smrg	 default:
102848b8605Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glFog" );
103848b8605Smrg            return;
104848b8605Smrg	 }
105848b8605Smrg	 if (ctx->Fog.Mode == m)
106848b8605Smrg	    return;
107848b8605Smrg	 FLUSH_VERTICES(ctx, _NEW_FOG);
108848b8605Smrg	 ctx->Fog.Mode = m;
109b8e80941Smrg	 ctx->Fog._PackedEnabledMode = ctx->Fog.Enabled ?
110b8e80941Smrg				       ctx->Fog._PackedMode : FOG_NONE;
111848b8605Smrg	 break;
112848b8605Smrg      case GL_FOG_DENSITY:
113b8e80941Smrg	 if (*params<0.0F) {
114848b8605Smrg	    _mesa_error( ctx, GL_INVALID_VALUE, "glFog" );
115848b8605Smrg            return;
116848b8605Smrg	 }
117848b8605Smrg	 if (ctx->Fog.Density == *params)
118848b8605Smrg	    return;
119848b8605Smrg	 FLUSH_VERTICES(ctx, _NEW_FOG);
120848b8605Smrg	 ctx->Fog.Density = *params;
121848b8605Smrg	 break;
122848b8605Smrg      case GL_FOG_START:
123848b8605Smrg         if (ctx->Fog.Start == *params)
124848b8605Smrg            return;
125848b8605Smrg         FLUSH_VERTICES(ctx, _NEW_FOG);
126848b8605Smrg         ctx->Fog.Start = *params;
127848b8605Smrg         break;
128848b8605Smrg      case GL_FOG_END:
129848b8605Smrg         if (ctx->Fog.End == *params)
130848b8605Smrg            return;
131848b8605Smrg         FLUSH_VERTICES(ctx, _NEW_FOG);
132848b8605Smrg         ctx->Fog.End = *params;
133848b8605Smrg         break;
134848b8605Smrg      case GL_FOG_INDEX:
135848b8605Smrg         if (ctx->API != API_OPENGL_COMPAT)
136848b8605Smrg            goto invalid_pname;
137848b8605Smrg 	 if (ctx->Fog.Index == *params)
138848b8605Smrg	    return;
139848b8605Smrg	 FLUSH_VERTICES(ctx, _NEW_FOG);
140848b8605Smrg 	 ctx->Fog.Index = *params;
141848b8605Smrg	 break;
142848b8605Smrg      case GL_FOG_COLOR:
143848b8605Smrg	 if (TEST_EQ_4V(ctx->Fog.Color, params))
144848b8605Smrg	    return;
145848b8605Smrg	 FLUSH_VERTICES(ctx, _NEW_FOG);
146848b8605Smrg	 ctx->Fog.ColorUnclamped[0] = params[0];
147848b8605Smrg	 ctx->Fog.ColorUnclamped[1] = params[1];
148848b8605Smrg	 ctx->Fog.ColorUnclamped[2] = params[2];
149848b8605Smrg	 ctx->Fog.ColorUnclamped[3] = params[3];
150848b8605Smrg	 ctx->Fog.Color[0] = CLAMP(params[0], 0.0F, 1.0F);
151848b8605Smrg	 ctx->Fog.Color[1] = CLAMP(params[1], 0.0F, 1.0F);
152848b8605Smrg	 ctx->Fog.Color[2] = CLAMP(params[2], 0.0F, 1.0F);
153848b8605Smrg	 ctx->Fog.Color[3] = CLAMP(params[3], 0.0F, 1.0F);
154848b8605Smrg         break;
155848b8605Smrg      case GL_FOG_COORDINATE_SOURCE_EXT: {
156848b8605Smrg	 GLenum p = (GLenum) (GLint) *params;
157848b8605Smrg         if (ctx->API != API_OPENGL_COMPAT ||
158848b8605Smrg             (p != GL_FOG_COORDINATE_EXT && p != GL_FRAGMENT_DEPTH_EXT)) {
159848b8605Smrg	    _mesa_error(ctx, GL_INVALID_ENUM, "glFog");
160848b8605Smrg	    return;
161848b8605Smrg	 }
162848b8605Smrg	 if (ctx->Fog.FogCoordinateSource == p)
163848b8605Smrg	    return;
164848b8605Smrg	 FLUSH_VERTICES(ctx, _NEW_FOG);
165848b8605Smrg	 ctx->Fog.FogCoordinateSource = p;
166848b8605Smrg	 break;
167848b8605Smrg      }
168848b8605Smrg      case GL_FOG_DISTANCE_MODE_NV: {
169848b8605Smrg	 GLenum p = (GLenum) (GLint) *params;
170848b8605Smrg         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.NV_fog_distance ||
171848b8605Smrg             (p != GL_EYE_RADIAL_NV && p != GL_EYE_PLANE && p != GL_EYE_PLANE_ABSOLUTE_NV)) {
172848b8605Smrg	    _mesa_error(ctx, GL_INVALID_ENUM, "glFog");
173848b8605Smrg	    return;
174848b8605Smrg	 }
175848b8605Smrg	 if (ctx->Fog.FogDistanceMode == p)
176848b8605Smrg	    return;
177848b8605Smrg	 FLUSH_VERTICES(ctx, _NEW_FOG);
178848b8605Smrg	 ctx->Fog.FogDistanceMode = p;
179848b8605Smrg	 break;
180848b8605Smrg      }
181848b8605Smrg      default:
182848b8605Smrg         goto invalid_pname;
183848b8605Smrg   }
184848b8605Smrg
185848b8605Smrg   if (ctx->Driver.Fogfv) {
186b8e80941Smrg      ctx->Driver.Fogfv( ctx, pname, params );
187848b8605Smrg   }
188848b8605Smrg
189848b8605Smrg   return;
190848b8605Smrg
191848b8605Smrginvalid_pname:
192848b8605Smrg   _mesa_error( ctx, GL_INVALID_ENUM, "glFog" );
193848b8605Smrg   return;
194848b8605Smrg}
195848b8605Smrg
196848b8605Smrg
197848b8605Smrg/**********************************************************************/
198848b8605Smrg/*****                      Initialization                        *****/
199848b8605Smrg/**********************************************************************/
200848b8605Smrg
201848b8605Smrgvoid _mesa_init_fog( struct gl_context * ctx )
202848b8605Smrg{
203848b8605Smrg   /* Fog group */
204848b8605Smrg   ctx->Fog.Enabled = GL_FALSE;
205848b8605Smrg   ctx->Fog.Mode = GL_EXP;
206b8e80941Smrg   ctx->Fog._PackedMode = FOG_EXP;
207b8e80941Smrg   ctx->Fog._PackedEnabledMode = FOG_NONE;
208848b8605Smrg   ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
209848b8605Smrg   ASSIGN_4V( ctx->Fog.ColorUnclamped, 0.0, 0.0, 0.0, 0.0 );
210848b8605Smrg   ctx->Fog.Index = 0.0;
211848b8605Smrg   ctx->Fog.Density = 1.0;
212848b8605Smrg   ctx->Fog.Start = 0.0;
213848b8605Smrg   ctx->Fog.End = 1.0;
214848b8605Smrg   ctx->Fog.ColorSumEnabled = GL_FALSE;
215848b8605Smrg   ctx->Fog.FogCoordinateSource = GL_FRAGMENT_DEPTH_EXT;
216848b8605Smrg   ctx->Fog.FogDistanceMode = GL_EYE_PLANE_ABSOLUTE_NV;
217848b8605Smrg}
218