1 2 /* 3 * Mesa 3-D graphics library 4 * Version: 3.5 5 * 6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Keith Whitwell <keith (at) tungstengraphics.com> 27 */ 28 #include "math/m_translate.h" 29 30 #if (HAVE_HW_VIEWPORT) 31 #define UNVIEWPORT_VARS 32 #define UNVIEWPORT_X(x) x 33 #define UNVIEWPORT_Y(x) x 34 #define UNVIEWPORT_Z(x) x 35 #endif 36 37 #ifndef LOCALVARS 38 #define LOCALVARS 39 #endif 40 41 #ifndef CHECK_HW_DIVIDE 42 #define CHECK_HW_DIVIDE 1 43 #endif 44 45 /* These don't need to be duplicated, but there's currently nowhere 46 * really convenient to put them. Need to build some actual .o files in 47 * this directory? 48 */ 49 static void copy_pv_rgba4_spec5( struct gl_context *ctx, GLuint edst, GLuint esrc ) 50 { 51 LOCALVARS 52 GLubyte *verts = GET_VERTEX_STORE(); 53 GLuint size = GET_VERTEX_SIZE(); 54 GLuint *dst = (GLuint *)(verts + (edst * size)); 55 GLuint *src = (GLuint *)(verts + (esrc * size)); 56 dst[4] = src[4]; 57 dst[5] = src[5]; 58 } 59 60 static void copy_pv_rgba4( struct gl_context *ctx, GLuint edst, GLuint esrc ) 61 { 62 LOCALVARS 63 GLubyte *verts = GET_VERTEX_STORE(); 64 GLuint size = GET_VERTEX_SIZE(); 65 GLuint *dst = (GLuint *)(verts + (edst * size)); 66 GLuint *src = (GLuint *)(verts + (esrc * size)); 67 dst[4] = src[4]; 68 } 69 70 static void copy_pv_rgba3( struct gl_context *ctx, GLuint edst, GLuint esrc ) 71 { 72 LOCALVARS 73 GLubyte *verts = GET_VERTEX_STORE(); 74 GLuint size = GET_VERTEX_SIZE(); 75 GLuint *dst = (GLuint *)(verts + (edst * size)); 76 GLuint *src = (GLuint *)(verts + (esrc * size)); 77 dst[3] = src[3]; 78 } 79 80 81 void TAG(translate_vertex)(struct gl_context *ctx, 82 const VERTEX *src, 83 SWvertex *dst) 84 { 85 LOCALVARS 86 GLuint format = GET_VERTEX_FORMAT(); 87 GLfloat *s = ctx->Viewport._WindowMap.m; 88 UNVIEWPORT_VARS; 89 90 if (format == TINY_VERTEX_FORMAT) { 91 if (HAVE_HW_VIEWPORT) { 92 dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0] * src->v.x + s[12]; 93 dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5] * src->v.y + s[13]; 94 dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14]; 95 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; 96 } else { 97 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x ); 98 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y ); 99 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z ); 100 dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; 101 } 102 103 dst->color[0] = src->tv.color.red; 104 dst->color[1] = src->tv.color.green; 105 dst->color[2] = src->tv.color.blue; 106 dst->color[3] = src->tv.color.alpha; 107 } 108 else { 109 if (HAVE_HW_VIEWPORT) { 110 if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { 111 GLfloat oow = 1.0 / src->v.w; 112 dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0] * src->v.x * oow + s[12]; 113 dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5] * src->v.y * oow + s[13]; 114 dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z * oow + s[14]; 115 dst->attrib[FRAG_ATTRIB_WPOS][3] = oow; 116 } else { 117 dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0] * src->v.x + s[12]; 118 dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5] * src->v.y + s[13]; 119 dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14]; 120 dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w; 121 } 122 } else { 123 dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x ); 124 dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y ); 125 dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z ); 126 dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w; 127 } 128 129 dst->color[0] = src->v.color.red; 130 dst->color[1] = src->v.color.green; 131 dst->color[2] = src->v.color.blue; 132 dst->color[3] = src->v.color.alpha; 133 134 dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(src->v.specular.red); 135 dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(src->v.specular.green); 136 dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(src->v.specular.blue); 137 138 dst->attrib[FRAG_ATTRIB_FOGC][0] = UBYTE_TO_FLOAT(src->v.specular.alpha); 139 140 if (HAVE_PTEX_VERTICES && 141 ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) || 142 (format == PROJ_TEX1_VERTEX_FORMAT))) { 143 144 dst->attrib[FRAG_ATTRIB_TEX0][0] = src->pv.u0; 145 dst->attrib[FRAG_ATTRIB_TEX0][1] = src->pv.v0; 146 dst->attrib[FRAG_ATTRIB_TEX0][3] = src->pv.q0; 147 148 dst->attrib[FRAG_ATTRIB_TEX1][0] = src->pv.u1; 149 dst->attrib[FRAG_ATTRIB_TEX1][1] = src->pv.v1; 150 dst->attrib[FRAG_ATTRIB_TEX1][3] = src->pv.q1; 151 152 if (HAVE_TEX2_VERTICES) { 153 dst->attrib[FRAG_ATTRIB_TEX2][0] = src->pv.u2; 154 dst->attrib[FRAG_ATTRIB_TEX2][1] = src->pv.v2; 155 dst->attrib[FRAG_ATTRIB_TEX2][3] = src->pv.q2; 156 } 157 158 if (HAVE_TEX3_VERTICES) { 159 dst->attrib[FRAG_ATTRIB_TEX3][0] = src->pv.u3; 160 dst->attrib[FRAG_ATTRIB_TEX3][1] = src->pv.v3; 161 dst->attrib[FRAG_ATTRIB_TEX3][3] = src->pv.q3; 162 } 163 } 164 else { 165 dst->attrib[FRAG_ATTRIB_TEX0][0] = src->v.u0; 166 dst->attrib[FRAG_ATTRIB_TEX0][1] = src->v.v0; 167 dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0; 168 169 dst->attrib[FRAG_ATTRIB_TEX1][0] = src->v.u1; 170 dst->attrib[FRAG_ATTRIB_TEX1][1] = src->v.v1; 171 dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0; 172 173 if (HAVE_TEX2_VERTICES) { 174 dst->attrib[FRAG_ATTRIB_TEX2][0] = src->v.u2; 175 dst->attrib[FRAG_ATTRIB_TEX2][1] = src->v.v2; 176 dst->attrib[FRAG_ATTRIB_TEX2][3] = 1.0; 177 } 178 179 if (HAVE_TEX3_VERTICES) { 180 dst->attrib[FRAG_ATTRIB_TEX3][0] = src->v.u3; 181 dst->attrib[FRAG_ATTRIB_TEX3][1] = src->v.v3; 182 dst->attrib[FRAG_ATTRIB_TEX3][3] = 1.0; 183 } 184 } 185 } 186 187 dst->pointSize = ctx->Point.Size; 188 } 189 190 191 /* prototype to silence warning */ 192 void TAG(print_vertex)( struct gl_context *ctx, const VERTEX *v ); 193 194 195 void TAG(print_vertex)( struct gl_context *ctx, const VERTEX *v ) 196 { 197 LOCALVARS 198 GLuint format = GET_VERTEX_FORMAT(); 199 200 fprintf(stderr, "(%x) ", format); 201 202 switch (format) { 203 #if HAVE_TINY_VERTICES 204 case TINY_VERTEX_FORMAT: 205 fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n", 206 v->v.x, v->v.y, v->v.z, 207 v->tv.color.red, 208 v->tv.color.green, 209 v->tv.color.blue, 210 v->tv.color.alpha); 211 break; 212 #endif 213 #if HAVE_NOTEX_VERTICES 214 case NOTEX_VERTEX_FORMAT: 215 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n", 216 v->v.x, v->v.y, v->v.z, v->v.w, 217 v->v.color.red, 218 v->v.color.green, 219 v->v.color.blue, 220 v->v.color.alpha, 221 v->v.specular.red, 222 v->v.specular.green, 223 v->v.specular.blue, 224 v->v.specular.alpha); 225 break; 226 #endif 227 #if HAVE_TEX0_VERTICES 228 case TEX0_VERTEX_FORMAT: 229 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n", 230 v->v.x, v->v.y, v->v.z, v->v.w, 231 v->v.color.red, 232 v->v.color.green, 233 v->v.color.blue, 234 v->v.color.alpha, 235 v->v.u0, 236 v->v.v0); 237 break; 238 #endif 239 #if HAVE_TEX1_VERTICES 240 case TEX1_VERTEX_FORMAT: 241 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n", 242 v->v.x, v->v.y, v->v.z, v->v.w, 243 v->v.color.red, 244 v->v.color.green, 245 v->v.color.blue, 246 v->v.color.alpha, 247 v->v.u0, 248 v->v.v0, 249 v->v.u1, 250 v->v.u2); 251 break; 252 #endif 253 #if HAVE_PTEX_VERTICES 254 case PROJ_TEX1_VERTEX_FORMAT: 255 fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n", 256 v->v.x, v->v.y, v->v.z, v->v.w, 257 v->v.color.red, 258 v->v.color.green, 259 v->v.color.blue, 260 v->v.color.alpha, 261 v->pv.u0, 262 v->pv.v0, 263 v->pv.q0, 264 v->pv.u1, 265 v->pv.v1, 266 v->pv.q1); 267 break; 268 #endif 269 default: 270 fprintf(stderr, "???\n"); 271 break; 272 } 273 274 fprintf(stderr, "\n"); 275 } 276 277 278 279 /* Interpolate the elements of the VB not included in typical hardware 280 * vertices. 281 * 282 * NOTE: All these arrays are guarenteed by tnl to be writeable and 283 * have good stride. 284 */ 285 #ifndef INTERP_QUALIFIER 286 #define INTERP_QUALIFIER static 287 #endif 288 289 #define GET_COLOR(ptr, idx) ((ptr)->data[idx]) 290 291 292 INTERP_QUALIFIER void TAG(interp_extras)( struct gl_context *ctx, 293 GLfloat t, 294 GLuint dst, GLuint out, GLuint in, 295 GLboolean force_boundary ) 296 { 297 LOCALVARS 298 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 299 300 if (VB->BackfaceColorPtr) { 301 assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat)); 302 303 INTERP_4F( t, 304 GET_COLOR(VB->BackfaceColorPtr, dst), 305 GET_COLOR(VB->BackfaceColorPtr, out), 306 GET_COLOR(VB->BackfaceColorPtr, in) ); 307 308 if (VB->BackfaceSecondaryColorPtr) { 309 INTERP_3F( t, 310 GET_COLOR(VB->BackfaceSecondaryColorPtr, dst), 311 GET_COLOR(VB->BackfaceSecondaryColorPtr, out), 312 GET_COLOR(VB->BackfaceSecondaryColorPtr, in) ); 313 } 314 } 315 316 if (VB->EdgeFlag) { 317 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; 318 } 319 320 INTERP_VERTEX(ctx, t, dst, out, in, force_boundary); 321 } 322 323 INTERP_QUALIFIER void TAG(copy_pv_extras)( struct gl_context *ctx, 324 GLuint dst, GLuint src ) 325 { 326 LOCALVARS 327 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 328 329 if (VB->BackfaceColorPtr) { 330 COPY_4FV( GET_COLOR(VB->BackfaceColorPtr, dst), 331 GET_COLOR(VB->BackfaceColorPtr, src) ); 332 333 if (VB->BackfaceSecondaryColorPtr) { 334 COPY_4FV( GET_COLOR(VB->BackfaceSecondaryColorPtr, dst), 335 GET_COLOR(VB->BackfaceSecondaryColorPtr, src) ); 336 } 337 } 338 339 COPY_PV_VERTEX(ctx, dst, src); 340 } 341 342 343 #undef INTERP_QUALIFIER 344 #undef GET_COLOR 345 346 #undef IND 347 #undef TAG 348