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
73 static void _XFORMAPI
TAG(transform_points1_general)74 TAG(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
99 static void _XFORMAPI
TAG(transform_points1_identity)100 TAG(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
119 static void _XFORMAPI
TAG(transform_points1_2d)120 TAG(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
141 static void _XFORMAPI
TAG(transform_points1_2d_no_rot)142 TAG(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
162 static void _XFORMAPI
TAG(transform_points1_3d)163 TAG(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
186 static void _XFORMAPI
TAG(transform_points1_3d_no_rot)187 TAG(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
209 static void _XFORMAPI
TAG(transform_points1_perspective)210 TAG(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 */
239 static void _XFORMAPI
TAG(transform_points2_general)240 TAG(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
265 static void _XFORMAPI
TAG(transform_points2_identity)266 TAG(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
286 static void _XFORMAPI
TAG(transform_points2_2d)287 TAG(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
308 static void _XFORMAPI
TAG(transform_points2_2d_no_rot)309 TAG(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
329 static void _XFORMAPI
TAG(transform_points2_3d)330 TAG(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 */
356 static void _XFORMAPI
TAG(transform_points2_3d_no_rot)357 TAG(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
385 static void _XFORMAPI
TAG(transform_points2_perspective)386 TAG(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
410 static void _XFORMAPI
TAG(transform_points3_general)411 TAG(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
436 static void _XFORMAPI
TAG(transform_points3_identity)437 TAG(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
458 static void _XFORMAPI
TAG(transform_points3_2d)459 TAG(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
481 static void _XFORMAPI
TAG(transform_points3_2d_no_rot)482 TAG(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
503 static void _XFORMAPI
TAG(transform_points3_3d)504 TAG(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 */
529 static void _XFORMAPI
TAG(transform_points3_3d_no_rot)530 TAG(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
552 static void _XFORMAPI
TAG(transform_points3_perspective)553 TAG(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
578 static void _XFORMAPI
TAG(transform_points4_general)579 TAG(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
604 static void _XFORMAPI
TAG(transform_points4_identity)605 TAG(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
627 static void _XFORMAPI
TAG(transform_points4_2d)628 TAG(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
651 static void _XFORMAPI
TAG(transform_points4_2d_no_rot)652 TAG(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
674 static void _XFORMAPI
TAG(transform_points4_3d)675 TAG(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
699 static void _XFORMAPI
TAG(transform_points4_3d_no_rot)700 TAG(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
723 static void _XFORMAPI
TAG(transform_points4_perspective)724 TAG(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
747 static transform_func TAG(transform_tab_1)[7];
748 static transform_func TAG(transform_tab_2)[7];
749 static transform_func TAG(transform_tab_3)[7];
750 static 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 */
TAG(init_c_transformations)756 static 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