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) {
70 /* since DO_PTEX is only true when we have 3 or more coords
71 in the first place we don't really need this right? */
74 else if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 4) {
75 rqcoordsnoswap
|= (1<<2);
78 tc2
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
84 if (VB
->TexCoordPtr
[1]) {
85 const GLuint t1
= GET_TEXSOURCE(1);
86 tc1
= (GLuint (*)[4])VB
->TexCoordPtr
[t1
]->data
;
87 tc1_stride
= VB
->TexCoordPtr
[t1
]->stride
;
88 if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 3) {
91 else if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 4) {
92 rqcoordsnoswap
|= (1<<1);
95 tc1
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
101 if (VB
->TexCoordPtr
[0]) {
102 const GLuint t0
= GET_TEXSOURCE(0);
103 tc0_stride
= VB
->TexCoordPtr
[t0
]->stride
;
104 tc0
= (GLuint (*)[4])VB
->TexCoordPtr
[t0
]->data
;
105 if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 3) {
108 else if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 4) {
109 rqcoordsnoswap
|= (1<<0);
112 tc0
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
120 norm_stride
= VB
->NormalPtr
->stride
;
121 norm
= (GLuint (*)[4])VB
->NormalPtr
->data
;
124 norm
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
129 if (VB
->ColorPtr
[0]) {
130 col
= VB
->ColorPtr
[0]->data
;
131 col_stride
= VB
->ColorPtr
[0]->stride
;
133 col
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
139 if (VB
->SecondaryColorPtr
[0]) {
140 spec
= VB
->SecondaryColorPtr
[0]->data
;
141 spec_stride
= VB
->SecondaryColorPtr
[0]->stride
;
143 spec
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
149 if (VB
->FogCoordPtr
) {
150 fog
= VB
->FogCoordPtr
->data
;
151 fog_stride
= VB
->FogCoordPtr
->stride
;
153 fog
= (GLfloat (*)[4])&dummy
; fog
[0][0] = 0.0F
;
160 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ start
* coord_stride
);
162 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
164 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
166 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ start
* tc2_stride
);
168 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ start
* norm_stride
);
170 STRIDE_4F(col
, start
* col_stride
);
172 STRIDE_4F(spec
, start
* spec_stride
);
174 STRIDE_4F(fog
, start
* fog_stride
);
179 for (i
=start
; i
< end
; i
++) {
181 v
[0].ui
= coord
[0][0];
182 v
[1].ui
= coord
[0][1];
183 v
[2].ui
= coord
[0][2];
185 v
[3].ui
= coord
[0][3];
190 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ coord_stride
);
193 v
[0].ui
= norm
[0][0];
194 v
[1].ui
= norm
[0][1];
195 v
[2].ui
= norm
[0][2];
197 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ norm_stride
);
200 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, col
[0][0]);
201 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, col
[0][1]);
202 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, col
[0][2]);
203 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, col
[0][3]);
204 STRIDE_4F(col
, col_stride
);
207 if (DO_SPEC
|| DO_FOG
) {
209 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, spec
[0][0]);
210 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, spec
[0][1]);
211 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, spec
[0][2]);
212 STRIDE_4F(spec
, spec_stride
);
215 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, fog
[0][0]);
216 fog
= (GLfloat (*)[4])((GLubyte
*)fog
+ fog_stride
);
218 if (TCL_DEBUG
) fprintf(stderr
, "%x ", v
[0].ui
);
224 if (TCL_DEBUG
) fprintf(stderr
, "t0: %.2f %.2f ", v
[0].f
, v
[1].f
);
226 if (fill_tex
& (1<<0))
228 else if (rqcoordsnoswap
& (1<<0))
232 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
237 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
242 if (TCL_DEBUG
) fprintf(stderr
, "t1: %.2f %.2f ", v
[0].f
, v
[1].f
);
244 if (fill_tex
& (1<<1))
246 else if (rqcoordsnoswap
& (1<<1))
250 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
255 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
261 if (fill_tex
& (1<<2))
263 else if (rqcoordsnoswap
& (1<<2))
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
;