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 */ 53static GLuint 54viewclip_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 */ 73static GLuint 74viewclip_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 */ 92static GLuint 93viewclip_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 */ 112static GLuint 113userclip_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 */ 140static void 141shade_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 */ 289static void 290compute_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 */ 397void 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 */ 532static void 533rasterpos(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 553void GLAPIENTRY 554_mesa_RasterPos2d(GLdouble x, GLdouble y) 555{ 556 rasterpos((GLfloat)x, (GLfloat)y, (GLfloat)0.0, (GLfloat)1.0); 557} 558 559void GLAPIENTRY 560_mesa_RasterPos2f(GLfloat x, GLfloat y) 561{ 562 rasterpos(x, y, 0.0F, 1.0F); 563} 564 565void GLAPIENTRY 566_mesa_RasterPos2i(GLint x, GLint y) 567{ 568 rasterpos((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 569} 570 571void GLAPIENTRY 572_mesa_RasterPos2s(GLshort x, GLshort y) 573{ 574 rasterpos(x, y, 0.0F, 1.0F); 575} 576 577void GLAPIENTRY 578_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z) 579{ 580 rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 581} 582 583void GLAPIENTRY 584_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z) 585{ 586 rasterpos(x, y, z, 1.0F); 587} 588 589void GLAPIENTRY 590_mesa_RasterPos3i(GLint x, GLint y, GLint z) 591{ 592 rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 593} 594 595void GLAPIENTRY 596_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z) 597{ 598 rasterpos(x, y, z, 1.0F); 599} 600 601void GLAPIENTRY 602_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) 603{ 604 rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); 605} 606 607void GLAPIENTRY 608_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 609{ 610 rasterpos(x, y, z, w); 611} 612 613void GLAPIENTRY 614_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w) 615{ 616 rasterpos((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); 617} 618 619void GLAPIENTRY 620_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) 621{ 622 rasterpos(x, y, z, w); 623} 624 625void GLAPIENTRY 626_mesa_RasterPos2dv(const GLdouble *v) 627{ 628 rasterpos((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 629} 630 631void GLAPIENTRY 632_mesa_RasterPos2fv(const GLfloat *v) 633{ 634 rasterpos(v[0], v[1], 0.0F, 1.0F); 635} 636 637void GLAPIENTRY 638_mesa_RasterPos2iv(const GLint *v) 639{ 640 rasterpos((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 641} 642 643void GLAPIENTRY 644_mesa_RasterPos2sv(const GLshort *v) 645{ 646 rasterpos(v[0], v[1], 0.0F, 1.0F); 647} 648 649void GLAPIENTRY 650_mesa_RasterPos3dv(const GLdouble *v) 651{ 652 rasterpos((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 653} 654 655void GLAPIENTRY 656_mesa_RasterPos3fv(const GLfloat *v) 657{ 658 rasterpos(v[0], v[1], v[2], 1.0F); 659} 660 661void GLAPIENTRY 662_mesa_RasterPos3iv(const GLint *v) 663{ 664 rasterpos((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 665} 666 667void GLAPIENTRY 668_mesa_RasterPos3sv(const GLshort *v) 669{ 670 rasterpos(v[0], v[1], v[2], 1.0F); 671} 672 673void GLAPIENTRY 674_mesa_RasterPos4dv(const GLdouble *v) 675{ 676 rasterpos((GLfloat) v[0], (GLfloat) v[1], 677 (GLfloat) v[2], (GLfloat) v[3]); 678} 679 680void GLAPIENTRY 681_mesa_RasterPos4fv(const GLfloat *v) 682{ 683 rasterpos(v[0], v[1], v[2], v[3]); 684} 685 686void GLAPIENTRY 687_mesa_RasterPos4iv(const GLint *v) 688{ 689 rasterpos((GLfloat) v[0], (GLfloat) v[1], 690 (GLfloat) v[2], (GLfloat) v[3]); 691} 692 693void GLAPIENTRY 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 */ 709static void 710window_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 */ 770static void 771window_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 779void GLAPIENTRY 780_mesa_WindowPos2d(GLdouble x, GLdouble y) 781{ 782 window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 783} 784 785void GLAPIENTRY 786_mesa_WindowPos2f(GLfloat x, GLfloat y) 787{ 788 window_pos4f(x, y, 0.0F, 1.0F); 789} 790 791void GLAPIENTRY 792_mesa_WindowPos2i(GLint x, GLint y) 793{ 794 window_pos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); 795} 796 797void GLAPIENTRY 798_mesa_WindowPos2s(GLshort x, GLshort y) 799{ 800 window_pos4f(x, y, 0.0F, 1.0F); 801} 802 803void GLAPIENTRY 804_mesa_WindowPos3d(GLdouble x, GLdouble y, GLdouble z) 805{ 806 window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 807} 808 809void GLAPIENTRY 810_mesa_WindowPos3f(GLfloat x, GLfloat y, GLfloat z) 811{ 812 window_pos4f(x, y, z, 1.0F); 813} 814 815void GLAPIENTRY 816_mesa_WindowPos3i(GLint x, GLint y, GLint z) 817{ 818 window_pos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); 819} 820 821void GLAPIENTRY 822_mesa_WindowPos3s(GLshort x, GLshort y, GLshort z) 823{ 824 window_pos4f(x, y, z, 1.0F); 825} 826 827void GLAPIENTRY 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 833void GLAPIENTRY 834_mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 835{ 836 window_pos4f(x, y, z, w); 837} 838 839void GLAPIENTRY 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 845void GLAPIENTRY 846_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w) 847{ 848 window_pos4f(x, y, z, w); 849} 850 851void GLAPIENTRY 852_mesa_WindowPos2dv(const GLdouble *v) 853{ 854 window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 855} 856 857void GLAPIENTRY 858_mesa_WindowPos2fv(const GLfloat *v) 859{ 860 window_pos4f(v[0], v[1], 0.0F, 1.0F); 861} 862 863void GLAPIENTRY 864_mesa_WindowPos2iv(const GLint *v) 865{ 866 window_pos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); 867} 868 869void GLAPIENTRY 870_mesa_WindowPos2sv(const GLshort *v) 871{ 872 window_pos4f(v[0], v[1], 0.0F, 1.0F); 873} 874 875void GLAPIENTRY 876_mesa_WindowPos3dv(const GLdouble *v) 877{ 878 window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 879} 880 881void GLAPIENTRY 882_mesa_WindowPos3fv(const GLfloat *v) 883{ 884 window_pos4f(v[0], v[1], v[2], 1.0); 885} 886 887void GLAPIENTRY 888_mesa_WindowPos3iv(const GLint *v) 889{ 890 window_pos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); 891} 892 893void GLAPIENTRY 894_mesa_WindowPos3sv(const GLshort *v) 895{ 896 window_pos4f(v[0], v[1], v[2], 1.0F); 897} 898 899void GLAPIENTRY 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 906void GLAPIENTRY 907_mesa_WindowPos4fvMESA(const GLfloat *v) 908{ 909 window_pos4f(v[0], v[1], v[2], v[3]); 910} 911 912void GLAPIENTRY 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 919void GLAPIENTRY 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 */ 931void 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 */ 979void _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