Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent_rasterpos.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00026 #include "main/glheader.h" 00027 #include "main/colormac.h" 00028 #include "main/context.h" 00029 #include "feedback.h" 00030 #include "light.h" 00031 #include "main/macros.h" 00032 #include "rastpos.h" 00033 #include "simple_list.h" 00034 #include "main/mtypes.h" 00035 00036 #include "math/m_matrix.h" 00037 #include "tnl/tnl.h" 00038 00039 00040 00048 static GLuint 00049 viewclip_point( const GLfloat v[] ) 00050 { 00051 if ( v[0] > v[3] || v[0] < -v[3] 00052 || v[1] > v[3] || v[1] < -v[3] 00053 || v[2] > v[3] || v[2] < -v[3] ) { 00054 return 0; 00055 } 00056 else { 00057 return 1; 00058 } 00059 } 00060 00061 00069 static GLuint 00070 viewclip_point_z( const GLfloat v[] ) 00071 { 00072 if (v[2] > v[3] || v[2] < -v[3] ) { 00073 return 0; 00074 } 00075 else { 00076 return 1; 00077 } 00078 } 00079 00080 00089 static GLuint 00090 userclip_point( GLcontext *ctx, const GLfloat v[] ) 00091 { 00092 GLuint p; 00093 00094 for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { 00095 if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { 00096 GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0] 00097 + v[1] * ctx->Transform._ClipUserPlane[p][1] 00098 + v[2] * ctx->Transform._ClipUserPlane[p][2] 00099 + v[3] * ctx->Transform._ClipUserPlane[p][3]; 00100 if (dot < 0.0F) { 00101 return 0; 00102 } 00103 } 00104 } 00105 00106 return 1; 00107 } 00108 00109 00119 static void 00120 shade_rastpos(GLcontext *ctx, 00121 const GLfloat vertex[4], 00122 const GLfloat normal[3], 00123 GLfloat Rcolor[4], 00124 GLfloat Rspec[4], 00125 GLfloat *Rindex) 00126 { 00127 /*const*/ GLfloat (*base)[3] = ctx->Light._BaseColor; 00128 const struct gl_light *light; 00129 GLfloat diffuseColor[4], specularColor[4]; /* for RGB mode only */ 00130 GLfloat diffuseCI = 0.0, specularCI = 0.0; /* for CI mode only */ 00131 00132 _mesa_validate_all_lighting_tables( ctx ); 00133 00134 COPY_3V(diffuseColor, base[0]); 00135 diffuseColor[3] = CLAMP( 00136 ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3], 0.0F, 1.0F ); 00137 ASSIGN_4V(specularColor, 0.0, 0.0, 0.0, 1.0); 00138 00139 foreach (light, &ctx->Light.EnabledList) { 00140 GLfloat attenuation = 1.0; 00141 GLfloat VP[3]; /* vector from vertex to light pos */ 00142 GLfloat n_dot_VP; 00143 GLfloat diffuseContrib[3], specularContrib[3]; 00144 00145 if (!(light->_Flags & LIGHT_POSITIONAL)) { 00146 /* light at infinity */ 00147 COPY_3V(VP, light->_VP_inf_norm); 00148 attenuation = light->_VP_inf_spot_attenuation; 00149 } 00150 else { 00151 /* local/positional light */ 00152 GLfloat d; 00153 00154 /* VP = vector from vertex pos to light[i].pos */ 00155 SUB_3V(VP, light->_Position, vertex); 00156 /* d = length(VP) */ 00157 d = (GLfloat) LEN_3FV( VP ); 00158 if (d > 1.0e-6) { 00159 /* normalize VP */ 00160 GLfloat invd = 1.0F / d; 00161 SELF_SCALE_SCALAR_3V(VP, invd); 00162 } 00163 00164 /* atti */ 00165 attenuation = 1.0F / (light->ConstantAttenuation + d * 00166 (light->LinearAttenuation + d * 00167 light->QuadraticAttenuation)); 00168 00169 if (light->_Flags & LIGHT_SPOT) { 00170 GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); 00171 00172 if (PV_dot_dir<light->_CosCutoff) { 00173 continue; 00174 } 00175 else { 00176 double x = PV_dot_dir * (EXP_TABLE_SIZE-1); 00177 int k = (int) x; 00178 GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] 00179 + (x-k)*light->_SpotExpTable[k][1]); 00180 attenuation *= spot; 00181 } 00182 } 00183 } 00184 00185 if (attenuation < 1e-3) 00186 continue; 00187 00188 n_dot_VP = DOT3( normal, VP ); 00189 00190 if (n_dot_VP < 0.0F) { 00191 ACC_SCALE_SCALAR_3V(diffuseColor, attenuation, light->_MatAmbient[0]); 00192 continue; 00193 } 00194 00195 /* Ambient + diffuse */ 00196 COPY_3V(diffuseContrib, light->_MatAmbient[0]); 00197 ACC_SCALE_SCALAR_3V(diffuseContrib, n_dot_VP, light->_MatDiffuse[0]); 00198 diffuseCI += n_dot_VP * light->_dli * attenuation; 00199 00200 /* Specular */ 00201 { 00202 const GLfloat *h; 00203 GLfloat n_dot_h; 00204 00205 ASSIGN_3V(specularContrib, 0.0, 0.0, 0.0); 00206 00207 if (ctx->Light.Model.LocalViewer) { 00208 GLfloat v[3]; 00209 COPY_3V(v, vertex); 00210 NORMALIZE_3FV(v); 00211 SUB_3V(VP, VP, v); 00212 NORMALIZE_3FV(VP); 00213 h = VP; 00214 } 00215 else if (light->_Flags & LIGHT_POSITIONAL) { 00216 ACC_3V(VP, ctx->_EyeZDir); 00217 NORMALIZE_3FV(VP); 00218 h = VP; 00219 } 00220 else { 00221 h = light->_h_inf_norm; 00222 } 00223 00224 n_dot_h = DOT3(normal, h); 00225 00226 if (n_dot_h > 0.0F) { 00227 GLfloat spec_coef; 00228 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef ); 00229 00230 if (spec_coef > 1.0e-10) { 00231 if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) { 00232 ACC_SCALE_SCALAR_3V( specularContrib, spec_coef, 00233 light->_MatSpecular[0]); 00234 } 00235 else { 00236 ACC_SCALE_SCALAR_3V( diffuseContrib, spec_coef, 00237 light->_MatSpecular[0]); 00238 } 00239 /*assert(light->_sli > 0.0);*/ 00240 specularCI += spec_coef * light->_sli * attenuation; 00241 } 00242 } 00243 } 00244 00245 ACC_SCALE_SCALAR_3V( diffuseColor, attenuation, diffuseContrib ); 00246 ACC_SCALE_SCALAR_3V( specularColor, attenuation, specularContrib ); 00247 } 00248 00249 if (ctx->Visual.rgbMode) { 00250 Rcolor[0] = CLAMP(diffuseColor[0], 0.0F, 1.0F); 00251 Rcolor[1] = CLAMP(diffuseColor[1], 0.0F, 1.0F); 00252 Rcolor[2] = CLAMP(diffuseColor[2], 0.0F, 1.0F); 00253 Rcolor[3] = CLAMP(diffuseColor[3], 0.0F, 1.0F); 00254 Rspec[0] = CLAMP(specularColor[0], 0.0F, 1.0F); 00255 Rspec[1] = CLAMP(specularColor[1], 0.0F, 1.0F); 00256 Rspec[2] = CLAMP(specularColor[2], 0.0F, 1.0F); 00257 Rspec[3] = CLAMP(specularColor[3], 0.0F, 1.0F); 00258 } 00259 else { 00260 GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES]; 00261 GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT]; 00262 GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT]; 00263 GLfloat i = (ind[MAT_INDEX_AMBIENT] 00264 + diffuseCI * (1.0F-specularCI) * d_a 00265 + specularCI * s_a); 00266 if (i > ind[MAT_INDEX_SPECULAR]) { 00267 i = ind[MAT_INDEX_SPECULAR]; 00268 } 00269 *Rindex = i; 00270 } 00271 } 00272 00273 00283 static void 00284 compute_texgen(GLcontext *ctx, const GLfloat vObj[4], const GLfloat vEye[4], 00285 const GLfloat normal[3], GLuint unit, GLfloat texcoord[4]) 00286 { 00287 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 00288 00289 /* always compute sphere map terms, just in case */ 00290 GLfloat u[3], two_nu, rx, ry, rz, m, mInv; 00291 COPY_3V(u, vEye); 00292 NORMALIZE_3FV(u); 00293 two_nu = 2.0F * DOT3(normal, u); 00294 rx = u[0] - normal[0] * two_nu; 00295 ry = u[1] - normal[1] * two_nu; 00296 rz = u[2] - normal[2] * two_nu; 00297 m = rx * rx + ry * ry + (rz + 1.0F) * (rz + 1.0F); 00298 if (m > 0.0F) 00299 mInv = 0.5F * _mesa_inv_sqrtf(m); 00300 else 00301 mInv = 0.0F; 00302 00303 if (texUnit->TexGenEnabled & S_BIT) { 00304 switch (texUnit->GenModeS) { 00305 case GL_OBJECT_LINEAR: 00306 texcoord[0] = DOT4(vObj, texUnit->ObjectPlaneS); 00307 break; 00308 case GL_EYE_LINEAR: 00309 texcoord[0] = DOT4(vEye, texUnit->EyePlaneS); 00310 break; 00311 case GL_SPHERE_MAP: 00312 texcoord[0] = rx * mInv + 0.5F; 00313 break; 00314 case GL_REFLECTION_MAP: 00315 texcoord[0] = rx; 00316 break; 00317 case GL_NORMAL_MAP: 00318 texcoord[0] = normal[0]; 00319 break; 00320 default: 00321 _mesa_problem(ctx, "Bad S texgen in compute_texgen()"); 00322 return; 00323 } 00324 } 00325 00326 if (texUnit->TexGenEnabled & T_BIT) { 00327 switch (texUnit->GenModeT) { 00328 case GL_OBJECT_LINEAR: 00329 texcoord[1] = DOT4(vObj, texUnit->ObjectPlaneT); 00330 break; 00331 case GL_EYE_LINEAR: 00332 texcoord[1] = DOT4(vEye, texUnit->EyePlaneT); 00333 break; 00334 case GL_SPHERE_MAP: 00335 texcoord[1] = ry * mInv + 0.5F; 00336 break; 00337 case GL_REFLECTION_MAP: 00338 texcoord[1] = ry; 00339 break; 00340 case GL_NORMAL_MAP: 00341 texcoord[1] = normal[1]; 00342 break; 00343 default: 00344 _mesa_problem(ctx, "Bad T texgen in compute_texgen()"); 00345 return; 00346 } 00347 } 00348 00349 if (texUnit->TexGenEnabled & R_BIT) { 00350 switch (texUnit->GenModeR) { 00351 case GL_OBJECT_LINEAR: 00352 texcoord[2] = DOT4(vObj, texUnit->ObjectPlaneR); 00353 break; 00354 case GL_EYE_LINEAR: 00355 texcoord[2] = DOT4(vEye, texUnit->EyePlaneR); 00356 break; 00357 case GL_REFLECTION_MAP: 00358 texcoord[2] = rz; 00359 break; 00360 case GL_NORMAL_MAP: 00361 texcoord[2] = normal[2]; 00362 break; 00363 default: 00364 _mesa_problem(ctx, "Bad R texgen in compute_texgen()"); 00365 return; 00366 } 00367 } 00368 00369 if (texUnit->TexGenEnabled & Q_BIT) { 00370 switch (texUnit->GenModeQ) { 00371 case GL_OBJECT_LINEAR: 00372 texcoord[3] = DOT4(vObj, texUnit->ObjectPlaneQ); 00373 break; 00374 case GL_EYE_LINEAR: 00375 texcoord[3] = DOT4(vEye, texUnit->EyePlaneQ); 00376 break; 00377 default: 00378 _mesa_problem(ctx, "Bad Q texgen in compute_texgen()"); 00379 return; 00380 } 00381 } 00382 } 00383 00384 00393 void 00394 _tnl_RasterPos(GLcontext *ctx, const GLfloat vObj[4]) 00395 { 00396 if (ctx->VertexProgram._Enabled) { 00397 /* XXX implement this */ 00398 _mesa_problem(ctx, "Vertex programs not implemented for glRasterPos"); 00399 return; 00400 } 00401 else { 00402 GLfloat eye[4], clip[4], ndc[3], d; 00403 GLfloat *norm, eyenorm[3]; 00404 GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; 00405 00406 /* apply modelview matrix: eye = MV * obj */ 00407 TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, vObj ); 00408 /* apply projection matrix: clip = Proj * eye */ 00409 TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye ); 00410 00411 /* clip to view volume */ 00412 if (ctx->Transform.RasterPositionUnclipped) { 00413 /* GL_IBM_rasterpos_clip: only clip against Z */ 00414 if (viewclip_point_z(clip) == 0) { 00415 ctx->Current.RasterPosValid = GL_FALSE; 00416 return; 00417 } 00418 } 00419 else if (viewclip_point(clip) == 0) { 00420 /* Normal OpenGL behaviour */ 00421 ctx->Current.RasterPosValid = GL_FALSE; 00422 return; 00423 } 00424 00425 /* clip to user clipping planes */ 00426 if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clip)) { 00427 ctx->Current.RasterPosValid = GL_FALSE; 00428 return; 00429 } 00430 00431 /* ndc = clip / W */ 00432 d = (clip[3] == 0.0F) ? 1.0F : 1.0F / clip[3]; 00433 ndc[0] = clip[0] * d; 00434 ndc[1] = clip[1] * d; 00435 ndc[2] = clip[2] * d; 00436 /* wincoord = viewport_mapping(ndc) */ 00437 ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport._WindowMap.m[MAT_SX] 00438 + ctx->Viewport._WindowMap.m[MAT_TX]); 00439 ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport._WindowMap.m[MAT_SY] 00440 + ctx->Viewport._WindowMap.m[MAT_TY]); 00441 ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ] 00442 + ctx->Viewport._WindowMap.m[MAT_TZ]) 00443 / ctx->DrawBuffer->_DepthMaxF; 00444 ctx->Current.RasterPos[3] = clip[3]; 00445 00446 /* compute raster distance */ 00447 if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) 00448 ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; 00449 else 00450 ctx->Current.RasterDistance = 00451 SQRTF( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] ); 00452 00453 /* compute transformed normal vector (for lighting or texgen) */ 00454 if (ctx->_NeedEyeCoords) { 00455 const GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv; 00456 TRANSFORM_NORMAL( eyenorm, objnorm, inv ); 00457 norm = eyenorm; 00458 } 00459 else { 00460 norm = objnorm; 00461 } 00462 00463 /* update raster color */ 00464 if (ctx->Light.Enabled) { 00465 /* lighting */ 00466 shade_rastpos( ctx, vObj, norm, 00467 ctx->Current.RasterColor, 00468 ctx->Current.RasterSecondaryColor, 00469 &ctx->Current.RasterIndex ); 00470 } 00471 else { 00472 /* use current color or index */ 00473 if (ctx->Visual.rgbMode) { 00474 COPY_4FV(ctx->Current.RasterColor, 00475 ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); 00476 COPY_4FV(ctx->Current.RasterSecondaryColor, 00477 ctx->Current.Attrib[VERT_ATTRIB_COLOR1]); 00478 } 00479 else { 00480 ctx->Current.RasterIndex 00481 = ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]; 00482 } 00483 } 00484 00485 /* texture coords */ 00486 { 00487 GLuint u; 00488 for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { 00489 GLfloat tc[4]; 00490 COPY_4V(tc, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]); 00491 if (ctx->Texture.Unit[u].TexGenEnabled) { 00492 compute_texgen(ctx, vObj, eye, norm, u, tc); 00493 } 00494 TRANSFORM_POINT(ctx->Current.RasterTexCoords[u], 00495 ctx->TextureMatrixStack[u].Top->m, tc); 00496 } 00497 } 00498 00499 ctx->Current.RasterPosValid = GL_TRUE; 00500 } 00501 00502 if (ctx->RenderMode == GL_SELECT) { 00503 _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); 00504 } 00505 } Generated on Sat May 26 2012 04:19:35 for ReactOS by
1.7.6.1
|