1 | /* $Id: xform.h,v 1.3 2000-05-23 20:35:00 jeroen Exp $ */
|
---|
2 |
|
---|
3 | /*
|
---|
4 | * Mesa 3-D graphics library
|
---|
5 | * Version: 3.3
|
---|
6 | *
|
---|
7 | * Copyright (C) 1999 Brian Paul All Rights Reserved.
|
---|
8 | *
|
---|
9 | * Permission is hereby granted, free of charge, to any person obtaining a
|
---|
10 | * copy of this software and associated documentation files (the "Software"),
|
---|
11 | * to deal in the Software without restriction, including without limitation
|
---|
12 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
---|
13 | * and/or sell copies of the Software, and to permit persons to whom the
|
---|
14 | * Software is furnished to do so, subject to the following conditions:
|
---|
15 | *
|
---|
16 | * The above copyright notice and this permission notice shall be included
|
---|
17 | * in all copies or substantial portions of the Software.
|
---|
18 | *
|
---|
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
20 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
---|
22 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
---|
23 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
---|
24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
---|
25 | */
|
---|
26 |
|
---|
27 |
|
---|
28 |
|
---|
29 |
|
---|
30 |
|
---|
31 | #ifndef XFORM_H
|
---|
32 | #define XFORM_H
|
---|
33 |
|
---|
34 |
|
---|
35 | #include "types.h"
|
---|
36 |
|
---|
37 | #ifdef USE_X86_ASM
|
---|
38 | #define _XFORMAPI _ASMAPI
|
---|
39 | #define _XFORMAPIP _ASMAPIP
|
---|
40 | #else
|
---|
41 | #define _XFORMAPI
|
---|
42 | #define _XFORMAPIP *
|
---|
43 | #endif
|
---|
44 |
|
---|
45 | /*
|
---|
46 | * Transform a point (column vector) by a matrix: Q = M * P
|
---|
47 | */
|
---|
48 | #define TRANSFORM_POINT( Q, M, P ) \
|
---|
49 | Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; \
|
---|
50 | Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; \
|
---|
51 | Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; \
|
---|
52 | Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3];
|
---|
53 |
|
---|
54 |
|
---|
55 | #define TRANSFORM_POINT3( Q, M, P ) \
|
---|
56 | Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; \
|
---|
57 | Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; \
|
---|
58 | Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; \
|
---|
59 | Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15];
|
---|
60 |
|
---|
61 |
|
---|
62 | /*
|
---|
63 | * Transform a normal (row vector) by a matrix: [NX NY NZ] = N * MAT
|
---|
64 | */
|
---|
65 | #define TRANSFORM_NORMAL( TO, N, MAT ) \
|
---|
66 | do { \
|
---|
67 | TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2]; \
|
---|
68 | TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6]; \
|
---|
69 | TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10]; \
|
---|
70 | } while (0)
|
---|
71 |
|
---|
72 |
|
---|
73 | extern void gl_transform_vector( GLfloat u[4],
|
---|
74 | const GLfloat v[4],
|
---|
75 | const GLfloat m[16] );
|
---|
76 |
|
---|
77 |
|
---|
78 | extern void gl_init_transformation( void );
|
---|
79 |
|
---|
80 |
|
---|
81 | /* KW: Clip functions now do projective divide as well. The projected
|
---|
82 | * coordinates are very useful to us because they let us cull
|
---|
83 | * backfaces and eliminate vertices from lighting, fogging, etc
|
---|
84 | * calculations. Despite the fact that this divide could be done one
|
---|
85 | * day in hardware, we would still have a reason to want to do it here
|
---|
86 | * as long as those other calculations remain in software.
|
---|
87 | *
|
---|
88 | * Clipping is a convenient place to do the divide on x86 as it should be
|
---|
89 | * possible to overlap with integer outcode calculations.
|
---|
90 | *
|
---|
91 | * There are two cases where we wouldn't want to do the divide in cliptest:
|
---|
92 | * - When we aren't clipping. We still might want to cull backfaces
|
---|
93 | * so the divide should be done elsewhere. This currently never
|
---|
94 | * happens.
|
---|
95 | *
|
---|
96 | * - When culling isn't likely to help us, such as when the GL culling
|
---|
97 | * is disabled and we not lighting or are only lighting
|
---|
98 | * one-sided. In this situation, backface determination provides
|
---|
99 | * us with no useful information. A tricky case to detect is when
|
---|
100 | * all input data is already culled, although hopefully the
|
---|
101 | * application wouldn't turn on culling in such cases.
|
---|
102 | *
|
---|
103 | * We supply a buffer to hold the [x/w,y/w,z/w,1/w] values which
|
---|
104 | * are the result of the projection. This is only used in the
|
---|
105 | * 4-vector case - in other cases, we just use the clip coordinates
|
---|
106 | * as the projected coordinates - they are identical.
|
---|
107 | *
|
---|
108 | * This is doubly convenient because it means the Win[] array is now
|
---|
109 | * of the same stride as all the others, so I can now turn map_vertices
|
---|
110 | * into a straight-forward matrix transformation, with asm acceleration
|
---|
111 | * automatically available.
|
---|
112 | */
|
---|
113 | typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip,
|
---|
114 | GLvector4f *vProj,
|
---|
115 | GLubyte clipMask[],
|
---|
116 | GLubyte *orMask,
|
---|
117 | GLubyte *andMask );
|
---|
118 |
|
---|
119 | typedef void (*dotprod_func)( GLvector4f *out_vec,
|
---|
120 | GLuint elt,
|
---|
121 | const GLvector4f *coord_vec,
|
---|
122 | const GLfloat plane[4],
|
---|
123 | const GLubyte mask[]);
|
---|
124 |
|
---|
125 | typedef void (*vec_copy_func)( GLvector4f *to,
|
---|
126 | const GLvector4f *from,
|
---|
127 | const GLubyte mask[]);
|
---|
128 |
|
---|
129 |
|
---|
130 |
|
---|
131 |
|
---|
132 | /* KW: New versions of the transform function allow a mask array
|
---|
133 | * specifying that individual vector transform should be skipped
|
---|
134 | * when the mask byte is zero. This is always present as a
|
---|
135 | * parameter, to allow a unified interface.
|
---|
136 | */
|
---|
137 | typedef void (_XFORMAPIP transform_func)( GLvector4f *to_vec,
|
---|
138 | const GLmatrix *mat,
|
---|
139 | const GLvector4f *from_vec,
|
---|
140 | const GLubyte *clipmask,
|
---|
141 | const GLubyte flag );
|
---|
142 |
|
---|
143 |
|
---|
144 | extern GLvector4f *gl_project_points( GLvector4f *to,
|
---|
145 | const GLvector4f *from );
|
---|
146 |
|
---|
147 | extern void gl_transform_bounds3( GLubyte *orMask, GLubyte *andMask,
|
---|
148 | const GLmatrix *mat,
|
---|
149 | CONST GLfloat src[][3] );
|
---|
150 |
|
---|
151 | extern void gl_transform_bounds2( GLubyte *orMask, GLubyte *andMask,
|
---|
152 | const GLmatrix *mat,
|
---|
153 | CONST GLfloat src[][3] );
|
---|
154 |
|
---|
155 |
|
---|
156 | extern dotprod_func gl_dotprod_tab[2][5];
|
---|
157 | extern vec_copy_func gl_copy_tab[2][0x10];
|
---|
158 | extern clip_func gl_clip_tab[5];
|
---|
159 | extern normal_func gl_normal_tab[0xf][0x4];
|
---|
160 |
|
---|
161 | /* Use of 3 layers of linked 1-dimensional arrays to reduce
|
---|
162 | * cost of lookup.
|
---|
163 | */
|
---|
164 | extern transform_func **(gl_transform_tab[2]);
|
---|
165 |
|
---|
166 |
|
---|
167 | extern void gl_transform_point_sz( GLfloat Q[4], const GLfloat M[16],
|
---|
168 | const GLfloat P[4], GLuint sz );
|
---|
169 |
|
---|
170 |
|
---|
171 | #define TransformRaw( to, mat, from ) \
|
---|
172 | ( (*gl_transform_tab[0][(from)->size][(mat)->type])( to, mat, from, 0, 0 ), \
|
---|
173 | (to) )
|
---|
174 |
|
---|
175 | #define Transform( to, mat, from, mask, cull ) \
|
---|
176 | ( (*gl_transform_tab[cull!=0][(from)->size][(mat)->type])( to, mat, from, mask, cull ), \
|
---|
177 | (to) )
|
---|
178 |
|
---|
179 |
|
---|
180 | #endif
|
---|