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