t_dd_vb.c revision 844cdaf461e3e181bcf1d4c0ba79ef5c4140cb4e
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 * Authors:
26 *    Keith Whitwell <keith@tungstengraphics.com>
27 */
28#include "math/m_translate.h"
29
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
35#endif
36
37#ifndef LOCALVARS
38#define LOCALVARS
39#endif
40
41#ifndef CHECK_HW_DIVIDE
42#define CHECK_HW_DIVIDE 1
43#endif
44
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
47 * this directory?
48 */
49static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc )
50{
51   LOCALVARS
52   GLubyte *verts = GET_VERTEX_STORE();
53   GLuint size = GET_VERTEX_SIZE();
54   GLuint *dst = (GLuint *)(verts + (edst * size));
55   GLuint *src = (GLuint *)(verts + (esrc * size));
56   dst[4] = src[4];
57   dst[5] = src[5];
58}
59
60static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc )
61{
62   LOCALVARS
63   GLubyte *verts = GET_VERTEX_STORE();
64   GLuint size = GET_VERTEX_SIZE();
65   GLuint *dst = (GLuint *)(verts + (edst * size));
66   GLuint *src = (GLuint *)(verts + (esrc * size));
67   dst[4] = src[4];
68}
69
70static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc )
71{
72   LOCALVARS
73   GLubyte *verts = GET_VERTEX_STORE();
74   GLuint size = GET_VERTEX_SIZE();
75   GLuint *dst = (GLuint *)(verts + (edst * size));
76   GLuint *src = (GLuint *)(verts + (esrc * size));
77   dst[3] = src[3];
78}
79
80
81void TAG(translate_vertex)(GLcontext *ctx,
82			   const VERTEX *src,
83			   SWvertex *dst)
84{
85   LOCALVARS
86   GLuint format = GET_VERTEX_FORMAT();
87   GLfloat *s = ctx->Viewport._WindowMap.m;
88   UNVIEWPORT_VARS;
89
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];
95	 dst->win[3] = 1.0;
96      } else {
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 );
100	 dst->win[3] = 1.0;
101      }
102
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;
107   }
108   else {
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];
115	    dst->win[3] = oow;
116	 } else {
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;
121	 }
122      } else {
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;
127      }
128
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;
133
134      dst->specular[0] = src->v.specular.red;
135      dst->specular[1] = src->v.specular.green;
136      dst->specular[2] = src->v.specular.blue;
137
138      dst->fog = src->v.specular.alpha/255.0;
139
140      if (HAVE_PTEX_VERTICES &&
141	  ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) ||
142	   (format == PROJ_TEX1_VERTEX_FORMAT))) {
143
144	 dst->texcoord[0][0] = src->pv.u0;
145	 dst->texcoord[0][1] = src->pv.v0;
146	 dst->texcoord[0][3] = src->pv.q0;
147
148	 dst->texcoord[1][0] = src->pv.u1;
149	 dst->texcoord[1][1] = src->pv.v1;
150	 dst->texcoord[1][3] = src->pv.q1;
151
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;
156	 }
157
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;
162	 }
163      }
164      else {
165	 dst->texcoord[0][0] = src->v.u0;
166	 dst->texcoord[0][1] = src->v.v0;
167	 dst->texcoord[0][3] = 1.0;
168
169	 dst->texcoord[1][0] = src->v.u1;
170	 dst->texcoord[1][1] = src->v.v1;
171	 dst->texcoord[1][3] = 1.0;
172
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;
177	 }
178
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;
183	 }
184      }
185   }
186
187   dst->pointSize = ctx->Point._Size;
188}
189
190
191
192void TAG(print_vertex)( GLcontext *ctx, const VERTEX *v )
193{
194   LOCALVARS
195   GLuint format = GET_VERTEX_FORMAT();
196
197   fprintf(stderr, "(%x) ", format);
198
199   switch (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,
204	      v->tv.color.red,
205	      v->tv.color.green,
206	      v->tv.color.blue,
207	      v->tv.color.alpha);
208      break;
209#endif
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,
214	      v->v.color.red,
215	      v->v.color.green,
216	      v->v.color.blue,
217	      v->v.color.alpha,
218	      v->v.specular.red,
219	      v->v.specular.green,
220	      v->v.specular.blue,
221	      v->v.specular.alpha);
222      break;
223#endif
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,
228	      v->v.color.red,
229	      v->v.color.green,
230	      v->v.color.blue,
231	      v->v.color.alpha,
232	      v->v.u0,
233	      v->v.v0);
234      break;
235#endif
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,
240	      v->v.color.red,
241	      v->v.color.green,
242	      v->v.color.blue,
243	      v->v.color.alpha,
244	      v->v.u0,
245	      v->v.v0,
246	      v->v.u1,
247	      v->v.u2);
248      break;
249#endif
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,
254	      v->v.color.red,
255	      v->v.color.green,
256	      v->v.color.blue,
257	      v->v.color.alpha,
258	      v->pv.u0,
259	      v->pv.v0,
260	      v->pv.q0,
261	      v->pv.u1,
262	      v->pv.v1,
263	      v->pv.q1);
264      break;
265#endif
266   default:
267      fprintf(stderr, "???\n");
268      break;
269   }
270
271   fprintf(stderr, "\n");
272}
273
274
275
276/* Interpolate the elements of the VB not included in typical hardware
277 * vertices.
278 *
279 * NOTE: All these arrays are guarenteed by tnl to be writeable and
280 * have good stride.
281 */
282#ifndef INTERP_QUALIFIER
283#define INTERP_QUALIFIER static
284#endif
285
286#define GET_COLOR(ptr, idx) ((ptr)->data[idx])
287
288
289INTERP_QUALIFIER void TAG(interp_extras)( GLcontext *ctx,
290					  GLfloat t,
291					  GLuint dst, GLuint out, GLuint in,
292					  GLboolean force_boundary )
293{
294   LOCALVARS
295   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
296
297   if (VB->ColorPtr[1]) {
298      assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
299
300      INTERP_4F( t,
301		    GET_COLOR(VB->ColorPtr[1], dst),
302		    GET_COLOR(VB->ColorPtr[1], out),
303		    GET_COLOR(VB->ColorPtr[1], in) );
304
305      if (VB->SecondaryColorPtr[1]) {
306	 INTERP_3F( t,
307		       GET_COLOR(VB->SecondaryColorPtr[1], dst),
308		       GET_COLOR(VB->SecondaryColorPtr[1], out),
309		       GET_COLOR(VB->SecondaryColorPtr[1], in) );
310      }
311   }
312
313   if (VB->EdgeFlag) {
314      VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary;
315   }
316
317   INTERP_VERTEX(ctx, t, dst, out, in, force_boundary);
318}
319
320INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx,
321					   GLuint dst, GLuint src )
322{
323   LOCALVARS
324      struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
325
326   if (VB->ColorPtr[1]) {
327      COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
328		GET_COLOR(VB->ColorPtr[1], src) );
329
330      if (VB->SecondaryColorPtr[1]) {
331	 COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
332		   GET_COLOR(VB->SecondaryColorPtr[1], src) );
333      }
334   }
335
336   COPY_PV_VERTEX(ctx, dst, src);
337}
338
339
340#undef INTERP_QUALIFIER
341#undef GET_COLOR
342
343#undef IND
344#undef TAG
345