2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keith@tungstengraphics.com>
37 static void TAG(emit
)( GLcontext
*ctx
,
38 GLuint start
, GLuint end
,
42 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
43 GLuint (*tc0
)[4], (*tc1
)[4], (*tc2
)[4];
44 GLfloat (*col
)[4], (*spec
)[4];
47 GLuint tc0_stride
, tc1_stride
, col_stride
, spec_stride
, fog_stride
;
48 GLuint tc2_stride
, norm_stride
;
50 GLuint rqcoordsnoswap
= 0;
52 GLuint coord_stride
; /* object coordinates */
56 union emit_union
*v
= (union emit_union
*)dest
;
58 if (RADEON_DEBUG
& DEBUG_VERTS
)
59 fprintf(stderr
, "%s\n", __FUNCTION__
);
61 coord
= (GLuint (*)[4])VB
->ObjPtr
->data
;
62 coord_stride
= VB
->ObjPtr
->stride
;
65 if (VB
->TexCoordPtr
[2]) {
66 const GLuint t2
= GET_TEXSOURCE(2);
67 tc2
= (GLuint (*)[4])VB
->TexCoordPtr
[t2
]->data
;
68 tc2_stride
= VB
->TexCoordPtr
[t2
]->stride
;
69 if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 3) {
72 else if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 4) {
73 rqcoordsnoswap
|= (1<<2);
76 tc2
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
82 if (VB
->TexCoordPtr
[1]) {
83 const GLuint t1
= GET_TEXSOURCE(1);
84 tc1
= (GLuint (*)[4])VB
->TexCoordPtr
[t1
]->data
;
85 tc1_stride
= VB
->TexCoordPtr
[t1
]->stride
;
86 if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 3) {
89 else if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 4) {
90 rqcoordsnoswap
|= (1<<1);
93 tc1
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
99 if (VB
->TexCoordPtr
[0]) {
100 const GLuint t0
= GET_TEXSOURCE(0);
101 tc0_stride
= VB
->TexCoordPtr
[t0
]->stride
;
102 tc0
= (GLuint (*)[4])VB
->TexCoordPtr
[t0
]->data
;
103 if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 3) {
106 else if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 4) {
107 rqcoordsnoswap
|= (1<<0);
110 tc0
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
118 norm_stride
= VB
->NormalPtr
->stride
;
119 norm
= (GLuint (*)[4])VB
->NormalPtr
->data
;
122 norm
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
127 if (VB
->ColorPtr
[0]) {
128 col
= VB
->ColorPtr
[0]->data
;
129 col_stride
= VB
->ColorPtr
[0]->stride
;
131 col
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
137 if (VB
->SecondaryColorPtr
[0]) {
138 spec
= VB
->SecondaryColorPtr
[0]->data
;
139 spec_stride
= VB
->SecondaryColorPtr
[0]->stride
;
141 spec
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
147 if (VB
->FogCoordPtr
) {
148 fog
= VB
->FogCoordPtr
->data
;
149 fog_stride
= VB
->FogCoordPtr
->stride
;
151 fog
= (GLfloat (*)[4])&dummy
; fog
[0][0] = 0.0F
;
158 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ start
* coord_stride
);
160 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
162 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
164 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ start
* tc2_stride
);
166 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ start
* norm_stride
);
168 STRIDE_4F(col
, start
* col_stride
);
170 STRIDE_4F(spec
, start
* spec_stride
);
172 STRIDE_4F(fog
, start
* fog_stride
);
177 for (i
=start
; i
< end
; i
++) {
179 v
[0].ui
= coord
[0][0];
180 v
[1].ui
= coord
[0][1];
181 v
[2].ui
= coord
[0][2];
183 v
[3].ui
= coord
[0][3];
188 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ coord_stride
);
191 v
[0].ui
= norm
[0][0];
192 v
[1].ui
= norm
[0][1];
193 v
[2].ui
= norm
[0][2];
195 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ norm_stride
);
198 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, col
[0][0]);
199 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, col
[0][1]);
200 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, col
[0][2]);
201 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, col
[0][3]);
202 STRIDE_4F(col
, col_stride
);
205 if (DO_SPEC
|| DO_FOG
) {
207 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, spec
[0][0]);
208 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, spec
[0][1]);
209 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, spec
[0][2]);
210 STRIDE_4F(spec
, spec_stride
);
213 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, fog
[0][0]);
214 fog
= (GLfloat (*)[4])((GLubyte
*)fog
+ fog_stride
);
216 if (TCL_DEBUG
) fprintf(stderr
, "%x ", v
[0].ui
);
222 if (TCL_DEBUG
) fprintf(stderr
, "t0: %.2f %.2f ", v
[0].f
, v
[1].f
);
224 if (fill_tex
& (1<<0))
226 else if (rqcoordsnoswap
& (1<<0))
230 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
235 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
240 if (TCL_DEBUG
) fprintf(stderr
, "t1: %.2f %.2f ", v
[0].f
, v
[1].f
);
242 if (fill_tex
& (1<<1))
244 else if (rqcoordsnoswap
& (1<<1))
248 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
253 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
258 if (TCL_DEBUG
) fprintf(stderr
, "t2: %.2f %.2f ", v
[0].f
, v
[1].f
);
260 if (fill_tex
& (1<<2))
262 else if (rqcoordsnoswap
& (1<<2))
266 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
271 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ tc2_stride
);
273 if (TCL_DEBUG
) fprintf(stderr
, "\n");
280 static void TAG(init
)( void )
284 if (DO_NORM
) sz
+= 3;
286 if (DO_SPEC
|| DO_FOG
) sz
++;
287 if (DO_TEX0
) sz
+= 2;
288 if (DO_TEX0
&& DO_PTEX
) sz
++;
289 if (DO_TEX1
) sz
+= 2;
290 if (DO_TEX1
&& DO_PTEX
) sz
++;
291 if (DO_TEX2
) sz
+= 2;
292 if (DO_TEX2
&& DO_PTEX
) sz
++;
294 setup_tab
[IDX
].emit
= TAG(emit
);
295 setup_tab
[IDX
].vertex_format
= IND
;
296 setup_tab
[IDX
].vertex_size
= sz
;