2865e7e0d49fea87491b6d9a3f83ff2e532bfc93
1 /* $Id: rastpos.c,v 1.17 2000/11/27 18:22:13 brianp 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.
41 #include "simple_list.h"
44 #include "math/m_matrix.h"
45 #include "math/m_xform.h"
50 * Clip a point against the view volume.
51 * Input: v - vertex-vector describing the point to clip
52 * Return: 0 = outside view volume
53 * 1 = inside view volume
55 static GLuint
gl_viewclip_point( const GLfloat v
[] )
57 if ( v
[0] > v
[3] || v
[0] < -v
[3]
58 || v
[1] > v
[3] || v
[1] < -v
[3]
59 || v
[2] > v
[3] || v
[2] < -v
[3] ) {
68 * Clip a point against the user clipping planes.
69 * Input: v - vertex-vector describing the point to clip.
70 * Return: 0 = point was clipped
71 * 1 = point not clipped
73 static GLuint
gl_userclip_point( GLcontext
* ctx
, const GLfloat v
[] )
77 for (p
= 0; p
< ctx
->Const
.MaxClipPlanes
; p
++) {
78 if (ctx
->Transform
.ClipEnabled
[p
]) {
79 GLfloat dot
= v
[0] * ctx
->Transform
._ClipUserPlane
[p
][0]
80 + v
[1] * ctx
->Transform
._ClipUserPlane
[p
][1]
81 + v
[2] * ctx
->Transform
._ClipUserPlane
[p
][2]
82 + v
[3] * ctx
->Transform
._ClipUserPlane
[p
][3];
93 /* This has been split off to allow the normal shade routines to
94 * get a little closer to the vertex buffer, and to use the
95 * GLvector objects directly.
97 static void gl_shade_rastpos( GLcontext
*ctx
,
103 GLfloat (*base
)[3] = ctx
->Light
._BaseColor
;
104 const GLchan
*sumA
= ctx
->Light
._BaseAlpha
;
105 struct gl_light
*light
;
107 GLfloat diffuse
= 0, specular
= 0;
109 COPY_3V(color
, base
[0]);
110 color
[3] = CHAN_TO_FLOAT( sumA
[0] );
112 foreach (light
, &ctx
->Light
.EnabledList
) {
114 GLfloat attenuation
= 1.0;
119 GLboolean normalized
;
121 if (!(light
->_Flags
& LIGHT_POSITIONAL
)) {
122 COPY_3V(VP
, light
->_VP_inf_norm
);
123 attenuation
= light
->_VP_inf_spot_attenuation
;
128 SUB_3V(VP
, light
->_Position
, vertex
);
132 GLfloat invd
= 1.0F
/ d
;
133 SELF_SCALE_SCALAR_3V(VP
, invd
);
135 attenuation
= 1.0F
/ (light
->ConstantAttenuation
+ d
*
136 (light
->LinearAttenuation
+ d
*
137 light
->QuadraticAttenuation
));
139 if (light
->_Flags
& LIGHT_SPOT
)
141 GLfloat PV_dot_dir
= - DOT3(VP
, light
->_NormDirection
);
143 if (PV_dot_dir
<light
->_CosCutoff
) {
148 double x
= PV_dot_dir
* (EXP_TABLE_SIZE
-1);
150 GLfloat spot
= (GLfloat
) (light
->_SpotExpTable
[k
][0]
151 + (x
-k
)*light
->_SpotExpTable
[k
][1]);
157 if (attenuation
< 1e-3)
160 n_dot_VP
= DOT3( normal
, VP
);
162 if (n_dot_VP
< 0.0F
) {
163 ACC_SCALE_SCALAR_3V(color
, attenuation
, light
->_MatAmbient
[0]);
167 COPY_3V(contrib
, light
->_MatAmbient
[0]);
168 ACC_SCALE_SCALAR_3V(contrib
, n_dot_VP
, light
->_MatDiffuse
[0]);
169 diffuse
+= n_dot_VP
* light
->_dli
* attenuation
;
172 if (ctx
->Light
.Model
.LocalViewer
) {
180 else if (light
->_Flags
& LIGHT_POSITIONAL
) {
182 ACC_3V(h
, ctx
->_EyeZDir
);
186 h
= light
->_h_inf_norm
;
190 n_dot_h
= DOT3(normal
, h
);
192 if (n_dot_h
> 0.0F
) {
193 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
195 GLfloat shininess
= mat
->Shininess
;
199 n_dot_h
/= LEN_SQUARED_3FV( h
);
203 GET_SHINE_TAB_ENTRY( ctx
->_ShineTable
[0], n_dot_h
, spec_coef
);
205 if (spec_coef
> 1.0e-10) {
206 ACC_SCALE_SCALAR_3V( contrib
, spec_coef
,
207 light
->_MatSpecular
[0]);
208 specular
+= spec_coef
* light
->_sli
* attenuation
;
213 ACC_SCALE_SCALAR_3V( color
, attenuation
, contrib
);
216 if (ctx
->Visual
.RGBAflag
) {
217 Rcolor
[0] = CLAMP(color
[0], 0.0F
, 1.0F
);
218 Rcolor
[1] = CLAMP(color
[1], 0.0F
, 1.0F
);
219 Rcolor
[2] = CLAMP(color
[2], 0.0F
, 1.0F
);
220 Rcolor
[3] = CLAMP(color
[3], 0.0F
, 1.0F
);
223 struct gl_material
*mat
= &ctx
->Light
.Material
[0];
224 GLfloat d_a
= mat
->DiffuseIndex
- mat
->AmbientIndex
;
225 GLfloat s_a
= mat
->SpecularIndex
- mat
->AmbientIndex
;
226 GLfloat ind
= mat
->AmbientIndex
227 + diffuse
* (1.0F
-specular
) * d_a
229 if (ind
> mat
->SpecularIndex
) {
230 ind
= mat
->SpecularIndex
;
232 *index
= (GLuint
) (GLint
) ind
;
238 * Caller: context->API.RasterPos4f
240 static void raster_pos4f( GLcontext
*ctx
,
241 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
243 GLfloat v
[4], eye
[4], clip
[4], ndc
[3], d
;
245 /* KW: Added this test, which is in the spec. We can't do this
246 * inside begin/end any more because the ctx->Current values
247 * aren't uptodate during that period.
249 FLUSH_TNL_RETURN(ctx
, (FLUSH_INSIDE_BEGIN_END
|
250 FLUSH_STORED_VERTICES
|
251 FLUSH_UPDATE_CURRENT
), "raster_pos4f");
254 gl_update_state( ctx
);
256 ASSIGN_4V( v
, x
, y
, z
, w
);
257 TRANSFORM_POINT( eye
, ctx
->ModelView
.m
, v
);
260 if (ctx
->Light
.Enabled
)
262 GLfloat
*norm
, eyenorm
[3];
263 GLfloat
*objnorm
= ctx
->Current
.Normal
;
265 if (ctx
->_NeedEyeCoords
) {
266 GLfloat
*inv
= ctx
->ModelView
.inv
;
267 TRANSFORM_NORMAL( eyenorm
, objnorm
, inv
);
273 gl_shade_rastpos( ctx
, v
, norm
,
274 ctx
->Current
.RasterColor
,
275 &ctx
->Current
.RasterIndex
);
279 /* use current color or index */
280 if (ctx
->Visual
.RGBAflag
) {
281 ctx
->Current
.RasterColor
[0] = CHAN_TO_FLOAT(ctx
->Current
.Color
[0]);
282 ctx
->Current
.RasterColor
[1] = CHAN_TO_FLOAT(ctx
->Current
.Color
[1]);
283 ctx
->Current
.RasterColor
[2] = CHAN_TO_FLOAT(ctx
->Current
.Color
[2]);
284 ctx
->Current
.RasterColor
[3] = CHAN_TO_FLOAT(ctx
->Current
.Color
[3]);
287 ctx
->Current
.RasterIndex
= ctx
->Current
.Index
;
291 /* compute raster distance */
292 ctx
->Current
.RasterDistance
= (GLfloat
)
293 GL_SQRT( eye
[0]*eye
[0] + eye
[1]*eye
[1] + eye
[2]*eye
[2] );
295 /* apply projection matrix: clip = Proj * eye */
296 TRANSFORM_POINT( clip
, ctx
->ProjectionMatrix
.m
, eye
);
298 /* clip to view volume */
299 if (gl_viewclip_point( clip
)==0) {
300 ctx
->Current
.RasterPosValid
= GL_FALSE
;
304 /* clip to user clipping planes */
305 if ( ctx
->Transform
._AnyClip
&&
306 gl_userclip_point(ctx
, clip
) == 0)
308 ctx
->Current
.RasterPosValid
= GL_FALSE
;
313 ASSERT( clip
[3]!=0.0 );
315 ndc
[0] = clip
[0] * d
;
316 ndc
[1] = clip
[1] * d
;
317 ndc
[2] = clip
[2] * d
;
319 ctx
->Current
.RasterPos
[0] = (ndc
[0] * ctx
->Viewport
._WindowMap
.m
[MAT_SX
] +
320 ctx
->Viewport
._WindowMap
.m
[MAT_TX
]);
321 ctx
->Current
.RasterPos
[1] = (ndc
[1] * ctx
->Viewport
._WindowMap
.m
[MAT_SY
] +
322 ctx
->Viewport
._WindowMap
.m
[MAT_TY
]);
323 ctx
->Current
.RasterPos
[2] = (ndc
[2] * ctx
->Viewport
._WindowMap
.m
[MAT_SZ
] +
324 ctx
->Viewport
._WindowMap
.m
[MAT_TZ
]) / ctx
->Visual
.DepthMaxF
;
325 ctx
->Current
.RasterPos
[3] = clip
[3];
326 ctx
->Current
.RasterPosValid
= GL_TRUE
;
332 for (texSet
= 0; texSet
< ctx
->Const
.MaxTextureUnits
; texSet
++) {
333 COPY_4FV( ctx
->Current
.RasterMultiTexCoord
[texSet
],
334 ctx
->Current
.Texcoord
[texSet
] );
338 if (ctx
->RenderMode
==GL_SELECT
) {
339 gl_update_hitflag( ctx
, ctx
->Current
.RasterPos
[2] );
347 _mesa_RasterPos2d(GLdouble x
, GLdouble y
)
349 _mesa_RasterPos4f(x
, y
, 0.0F
, 1.0F
);
353 _mesa_RasterPos2f(GLfloat x
, GLfloat y
)
355 _mesa_RasterPos4f(x
, y
, 0.0F
, 1.0F
);
359 _mesa_RasterPos2i(GLint x
, GLint y
)
361 _mesa_RasterPos4f(x
, y
, 0.0F
, 1.0F
);
365 _mesa_RasterPos2s(GLshort x
, GLshort y
)
367 _mesa_RasterPos4f(x
, y
, 0.0F
, 1.0F
);
371 _mesa_RasterPos3d(GLdouble x
, GLdouble y
, GLdouble z
)
373 _mesa_RasterPos4f(x
, y
, z
, 1.0F
);
377 _mesa_RasterPos3f(GLfloat x
, GLfloat y
, GLfloat z
)
379 _mesa_RasterPos4f(x
, y
, z
, 1.0F
);
383 _mesa_RasterPos3i(GLint x
, GLint y
, GLint z
)
385 _mesa_RasterPos4f(x
, y
, z
, 1.0F
);
389 _mesa_RasterPos3s(GLshort x
, GLshort y
, GLshort z
)
391 _mesa_RasterPos4f(x
, y
, z
, 1.0F
);
395 _mesa_RasterPos4d(GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
397 _mesa_RasterPos4f(x
, y
, z
, w
);
401 _mesa_RasterPos4f(GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
403 GET_CURRENT_CONTEXT(ctx
);
404 raster_pos4f(ctx
, x
, y
, z
, w
);
408 _mesa_RasterPos4i(GLint x
, GLint y
, GLint z
, GLint w
)
410 _mesa_RasterPos4f(x
, y
, z
, w
);
414 _mesa_RasterPos4s(GLshort x
, GLshort y
, GLshort z
, GLshort w
)
416 _mesa_RasterPos4f(x
, y
, z
, w
);
420 _mesa_RasterPos2dv(const GLdouble
*v
)
422 _mesa_RasterPos4f(v
[0], v
[1], 0.0F
, 1.0F
);
426 _mesa_RasterPos2fv(const GLfloat
*v
)
428 _mesa_RasterPos4f(v
[0], v
[1], 0.0F
, 1.0F
);
432 _mesa_RasterPos2iv(const GLint
*v
)
434 _mesa_RasterPos4f(v
[0], v
[1], 0.0F
, 1.0F
);
438 _mesa_RasterPos2sv(const GLshort
*v
)
440 _mesa_RasterPos4f(v
[0], v
[1], 0.0F
, 1.0F
);
444 _mesa_RasterPos3dv(const GLdouble
*v
)
446 _mesa_RasterPos4f(v
[0], v
[1], v
[2], 1.0F
);
450 _mesa_RasterPos3fv(const GLfloat
*v
)
452 _mesa_RasterPos4f(v
[0], v
[1], v
[2], 1.0F
);
456 _mesa_RasterPos3iv(const GLint
*v
)
458 _mesa_RasterPos4f(v
[0], v
[1], v
[2], 1.0F
);
462 _mesa_RasterPos3sv(const GLshort
*v
)
464 _mesa_RasterPos4f(v
[0], v
[1], v
[2], 1.0F
);
468 _mesa_RasterPos4dv(const GLdouble
*v
)
470 _mesa_RasterPos4f(v
[0], v
[1], v
[2], v
[3]);
474 _mesa_RasterPos4fv(const GLfloat
*v
)
476 _mesa_RasterPos4f(v
[0], v
[1], v
[2], v
[3]);
480 _mesa_RasterPos4iv(const GLint
*v
)
482 _mesa_RasterPos4f(v
[0], v
[1], v
[2], v
[3]);
486 _mesa_RasterPos4sv(const GLshort
*v
)
488 _mesa_RasterPos4f(v
[0], v
[1], v
[2], v
[3]);