rastpos.c revision c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8c
1/**
2 * \file rastpos.c
3 * Raster position operations.
4 */
5
6/*
7 * Mesa 3-D graphics library
8 * Version:  5.1
9 *
10 * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 */
29
30
31#include "glheader.h"
32/*#include "clip.h"*/
33#include "colormac.h"
34#include "context.h"
35#include "feedback.h"
36#include "light.h"
37#include "macros.h"
38#include "rastpos.h"
39#include "state.h"
40#include "simple_list.h"
41#include "mtypes.h"
42
43#include "math/m_matrix.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 */
53static GLuint
54viewclip_point( const GLfloat v[] )
55{
56   if (   v[0] > v[3] || v[0] < -v[3]
57       || v[1] > v[3] || v[1] < -v[3]
58       || v[2] > v[3] || v[2] < -v[3] ) {
59      return 0;
60   }
61   else {
62      return 1;
63   }
64}
65
66
67/**
68 * Clip a point against the far/near Z clipping planes.
69 *
70 * \param v vertex vector describing the point to clip.
71 *
72 * \return zero if outside view volume, or one if inside.
73 */
74static GLuint
75viewclip_point_z( const GLfloat v[] )
76{
77   if (v[2] > v[3] || v[2] < -v[3] ) {
78      return 0;
79   }
80   else {
81      return 1;
82   }
83}
84
85
86/**
87 * Clip a point against the user clipping planes.
88 *
89 * \param ctx GL context.
90 * \param v vertex vector describing the point to clip.
91 *
92 * \return zero if the point was clipped, or one otherwise.
93 */
94static GLuint
95userclip_point( GLcontext *ctx, const GLfloat v[] )
96{
97   GLuint p;
98
99   for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
100      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
101	 GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0]
102		     + v[1] * ctx->Transform._ClipUserPlane[p][1]
103		     + v[2] * ctx->Transform._ClipUserPlane[p][2]
104		     + v[3] * ctx->Transform._ClipUserPlane[p][3];
105         if (dot < 0.0F) {
106            return 0;
107         }
108      }
109   }
110
111   return 1;
112}
113
114
115/**
116 * This has been split off to allow the normal shade routines to
117 * get a little closer to the vertex buffer, and to use the
118 * GLvector objects directly.
119 * \param ctx the context
120 * \param vertex vertex location
121 * \param normal normal vector
122 * \param Rcolor returned color
123 * \param Rspec returned specular color (if separate specular enabled)
124 * \param Rindex returned color index
125 */
126static void
127shade_rastpos(GLcontext *ctx,
128              const GLfloat vertex[4],
129              const GLfloat normal[3],
130              GLfloat Rcolor[4],
131              GLfloat Rspec[4],
132              GLuint *Rindex)
133{
134   GLfloat (*base)[3] = ctx->Light._BaseColor;
135   struct gl_light *light;
136   GLfloat diffuseColor[4], specularColor[4];
137   GLfloat diffuse = 0, specular = 0;
138
139   if (!ctx->_ShineTable[0] || !ctx->_ShineTable[1])
140      _mesa_validate_all_lighting_tables( ctx );
141
142   COPY_3V(diffuseColor, base[0]);
143   diffuseColor[3] = CLAMP(
144      ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3], 0.0F, 1.0F );
145   ASSIGN_4V(specularColor, 0.0, 0.0, 0.0, 0.0);
146
147   foreach (light, &ctx->Light.EnabledList) {
148      GLfloat n_dot_h;
149      GLfloat attenuation = 1.0;
150      GLfloat VP[3];
151      GLfloat n_dot_VP;
152      GLfloat *h;
153      GLfloat diffuseContrib[3], specularContrib[3];
154      GLboolean normalized;
155
156      if (!(light->_Flags & LIGHT_POSITIONAL)) {
157	 COPY_3V(VP, light->_VP_inf_norm);
158	 attenuation = light->_VP_inf_spot_attenuation;
159      }
160      else {
161	 GLfloat d;
162
163	 SUB_3V(VP, light->_Position, vertex);
164	 d = (GLfloat) LEN_3FV( VP );
165
166	 if ( d > 1e-6) {
167	    GLfloat invd = 1.0F / d;
168	    SELF_SCALE_SCALAR_3V(VP, invd);
169	 }
170	 attenuation = 1.0F / (light->ConstantAttenuation + d *
171			       (light->LinearAttenuation + d *
172				light->QuadraticAttenuation));
173
174	 if (light->_Flags & LIGHT_SPOT) {
175	    GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
176
177	    if (PV_dot_dir<light->_CosCutoff) {
178	       continue;
179	    }
180	    else {
181	       double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
182	       int k = (int) x;
183	       GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
184			       + (x-k)*light->_SpotExpTable[k][1]);
185	       attenuation *= spot;
186	    }
187	 }
188      }
189
190      if (attenuation < 1e-3)
191	 continue;
192
193      n_dot_VP = DOT3( normal, VP );
194
195      if (n_dot_VP < 0.0F) {
196	 ACC_SCALE_SCALAR_3V(diffuseColor, attenuation, light->_MatAmbient[0]);
197	 continue;
198      }
199
200      COPY_3V(diffuseContrib, light->_MatAmbient[0]);
201      ACC_SCALE_SCALAR_3V(diffuseContrib, n_dot_VP, light->_MatDiffuse[0]);
202      diffuse += n_dot_VP * light->_dli * attenuation;
203      ASSIGN_3V(specularContrib, 0.0, 0.0, 0.0);
204
205      {
206	 if (ctx->Light.Model.LocalViewer) {
207	    GLfloat v[3];
208	    COPY_3V(v, vertex);
209	    NORMALIZE_3FV(v);
210	    SUB_3V(VP, VP, v);
211	    h = VP;
212	    normalized = 0;
213	 }
214	 else if (light->_Flags & LIGHT_POSITIONAL) {
215	    h = VP;
216	    ACC_3V(h, ctx->_EyeZDir);
217	    normalized = 0;
218	 }
219         else {
220	    h = light->_h_inf_norm;
221	    normalized = 1;
222	 }
223
224	 n_dot_h = DOT3(normal, h);
225
226	 if (n_dot_h > 0.0F) {
227	    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
228	    GLfloat spec_coef;
229	    GLfloat shininess = mat[MAT_ATTRIB_FRONT_SHININESS][0];
230
231	    if (!normalized) {
232	       n_dot_h *= n_dot_h;
233	       n_dot_h /= LEN_SQUARED_3FV( h );
234	       shininess *= .5;
235	    }
236
237	    GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef );
238
239	    if (spec_coef > 1.0e-10) {
240               if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
241                  ACC_SCALE_SCALAR_3V( specularContrib, spec_coef,
242                                       light->_MatSpecular[0]);
243               }
244               else {
245                  ACC_SCALE_SCALAR_3V( diffuseContrib, spec_coef,
246                                       light->_MatSpecular[0]);
247               }
248	       specular += spec_coef * light->_sli * attenuation;
249	    }
250	 }
251      }
252
253      ACC_SCALE_SCALAR_3V( diffuseColor, attenuation, diffuseContrib );
254      ACC_SCALE_SCALAR_3V( specularColor, attenuation, specularContrib );
255   }
256
257   if (ctx->Visual.rgbMode) {
258      Rcolor[0] = CLAMP(diffuseColor[0], 0.0F, 1.0F);
259      Rcolor[1] = CLAMP(diffuseColor[1], 0.0F, 1.0F);
260      Rcolor[2] = CLAMP(diffuseColor[2], 0.0F, 1.0F);
261      Rcolor[3] = CLAMP(diffuseColor[3], 0.0F, 1.0F);
262      Rspec[0] = CLAMP(specularColor[0], 0.0F, 1.0F);
263      Rspec[1] = CLAMP(specularColor[1], 0.0F, 1.0F);
264      Rspec[2] = CLAMP(specularColor[2], 0.0F, 1.0F);
265      Rspec[3] = CLAMP(specularColor[3], 0.0F, 1.0F);
266   }
267   else {
268      GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES];
269      GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT];
270      GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT];
271      GLfloat i = (ind[MAT_INDEX_AMBIENT]
272		   + diffuse * (1.0F-specular) * d_a
273		   + specular * s_a);
274      if (i > ind[MAT_INDEX_SPECULAR]) {
275	 i = ind[MAT_INDEX_SPECULAR];
276      }
277      *Rindex = (GLuint) (GLint) i;
278   }
279}
280
281
282/**
283 * Set the raster position for pixel operations.
284 *
285 * All glRasterPos command call this function to update the current
286 * raster position.
287 *
288 * \param ctx GL context.
289 * \param x x coordinate for the raster position.
290 * \param y y coordinate for the raster position.
291 * \param z z coordinate for the raster position.
292 * \param w w coordinate for the raster position.
293 *
294 * \sa Called by _mesa_RasterPos4f().
295 *
296 * Flushes the vertices, transforms and clips the vertex coordinates, and
297 * finally sets the current raster position and associated data in
298 * __GLcontextRec::Current.  When in selection mode calls
299 * _mesa_update_hitflag() with the current raster position.
300 */
301static void
302raster_pos4f(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
303{
304   GLfloat v[4], eye[4], clip[4], ndc[3], d;
305   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
306   FLUSH_CURRENT(ctx, 0);
307
308   if (ctx->NewState)
309      _mesa_update_state( ctx );
310
311   if (ctx->VertexProgram.Enabled) {
312      /* XXX implement this */
313      _mesa_problem(ctx, "Vertex programs not implemented for glRasterPos");
314      return;
315   }
316   else {
317      ASSIGN_4V( v, x, y, z, w );
318      TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, v );
319
320      /* raster color */
321      if (ctx->Light.Enabled) {
322         GLfloat *norm, eyenorm[3];
323         GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
324
325         if (ctx->_NeedEyeCoords) {
326            GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv;
327            TRANSFORM_NORMAL( eyenorm, objnorm, inv );
328            norm = eyenorm;
329         }
330         else {
331            norm = objnorm;
332         }
333
334         shade_rastpos( ctx, v, norm,
335                        ctx->Current.RasterColor,
336                        ctx->Current.RasterSecondaryColor,
337                        &ctx->Current.RasterIndex );
338      }
339      else {
340         /* use current color or index */
341         if (ctx->Visual.rgbMode) {
342            COPY_4FV(ctx->Current.RasterColor,
343                     ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
344            COPY_4FV(ctx->Current.RasterSecondaryColor,
345                     ctx->Current.Attrib[VERT_ATTRIB_COLOR1]);
346         }
347         else {
348            ctx->Current.RasterIndex = ctx->Current.Index;
349         }
350      }
351
352      /* compute raster distance */
353      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
354         ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
355      else
356         ctx->Current.RasterDistance =
357                         SQRTF( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );
358
359      /* apply projection matrix:  clip = Proj * eye */
360      TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
361
362      /* clip to view volume */
363      if (ctx->Transform.RasterPositionUnclipped) {
364         /* GL_IBM_rasterpos_clip: only clip against Z */
365         if (viewclip_point_z(clip) == 0) {
366            ctx->Current.RasterPosValid = GL_FALSE;
367            return;
368         }
369      }
370      else if (viewclip_point(clip) == 0) {
371         /* Normal OpenGL behaviour */
372         ctx->Current.RasterPosValid = GL_FALSE;
373         return;
374      }
375
376      /* clip to user clipping planes */
377      if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clip)) {
378         ctx->Current.RasterPosValid = GL_FALSE;
379         return;
380      }
381
382      /* ndc = clip / W */
383      d = (clip[3] == 0.0F) ? 1.0F : 1.0F / clip[3];
384      ndc[0] = clip[0] * d;
385      ndc[1] = clip[1] * d;
386      ndc[2] = clip[2] * d;
387
388      ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport._WindowMap.m[MAT_SX] +
389                                   ctx->Viewport._WindowMap.m[MAT_TX]);
390      ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport._WindowMap.m[MAT_SY] +
391                                   ctx->Viewport._WindowMap.m[MAT_TY]);
392      ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ] +
393                                   ctx->Viewport._WindowMap.m[MAT_TZ]) / ctx->DepthMaxF;
394      ctx->Current.RasterPos[3] = clip[3];
395      ctx->Current.RasterPosValid = GL_TRUE;
396
397      {
398         GLuint texSet;
399         for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) {
400            COPY_4FV( ctx->Current.RasterTexCoords[texSet],
401                     ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] );
402         }
403      }
404
405   }
406
407   if (ctx->RenderMode==GL_SELECT) {
408      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
409   }
410}
411
412
413/** Calls _mesa_RasterPos4f() */
414void GLAPIENTRY
415_mesa_RasterPos2d(GLdouble x, GLdouble y)
416{
417   _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
418}
419
420/** Calls _mesa_RasterPos4f() */
421void GLAPIENTRY
422_mesa_RasterPos2f(GLfloat x, GLfloat y)
423{
424   _mesa_RasterPos4f(x, y, 0.0F, 1.0F);
425}
426
427/** Calls _mesa_RasterPos4f() */
428void GLAPIENTRY
429_mesa_RasterPos2i(GLint x, GLint y)
430{
431   _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
432}
433
434/** Calls _mesa_RasterPos4f() */
435void GLAPIENTRY
436_mesa_RasterPos2s(GLshort x, GLshort y)
437{
438   _mesa_RasterPos4f(x, y, 0.0F, 1.0F);
439}
440
441/** Calls _mesa_RasterPos4f() */
442void GLAPIENTRY
443_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z)
444{
445   _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
446}
447
448/** Calls _mesa_RasterPos4f() */
449void GLAPIENTRY
450_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z)
451{
452   _mesa_RasterPos4f(x, y, z, 1.0F);
453}
454
455/** Calls _mesa_RasterPos4f() */
456void GLAPIENTRY
457_mesa_RasterPos3i(GLint x, GLint y, GLint z)
458{
459   _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
460}
461
462/** Calls _mesa_RasterPos4f() */
463void GLAPIENTRY
464_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z)
465{
466   _mesa_RasterPos4f(x, y, z, 1.0F);
467}
468
469/** Calls _mesa_RasterPos4f() */
470void GLAPIENTRY
471_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
472{
473   _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
474}
475
476/** Calls raster_pos4f() */
477void GLAPIENTRY
478_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
479{
480   GET_CURRENT_CONTEXT(ctx);
481   raster_pos4f(ctx, x, y, z, w);
482}
483
484/** Calls _mesa_RasterPos4f() */
485void GLAPIENTRY
486_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w)
487{
488   _mesa_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
489}
490
491/** Calls _mesa_RasterPos4f() */
492void GLAPIENTRY
493_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
494{
495   _mesa_RasterPos4f(x, y, z, w);
496}
497
498/** Calls _mesa_RasterPos4f() */
499void GLAPIENTRY
500_mesa_RasterPos2dv(const GLdouble *v)
501{
502   _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
503}
504
505/** Calls _mesa_RasterPos4f() */
506void GLAPIENTRY
507_mesa_RasterPos2fv(const GLfloat *v)
508{
509   _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
510}
511
512/** Calls _mesa_RasterPos4f() */
513void GLAPIENTRY
514_mesa_RasterPos2iv(const GLint *v)
515{
516   _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
517}
518
519/** Calls _mesa_RasterPos4f() */
520void GLAPIENTRY
521_mesa_RasterPos2sv(const GLshort *v)
522{
523   _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F);
524}
525
526/** Calls _mesa_RasterPos4f() */
527void GLAPIENTRY
528_mesa_RasterPos3dv(const GLdouble *v)
529{
530   _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
531}
532
533/** Calls _mesa_RasterPos4f() */
534void GLAPIENTRY
535_mesa_RasterPos3fv(const GLfloat *v)
536{
537   _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F);
538}
539
540/** Calls _mesa_RasterPos4f() */
541void GLAPIENTRY
542_mesa_RasterPos3iv(const GLint *v)
543{
544   _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
545}
546
547/** Calls _mesa_RasterPos4f() */
548void GLAPIENTRY
549_mesa_RasterPos3sv(const GLshort *v)
550{
551   _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F);
552}
553
554/** Calls _mesa_RasterPos4f() */
555void GLAPIENTRY
556_mesa_RasterPos4dv(const GLdouble *v)
557{
558   _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
559		     (GLfloat) v[2], (GLfloat) v[3]);
560}
561
562/** Calls _mesa_RasterPos4f() */
563void GLAPIENTRY
564_mesa_RasterPos4fv(const GLfloat *v)
565{
566   _mesa_RasterPos4f(v[0], v[1], v[2], v[3]);
567}
568
569/** Calls _mesa_RasterPos4f() */
570void GLAPIENTRY
571_mesa_RasterPos4iv(const GLint *v)
572{
573   _mesa_RasterPos4f((GLfloat) v[0], (GLfloat) v[1],
574		     (GLfloat) v[2], (GLfloat) v[3]);
575}
576
577/** Calls _mesa_RasterPos4f() */
578void GLAPIENTRY
579_mesa_RasterPos4sv(const GLshort *v)
580{
581   _mesa_RasterPos4f(v[0], v[1], v[2], v[3]);
582}
583
584
585/**********************************************************************/
586/***           GL_ARB_window_pos / GL_MESA_window_pos               ***/
587/**********************************************************************/
588
589#if FEATURE_windowpos
590/**
591 * All glWindowPosMESA and glWindowPosARB commands call this function to
592 * update the current raster position.
593 */
594static void
595window_pos3f(GLfloat x, GLfloat y, GLfloat z)
596{
597   GET_CURRENT_CONTEXT(ctx);
598   GLfloat z2;
599
600   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
601   FLUSH_CURRENT(ctx, 0);
602
603   z2 = CLAMP(z, 0.0F, 1.0F) * (ctx->Viewport.Far - ctx->Viewport.Near)
604      + ctx->Viewport.Near;
605
606   /* set raster position */
607   ctx->Current.RasterPos[0] = x;
608   ctx->Current.RasterPos[1] = y;
609   ctx->Current.RasterPos[2] = z2;
610   ctx->Current.RasterPos[3] = 1.0F;
611
612   ctx->Current.RasterPosValid = GL_TRUE;
613
614   if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
615      ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
616   else
617      ctx->Current.RasterDistance = 0.0;
618
619   /* raster color = current color or index */
620   if (ctx->Visual.rgbMode) {
621      ctx->Current.RasterColor[0]
622         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F);
623      ctx->Current.RasterColor[1]
624         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F);
625      ctx->Current.RasterColor[2]
626         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F);
627      ctx->Current.RasterColor[3]
628         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F);
629      ctx->Current.RasterSecondaryColor[0]
630         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F);
631      ctx->Current.RasterSecondaryColor[1]
632         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F);
633      ctx->Current.RasterSecondaryColor[2]
634         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F);
635      ctx->Current.RasterSecondaryColor[3]
636         = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F);
637   }
638   else {
639      ctx->Current.RasterIndex = ctx->Current.Index;
640   }
641
642   /* raster texcoord = current texcoord */
643   {
644      GLuint texSet;
645      for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) {
646         COPY_4FV( ctx->Current.RasterTexCoords[texSet],
647                  ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] );
648      }
649   }
650
651   if (ctx->RenderMode==GL_SELECT) {
652      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
653   }
654}
655
656
657/* This is just to support the GL_MESA_window_pos version */
658static void
659window_pos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
660{
661   GET_CURRENT_CONTEXT(ctx);
662   window_pos3f(x, y, z);
663   ctx->Current.RasterPos[3] = w;
664}
665
666
667void GLAPIENTRY
668_mesa_WindowPos2dMESA(GLdouble x, GLdouble y)
669{
670   window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
671}
672
673void GLAPIENTRY
674_mesa_WindowPos2fMESA(GLfloat x, GLfloat y)
675{
676   window_pos4f(x, y, 0.0F, 1.0F);
677}
678
679void GLAPIENTRY
680_mesa_WindowPos2iMESA(GLint x, GLint y)
681{
682   window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
683}
684
685void GLAPIENTRY
686_mesa_WindowPos2sMESA(GLshort x, GLshort y)
687{
688   window_pos4f(x, y, 0.0F, 1.0F);
689}
690
691void GLAPIENTRY
692_mesa_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
693{
694   window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
695}
696
697void GLAPIENTRY
698_mesa_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z)
699{
700   window_pos4f(x, y, z, 1.0F);
701}
702
703void GLAPIENTRY
704_mesa_WindowPos3iMESA(GLint x, GLint y, GLint z)
705{
706   window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
707}
708
709void GLAPIENTRY
710_mesa_WindowPos3sMESA(GLshort x, GLshort y, GLshort z)
711{
712   window_pos4f(x, y, z, 1.0F);
713}
714
715void GLAPIENTRY
716_mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
717{
718   window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
719}
720
721void GLAPIENTRY
722_mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
723{
724   window_pos4f(x, y, z, w);
725}
726
727void GLAPIENTRY
728_mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w)
729{
730   window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
731}
732
733void GLAPIENTRY
734_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w)
735{
736   window_pos4f(x, y, z, w);
737}
738
739void GLAPIENTRY
740_mesa_WindowPos2dvMESA(const GLdouble *v)
741{
742   window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
743}
744
745void GLAPIENTRY
746_mesa_WindowPos2fvMESA(const GLfloat *v)
747{
748   window_pos4f(v[0], v[1], 0.0F, 1.0F);
749}
750
751void GLAPIENTRY
752_mesa_WindowPos2ivMESA(const GLint *v)
753{
754   window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
755}
756
757void GLAPIENTRY
758_mesa_WindowPos2svMESA(const GLshort *v)
759{
760   window_pos4f(v[0], v[1], 0.0F, 1.0F);
761}
762
763void GLAPIENTRY
764_mesa_WindowPos3dvMESA(const GLdouble *v)
765{
766   window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
767}
768
769void GLAPIENTRY
770_mesa_WindowPos3fvMESA(const GLfloat *v)
771{
772   window_pos4f(v[0], v[1], v[2], 1.0);
773}
774
775void GLAPIENTRY
776_mesa_WindowPos3ivMESA(const GLint *v)
777{
778   window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
779}
780
781void GLAPIENTRY
782_mesa_WindowPos3svMESA(const GLshort *v)
783{
784   window_pos4f(v[0], v[1], v[2], 1.0F);
785}
786
787void GLAPIENTRY
788_mesa_WindowPos4dvMESA(const GLdouble *v)
789{
790   window_pos4f((GLfloat) v[0], (GLfloat) v[1],
791			 (GLfloat) v[2], (GLfloat) v[3]);
792}
793
794void GLAPIENTRY
795_mesa_WindowPos4fvMESA(const GLfloat *v)
796{
797   window_pos4f(v[0], v[1], v[2], v[3]);
798}
799
800void GLAPIENTRY
801_mesa_WindowPos4ivMESA(const GLint *v)
802{
803   window_pos4f((GLfloat) v[0], (GLfloat) v[1],
804			 (GLfloat) v[2], (GLfloat) v[3]);
805}
806
807void GLAPIENTRY
808_mesa_WindowPos4svMESA(const GLshort *v)
809{
810   window_pos4f(v[0], v[1], v[2], v[3]);
811}
812
813#endif
814
815#if 0
816
817/*
818 * OpenGL implementation of glWindowPos*MESA()
819 */
820void glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
821{
822   GLfloat fx, fy;
823
824   /* Push current matrix mode and viewport attributes */
825   glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
826
827   /* Setup projection parameters */
828   glMatrixMode( GL_PROJECTION );
829   glPushMatrix();
830   glLoadIdentity();
831   glMatrixMode( GL_MODELVIEW );
832   glPushMatrix();
833   glLoadIdentity();
834
835   glDepthRange( z, z );
836   glViewport( (int) x - 1, (int) y - 1, 2, 2 );
837
838   /* set the raster (window) position */
839   fx = x - (int) x;
840   fy = y - (int) y;
841   glRasterPos4f( fx, fy, 0.0, w );
842
843   /* restore matrices, viewport and matrix mode */
844   glPopMatrix();
845   glMatrixMode( GL_PROJECTION );
846   glPopMatrix();
847
848   glPopAttrib();
849}
850
851#endif
852
853
854/**********************************************************************/
855/** \name Initialization                                              */
856/**********************************************************************/
857/*@{*/
858
859/**
860 * Initialize the context current raster position information.
861 *
862 * \param ctx GL context.
863 *
864 * Initialize the current raster position information in
865 * __GLcontextRec::Current, and adds the extension entry points to the
866 * dispatcher.
867 */
868void _mesa_init_rastpos( GLcontext * ctx )
869{
870   int i;
871
872   ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
873   ctx->Current.RasterDistance = 0.0;
874   ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
875   ctx->Current.RasterIndex = 1;
876   for (i=0; i<MAX_TEXTURE_UNITS; i++)
877      ASSIGN_4V( ctx->Current.RasterTexCoords[i], 0.0, 0.0, 0.0, 1.0 );
878   ctx->Current.RasterPosValid = GL_TRUE;
879
880  /*
881    * For XFree86/DRI: tell libGL to add these functions to the dispatcher.
882    * Basically, we should add all extension functions above offset 577.
883    * This enables older libGL libraries to work with newer drivers that
884    * have newer extensions.
885    */
886   /* GL_ARB_window_pos aliases with GL_MESA_window_pos */
887   _glapi_add_entrypoint("glWindowPos2dARB", 513);
888   _glapi_add_entrypoint("glWindowPos2dvARB", 514);
889   _glapi_add_entrypoint("glWindowPos2fARB", 515);
890   _glapi_add_entrypoint("glWindowPos2fvARB", 516);
891   _glapi_add_entrypoint("glWindowPos2iARB", 517);
892   _glapi_add_entrypoint("glWindowPos2ivARB", 518);
893   _glapi_add_entrypoint("glWindowPos2sARB", 519);
894   _glapi_add_entrypoint("glWindowPos2svARB", 520);
895   _glapi_add_entrypoint("glWindowPos3dARB", 521);
896   _glapi_add_entrypoint("glWindowPos3dvARB", 522);
897   _glapi_add_entrypoint("glWindowPos3fARB", 523);
898   _glapi_add_entrypoint("glWindowPos3fvARB", 524);
899   _glapi_add_entrypoint("glWindowPos3iARB", 525);
900   _glapi_add_entrypoint("glWindowPos3ivARB", 526);
901   _glapi_add_entrypoint("glWindowPos3sARB", 527);
902   _glapi_add_entrypoint("glWindowPos3svARB", 528);
903}
904
905/*@}*/
906