1 /* $Id: fog.c,v 1.27 2000/10/31 18:09:44 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 _mesa_Fogf(GLenum pname
, GLfloat param
)
46 _mesa_Fogfv(pname
, ¶m
);
51 _mesa_Fogi(GLenum pname
, GLint param
)
53 GLfloat fparam
= (GLfloat
) param
;
54 _mesa_Fogfv(pname
, &fparam
);
59 _mesa_Fogiv(GLenum pname
, const GLint
*params
)
68 case GL_FOG_COORDINATE_SOURCE_EXT
:
69 p
[0] = (GLfloat
) *params
;
72 p
[0] = INT_TO_FLOAT( params
[0] );
73 p
[1] = INT_TO_FLOAT( params
[1] );
74 p
[2] = INT_TO_FLOAT( params
[2] );
75 p
[3] = INT_TO_FLOAT( params
[3] );
78 /* Error will be caught later in _mesa_Fogfv */
81 _mesa_Fogfv(pname
, p
);
86 _mesa_Fogfv( GLenum pname
, const GLfloat
*params
)
88 GET_CURRENT_CONTEXT(ctx
);
91 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glFog");
95 m
= (GLenum
) (GLint
) *params
;
96 if (m
==GL_LINEAR
|| m
==GL_EXP
|| m
==GL_EXP2
) {
100 gl_error( ctx
, GL_INVALID_ENUM
, "glFog" );
106 gl_error( ctx
, GL_INVALID_VALUE
, "glFog" );
110 ctx
->Fog
.Density
= *params
;
114 ctx
->Fog
.Start
= *params
;
117 ctx
->Fog
.End
= *params
;
120 ctx
->Fog
.Index
= *params
;
123 ctx
->Fog
.Color
[0] = params
[0];
124 ctx
->Fog
.Color
[1] = params
[1];
125 ctx
->Fog
.Color
[2] = params
[2];
126 ctx
->Fog
.Color
[3] = params
[3];
128 case GL_FOG_COORDINATE_SOURCE_EXT
: {
129 GLenum p
= (GLenum
)(GLint
) *params
;
130 if (p
== GL_FOG_COORDINATE_EXT
|| p
== GL_FRAGMENT_DEPTH_EXT
)
131 ctx
->Fog
.FogCoordinateSource
= p
;
133 gl_error( ctx
, GL_INVALID_ENUM
, "glFog" );
137 gl_error( ctx
, GL_INVALID_ENUM
, "glFog" );
141 if (ctx
->Driver
.Fogfv
) {
142 (*ctx
->Driver
.Fogfv
)( ctx
, pname
, params
);
145 ctx
->NewState
|= _NEW_FOG
;
152 static GLvector1f
*get_fogcoord_ptr( GLcontext
*ctx
, GLvector1f
*tmp
)
154 struct vertex_buffer
*VB
= ctx
->VB
;
156 if (ctx
->Fog
.FogCoordinateSource
== GL_FRAGMENT_DEPTH_EXT
) {
157 if (!ctx
->NeedEyeCoords
) {
158 GLfloat
*m
= ctx
->ModelView
.m
;
166 /* Full eye coords weren't required, just calculate the
169 gl_dotprod_tab
[0][VB
->ObjPtr
->size
](&VB
->Eye
, 2,
170 VB
->ObjPtr
, plane
, 0 );
172 tmp
->data
= &(VB
->Eye
.data
[0][2]);
173 tmp
->start
= VB
->Eye
.start
+2;
174 tmp
->stride
= VB
->Eye
.stride
;
179 if (VB
->EyePtr
->size
< 2)
180 gl_vector4f_clean_elem( &VB
->Eye
, VB
->Count
, 2 );
182 tmp
->data
= &(VB
->EyePtr
->data
[0][2]);
183 tmp
->start
= VB
->EyePtr
->start
+2;
184 tmp
->stride
= VB
->EyePtr
->stride
;
188 return VB
->FogCoordPtr
;
192 /* Use lookup table & interpolation?
195 make_win_fog_coords( struct vertex_buffer
*VB
,
196 GLvector1f
*fogcoord
)
198 const GLcontext
*ctx
= VB
->ctx
;
199 GLfloat end
= ctx
->Fog
.End
;
200 GLfloat
*v
= fogcoord
->start
;
201 GLuint stride
= fogcoord
->stride
;
202 GLuint n
= VB
->Count
- VB
->Start
;
207 VB
->FogCoordPtr
= VB
->store
.FogCoord
;
208 out
= VB
->FogCoordPtr
->data
+ VB
->Start
;
210 switch (ctx
->Fog
.Mode
) {
212 d
= 1.0F
/ (ctx
->Fog
.End
- ctx
->Fog
.Start
);
213 for ( i
= 0 ; i
< n
; i
++, STRIDE_F(v
, stride
)) {
214 out
[i
] = (end
- ABSF(*v
)) * d
;
215 if (0) fprintf(stderr
, "z %f out %f\n", *v
, out
[i
]);
219 d
= -ctx
->Fog
.Density
;
220 for ( i
= 0 ; i
< n
; i
++, STRIDE_F(v
,stride
)) {
221 out
[i
] = exp( d
*ABSF(*v
) );
222 if (0) fprintf(stderr
, "z %f out %f\n", *v
, out
[i
]);
226 d
= -(ctx
->Fog
.Density
*ctx
->Fog
.Density
);
227 for ( i
= 0 ; i
< n
; i
++, STRIDE_F(v
, stride
)) {
229 out
[i
] = exp( d
*z
*z
);
230 if (0) fprintf(stderr
, "z %f out %f\n", *v
, out
[i
]);
234 gl_problem(ctx
, "Bad fog mode in make_fog_coord");
241 _mesa_make_win_fog_coords( struct vertex_buffer
*VB
)
245 make_win_fog_coords( VB
, get_fogcoord_ptr( VB
->ctx
, &tmp
) );