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 26/* 27 * New (3.1) transformation code written by Keith Whitwell. 28 */ 29 30 31/*---------------------------------------------------------------------- 32 * Begin Keith's new code 33 * 34 *---------------------------------------------------------------------- 35 */ 36 37/* KW: Fixed stride, now measured in bytes as is the OpenGL array stride. 38 */ 39 40/* KW: These are now parameterized to produce two versions, one 41 * which transforms all incoming points, and a second which 42 * takes notice of a cullmask array, and only transforms 43 * unculled vertices. 44 */ 45 46/* KW: 1-vectors can sneak into the texture pipeline via the array 47 * interface. These functions are here because I want consistant 48 * treatment of the vertex sizes and a lazy strategy for 49 * cleaning unused parts of the vector, and so as not to exclude 50 * them from the vertex array interface. 51 * 52 * Under our current analysis of matrices, there is no way that 53 * the product of a matrix and a 1-vector can remain a 1-vector, 54 * with the exception of the identity transform. 55 */ 56 57/* KW: No longer zero-pad outgoing vectors. Now that external 58 * vectors can get into the pipeline we cannot ever assume 59 * that there is more to a vector than indicated by its 60 * size. 61 */ 62 63/* KW: Now uses clipmask and a flag to allow us to skip both/either 64 * cliped and/or culled vertices. 65 */ 66 67/* GH: Not any more -- it's easier (and faster) to just process the 68 * entire vector. Clipping and culling are handled further down 69 * the pipe, most often during or after the conversion to some 70 * driver-specific vertex format. 71 */ 72 73static void _XFORMAPI 74TAG(transform_points1_general)( GLvector4f *to_vec, 75 const GLfloat m[16], 76 const GLvector4f *from_vec ) 77{ 78 const GLuint stride = from_vec->stride; 79 GLfloat *from = from_vec->start; 80 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 81 GLuint count = from_vec->count; 82 const GLfloat m0 = m[0], m12 = m[12]; 83 const GLfloat m1 = m[1], m13 = m[13]; 84 const GLfloat m2 = m[2], m14 = m[14]; 85 const GLfloat m3 = m[3], m15 = m[15]; 86 GLuint i; 87 STRIDE_LOOP { 88 const GLfloat ox = from[0]; 89 to[i][0] = m0 * ox + m12; 90 to[i][1] = m1 * ox + m13; 91 to[i][2] = m2 * ox + m14; 92 to[i][3] = m3 * ox + m15; 93 } 94 to_vec->size = 4; 95 to_vec->flags |= VEC_SIZE_4; 96 to_vec->count = from_vec->count; 97} 98 99static void _XFORMAPI 100TAG(transform_points1_identity)( GLvector4f *to_vec, 101 const GLfloat m[16], 102 const GLvector4f *from_vec ) 103{ 104 const GLuint stride = from_vec->stride; 105 GLfloat *from = from_vec->start; 106 GLuint count = from_vec->count; 107 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 108 GLuint i; 109 (void) m; 110 if (to_vec == from_vec) return; 111 STRIDE_LOOP { 112 to[i][0] = from[0]; 113 } 114 to_vec->size = 1; 115 to_vec->flags |= VEC_SIZE_1; 116 to_vec->count = from_vec->count; 117} 118 119static void _XFORMAPI 120TAG(transform_points1_2d)( GLvector4f *to_vec, 121 const GLfloat m[16], 122 const GLvector4f *from_vec ) 123{ 124 const GLuint stride = from_vec->stride; 125 GLfloat *from = from_vec->start; 126 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 127 GLuint count = from_vec->count; 128 const GLfloat m0 = m[0], m1 = m[1]; 129 const GLfloat m12 = m[12], m13 = m[13]; 130 GLuint i; 131 STRIDE_LOOP { 132 const GLfloat ox = from[0]; 133 to[i][0] = m0 * ox + m12; 134 to[i][1] = m1 * ox + m13; 135 } 136 to_vec->size = 2; 137 to_vec->flags |= VEC_SIZE_2; 138 to_vec->count = from_vec->count; 139} 140 141static void _XFORMAPI 142TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec, 143 const GLfloat m[16], 144 const GLvector4f *from_vec ) 145{ 146 const GLuint stride = from_vec->stride; 147 GLfloat *from = from_vec->start; 148 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 149 GLuint count = from_vec->count; 150 const GLfloat m0 = m[0], m12 = m[12], m13 = m[13]; 151 GLuint i; 152 STRIDE_LOOP { 153 const GLfloat ox = from[0]; 154 to[i][0] = m0 * ox + m12; 155 to[i][1] = m13; 156 } 157 to_vec->size = 2; 158 to_vec->flags |= VEC_SIZE_2; 159 to_vec->count = from_vec->count; 160} 161 162static void _XFORMAPI 163TAG(transform_points1_3d)( GLvector4f *to_vec, 164 const GLfloat m[16], 165 const GLvector4f *from_vec ) 166{ 167 const GLuint stride = from_vec->stride; 168 GLfloat *from = from_vec->start; 169 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 170 GLuint count = from_vec->count; 171 const GLfloat m0 = m[0], m1 = m[1], m2 = m[2]; 172 const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; 173 GLuint i; 174 STRIDE_LOOP { 175 const GLfloat ox = from[0]; 176 to[i][0] = m0 * ox + m12; 177 to[i][1] = m1 * ox + m13; 178 to[i][2] = m2 * ox + m14; 179 } 180 to_vec->size = 3; 181 to_vec->flags |= VEC_SIZE_3; 182 to_vec->count = from_vec->count; 183} 184 185 186static void _XFORMAPI 187TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec, 188 const GLfloat m[16], 189 const GLvector4f *from_vec ) 190{ 191 const GLuint stride = from_vec->stride; 192 GLfloat *from = from_vec->start; 193 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 194 GLuint count = from_vec->count; 195 const GLfloat m0 = m[0]; 196 const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; 197 GLuint i; 198 STRIDE_LOOP { 199 const GLfloat ox = from[0]; 200 to[i][0] = m0 * ox + m12; 201 to[i][1] = m13; 202 to[i][2] = m14; 203 } 204 to_vec->size = 3; 205 to_vec->flags |= VEC_SIZE_3; 206 to_vec->count = from_vec->count; 207} 208 209static void _XFORMAPI 210TAG(transform_points1_perspective)( GLvector4f *to_vec, 211 const GLfloat m[16], 212 const GLvector4f *from_vec ) 213{ 214 const GLuint stride = from_vec->stride; 215 GLfloat *from = from_vec->start; 216 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 217 GLuint count = from_vec->count; 218 const GLfloat m0 = m[0], m14 = m[14]; 219 GLuint i; 220 STRIDE_LOOP { 221 const GLfloat ox = from[0]; 222 to[i][0] = m0 * ox ; 223 to[i][1] = 0 ; 224 to[i][2] = m14; 225 to[i][3] = 0; 226 } 227 to_vec->size = 4; 228 to_vec->flags |= VEC_SIZE_4; 229 to_vec->count = from_vec->count; 230} 231 232 233 234 235/* 2-vectors, which are a lot more relevant than 1-vectors, are 236 * present early in the geometry pipeline and throughout the 237 * texture pipeline. 238 */ 239static void _XFORMAPI 240TAG(transform_points2_general)( GLvector4f *to_vec, 241 const GLfloat m[16], 242 const GLvector4f *from_vec ) 243{ 244 const GLuint stride = from_vec->stride; 245 GLfloat *from = from_vec->start; 246 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 247 GLuint count = from_vec->count; 248 const GLfloat m0 = m[0], m4 = m[4], m12 = m[12]; 249 const GLfloat m1 = m[1], m5 = m[5], m13 = m[13]; 250 const GLfloat m2 = m[2], m6 = m[6], m14 = m[14]; 251 const GLfloat m3 = m[3], m7 = m[7], m15 = m[15]; 252 GLuint i; 253 STRIDE_LOOP { 254 const GLfloat ox = from[0], oy = from[1]; 255 to[i][0] = m0 * ox + m4 * oy + m12; 256 to[i][1] = m1 * ox + m5 * oy + m13; 257 to[i][2] = m2 * ox + m6 * oy + m14; 258 to[i][3] = m3 * ox + m7 * oy + m15; 259 } 260 to_vec->size = 4; 261 to_vec->flags |= VEC_SIZE_4; 262 to_vec->count = from_vec->count; 263} 264 265static void _XFORMAPI 266TAG(transform_points2_identity)( GLvector4f *to_vec, 267 const GLfloat m[16], 268 const GLvector4f *from_vec ) 269{ 270 const GLuint stride = from_vec->stride; 271 GLfloat *from = from_vec->start; 272 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 273 GLuint count = from_vec->count; 274 GLuint i; 275 (void) m; 276 if (to_vec == from_vec) return; 277 STRIDE_LOOP { 278 to[i][0] = from[0]; 279 to[i][1] = from[1]; 280 } 281 to_vec->size = 2; 282 to_vec->flags |= VEC_SIZE_2; 283 to_vec->count = from_vec->count; 284} 285 286static void _XFORMAPI 287TAG(transform_points2_2d)( GLvector4f *to_vec, 288 const GLfloat m[16], 289 const GLvector4f *from_vec ) 290{ 291 const GLuint stride = from_vec->stride; 292 GLfloat *from = from_vec->start; 293 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 294 GLuint count = from_vec->count; 295 const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; 296 const GLfloat m12 = m[12], m13 = m[13]; 297 GLuint i; 298 STRIDE_LOOP { 299 const GLfloat ox = from[0], oy = from[1]; 300 to[i][0] = m0 * ox + m4 * oy + m12; 301 to[i][1] = m1 * ox + m5 * oy + m13; 302 } 303 to_vec->size = 2; 304 to_vec->flags |= VEC_SIZE_2; 305 to_vec->count = from_vec->count; 306} 307 308static void _XFORMAPI 309TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec, 310 const GLfloat m[16], 311 const GLvector4f *from_vec ) 312{ 313 const GLuint stride = from_vec->stride; 314 GLfloat *from = from_vec->start; 315 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 316 GLuint count = from_vec->count; 317 const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; 318 GLuint i; 319 STRIDE_LOOP { 320 const GLfloat ox = from[0], oy = from[1]; 321 to[i][0] = m0 * ox + m12; 322 to[i][1] = m5 * oy + m13; 323 } 324 to_vec->size = 2; 325 to_vec->flags |= VEC_SIZE_2; 326 to_vec->count = from_vec->count; 327} 328 329static void _XFORMAPI 330TAG(transform_points2_3d)( GLvector4f *to_vec, 331 const GLfloat m[16], 332 const GLvector4f *from_vec ) 333{ 334 const GLuint stride = from_vec->stride; 335 GLfloat *from = from_vec->start; 336 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 337 GLuint count = from_vec->count; 338 const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; 339 const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14]; 340 GLuint i; 341 STRIDE_LOOP { 342 const GLfloat ox = from[0], oy = from[1]; 343 to[i][0] = m0 * ox + m4 * oy + m12; 344 to[i][1] = m1 * ox + m5 * oy + m13; 345 to[i][2] = m2 * ox + m6 * oy + m14; 346 } 347 to_vec->size = 3; 348 to_vec->flags |= VEC_SIZE_3; 349 to_vec->count = from_vec->count; 350} 351 352 353/* I would actually say this was a fairly important function, from 354 * a texture transformation point of view. 355 */ 356static void _XFORMAPI 357TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec, 358 const GLfloat m[16], 359 const GLvector4f *from_vec ) 360{ 361 const GLuint stride = from_vec->stride; 362 GLfloat *from = from_vec->start; 363 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 364 GLuint count = from_vec->count; 365 const GLfloat m0 = m[0], m5 = m[5]; 366 const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; 367 GLuint i; 368 STRIDE_LOOP { 369 const GLfloat ox = from[0], oy = from[1]; 370 to[i][0] = m0 * ox + m12; 371 to[i][1] = m5 * oy + m13; 372 to[i][2] = m14; 373 } 374 if (m14 == 0) { 375 to_vec->size = 2; 376 to_vec->flags |= VEC_SIZE_2; 377 } else { 378 to_vec->size = 3; 379 to_vec->flags |= VEC_SIZE_3; 380 } 381 to_vec->count = from_vec->count; 382} 383 384 385static void _XFORMAPI 386TAG(transform_points2_perspective)( GLvector4f *to_vec, 387 const GLfloat m[16], 388 const GLvector4f *from_vec ) 389{ 390 const GLuint stride = from_vec->stride; 391 GLfloat *from = from_vec->start; 392 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 393 GLuint count = from_vec->count; 394 const GLfloat m0 = m[0], m5 = m[5], m14 = m[14]; 395 GLuint i; 396 STRIDE_LOOP { 397 const GLfloat ox = from[0], oy = from[1]; 398 to[i][0] = m0 * ox ; 399 to[i][1] = m5 * oy ; 400 to[i][2] = m14; 401 to[i][3] = 0; 402 } 403 to_vec->size = 4; 404 to_vec->flags |= VEC_SIZE_4; 405 to_vec->count = from_vec->count; 406} 407 408 409 410static void _XFORMAPI 411TAG(transform_points3_general)( GLvector4f *to_vec, 412 const GLfloat m[16], 413 const GLvector4f *from_vec ) 414{ 415 const GLuint stride = from_vec->stride; 416 GLfloat *from = from_vec->start; 417 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 418 GLuint count = from_vec->count; 419 const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; 420 const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; 421 const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; 422 const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; 423 GLuint i; 424 STRIDE_LOOP { 425 const GLfloat ox = from[0], oy = from[1], oz = from[2]; 426 to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12; 427 to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13; 428 to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14; 429 to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15; 430 } 431 to_vec->size = 4; 432 to_vec->flags |= VEC_SIZE_4; 433 to_vec->count = from_vec->count; 434} 435 436static void _XFORMAPI 437TAG(transform_points3_identity)( GLvector4f *to_vec, 438 const GLfloat m[16], 439 const GLvector4f *from_vec ) 440{ 441 const GLuint stride = from_vec->stride; 442 GLfloat *from = from_vec->start; 443 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 444 GLuint count = from_vec->count; 445 GLuint i; 446 (void) m; 447 if (to_vec == from_vec) return; 448 STRIDE_LOOP { 449 to[i][0] = from[0]; 450 to[i][1] = from[1]; 451 to[i][2] = from[2]; 452 } 453 to_vec->size = 3; 454 to_vec->flags |= VEC_SIZE_3; 455 to_vec->count = from_vec->count; 456} 457 458static void _XFORMAPI 459TAG(transform_points3_2d)( GLvector4f *to_vec, 460 const GLfloat m[16], 461 const GLvector4f *from_vec ) 462{ 463 const GLuint stride = from_vec->stride; 464 GLfloat *from = from_vec->start; 465 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 466 GLuint count = from_vec->count; 467 const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; 468 const GLfloat m12 = m[12], m13 = m[13]; 469 GLuint i; 470 STRIDE_LOOP { 471 const GLfloat ox = from[0], oy = from[1], oz = from[2]; 472 to[i][0] = m0 * ox + m4 * oy + m12 ; 473 to[i][1] = m1 * ox + m5 * oy + m13 ; 474 to[i][2] = + oz ; 475 } 476 to_vec->size = 3; 477 to_vec->flags |= VEC_SIZE_3; 478 to_vec->count = from_vec->count; 479} 480 481static void _XFORMAPI 482TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec, 483 const GLfloat m[16], 484 const GLvector4f *from_vec ) 485{ 486 const GLuint stride = from_vec->stride; 487 GLfloat *from = from_vec->start; 488 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 489 GLuint count = from_vec->count; 490 const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; 491 GLuint i; 492 STRIDE_LOOP { 493 const GLfloat ox = from[0], oy = from[1], oz = from[2]; 494 to[i][0] = m0 * ox + m12 ; 495 to[i][1] = m5 * oy + m13 ; 496 to[i][2] = + oz ; 497 } 498 to_vec->size = 3; 499 to_vec->flags |= VEC_SIZE_3; 500 to_vec->count = from_vec->count; 501} 502 503static void _XFORMAPI 504TAG(transform_points3_3d)( GLvector4f *to_vec, 505 const GLfloat m[16], 506 const GLvector4f *from_vec ) 507{ 508 const GLuint stride = from_vec->stride; 509 GLfloat *from = from_vec->start; 510 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 511 GLuint count = from_vec->count; 512 const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; 513 const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; 514 const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; 515 GLuint i; 516 STRIDE_LOOP { 517 const GLfloat ox = from[0], oy = from[1], oz = from[2]; 518 to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 ; 519 to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 ; 520 to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 ; 521 } 522 to_vec->size = 3; 523 to_vec->flags |= VEC_SIZE_3; 524 to_vec->count = from_vec->count; 525} 526 527/* previously known as ortho... 528 */ 529static void _XFORMAPI 530TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec, 531 const GLfloat m[16], 532 const GLvector4f *from_vec ) 533{ 534 const GLuint stride = from_vec->stride; 535 GLfloat *from = from_vec->start; 536 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 537 GLuint count = from_vec->count; 538 const GLfloat m0 = m[0], m5 = m[5]; 539 const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; 540 GLuint i; 541 STRIDE_LOOP { 542 const GLfloat ox = from[0], oy = from[1], oz = from[2]; 543 to[i][0] = m0 * ox + m12 ; 544 to[i][1] = m5 * oy + m13 ; 545 to[i][2] = m10 * oz + m14 ; 546 } 547 to_vec->size = 3; 548 to_vec->flags |= VEC_SIZE_3; 549 to_vec->count = from_vec->count; 550} 551 552static void _XFORMAPI 553TAG(transform_points3_perspective)( GLvector4f *to_vec, 554 const GLfloat m[16], 555 const GLvector4f *from_vec ) 556{ 557 const GLuint stride = from_vec->stride; 558 GLfloat *from = from_vec->start; 559 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 560 GLuint count = from_vec->count; 561 const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; 562 const GLfloat m10 = m[10], m14 = m[14]; 563 GLuint i; 564 STRIDE_LOOP { 565 const GLfloat ox = from[0], oy = from[1], oz = from[2]; 566 to[i][0] = m0 * ox + m8 * oz ; 567 to[i][1] = m5 * oy + m9 * oz ; 568 to[i][2] = m10 * oz + m14 ; 569 to[i][3] = -oz ; 570 } 571 to_vec->size = 4; 572 to_vec->flags |= VEC_SIZE_4; 573 to_vec->count = from_vec->count; 574} 575 576 577 578static void _XFORMAPI 579TAG(transform_points4_general)( GLvector4f *to_vec, 580 const GLfloat m[16], 581 const GLvector4f *from_vec ) 582{ 583 const GLuint stride = from_vec->stride; 584 GLfloat *from = from_vec->start; 585 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 586 GLuint count = from_vec->count; 587 const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; 588 const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; 589 const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; 590 const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; 591 GLuint i; 592 STRIDE_LOOP { 593 const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; 594 to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; 595 to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; 596 to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; 597 to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow; 598 } 599 to_vec->size = 4; 600 to_vec->flags |= VEC_SIZE_4; 601 to_vec->count = from_vec->count; 602} 603 604static void _XFORMAPI 605TAG(transform_points4_identity)( GLvector4f *to_vec, 606 const GLfloat m[16], 607 const GLvector4f *from_vec ) 608{ 609 const GLuint stride = from_vec->stride; 610 GLfloat *from = from_vec->start; 611 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 612 GLuint count = from_vec->count; 613 GLuint i; 614 (void) m; 615 if (to_vec == from_vec) return; 616 STRIDE_LOOP { 617 to[i][0] = from[0]; 618 to[i][1] = from[1]; 619 to[i][2] = from[2]; 620 to[i][3] = from[3]; 621 } 622 to_vec->size = 4; 623 to_vec->flags |= VEC_SIZE_4; 624 to_vec->count = from_vec->count; 625} 626 627static void _XFORMAPI 628TAG(transform_points4_2d)( GLvector4f *to_vec, 629 const GLfloat m[16], 630 const GLvector4f *from_vec ) 631{ 632 const GLuint stride = from_vec->stride; 633 GLfloat *from = from_vec->start; 634 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 635 GLuint count = from_vec->count; 636 const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; 637 const GLfloat m12 = m[12], m13 = m[13]; 638 GLuint i; 639 STRIDE_LOOP { 640 const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; 641 to[i][0] = m0 * ox + m4 * oy + m12 * ow; 642 to[i][1] = m1 * ox + m5 * oy + m13 * ow; 643 to[i][2] = + oz ; 644 to[i][3] = ow; 645 } 646 to_vec->size = 4; 647 to_vec->flags |= VEC_SIZE_4; 648 to_vec->count = from_vec->count; 649} 650 651static void _XFORMAPI 652TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec, 653 const GLfloat m[16], 654 const GLvector4f *from_vec ) 655{ 656 const GLuint stride = from_vec->stride; 657 GLfloat *from = from_vec->start; 658 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 659 GLuint count = from_vec->count; 660 const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; 661 GLuint i; 662 STRIDE_LOOP { 663 const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; 664 to[i][0] = m0 * ox + m12 * ow; 665 to[i][1] = m5 * oy + m13 * ow; 666 to[i][2] = + oz ; 667 to[i][3] = ow; 668 } 669 to_vec->size = 4; 670 to_vec->flags |= VEC_SIZE_4; 671 to_vec->count = from_vec->count; 672} 673 674static void _XFORMAPI 675TAG(transform_points4_3d)( GLvector4f *to_vec, 676 const GLfloat m[16], 677 const GLvector4f *from_vec ) 678{ 679 const GLuint stride = from_vec->stride; 680 GLfloat *from = from_vec->start; 681 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 682 GLuint count = from_vec->count; 683 const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; 684 const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; 685 const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; 686 GLuint i; 687 STRIDE_LOOP { 688 const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; 689 to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; 690 to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; 691 to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; 692 to[i][3] = ow; 693 } 694 to_vec->size = 4; 695 to_vec->flags |= VEC_SIZE_4; 696 to_vec->count = from_vec->count; 697} 698 699static void _XFORMAPI 700TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec, 701 const GLfloat m[16], 702 const GLvector4f *from_vec ) 703{ 704 const GLuint stride = from_vec->stride; 705 GLfloat *from = from_vec->start; 706 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 707 GLuint count = from_vec->count; 708 const GLfloat m0 = m[0], m5 = m[5]; 709 const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; 710 GLuint i; 711 STRIDE_LOOP { 712 const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; 713 to[i][0] = m0 * ox + m12 * ow; 714 to[i][1] = m5 * oy + m13 * ow; 715 to[i][2] = m10 * oz + m14 * ow; 716 to[i][3] = ow; 717 } 718 to_vec->size = 4; 719 to_vec->flags |= VEC_SIZE_4; 720 to_vec->count = from_vec->count; 721} 722 723static void _XFORMAPI 724TAG(transform_points4_perspective)( GLvector4f *to_vec, 725 const GLfloat m[16], 726 const GLvector4f *from_vec ) 727{ 728 const GLuint stride = from_vec->stride; 729 GLfloat *from = from_vec->start; 730 GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; 731 GLuint count = from_vec->count; 732 const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; 733 const GLfloat m10 = m[10], m14 = m[14]; 734 GLuint i; 735 STRIDE_LOOP { 736 const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; 737 to[i][0] = m0 * ox + m8 * oz ; 738 to[i][1] = m5 * oy + m9 * oz ; 739 to[i][2] = m10 * oz + m14 * ow ; 740 to[i][3] = -oz ; 741 } 742 to_vec->size = 4; 743 to_vec->flags |= VEC_SIZE_4; 744 to_vec->count = from_vec->count; 745} 746 747static transform_func TAG(transform_tab_1)[7]; 748static transform_func TAG(transform_tab_2)[7]; 749static transform_func TAG(transform_tab_3)[7]; 750static transform_func TAG(transform_tab_4)[7]; 751 752/* Similar functions could be called several times, with more highly 753 * optimized routines overwriting the arrays. This only occurs during 754 * startup. 755 */ 756static void _XFORMAPI TAG(init_c_transformations)( void ) 757{ 758#define TAG_TAB _mesa_transform_tab 759#define TAG_TAB_1 TAG(transform_tab_1) 760#define TAG_TAB_2 TAG(transform_tab_2) 761#define TAG_TAB_3 TAG(transform_tab_3) 762#define TAG_TAB_4 TAG(transform_tab_4) 763 764 TAG_TAB[1] = TAG_TAB_1; 765 TAG_TAB[2] = TAG_TAB_2; 766 TAG_TAB[3] = TAG_TAB_3; 767 TAG_TAB[4] = TAG_TAB_4; 768 769 /* 1-D points (ie texcoords) */ 770 TAG_TAB_1[MATRIX_GENERAL] = TAG(transform_points1_general); 771 TAG_TAB_1[MATRIX_IDENTITY] = TAG(transform_points1_identity); 772 TAG_TAB_1[MATRIX_3D_NO_ROT] = TAG(transform_points1_3d_no_rot); 773 TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective); 774 TAG_TAB_1[MATRIX_2D] = TAG(transform_points1_2d); 775 TAG_TAB_1[MATRIX_2D_NO_ROT] = TAG(transform_points1_2d_no_rot); 776 TAG_TAB_1[MATRIX_3D] = TAG(transform_points1_3d); 777 778 /* 2-D points */ 779 TAG_TAB_2[MATRIX_GENERAL] = TAG(transform_points2_general); 780 TAG_TAB_2[MATRIX_IDENTITY] = TAG(transform_points2_identity); 781 TAG_TAB_2[MATRIX_3D_NO_ROT] = TAG(transform_points2_3d_no_rot); 782 TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective); 783 TAG_TAB_2[MATRIX_2D] = TAG(transform_points2_2d); 784 TAG_TAB_2[MATRIX_2D_NO_ROT] = TAG(transform_points2_2d_no_rot); 785 TAG_TAB_2[MATRIX_3D] = TAG(transform_points2_3d); 786 787 /* 3-D points */ 788 TAG_TAB_3[MATRIX_GENERAL] = TAG(transform_points3_general); 789 TAG_TAB_3[MATRIX_IDENTITY] = TAG(transform_points3_identity); 790 TAG_TAB_3[MATRIX_3D_NO_ROT] = TAG(transform_points3_3d_no_rot); 791 TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective); 792 TAG_TAB_3[MATRIX_2D] = TAG(transform_points3_2d); 793 TAG_TAB_3[MATRIX_2D_NO_ROT] = TAG(transform_points3_2d_no_rot); 794 TAG_TAB_3[MATRIX_3D] = TAG(transform_points3_3d); 795 796 /* 4-D points */ 797 TAG_TAB_4[MATRIX_GENERAL] = TAG(transform_points4_general); 798 TAG_TAB_4[MATRIX_IDENTITY] = TAG(transform_points4_identity); 799 TAG_TAB_4[MATRIX_3D_NO_ROT] = TAG(transform_points4_3d_no_rot); 800 TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective); 801 TAG_TAB_4[MATRIX_2D] = TAG(transform_points4_2d); 802 TAG_TAB_4[MATRIX_2D_NO_ROT] = TAG(transform_points4_2d_no_rot); 803 TAG_TAB_4[MATRIX_3D] = TAG(transform_points4_3d); 804 805#undef TAG_TAB 806#undef TAG_TAB_1 807#undef TAG_TAB_2 808#undef TAG_TAB_3 809#undef TAG_TAB_4 810} 811