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