1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 
26 /**
27  * \file rastpos.c
28  * Raster position operations.
29  */
30 
31 #include "glheader.h"
32 #include "context.h"
33 #include "feedback.h"
34 #include "macros.h"
35 #include "mtypes.h"
36 #include "rastpos.h"
37 #include "state.h"
38 #include "main/light.h"
39 #include "main/viewport.h"
40 #include "util/bitscan.h"
41 
42 #include "state_tracker/st_cb_rasterpos.h"
43 #include "api_exec_decl.h"
44 
45 
46 /**
47  * Clip a point against the view volume.
48  *
49  * \param v vertex vector describing the point to clip.
50  *
51  * \return zero if outside view volume, or one if inside.
52  */
53 static GLuint
viewclip_point_xy(const GLfloat v[])54 viewclip_point_xy( const GLfloat v[] )
55 {
56    if (   v[0] > v[3] || v[0] < -v[3]
57        || v[1] > v[3] || v[1] < -v[3] ) {
58       return 0;
59    }
60    else {
61       return 1;
62    }
63 }
64 
65 
66 /**
67  * Clip a point against the near Z clipping planes.
68  *
69  * \param v vertex vector describing the point to clip.
70  *
71  * \return zero if outside view volume, or one if inside.
72  */
73 static GLuint
viewclip_point_near_z(const GLfloat v[])74 viewclip_point_near_z( const GLfloat v[] )
75 {
76    if (v[2] < -v[3]) {
77       return 0;
78    }
79    else {
80       return 1;
81    }
82 }
83 
84 
85 /**
86  * Clip a point against the far Z clipping planes.
87  *
88  * \param v vertex vector describing the point to clip.
89  *
90  * \return zero if outside view volume, or one if inside.
91  */
92 static GLuint
viewclip_point_far_z(const GLfloat v[])93 viewclip_point_far_z( const GLfloat v[] )
94 {
95    if (v[2] > v[3]) {
96       return 0;
97    }
98    else {
99       return 1;
100    }
101 }
102 
103 
104 /**
105  * Clip a point against the user clipping planes.
106  *
107  * \param ctx GL context.
108  * \param v vertex vector describing the point to clip.
109  *
110  * \return zero if the point was clipped, or one otherwise.
111  */
112 static GLuint
userclip_point(struct gl_context * ctx,const GLfloat v[])113 userclip_point( struct gl_context *ctx, const GLfloat v[] )
114 {
115    GLbitfield mask = ctx->Transform.ClipPlanesEnabled;
116    while (mask) {
117       const int p = u_bit_scan(&mask);
118       GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0]
119          + v[1] * ctx->Transform._ClipUserPlane[p][1]
120          + v[2] * ctx->Transform._ClipUserPlane[p][2]
121          + v[3] * ctx->Transform._ClipUserPlane[p][3];
122 
123       if (dot < 0.0F) {
124          return 0;
125       }
126    }
127 
128    return 1;
129 }
130 
131 
132 /**
133  * Compute lighting for the raster position.  RGB modes computed.
134  * \param ctx the context
135  * \param vertex vertex location
136  * \param normal normal vector
137  * \param Rcolor returned color
138  * \param Rspec returned specular color (if separate specular enabled)
139  */
140 static void
shade_rastpos(struct gl_context * ctx,const GLfloat vertex[4],const GLfloat normal[3],GLfloat Rcolor[4],GLfloat Rspec[4])141 shade_rastpos(struct gl_context *ctx,
142               const GLfloat vertex[4],
143               const GLfloat normal[3],
144               GLfloat Rcolor[4],
145               GLfloat Rspec[4])
146 {
147    /*const*/ GLfloat (*base)[3] = ctx->Light._BaseColor;
148    GLbitfield mask;
149    GLfloat diffuseColor[4], specularColor[4];  /* for RGB mode only */
150 
151    _mesa_update_light_materials(ctx);
152 
153    COPY_3V(diffuseColor, base[0]);
154    diffuseColor[3] = CLAMP(
155       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3], 0.0F, 1.0F );
156    ASSIGN_4V(specularColor, 0.0, 0.0, 0.0, 1.0);
157 
158    mask = ctx->Light._EnabledLights;
159    while (mask) {
160       const int i = u_bit_scan(&mask);
161       struct gl_light *light = &ctx->Light.Light[i];
162       struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
163       GLfloat attenuation = 1.0;
164       GLfloat VP[3]; /* vector from vertex to light pos */
165       GLfloat n_dot_VP;
166       GLfloat diffuseContrib[3], specularContrib[3];
167 
168       if (!(light->_Flags & LIGHT_POSITIONAL)) {
169          /* light at infinity */
170 	 COPY_3V(VP, light->_VP_inf_norm);
171 	 attenuation = light->_VP_inf_spot_attenuation;
172       }
173       else {
174          /* local/positional light */
175 	 GLfloat d;
176 
177          /* VP = vector from vertex pos to light[i].pos */
178 	 SUB_3V(VP, light->_Position, vertex);
179          /* d = length(VP) */
180 	 d = (GLfloat) LEN_3FV( VP );
181 	 if (d > 1.0e-6F) {
182             /* normalize VP */
183 	    GLfloat invd = 1.0F / d;
184 	    SELF_SCALE_SCALAR_3V(VP, invd);
185 	 }
186 
187          /* atti */
188 	 attenuation = 1.0F / (lu->ConstantAttenuation + d *
189 			       (lu->LinearAttenuation + d *
190 				lu->QuadraticAttenuation));
191 
192 	 if (light->_Flags & LIGHT_SPOT) {
193 	    GLfloat PV_dot_dir = - DOT3(VP, light->_NormSpotDirection);
194 
195 	    if (PV_dot_dir<lu->_CosCutoff) {
196 	       continue;
197 	    }
198 	    else {
199                GLfloat spot = powf(PV_dot_dir, lu->SpotExponent);
200 	       attenuation *= spot;
201 	    }
202 	 }
203       }
204 
205       if (attenuation < 1e-3F)
206 	 continue;
207 
208       n_dot_VP = DOT3( normal, VP );
209 
210       if (n_dot_VP < 0.0F) {
211 	 ACC_SCALE_SCALAR_3V(diffuseColor, attenuation, light->_MatAmbient[0]);
212 	 continue;
213       }
214 
215       /* Ambient + diffuse */
216       COPY_3V(diffuseContrib, light->_MatAmbient[0]);
217       ACC_SCALE_SCALAR_3V(diffuseContrib, n_dot_VP, light->_MatDiffuse[0]);
218 
219       /* Specular */
220       {
221          const GLfloat *h;
222          GLfloat n_dot_h;
223 
224          ASSIGN_3V(specularContrib, 0.0, 0.0, 0.0);
225 
226 	 if (ctx->Light.Model.LocalViewer) {
227 	    GLfloat v[3];
228 	    COPY_3V(v, vertex);
229 	    NORMALIZE_3FV(v);
230 	    SUB_3V(VP, VP, v);
231             NORMALIZE_3FV(VP);
232 	    h = VP;
233 	 }
234 	 else if (light->_Flags & LIGHT_POSITIONAL) {
235 	    ACC_3V(VP, ctx->_EyeZDir);
236             NORMALIZE_3FV(VP);
237 	    h = VP;
238 	 }
239          else {
240 	    h = light->_h_inf_norm;
241 	 }
242 
243 	 n_dot_h = DOT3(normal, h);
244 
245 	 if (n_dot_h > 0.0F) {
246 	    GLfloat shine;
247 	    GLfloat spec_coef;
248 
249 	    shine = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0];
250 	    spec_coef = powf(n_dot_h, shine);
251 
252 	    if (spec_coef > 1.0e-10F) {
253                if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
254                   ACC_SCALE_SCALAR_3V( specularContrib, spec_coef,
255                                        light->_MatSpecular[0]);
256                }
257                else {
258                   ACC_SCALE_SCALAR_3V( diffuseContrib, spec_coef,
259                                        light->_MatSpecular[0]);
260                }
261 	    }
262 	 }
263       }
264 
265       ACC_SCALE_SCALAR_3V( diffuseColor, attenuation, diffuseContrib );
266       ACC_SCALE_SCALAR_3V( specularColor, attenuation, specularContrib );
267    }
268 
269    Rcolor[0] = CLAMP(diffuseColor[0], 0.0F, 1.0F);
270    Rcolor[1] = CLAMP(diffuseColor[1], 0.0F, 1.0F);
271    Rcolor[2] = CLAMP(diffuseColor[2], 0.0F, 1.0F);
272    Rcolor[3] = CLAMP(diffuseColor[3], 0.0F, 1.0F);
273    Rspec[0] = CLAMP(specularColor[0], 0.0F, 1.0F);
274    Rspec[1] = CLAMP(specularColor[1], 0.0F, 1.0F);
275    Rspec[2] = CLAMP(specularColor[2], 0.0F, 1.0F);
276    Rspec[3] = CLAMP(specularColor[3], 0.0F, 1.0F);
277 }
278 
279 
280 /**
281  * Do texgen needed for glRasterPos.
282  * \param ctx  rendering context
283  * \param vObj  object-space vertex coordinate
284  * \param vEye  eye-space vertex coordinate
285  * \param normal  vertex normal
286  * \param unit  texture unit number
287  * \param texcoord  incoming texcoord and resulting texcoord
288  */
289 static void
compute_texgen(struct gl_context * ctx,const GLfloat vObj[4],const GLfloat vEye[4],const GLfloat normal[3],GLuint unit,GLfloat texcoord[4])290 compute_texgen(struct gl_context *ctx, const GLfloat vObj[4], const GLfloat vEye[4],
291                const GLfloat normal[3], GLuint unit, GLfloat texcoord[4])
292 {
293    const struct gl_fixedfunc_texture_unit *texUnit =
294       &ctx->Texture.FixedFuncUnit[unit];
295 
296    /* always compute sphere map terms, just in case */
297    GLfloat u[3], two_nu, rx, ry, rz, m, mInv;
298    COPY_3V(u, vEye);
299    NORMALIZE_3FV(u);
300    two_nu = 2.0F * DOT3(normal, u);
301    rx = u[0] - normal[0] * two_nu;
302    ry = u[1] - normal[1] * two_nu;
303    rz = u[2] - normal[2] * two_nu;
304    m = rx * rx + ry * ry + (rz + 1.0F) * (rz + 1.0F);
305    if (m > 0.0F)
306       mInv = 0.5F * (1.0f / sqrtf(m));
307    else
308       mInv = 0.0F;
309 
310    if (texUnit->TexGenEnabled & S_BIT) {
311       switch (texUnit->GenS.Mode) {
312          case GL_OBJECT_LINEAR:
313             texcoord[0] = DOT4(vObj, texUnit->ObjectPlane[GEN_S]);
314             break;
315          case GL_EYE_LINEAR:
316             texcoord[0] = DOT4(vEye, texUnit->EyePlane[GEN_S]);
317             break;
318          case GL_SPHERE_MAP:
319             texcoord[0] = rx * mInv + 0.5F;
320             break;
321          case GL_REFLECTION_MAP:
322             texcoord[0] = rx;
323             break;
324          case GL_NORMAL_MAP:
325             texcoord[0] = normal[0];
326             break;
327          default:
328             _mesa_problem(ctx, "Bad S texgen in compute_texgen()");
329             return;
330       }
331    }
332 
333    if (texUnit->TexGenEnabled & T_BIT) {
334       switch (texUnit->GenT.Mode) {
335          case GL_OBJECT_LINEAR:
336             texcoord[1] = DOT4(vObj, texUnit->ObjectPlane[GEN_T]);
337             break;
338          case GL_EYE_LINEAR:
339             texcoord[1] = DOT4(vEye, texUnit->EyePlane[GEN_T]);
340             break;
341          case GL_SPHERE_MAP:
342             texcoord[1] = ry * mInv + 0.5F;
343             break;
344          case GL_REFLECTION_MAP:
345             texcoord[1] = ry;
346             break;
347          case GL_NORMAL_MAP:
348             texcoord[1] = normal[1];
349             break;
350          default:
351             _mesa_problem(ctx, "Bad T texgen in compute_texgen()");
352             return;
353       }
354    }
355 
356    if (texUnit->TexGenEnabled & R_BIT) {
357       switch (texUnit->GenR.Mode) {
358          case GL_OBJECT_LINEAR:
359             texcoord[2] = DOT4(vObj, texUnit->ObjectPlane[GEN_R]);
360             break;
361          case GL_EYE_LINEAR:
362             texcoord[2] = DOT4(vEye, texUnit->EyePlane[GEN_R]);
363             break;
364          case GL_REFLECTION_MAP:
365             texcoord[2] = rz;
366             break;
367          case GL_NORMAL_MAP:
368             texcoord[2] = normal[2];
369             break;
370          default:
371             _mesa_problem(ctx, "Bad R texgen in compute_texgen()");
372             return;
373       }
374    }
375 
376    if (texUnit->TexGenEnabled & Q_BIT) {
377       switch (texUnit->GenQ.Mode) {
378          case GL_OBJECT_LINEAR:
379             texcoord[3] = DOT4(vObj, texUnit->ObjectPlane[GEN_Q]);
380             break;
381          case GL_EYE_LINEAR:
382             texcoord[3] = DOT4(vEye, texUnit->EyePlane[GEN_Q]);
383             break;
384          default:
385             _mesa_problem(ctx, "Bad Q texgen in compute_texgen()");
386             return;
387       }
388    }
389 }
390 
391 
392 /**
393  * glRasterPos transformation.
394  *
395  * \param vObj  vertex position in object space
396  */
397 void
_mesa_RasterPos(struct gl_context * ctx,const GLfloat vObj[4])398 _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4])
399 {
400    ctx->PopAttribState |= GL_CURRENT_BIT;
401 
402    if (_mesa_arb_vertex_program_enabled(ctx)) {
403       /* XXX implement this */
404       _mesa_problem(ctx, "Vertex programs not implemented for glRasterPos");
405       return;
406    }
407    else {
408       GLfloat eye[4], clip[4], ndc[3], d;
409       GLfloat *norm, eyenorm[3];
410       GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
411       float scale[3], translate[3];
412 
413       /* apply modelview matrix:  eye = MV * obj */
414       TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, vObj );
415       /* apply projection matrix:  clip = Proj * eye */
416       TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
417 
418       /* clip to view volume. */
419       if (!ctx->Transform.DepthClampNear) {
420          if (viewclip_point_near_z(clip) == 0) {
421             ctx->Current.RasterPosValid = GL_FALSE;
422             return;
423          }
424       }
425       if (!ctx->Transform.DepthClampFar) {
426          if (viewclip_point_far_z(clip) == 0) {
427             ctx->Current.RasterPosValid = GL_FALSE;
428             return;
429          }
430       }
431       if (!ctx->Transform.RasterPositionUnclipped) {
432          if (viewclip_point_xy(clip) == 0) {
433             ctx->Current.RasterPosValid = GL_FALSE;
434             return;
435          }
436       }
437 
438       /* clip to user clipping planes */
439       if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clip)) {
440          ctx->Current.RasterPosValid = GL_FALSE;
441          return;
442       }
443 
444       /* ndc = clip / W */
445       d = (clip[3] == 0.0F) ? 1.0F : 1.0F / clip[3];
446       ndc[0] = clip[0] * d;
447       ndc[1] = clip[1] * d;
448       ndc[2] = clip[2] * d;
449       /* wincoord = viewport_mapping(ndc) */
450       _mesa_get_viewport_xform(ctx, 0, scale, translate);
451       ctx->Current.RasterPos[0] = ndc[0] * scale[0] + translate[0];
452       ctx->Current.RasterPos[1] = ndc[1] * scale[1] + translate[1];
453       ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2];
454       ctx->Current.RasterPos[3] = clip[3];
455 
456       if (ctx->Transform.DepthClampNear &&
457           ctx->Transform.DepthClampFar) {
458          ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
459                                            ctx->ViewportArray[0].Near,
460                                            ctx->ViewportArray[0].Far);
461       } else {
462          /* Clamp against near and far plane separately */
463          if (ctx->Transform.DepthClampNear) {
464             ctx->Current.RasterPos[3] = MAX2(ctx->Current.RasterPos[3],
465                                              ctx->ViewportArray[0].Near);
466          }
467 
468          if (ctx->Transform.DepthClampFar) {
469             ctx->Current.RasterPos[3] = MIN2(ctx->Current.RasterPos[3],
470                                              ctx->ViewportArray[0].Far);
471          }
472       }
473 
474       /* compute raster distance */
475       if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
476          ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
477       else
478          ctx->Current.RasterDistance =
479                         sqrtf( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );
480 
481       /* compute transformed normal vector (for lighting or texgen) */
482       if (ctx->_NeedEyeCoords) {
483          const GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv;
484          TRANSFORM_NORMAL( eyenorm, objnorm, inv );
485          norm = eyenorm;
486       }
487       else {
488          norm = objnorm;
489       }
490 
491       /* update raster color */
492       if (ctx->Light.Enabled) {
493          /* lighting */
494          shade_rastpos( ctx, vObj, norm,
495                         ctx->Current.RasterColor,
496                         ctx->Current.RasterSecondaryColor );
497       }
498       else {
499          /* use current color */
500 	 COPY_4FV(ctx->Current.RasterColor,
501 		  ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
502 	 COPY_4FV(ctx->Current.RasterSecondaryColor,
503 		  ctx->Current.Attrib[VERT_ATTRIB_COLOR1]);
504       }
505 
506       /* texture coords */
507       {
508          GLuint u;
509          for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
510             GLfloat tc[4];
511             COPY_4V(tc, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]);
512             if (ctx->Texture.FixedFuncUnit[u].TexGenEnabled) {
513                compute_texgen(ctx, vObj, eye, norm, u, tc);
514             }
515             TRANSFORM_POINT(ctx->Current.RasterTexCoords[u],
516                             ctx->TextureMatrixStack[u].Top->m, tc);
517          }
518       }
519 
520       ctx->Current.RasterPosValid = GL_TRUE;
521    }
522 
523    if (ctx->RenderMode == GL_SELECT) {
524       _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
525    }
526 }
527 
528 
529 /**
530  * Helper function for all the RasterPos functions.
531  */
532 static void
rasterpos(GLfloat x,GLfloat y,GLfloat z,GLfloat w)533 rasterpos(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
534 {
535    GET_CURRENT_CONTEXT(ctx);
536    GLfloat p[4];
537 
538    p[0] = x;
539    p[1] = y;
540    p[2] = z;
541    p[3] = w;
542 
543    FLUSH_VERTICES(ctx, 0, 0);
544    FLUSH_CURRENT(ctx, 0);
545 
546    if (ctx->NewState)
547       _mesa_update_state( ctx );
548 
549    st_RasterPos(ctx, p);
550 }
551 
552 
553 void GLAPIENTRY
_mesa_RasterPos2d(GLdouble x,GLdouble y)554 _mesa_RasterPos2d(GLdouble x, GLdouble y)
555 {
556    rasterpos((GLfloat)x, (GLfloat)y, (GLfloat)0.0, (GLfloat)1.0);
557 }
558 
559 void GLAPIENTRY
_mesa_RasterPos2f(GLfloat x,GLfloat y)560 _mesa_RasterPos2f(GLfloat x, GLfloat y)
561 {
562    rasterpos(x, y, 0.0F, 1.0F);
563 }
564 
565 void GLAPIENTRY
_mesa_RasterPos2i(GLint x,GLint y)566 _mesa_RasterPos2i(GLint x, GLint y)
567 {
568    rasterpos((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
569 }
570 
571 void GLAPIENTRY
_mesa_RasterPos2s(GLshort x,GLshort y)572 _mesa_RasterPos2s(GLshort x, GLshort y)
573 {
574    rasterpos(x, y, 0.0F, 1.0F);
575 }
576 
577 void GLAPIENTRY
_mesa_RasterPos3d(GLdouble x,GLdouble y,GLdouble z)578 _mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
579 {
580    rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
581 }
582 
583 void GLAPIENTRY
_mesa_RasterPos3f(GLfloat x,GLfloat y,GLfloat z)584 _mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
585 {
586    rasterpos(x, y, z, 1.0F);
587 }
588 
589 void GLAPIENTRY
_mesa_RasterPos3i(GLint x,GLint y,GLint z)590 _mesa_RasterPos3i(GLint x, GLint y, GLint z)
591 {
592    rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
593 }
594 
595 void GLAPIENTRY
_mesa_RasterPos3s(GLshort x,GLshort y,GLshort z)596 _mesa_RasterPos3s(GLshort x, GLshort y, GLshort z)
597 {
598    rasterpos(x, y, z, 1.0F);
599 }
600 
601 void GLAPIENTRY
_mesa_RasterPos4d(GLdouble x,GLdouble y,GLdouble z,GLdouble w)602 _mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
603 {
604    rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
605 }
606 
607 void GLAPIENTRY
_mesa_RasterPos4f(GLfloat x,GLfloat y,GLfloat z,GLfloat w)608 _mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
609 {
610    rasterpos(x, y, z, w);
611 }
612 
613 void GLAPIENTRY
_mesa_RasterPos4i(GLint x,GLint y,GLint z,GLint w)614 _mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
615 {
616    rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
617 }
618 
619 void GLAPIENTRY
_mesa_RasterPos4s(GLshort x,GLshort y,GLshort z,GLshort w)620 _mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
621 {
622    rasterpos(x, y, z, w);
623 }
624 
625 void GLAPIENTRY
_mesa_RasterPos2dv(const GLdouble * v)626 _mesa_RasterPos2dv(const GLdouble *v)
627 {
628    rasterpos((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
629 }
630 
631 void GLAPIENTRY
_mesa_RasterPos2fv(const GLfloat * v)632 _mesa_RasterPos2fv(const GLfloat *v)
633 {
634    rasterpos(v[0], v[1], 0.0F, 1.0F);
635 }
636 
637 void GLAPIENTRY
_mesa_RasterPos2iv(const GLint * v)638 _mesa_RasterPos2iv(const GLint *v)
639 {
640    rasterpos((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
641 }
642 
643 void GLAPIENTRY
_mesa_RasterPos2sv(const GLshort * v)644 _mesa_RasterPos2sv(const GLshort *v)
645 {
646    rasterpos(v[0], v[1], 0.0F, 1.0F);
647 }
648 
649 void GLAPIENTRY
_mesa_RasterPos3dv(const GLdouble * v)650 _mesa_RasterPos3dv(const GLdouble *v)
651 {
652    rasterpos((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
653 }
654 
655 void GLAPIENTRY
_mesa_RasterPos3fv(const GLfloat * v)656 _mesa_RasterPos3fv(const GLfloat *v)
657 {
658    rasterpos(v[0], v[1], v[2], 1.0F);
659 }
660 
661 void GLAPIENTRY
_mesa_RasterPos3iv(const GLint * v)662 _mesa_RasterPos3iv(const GLint *v)
663 {
664    rasterpos((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
665 }
666 
667 void GLAPIENTRY
_mesa_RasterPos3sv(const GLshort * v)668 _mesa_RasterPos3sv(const GLshort *v)
669 {
670    rasterpos(v[0], v[1], v[2], 1.0F);
671 }
672 
673 void GLAPIENTRY
_mesa_RasterPos4dv(const GLdouble * v)674 _mesa_RasterPos4dv(const GLdouble *v)
675 {
676    rasterpos((GLfloat) v[0], (GLfloat) v[1],
677 		     (GLfloat) v[2], (GLfloat) v[3]);
678 }
679 
680 void GLAPIENTRY
_mesa_RasterPos4fv(const GLfloat * v)681 _mesa_RasterPos4fv(const GLfloat *v)
682 {
683    rasterpos(v[0], v[1], v[2], v[3]);
684 }
685 
686 void GLAPIENTRY
_mesa_RasterPos4iv(const GLint * v)687 _mesa_RasterPos4iv(const GLint *v)
688 {
689    rasterpos((GLfloat) v[0], (GLfloat) v[1],
690 		     (GLfloat) v[2], (GLfloat) v[3]);
691 }
692 
693 void GLAPIENTRY
_mesa_RasterPos4sv(const GLshort * v)694 _mesa_RasterPos4sv(const GLshort *v)
695 {
696    rasterpos(v[0], v[1], v[2], v[3]);
697 }
698 
699 
700 /**********************************************************************/
701 /***           GL_ARB_window_pos / GL_MESA_window_pos               ***/
702 /**********************************************************************/
703 
704 
705 /**
706  * All glWindowPosMESA and glWindowPosARB commands call this function to
707  * update the current raster position.
708  */
709 static void
window_pos3f(GLfloat x,GLfloat y,GLfloat z)710 window_pos3f(GLfloat x, GLfloat y, GLfloat z)
711 {
712    GET_CURRENT_CONTEXT(ctx);
713    GLfloat z2;
714 
715    FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT);
716    FLUSH_CURRENT(ctx, 0);
717 
718    z2 = CLAMP(z, 0.0F, 1.0F)
719       * (ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near)
720       + ctx->ViewportArray[0].Near;
721 
722    /* set raster position */
723    ctx->Current.RasterPos[0] = x;
724    ctx->Current.RasterPos[1] = y;
725    ctx->Current.RasterPos[2] = z2;
726    ctx->Current.RasterPos[3] = 1.0F;
727 
728    ctx->Current.RasterPosValid = GL_TRUE;
729 
730    if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
731       ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
732    else
733       ctx->Current.RasterDistance = 0.0;
734 
735    /* raster color = current color or index */
736    ctx->Current.RasterColor[0]
737       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F);
738    ctx->Current.RasterColor[1]
739       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F);
740    ctx->Current.RasterColor[2]
741       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F);
742    ctx->Current.RasterColor[3]
743       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F);
744    ctx->Current.RasterSecondaryColor[0]
745       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F);
746    ctx->Current.RasterSecondaryColor[1]
747       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F);
748    ctx->Current.RasterSecondaryColor[2]
749       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F);
750    ctx->Current.RasterSecondaryColor[3]
751       = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F);
752 
753    /* raster texcoord = current texcoord */
754    {
755       GLuint texSet;
756       for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) {
757          assert(texSet < ARRAY_SIZE(ctx->Current.RasterTexCoords));
758          COPY_4FV( ctx->Current.RasterTexCoords[texSet],
759                   ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] );
760       }
761    }
762 
763    if (ctx->RenderMode==GL_SELECT) {
764       _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
765    }
766 }
767 
768 
769 /* This is just to support the GL_MESA_window_pos version */
770 static void
window_pos4f(GLfloat x,GLfloat y,GLfloat z,GLfloat w)771 window_pos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
772 {
773    GET_CURRENT_CONTEXT(ctx);
774    window_pos3f(x, y, z);
775    ctx->Current.RasterPos[3] = w;
776 }
777 
778 
779 void GLAPIENTRY
_mesa_WindowPos2d(GLdouble x,GLdouble y)780 _mesa_WindowPos2d(GLdouble x, GLdouble y)
781 {
782    window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
783 }
784 
785 void GLAPIENTRY
_mesa_WindowPos2f(GLfloat x,GLfloat y)786 _mesa_WindowPos2f(GLfloat x, GLfloat y)
787 {
788    window_pos4f(x, y, 0.0F, 1.0F);
789 }
790 
791 void GLAPIENTRY
_mesa_WindowPos2i(GLint x,GLint y)792 _mesa_WindowPos2i(GLint x, GLint y)
793 {
794    window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
795 }
796 
797 void GLAPIENTRY
_mesa_WindowPos2s(GLshort x,GLshort y)798 _mesa_WindowPos2s(GLshort x, GLshort y)
799 {
800    window_pos4f(x, y, 0.0F, 1.0F);
801 }
802 
803 void GLAPIENTRY
_mesa_WindowPos3d(GLdouble x,GLdouble y,GLdouble z)804 _mesa_WindowPos3d(GLdouble x, GLdouble y, GLdouble z)
805 {
806    window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
807 }
808 
809 void GLAPIENTRY
_mesa_WindowPos3f(GLfloat x,GLfloat y,GLfloat z)810 _mesa_WindowPos3f(GLfloat x, GLfloat y, GLfloat z)
811 {
812    window_pos4f(x, y, z, 1.0F);
813 }
814 
815 void GLAPIENTRY
_mesa_WindowPos3i(GLint x,GLint y,GLint z)816 _mesa_WindowPos3i(GLint x, GLint y, GLint z)
817 {
818    window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
819 }
820 
821 void GLAPIENTRY
_mesa_WindowPos3s(GLshort x,GLshort y,GLshort z)822 _mesa_WindowPos3s(GLshort x, GLshort y, GLshort z)
823 {
824    window_pos4f(x, y, z, 1.0F);
825 }
826 
827 void GLAPIENTRY
_mesa_WindowPos4dMESA(GLdouble x,GLdouble y,GLdouble z,GLdouble w)828 _mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
829 {
830    window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
831 }
832 
833 void GLAPIENTRY
_mesa_WindowPos4fMESA(GLfloat x,GLfloat y,GLfloat z,GLfloat w)834 _mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
835 {
836    window_pos4f(x, y, z, w);
837 }
838 
839 void GLAPIENTRY
_mesa_WindowPos4iMESA(GLint x,GLint y,GLint z,GLint w)840 _mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w)
841 {
842    window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
843 }
844 
845 void GLAPIENTRY
_mesa_WindowPos4sMESA(GLshort x,GLshort y,GLshort z,GLshort w)846 _mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w)
847 {
848    window_pos4f(x, y, z, w);
849 }
850 
851 void GLAPIENTRY
_mesa_WindowPos2dv(const GLdouble * v)852 _mesa_WindowPos2dv(const GLdouble *v)
853 {
854    window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
855 }
856 
857 void GLAPIENTRY
_mesa_WindowPos2fv(const GLfloat * v)858 _mesa_WindowPos2fv(const GLfloat *v)
859 {
860    window_pos4f(v[0], v[1], 0.0F, 1.0F);
861 }
862 
863 void GLAPIENTRY
_mesa_WindowPos2iv(const GLint * v)864 _mesa_WindowPos2iv(const GLint *v)
865 {
866    window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
867 }
868 
869 void GLAPIENTRY
_mesa_WindowPos2sv(const GLshort * v)870 _mesa_WindowPos2sv(const GLshort *v)
871 {
872    window_pos4f(v[0], v[1], 0.0F, 1.0F);
873 }
874 
875 void GLAPIENTRY
_mesa_WindowPos3dv(const GLdouble * v)876 _mesa_WindowPos3dv(const GLdouble *v)
877 {
878    window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
879 }
880 
881 void GLAPIENTRY
_mesa_WindowPos3fv(const GLfloat * v)882 _mesa_WindowPos3fv(const GLfloat *v)
883 {
884    window_pos4f(v[0], v[1], v[2], 1.0);
885 }
886 
887 void GLAPIENTRY
_mesa_WindowPos3iv(const GLint * v)888 _mesa_WindowPos3iv(const GLint *v)
889 {
890    window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
891 }
892 
893 void GLAPIENTRY
_mesa_WindowPos3sv(const GLshort * v)894 _mesa_WindowPos3sv(const GLshort *v)
895 {
896    window_pos4f(v[0], v[1], v[2], 1.0F);
897 }
898 
899 void GLAPIENTRY
_mesa_WindowPos4dvMESA(const GLdouble * v)900 _mesa_WindowPos4dvMESA(const GLdouble *v)
901 {
902    window_pos4f((GLfloat) v[0], (GLfloat) v[1],
903 			 (GLfloat) v[2], (GLfloat) v[3]);
904 }
905 
906 void GLAPIENTRY
_mesa_WindowPos4fvMESA(const GLfloat * v)907 _mesa_WindowPos4fvMESA(const GLfloat *v)
908 {
909    window_pos4f(v[0], v[1], v[2], v[3]);
910 }
911 
912 void GLAPIENTRY
_mesa_WindowPos4ivMESA(const GLint * v)913 _mesa_WindowPos4ivMESA(const GLint *v)
914 {
915    window_pos4f((GLfloat) v[0], (GLfloat) v[1],
916 			 (GLfloat) v[2], (GLfloat) v[3]);
917 }
918 
919 void GLAPIENTRY
_mesa_WindowPos4svMESA(const GLshort * v)920 _mesa_WindowPos4svMESA(const GLshort *v)
921 {
922    window_pos4f(v[0], v[1], v[2], v[3]);
923 }
924 
925 
926 #if 0
927 
928 /*
929  * OpenGL implementation of glWindowPos*MESA()
930  */
931 void glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
932 {
933    GLfloat fx, fy;
934 
935    /* Push current matrix mode and viewport attributes */
936    glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
937 
938    /* Setup projection parameters */
939    glMatrixMode( GL_PROJECTION );
940    glPushMatrix();
941    glLoadIdentity();
942    glMatrixMode( GL_MODELVIEW );
943    glPushMatrix();
944    glLoadIdentity();
945 
946    glDepthRange( z, z );
947    glViewport( (int) x - 1, (int) y - 1, 2, 2 );
948 
949    /* set the raster (window) position */
950    fx = x - (int) x;
951    fy = y - (int) y;
952    glRasterPos4f( fx, fy, 0.0, w );
953 
954    /* restore matrices, viewport and matrix mode */
955    glPopMatrix();
956    glMatrixMode( GL_PROJECTION );
957    glPopMatrix();
958 
959    glPopAttrib();
960 }
961 
962 #endif
963 
964 
965 /**********************************************************************/
966 /** \name Initialization                                              */
967 /**********************************************************************/
968 /*@{*/
969 
970 /**
971  * Initialize the context current raster position information.
972  *
973  * \param ctx GL context.
974  *
975  * Initialize the current raster position information in
976  * __struct gl_contextRec::Current, and adds the extension entry points to the
977  * dispatcher.
978  */
_mesa_init_rastpos(struct gl_context * ctx)979 void _mesa_init_rastpos( struct gl_context * ctx )
980 {
981    unsigned i;
982 
983    ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
984    ctx->Current.RasterDistance = 0.0;
985    ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
986    ASSIGN_4V( ctx->Current.RasterSecondaryColor, 0.0, 0.0, 0.0, 1.0 );
987    for (i = 0; i < ARRAY_SIZE(ctx->Current.RasterTexCoords); i++)
988       ASSIGN_4V( ctx->Current.RasterTexCoords[i], 0.0, 0.0, 0.0, 1.0 );
989    ctx->Current.RasterPosValid = GL_TRUE;
990 }
991 
992 /*@}*/
993