3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
26 * Keith Whitwell <keithw@valinux.com>
28 #include "math/m_translate.h"
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
41 #ifndef CHECK_HW_DIVIDE
42 #define CHECK_HW_DIVIDE 1
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
49 static void copy_pv_rgba4_spec5( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
52 GLubyte
*verts
= GET_VERTEX_STORE();
53 GLuint shift
= GET_VERTEX_STRIDE_SHIFT();
54 GLuint
*dst
= (GLuint
*)(verts
+ (edst
<< shift
));
55 GLuint
*src
= (GLuint
*)(verts
+ (esrc
<< shift
));
60 static void copy_pv_rgba4( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
63 GLubyte
*verts
= GET_VERTEX_STORE();
64 GLuint shift
= GET_VERTEX_STRIDE_SHIFT();
65 GLuint
*dst
= (GLuint
*)(verts
+ (edst
<< shift
));
66 GLuint
*src
= (GLuint
*)(verts
+ (esrc
<< shift
));
70 static void copy_pv_rgba3( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
73 GLubyte
*verts
= GET_VERTEX_STORE();
74 GLuint shift
= GET_VERTEX_STRIDE_SHIFT();
75 GLuint
*dst
= (GLuint
*)(verts
+ (edst
<< shift
));
76 GLuint
*src
= (GLuint
*)(verts
+ (esrc
<< shift
));
81 void TAG(translate_vertex
)(GLcontext
*ctx
,
86 GLuint format
= GET_VERTEX_FORMAT();
87 GLfloat
*s
= ctx
->Viewport
._WindowMap
.m
;
90 if (format
== TINY_VERTEX_FORMAT
) {
91 if (HAVE_HW_VIEWPORT
) {
92 dst
->win
[0] = s
[0] * src
->v
.x
+ s
[12];
93 dst
->win
[1] = s
[5] * src
->v
.y
+ s
[13];
94 dst
->win
[2] = s
[10] * src
->v
.z
+ s
[14];
97 dst
->win
[0] = UNVIEWPORT_X( src
->v
.x
);
98 dst
->win
[1] = UNVIEWPORT_Y( src
->v
.y
);
99 dst
->win
[2] = UNVIEWPORT_Z( src
->v
.z
);
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
;
109 if (HAVE_HW_VIEWPORT
) {
110 if (HAVE_HW_DIVIDE
&& CHECK_HW_DIVIDE
) {
111 GLfloat oow
= 1.0 / src
->v
.w
;
112 dst
->win
[0] = s
[0] * src
->v
.x
* oow
+ s
[12];
113 dst
->win
[1] = s
[5] * src
->v
.y
* oow
+ s
[13];
114 dst
->win
[2] = s
[10] * src
->v
.z
* oow
+ s
[14];
117 dst
->win
[0] = s
[0] * src
->v
.x
+ s
[12];
118 dst
->win
[1] = s
[5] * src
->v
.y
+ s
[13];
119 dst
->win
[2] = s
[10] * src
->v
.z
+ s
[14];
120 dst
->win
[3] = src
->v
.w
;
123 dst
->win
[0] = UNVIEWPORT_X( src
->v
.x
);
124 dst
->win
[1] = UNVIEWPORT_Y( src
->v
.y
);
125 dst
->win
[2] = UNVIEWPORT_Z( src
->v
.z
);
126 dst
->win
[3] = src
->v
.w
;
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
;
134 dst
->specular
[0] = src
->v
.specular
.red
;
135 dst
->specular
[1] = src
->v
.specular
.green
;
136 dst
->specular
[2] = src
->v
.specular
.blue
;
138 dst
->fog
= src
->v
.specular
.alpha
/255.0;
140 if (HAVE_PTEX_VERTICES
&&
141 ((HAVE_TEX2_VERTICES
&& format
== PROJ_TEX3_VERTEX_FORMAT
) ||
142 (format
== PROJ_TEX1_VERTEX_FORMAT
))) {
144 dst
->texcoord
[0][0] = src
->pv
.u0
;
145 dst
->texcoord
[0][1] = src
->pv
.v0
;
146 dst
->texcoord
[0][3] = src
->pv
.q0
;
148 dst
->texcoord
[1][0] = src
->pv
.u1
;
149 dst
->texcoord
[1][1] = src
->pv
.v1
;
150 dst
->texcoord
[1][3] = src
->pv
.q1
;
152 if (HAVE_TEX2_VERTICES
) {
153 dst
->texcoord
[2][0] = src
->pv
.u2
;
154 dst
->texcoord
[2][1] = src
->pv
.v2
;
155 dst
->texcoord
[2][3] = src
->pv
.q2
;
158 if (HAVE_TEX3_VERTICES
) {
159 dst
->texcoord
[3][0] = src
->pv
.u3
;
160 dst
->texcoord
[3][1] = src
->pv
.v3
;
161 dst
->texcoord
[3][3] = src
->pv
.q3
;
165 dst
->texcoord
[0][0] = src
->v
.u0
;
166 dst
->texcoord
[0][1] = src
->v
.v0
;
167 dst
->texcoord
[0][3] = 1.0;
169 dst
->texcoord
[1][0] = src
->v
.u1
;
170 dst
->texcoord
[1][1] = src
->v
.v1
;
171 dst
->texcoord
[1][3] = 1.0;
173 if (HAVE_TEX2_VERTICES
) {
174 dst
->texcoord
[2][0] = src
->v
.u2
;
175 dst
->texcoord
[2][1] = src
->v
.v2
;
176 dst
->texcoord
[2][3] = 1.0;
179 if (HAVE_TEX3_VERTICES
) {
180 dst
->texcoord
[3][0] = src
->v
.u3
;
181 dst
->texcoord
[3][1] = src
->v
.v3
;
182 dst
->texcoord
[3][3] = 1.0;
187 dst
->pointSize
= ctx
->Point
._Size
;
192 void TAG(print_vertex
)( GLcontext
*ctx
, const VERTEX
*v
)
195 GLuint format
= GET_VERTEX_FORMAT();
197 fprintf(stderr
, "(%x) ", format
);
200 #if HAVE_TINY_VERTICES
201 case TINY_VERTEX_FORMAT
:
202 fprintf(stderr
, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n",
203 v
->v
.x
, v
->v
.y
, v
->v
.z
,
210 #if HAVE_NOTEX_VERTICES
211 case NOTEX_VERTEX_FORMAT
:
212 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n",
213 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
221 v
->v
.specular
.alpha
);
224 #if HAVE_TEX0_VERTICES
225 case TEX0_VERTEX_FORMAT
:
226 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n",
227 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
236 #if HAVE_TEX1_VERTICES
237 case TEX1_VERTEX_FORMAT
:
238 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n",
239 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
250 #if HAVE_PTEX_VERTICES
251 case PROJ_TEX1_VERTEX_FORMAT
:
252 fprintf(stderr
, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n",
253 v
->v
.x
, v
->v
.y
, v
->v
.z
, v
->v
.w
,
267 fprintf(stderr
, "???\n");
271 fprintf(stderr
, "\n");
274 static void do_import( struct vertex_buffer
*VB
,
275 struct gl_client_array
*to
,
276 struct gl_client_array
*from
)
278 GLuint count
= VB
->Count
;
281 to
->Ptr
= ALIGN_MALLOC( VB
->Size
* 4 * sizeof(GLubyte
), 32 );
282 to
->Type
= GL_UNSIGNED_BYTE
;
285 /* No need to transform the same value 3000 times.
287 if (!from
->StrideB
) {
292 to
->StrideB
= 4 * sizeof(GLubyte
);
294 _math_trans_4ub( (GLubyte (*)[4]) to
->Ptr
,
303 #ifndef IMPORT_QUALIFIER
304 #define IMPORT_QUALIFIER static
307 IMPORT_QUALIFIER
void TAG(import_float_colors
)( GLcontext
*ctx
)
310 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
311 struct gl_client_array
*to
= GET_UBYTE_COLOR_STORE();
312 do_import( VB
, to
, VB
->ColorPtr
[0] );
313 VB
->ColorPtr
[0] = to
;
316 IMPORT_QUALIFIER
void TAG(import_float_spec_colors
)( GLcontext
*ctx
)
319 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
320 struct gl_client_array
*to
= GET_UBYTE_SPEC_COLOR_STORE();
321 do_import( VB
, to
, VB
->SecondaryColorPtr
[0] );
322 VB
->SecondaryColorPtr
[0] = to
;
325 /* Interpolate the elements of the VB not included in typical hardware
328 * NOTE: All these arrays are guarenteed by tnl to be writeable and
331 #ifndef INTERP_QUALIFIER
332 #define INTERP_QUALIFIER static
335 #define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
338 INTERP_QUALIFIER
void TAG(interp_extras
)( GLcontext
*ctx
,
340 GLuint dst
, GLuint out
, GLuint in
,
341 GLboolean force_boundary
)
344 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
346 if (VB
->ColorPtr
[1]) {
348 GET_COLOR(VB
->ColorPtr
[1], dst
),
349 GET_COLOR(VB
->ColorPtr
[1], out
),
350 GET_COLOR(VB
->ColorPtr
[1], in
) );
352 if (VB
->SecondaryColorPtr
[1]) {
354 GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
355 GET_COLOR(VB
->SecondaryColorPtr
[1], out
),
356 GET_COLOR(VB
->SecondaryColorPtr
[1], in
) );
361 VB
->EdgeFlag
[dst
] = VB
->EdgeFlag
[out
] || force_boundary
;
364 INTERP_VERTEX(ctx
, t
, dst
, out
, in
, force_boundary
);
367 INTERP_QUALIFIER
void TAG(copy_pv_extras
)( GLcontext
*ctx
,
368 GLuint dst
, GLuint src
)
371 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
373 if (VB
->ColorPtr
[1]) {
374 COPY_CHAN4( GET_COLOR(VB
->ColorPtr
[1], dst
),
375 GET_COLOR(VB
->ColorPtr
[1], src
) );
377 if (VB
->SecondaryColorPtr
[1]) {
378 COPY_CHAN4( GET_COLOR(VB
->SecondaryColorPtr
[1], dst
),
379 GET_COLOR(VB
->SecondaryColorPtr
[1], src
) );
383 COPY_PV_VERTEX(ctx
, dst
, src
);
387 #undef INTERP_QUALIFIER
388 #undef IMPORT_QUALIFIER