Make R128 driver use sarea/defines from DRM. removed r128_common.h
[mesa.git] / src / mesa / drivers / d3d / D3Dvbrender.c
1 /*===========================================================================*/
2 /* */
3 /* Mesa-3.0 DirectX 6 Driver */
4 /* */
5 /* By Leigh McRae */
6 /* */
7 /* http://www.altsoftware.com/ */
8 /* */
9 /* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */
10 /*===========================================================================*/
11 #include <stdio.h>
12 #include "clip.h"
13 #include "context.h"
14 #include "light.h"
15 #include "lines.h"
16 #include "macros.h"
17 #include "matrix.h"
18 #include "pb.h"
19 #include "points.h"
20 #include "mtypes.h"
21 #include "vb.h"
22 #include "vbrender.h"
23 #include "xform.h"
24 #include "D3DMesa.h"
25
26 static void SetRenderStates( GLcontext *ctx );
27 static void DebugRenderStates( GLcontext *ctx, BOOL bForce );
28
29 static void RenderPointsVB( GLcontext *ctx, GLuint start, GLuint end );
30 static void RenderTriangleVB( GLcontext *ctx, GLuint start, GLuint end );
31 static void RenderTriangleFanVB( GLcontext *ctx, GLuint start, GLuint end );
32 static void RenderTriangleStripVB( GLcontext *ctx, GLuint start, GLuint end );
33 static void RenderQuadVB( GLcontext *ctx, GLuint start, GLuint end );
34 static void RenderQuad( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv );
35 void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );
36 void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );
37
38 /* I went with a D3D vertex buffer that is 6 times that of the Mesa one */
39 /* instead of having the D3D one flush when its full. This way Mesa will*/
40 /* handle all the flushing. I need x6 as points can use 4 vertex each. */
41 D3DTLVERTEX D3DTLVertices[ (VB_MAX*6) ];
42 GLuint VList[VB_SIZE];
43 /*===========================================================================*/
44 /* Compute Z offsets for a polygon with plane defined by (A,B,C,D) */
45 /* D is not needed. TODO: Currently we are calculating this but not using it.*/
46 /*===========================================================================*/
47 /* RETURN: */
48 /*===========================================================================*/
49 static void OffsetPolygon( GLcontext *ctx, GLfloat a, GLfloat b, GLfloat c )
50 {
51 GLfloat ac,
52 bc,
53 m,
54 offset;
55
56 DPF(( DBG_FUNC, "OffsetPolygon();" ));
57
58 if ( (c < 0.001F) && (c > - 0.001F) )
59 {
60 /* Prevents underflow problems. */
61 ctx->PointZoffset = 0.0F;
62 ctx->LineZoffset = 0.0F;
63 ctx->PolygonZoffset = 0.0F;
64 }
65 else
66 {
67 ac = a / c;
68 bc = b / c;
69 if ( ac < 0.0F )
70 ac = -ac;
71 if ( bc<0.0F )
72 bc = -bc;
73 m = MAX2( ac, bc ); /* m = sqrt( ac*ac + bc*bc ); */
74
75 offset = (m * ctx->Polygon.OffsetFactor + ctx->Polygon.OffsetUnits);
76 ctx->PointZoffset = ctx->Polygon.OffsetPoint ? offset : 0.0F;
77 ctx->LineZoffset = ctx->Polygon.OffsetLine ? offset : 0.0F;
78 ctx->PolygonZoffset = ctx->Polygon.OffsetFill ? offset : 0.0F;
79 }
80
81 DPF(( DBG_PRIM_INFO, "OffsetPolygon: %f", offset ));
82 }
83 /*===========================================================================*/
84 /* Compute signed area of the n-sided polgyon specified by vertices */
85 /* vb->Win[] and vertex list vlist[]. */
86 /* A clockwise polygon will return a negative area. A counter-clockwise */
87 /* polygon will return a positive area. I have changed this function to */
88 /* actually calculate twice the area as its faster and still gives the sign. */
89 /*===========================================================================*/
90 /* RETURN: signed area of the polgon. */
91 /*===========================================================================*/
92 static GLfloat PolygonArea( const struct vertex_buffer *vb, GLuint n, const GLuint vlist[] )
93 {
94 GLfloat area;
95 GLuint i;
96
97 DPF(( DBG_FUNC, "PolygonArea();" ));
98
99 #define j0 vlist[i]
100 #define j1 vlist[(i+1)%n]
101 #define x0 vb->Win[j0][0]
102 #define y0 vb->Win[j0][1]
103 #define x1 vb->Win[j1][0]
104 #define y1 vb->Win[j1][1]
105
106 /* area = sum of trapezoids */
107 for( i = 0, area = 0.0; i < n; i++ )
108 area += ((x0 - x1) * (y0 + y1)); /* Note: no divide by two here! */
109
110 #undef x0
111 #undef y0
112 #undef x1
113 #undef y1
114 #undef j1
115 #undef j0
116
117 // TODO: I don't see the point or * 0.5 as we just want the sign...
118 return area;
119 }
120 /*===========================================================================*/
121 /* Render a polygon that needs clipping on at least one vertex. The function*/
122 /* will first clip the polygon to any user clipping planes then clip to the */
123 /* viewing volume. The final polygon will be draw as single triangles that */
124 /* first need minor proccessing (culling, offset, etc) before we draw the */
125 /* polygon as a fan. NOTE: the fan is draw as single triangles as its not */
126 /* formed sequentaly in the VB but is in the vlist[]. */
127 /*===========================================================================*/
128 /* RETURN: */
129 /*===========================================================================*/
130 static void RenderClippedPolygon( GLcontext *ctx, GLuint n, GLuint vlist[] )
131 {
132 struct vertex_buffer *VB = ctx->VB;
133 GLfloat (*win)[3] = VB->Win,
134 *proj = ctx->ProjectionMatrix,
135 ex, ey,
136 fx, fy, c,
137 wInv;
138 GLuint index,
139 pv,
140 facing;
141
142 DPF(( DBG_FUNC, "RenderClippedPolygon();" ));
143
144 DPF(( DBG_PRIM_INFO, "RenderClippedtPolygon( %d )", n ));
145
146 /* Which vertex dictates the color when flat shading. */
147 pv = (ctx->Primitive==GL_POLYGON) ? vlist[0] : vlist[n-1];
148
149 /* Clipping may introduce new vertices. New vertices will be stored in */
150 /* the vertex buffer arrays starting with location VB->Free. After we've*/
151 /* rendered the polygon, these extra vertices can be overwritten. */
152 VB->Free = VB_MAX;
153
154 /* Clip against user clipping planes in eye coord space. */
155 if ( ctx->Transform.AnyClip )
156 {
157 n = gl_userclip_polygon( ctx, n, vlist );
158 if ( n < 3 )
159 return;
160
161 /* Transform vertices from eye to clip coordinates: clip = Proj * eye */
162 for( index = 0; index < n; index++ )
163 {
164 TRANSFORM_POINT( VB->Clip[vlist[index]], proj, VB->Eye[vlist[index]] );
165 }
166 }
167
168 /* Clip against view volume in clip coord space */
169 n = gl_viewclip_polygon( ctx, n, vlist );
170 if ( n < 3 )
171 return;
172
173 /* Transform new vertices from clip to ndc to window coords. */
174 /* ndc = clip / W window = viewport_mapping(ndc) */
175 /* Note that window Z values are scaled to the range of integer */
176 /* depth buffer values. */
177
178 /* Only need to compute window coords for new vertices */
179 for( index = VB_MAX; index < VB->Free; index++ )
180 {
181 if ( VB->Clip[index][3] != 0.0F )
182 {
183 wInv = 1.0F / VB->Clip[index][3];
184
185 win[index][0] = VB->Clip[index][0] * wInv * ctx->Viewport.Sx + ctx->Viewport.Tx;
186 win[index][1] = VB->Clip[index][1] * wInv * ctx->Viewport.Sy + ctx->Viewport.Ty;
187 win[index][2] = VB->Clip[index][2] * wInv * ctx->Viewport.Sz + ctx->Viewport.Tz;
188 }
189 else
190 {
191 /* Can't divide by zero, so... */
192 win[index][0] = win[index][1] = win[index][2] = 0.0F;
193 }
194 }
195
196 /* Draw filled polygon as a triangle fan */
197 for( index = 2; index < n; index++ )
198 {
199 /* Compute orientation of triangle */
200 ex = win[vlist[index-1]][0] - win[vlist[0]][0];
201 ey = win[vlist[index-1]][1] - win[vlist[0]][1];
202 fx = win[vlist[index]][0] - win[vlist[0]][0];
203 fy = win[vlist[index]][1] - win[vlist[0]][1];
204 c = (ex * fy) - (ey * fx);
205
206 /* polygon is perpindicular to view plane, don't draw it */
207 if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
208 continue;
209
210 /* Backface culling. */
211 facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
212 if ( (facing + 1) & ctx->Polygon.CullBits )
213 continue;
214
215 if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
216 {
217 if ( facing == 1 )
218 {
219 /* use back color */
220 VB->Color = VB->Bcolor;
221 VB->Specular= VB->Bspec;
222 }
223 else
224 {
225 /* use front color */
226 VB->Color = VB->Fcolor;
227 VB->Specular= VB->Fspec;
228 }
229 }
230
231 if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
232 {
233 /* finish computing plane equation of polygon, compute offset */
234 GLfloat fz = win[vlist[index]][2] - win[vlist[0]][2];
235 GLfloat ez = win[vlist[index-1]][2] - win[vlist[0]][2];
236 GLfloat a = (ey * fz) - (ez * fy);
237 GLfloat b = (ez * fx) - (ex * fz);
238 OffsetPolygon( ctx, a, b, c );
239 }
240 RenderOneTriangle( ctx, vlist[0], vlist[index-1], vlist[index], pv );
241 }
242 }
243 /*===========================================================================*/
244 /* This function gets called when either the vertex buffer is full or glEnd */
245 /* has been called. If the we aren't in rendering mode (FEEDBACK) then I */
246 /* pass the vertex buffer back to Mesa to deal with by returning FALSE. */
247 /* If I can render the primitive types in the buffer directly then I will */
248 /* return TRUE after I render the vertex buffer and reset the vertex buffer. */
249 /* */
250 /* TODO: I don't handle the special case of when the vertex buffer is full */
251 /* and we have a primitive that bounds this buffer and the next one to */
252 /* come. I'm not sure right now if Mesa handles this for me... */
253 /*===========================================================================*/
254 /* RETURN: TRUE, FALSE. */
255 /*===========================================================================*/
256 GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone )
257 {
258 struct vertex_buffer *VB = ctx->VB;
259 GLuint index,
260 vlist[VB_SIZE];
261
262 DPF(( DBG_FUNC, "RenderVertexBuffer();" ));
263
264 /* We only need to hook actual tri's that need rendering. */
265 if ( ctx->RenderMode != GL_RENDER )
266 {
267 // (ctx->Visual->AccumBits > 0) )
268 // (ctx->Visual->StencilBits > 0) )
269 DPF(( DBG_PRIM_INFO, "Passing VB back to Mesa" ));
270 return FALSE;
271 }
272
273 /* I'm going to set the states here so that all functions will */
274 /* be assured to have the right states. If Mesa's vertex bufefr */
275 /* function calls one of my primitive functions (TRI,POINT,LINE) */
276 /* it will need the right states. So instead of doing it in the */
277 /* primitive function I will always do it here at risk of some */
278 /* slow down to some cases... */
279 SetRenderStates( ctx );
280
281 switch( ctx->Primitive )
282 {
283 case GL_POINTS:
284 DPF(( DBG_PRIM_INFO, "GL_POINTS( %d )", VB->Count ));
285 RenderPointsVB( ctx, 0, VB->Count );
286 break;
287
288 case GL_LINES:
289 case GL_LINE_STRIP:
290 case GL_LINE_LOOP:
291 /* Not supported functions yet so pass back that we failed to */
292 /* render the vertex buffer and Mesa will have to do it. */
293 DPF(( DBG_PRIM_INFO, "GL_LINE_?( %d )", VB->Count ));
294 return FALSE;
295
296 case GL_TRIANGLES:
297 if ( VB->Count < 3 )
298 {
299 DPF(( DBG_PRIM_WARN, "GL_TRIANGLES( %d )", VB->Count ));
300 return FALSE;
301 }
302
303 DPF(( DBG_PRIM_INFO, "GL_TRIANGLES( %d )", VB->Count ));
304 RenderTriangleVB( ctx, 0, VB->Count );
305 break;
306
307 case GL_TRIANGLE_STRIP:
308 if ( VB->Count < 3 )
309 {
310 DPF(( DBG_PRIM_WARN, "GL_TRIANGLE_STRIP( %d )", VB->Count ));
311 return FALSE;
312 }
313
314 DPF(( DBG_PRIM_INFO, "GL_TRIANGLE_STRIP( %d )", VB->Count ));
315 RenderTriangleStripVB( ctx, 0, VB->Count );
316 break;
317
318 case GL_TRIANGLE_FAN:
319 if ( VB->Count < 3 )
320 {
321 DPF(( DBG_PRIM_WARN, "GL_TRIANGLE_FAN( %d )", VB->Count ));
322 return FALSE;
323 }
324
325 DPF(( DBG_PRIM_INFO, "GL_TRIANGLE_FAN( %d )", VB->Count ));
326 RenderTriangleFanVB( ctx, 0, VB->Count );
327 break;
328
329 case GL_QUADS:
330 if ( VB->Count < 4 )
331 {
332 DPF(( DBG_PRIM_WARN, "GL_QUADS( %d )", VB->Count ));
333 return FALSE;
334 }
335
336 DPF(( DBG_PRIM_INFO, "GL_QUADS( %d )", VB->Count ));
337 RenderQuadVB( ctx, 0, VB->Count );
338 break;
339
340 case GL_QUAD_STRIP:
341 if ( VB->Count < 4 )
342 {
343 DPF(( DBG_PRIM_WARN, "GL_QUAD_STRIP( %d )", VB->Count ));
344 return FALSE;
345 }
346
347 DPF(( DBG_PRIM_INFO, "GL_QUAD_STRIP( %d )", VB->Count ));
348
349 if ( VB->ClipOrMask )
350 {
351 for( index = 3; index < VB->Count; index += 2 )
352 {
353 if ( VB->ClipMask[index-3] & VB->ClipMask[index-2] & VB->ClipMask[index-1] & VB->ClipMask[index] & CLIP_ALL_BITS )
354 {
355 /* All points clipped by common plane */
356 DPF(( DBG_PRIM_WARN, "GL_QUAD_STRIP( %d )", VB->Count ));
357 continue;
358 }
359 else if ( VB->ClipMask[index-3] | VB->ClipMask[index-2] | VB->ClipMask[index-1] | VB->ClipMask[index] )
360 {
361 vlist[0] = index - 3;
362 vlist[1] = index - 2;
363 vlist[2] = index;
364 vlist[3] = index - 1;
365 RenderClippedPolygon( ctx, 4, vlist );
366 }
367 else
368 {
369 RenderQuad( ctx, (index-3), (index-2), index, (index-1), index );
370 }
371 }
372 }
373 else
374 {
375 /* No clipping needed */
376 for( index = 3; index < VB->Count; index += 2 )
377 RenderQuad( ctx, (index-3), (index-2), index, (index-1), index );
378 }
379 break;
380
381 case GL_POLYGON:
382 if ( VB->Count < 3 )
383 {
384 DPF(( DBG_PRIM_WARN, "GL_POLYGON( %d )", VB->Count ));
385 return FALSE;
386 }
387
388 DPF(( DBG_PRIM_INFO, "GL_POLYGON( %d )", VB->Count ));
389
390 /* All points clipped by common plane, draw nothing */
391 if ( !(VB->ClipAndMask & CLIP_ALL_BITS) )
392 RenderTriangleFanVB( ctx, 0, VB->Count );
393 break;
394
395 default:
396 /* should never get here */
397 _mesa_problem( ctx, "invalid mode in gl_render_vb" );
398 }
399
400 DPF(( DBG_PRIM_INFO, "ResetVB" ));
401
402 /* We return TRUE to indicate we rendered the VB. */
403 gl_reset_vb( ctx, allDone );
404 return TRUE;
405 }
406 /*===========================================================================*/
407 /* This function will render the current vertex buffer as triangles. The */
408 /* buffer has to be able to be rendered directly. This means that we are */
409 /* filled, no offsets, no culling and one sided rendering. Also we must be */
410 /* in render mode of course. */
411 /* First I will fill the global D3D vertice buffer. Next I will set all the*/
412 /* states for D3D based on the current OGL state. Finally I pass the D3D VB */
413 /* to the wrapper that call DrawPrimitives. */
414 /*===========================================================================*/
415 /* RETURN: */
416 /*===========================================================================*/
417 static void RenderTriangleVB( GLcontext *ctx, GLuint start, GLuint end )
418 {
419 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
420 struct vertex_buffer *VB = ctx->VB;
421 int index,
422 cVertex,
423 height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
424 DWORD dwPVColor;
425 GLfloat ex, ey,
426 fx, fy, c;
427 GLuint facing;
428
429 DPF(( DBG_FUNC, "RenderTriangleVB" ));
430
431 if ( !VB->ClipOrMask )
432 {
433 DPF(( DBG_PRIM_INFO, "DirectTriangles( %d )", (end-start) ));
434 for( index = start, cVertex = 0; index < end; )
435 {
436 dwPVColor = (VB->Color[(index+2)][3]<<24) | (VB->Color[(index+2)][0]<<16) | (VB->Color[(index+2)][1]<<8) | VB->Color[(index+2)][2];
437
438 /*=====================================*/
439 /* Populate the the triangle vertices. */
440 /*=====================================*/
441 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
442 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
443 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
444 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
445 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
446 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
447 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
448 dwPVColor :
449 (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
450 index++;
451
452 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
453 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
454 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
455 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
456 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
457 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
458 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
459 dwPVColor :
460 (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
461 index++;
462
463 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
464 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
465 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
466 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
467 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
468 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
469 D3DTLVertices[cVertex++].color= dwPVColor;
470 index++;
471 }
472 }
473 else
474 {
475 #define v1 index
476 #define v2 (index+1)
477 #define v3 (index+2)
478
479 for( index = start, cVertex = 0; index < end; index += 3 )
480 {
481 if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS )
482 {
483 continue;
484 }
485 else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] )
486 {
487 VList[0] = v1;
488 VList[1] = v2;
489 VList[2] = v3;
490 RenderClippedPolygon( ctx, 3, VList );
491 continue;
492 }
493
494 /* Compute orientation of triangle */
495 ex = VB->Win[v2][0] - VB->Win[v1][0];
496 ey = VB->Win[v2][1] - VB->Win[v1][1];
497 fx = VB->Win[v3][0] - VB->Win[v1][0];
498 fy = VB->Win[v3][1] - VB->Win[v1][1];
499 c = (ex * fy) - (ey * fx);
500
501 /* polygon is perpindicular to view plane, don't draw it */
502 if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
503 continue;
504
505 /* Backface culling. */
506 facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
507 if ( (facing + 1) & ctx->Polygon.CullBits )
508 continue;
509
510 if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
511 {
512 if ( facing == 1 )
513 {
514 /* use back color */
515 VB->Color = VB->Bcolor;
516 VB->Specular= VB->Bspec;
517 }
518 else
519 {
520 /* use front color */
521 VB->Color = VB->Fcolor;
522 VB->Specular= VB->Fspec;
523 }
524 }
525
526 if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
527 {
528 /* Finish computing plane equation of polygon, compute offset */
529 GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
530 GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
531 GLfloat a = (ey * fz) - (ez * fy);
532 GLfloat b = (ez * fx) - (ex * fz);
533 OffsetPolygon( ctx, a, b, c );
534 }
535
536 /*=====================================*/
537 /* Populate the the triangle vertices. */
538 /*=====================================*/
539 /* Solve the prevoking vertex color as we need it for the 3rd triangle and flat shading. */
540 dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
541
542 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
543 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
544 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
545 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
546 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
547 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
548 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
549 dwPVColor :
550 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
551
552 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
553 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
554 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
555 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
556 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
557 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
558 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
559 dwPVColor :
560 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
561
562 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
563 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
564 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
565 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
566 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
567 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
568 D3DTLVertices[cVertex++].color= dwPVColor;
569 }
570 #undef v1
571 #undef v2
572 #undef v3
573 }
574
575 /* Render the converted vertex buffer. */
576 if ( cVertex > 2 )
577 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
578 }
579 /*===========================================================================*/
580 /* This function will render the current vertex buffer as a triangle fan. */
581 /* The buffer has to be able to be rendered directly. This means that we are*/
582 /* filled, no offsets, no culling and one sided rendering. Also we must be */
583 /* in render mode of course. */
584 /* First I will fill the global D3D vertice buffer. Next I will set all the*/
585 /* states for D3D based on the current OGL state. Finally I pass the D3D VB */
586 /* to the wrapper that call DrawPrimitives. */
587 /*===========================================================================*/
588 /* RETURN: */
589 /*===========================================================================*/
590 static void RenderTriangleFanVB( GLcontext *ctx, GLuint start, GLuint end )
591 {
592 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
593 struct vertex_buffer *VB = ctx->VB;
594 int index,
595 cVertex,
596 height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
597 GLfloat ex, ey,
598 fx, fy, c;
599 GLuint facing;
600 DWORD dwPVColor;
601
602 DPF(( DBG_FUNC, "RenderTriangleFanVB();" ));
603
604 /* Special case that we can blast the fan without culling, offset, etc... */
605 if ( !VB->ClipOrMask && (ctx->Light.ShadeModel != GL_FLAT) )
606 {
607 DPF(( DBG_PRIM_INFO, "DirectTriangles( %d )", (end-start) ));
608
609 /* Seed the the fan. */
610 D3DTLVertices[0].sx = D3DVAL( VB->Win[start][0] );
611 D3DTLVertices[0].sy = D3DVAL( (height - VB->Win[start][1]) );
612 D3DTLVertices[0].sz = D3DVAL( VB->Win[start][2] );
613 D3DTLVertices[0].tu = D3DVAL( VB->TexCoord[start][0] );
614 D3DTLVertices[0].tv = D3DVAL( VB->TexCoord[start][1] );
615 D3DTLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[start][3]) );
616 D3DTLVertices[0].color= (VB->Color[start][3]<<24) | (VB->Color[start][0]<<16) | (VB->Color[start][1]<<8) | VB->Color[start][2];
617
618 /* Seed the the fan. */
619 D3DTLVertices[1].sx = D3DVAL( VB->Win[(start+1)][0] );
620 D3DTLVertices[1].sy = D3DVAL( (height - VB->Win[(start+1)][1]) );
621 D3DTLVertices[1].sz = D3DVAL( VB->Win[(start+1)][2] );
622 D3DTLVertices[1].tu = D3DVAL( VB->TexCoord[(start+1)][0] );
623 D3DTLVertices[1].tv = D3DVAL( VB->TexCoord[(start+1)][1] );
624 D3DTLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[(start+1)][3]) );
625 D3DTLVertices[1].color= (VB->Color[(start+1)][3]<<24) | (VB->Color[(start+1)][0]<<16) | (VB->Color[(start+1)][1]<<8) | VB->Color[(start+1)][2];
626
627 for( index = (start+2), cVertex = 2; index < end; index++, cVertex++ )
628 {
629 /*=================================*/
630 /* Add the next vertex to the fan. */
631 /*=================================*/
632 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
633 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
634 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
635 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
636 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
637 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
638 D3DTLVertices[cVertex].color = (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
639 }
640
641 /* Render the converted vertex buffer. */
642 if ( cVertex )
643 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLEFAN, &D3DTLVertices[0], cVertex );
644 }
645 else
646 {
647 #define v1 start
648 #define v2 (index-1)
649 #define v3 index
650
651 for( index = (start+2), cVertex = 0; index < end; index++ )
652 {
653 if ( VB->ClipOrMask )
654 {
655 /* All points clipped by common plane */
656 if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS )
657 {
658 continue;
659 }
660 else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] )
661 {
662 VList[0] = v1;
663 VList[1] = v2;
664 VList[2] = v3;
665 RenderClippedPolygon( ctx, 3, VList );
666 continue;
667 }
668 }
669
670 /* Compute orientation of triangle */
671 ex = VB->Win[v2][0] - VB->Win[v1][0];
672 ey = VB->Win[v2][1] - VB->Win[v1][1];
673 fx = VB->Win[v3][0] - VB->Win[v1][0];
674 fy = VB->Win[v3][1] - VB->Win[v1][1];
675 c = (ex * fy) - (ey * fx);
676
677 /* polygon is perpindicular to view plane, don't draw it */
678 if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
679 continue;
680
681 /* Backface culling. */
682 facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
683 if ( (facing + 1) & ctx->Polygon.CullBits )
684 continue;
685
686 if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
687 {
688 /* Finish computing plane equation of polygon, compute offset */
689 GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
690 GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
691 GLfloat a = (ey * fz) - (ez * fy);
692 GLfloat b = (ez * fx) - (ex * fz);
693 OffsetPolygon( ctx, a, b, c );
694 }
695
696 /*=====================================*/
697 /* Populate the the triangle vertices. */
698 /*=====================================*/
699 dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
700
701 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
702 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
703 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
704 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
705 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
706 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
707 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
708 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
709
710 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
711 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
712 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
713 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
714 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
715 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
716 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
717 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
718
719 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
720 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
721 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
722 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
723 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
724 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
725 D3DTLVertices[cVertex++].color= dwPVColor;
726 }
727
728 /* Render the converted vertex buffer. */
729 if ( cVertex )
730 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
731 #undef v1
732 #undef v2
733 #undef v3
734 }
735 }
736 /*===========================================================================*/
737 /* This function will render the current vertex buffer as a triangle strip. */
738 /* The buffer has to be able to be rendered directly. This means that we are*/
739 /* filled, no offsets, no culling and one sided rendering. Also we must be */
740 /* in render mode of course. */
741 /* First I will fill the global D3D vertice buffer. Next I will set all the*/
742 /* states for D3D based on the current OGL state. Finally I pass the D3D VB */
743 /* to the wrapper that call DrawPrimitives. */
744 /*===========================================================================*/
745 /* RETURN: */
746 /*===========================================================================*/
747 static void RenderTriangleStripVB( GLcontext *ctx, GLuint start, GLuint end )
748 {
749 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
750 struct vertex_buffer *VB = ctx->VB;
751 int index,
752 cVertex = 0,
753 v1, v2, v3,
754 height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
755 GLfloat ex, ey,
756 fx, fy, c;
757 GLuint facing;
758 DWORD dwPVColor;
759
760 DPF(( DBG_FUNC, "RenderTriangleStripVB();" ));
761
762 /* Special case that we can blast the fan without culling, offset, etc... */
763 if ( !VB->ClipOrMask && (ctx->Light.ShadeModel != GL_FLAT) )
764 {
765 DPF(( DBG_PRIM_PROFILE, "DirectTriangles" ));
766
767 /* Seed the the strip. */
768 D3DTLVertices[0].sx = D3DVAL( VB->Win[start][0] );
769 D3DTLVertices[0].sy = D3DVAL( (height - VB->Win[start][1]) );
770 D3DTLVertices[0].sz = D3DVAL( VB->Win[start][2] );
771 D3DTLVertices[0].tu = D3DVAL( VB->TexCoord[start][0] );
772 D3DTLVertices[0].tv = D3DVAL( VB->TexCoord[start][1] );
773 D3DTLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[start][3]) );
774 D3DTLVertices[0].color= (VB->Color[start][3]<<24) | (VB->Color[start][0]<<16) | (VB->Color[start][1]<<8) | VB->Color[start][2];
775
776 /* Seed the the strip. */
777 D3DTLVertices[1].sx = D3DVAL( VB->Win[(start+1)][0] );
778 D3DTLVertices[1].sy = D3DVAL( (height - VB->Win[(start+1)][1]) );
779 D3DTLVertices[1].sz = D3DVAL( VB->Win[(start+1)][2] );
780 D3DTLVertices[1].tu = D3DVAL( VB->TexCoord[(start+1)][0] );
781 D3DTLVertices[1].tv = D3DVAL( VB->TexCoord[(start+1)][1] );
782 D3DTLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[(start+1)][3]) );
783 D3DTLVertices[1].color= (VB->Color[(start+1)][3]<<24) | (VB->Color[(start+1)][0]<<16) | (VB->Color[(start+1)][1]<<8) | VB->Color[(start+1)][2];
784
785 for( index = (start+2), cVertex = 2; index < end; index++, cVertex++ )
786 {
787 /*===================================*/
788 /* Add the next vertex to the strip. */
789 /*===================================*/
790 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
791 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
792 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
793 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
794 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
795 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
796 D3DTLVertices[cVertex].color = (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
797 }
798
799 /* Render the converted vertex buffer. */
800 if ( cVertex )
801 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLESTRIP, &D3DTLVertices[0], cVertex );
802 }
803 else
804 {
805 for( index = (start+2); index < end; index++ )
806 {
807 /* We need to switch order so that winding won't be a problem. */
808 if ( index & 1 )
809 {
810 v1 = index - 1;
811 v2 = index - 2;
812 v3 = index - 0;
813 }
814 else
815 {
816 v1 = index - 2;
817 v2 = index - 1;
818 v3 = index - 0;
819 }
820
821 /* All vertices clipped by common plane */
822 if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS )
823 continue;
824
825 /* Check if any vertices need clipping. */
826 if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] )
827 {
828 VList[0] = v1;
829 VList[1] = v2;
830 VList[2] = v3;
831 RenderClippedPolygon( ctx, 3, VList );
832 }
833 else
834 {
835 /* Compute orientation of triangle */
836 ex = VB->Win[v2][0] - VB->Win[v1][0];
837 ey = VB->Win[v2][1] - VB->Win[v1][1];
838 fx = VB->Win[v3][0] - VB->Win[v1][0];
839 fy = VB->Win[v3][1] - VB->Win[v1][1];
840 c = (ex * fy) - (ey * fx);
841
842 /* Polygon is perpindicular to view plane, don't draw it */
843 if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
844 continue;
845
846 /* Backface culling. */
847 facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
848 if ( (facing + 1) & ctx->Polygon.CullBits )
849 continue;
850
851 /* Need right color if we have two sided lighting. */
852 if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
853 {
854 if ( facing == 1 )
855 {
856 /* use back color */
857 VB->Color = VB->Bcolor;
858 VB->Specular= VB->Bspec;
859 }
860 else
861 {
862 /* use front color */
863 VB->Color = VB->Fcolor;
864 VB->Specular= VB->Fspec;
865 }
866 }
867
868 if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
869 {
870 /* Finish computing plane equation of polygon, compute offset */
871 GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
872 GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
873 GLfloat a = (ey * fz) - (ez * fy);
874 GLfloat b = (ez * fx) - (ex * fz);
875 OffsetPolygon( ctx, a, b, c );
876 }
877 /*=====================================*/
878 /* Populate the the triangle vertices. */
879 /*=====================================*/
880
881 /* Solve the prevoking vertex color as we need it for the 3rd triangle and flat shading. */
882 dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
883
884 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
885 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
886 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
887 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
888 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
889 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
890 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
891 dwPVColor :
892 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
893
894 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
895 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
896 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
897 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
898 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
899 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
900 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
901 dwPVColor :
902 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
903
904 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
905 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
906 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
907 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
908 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
909 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
910 D3DTLVertices[cVertex++].color= dwPVColor;
911 }
912 }
913
914 /* Render the converted vertex buffer. */
915 if ( cVertex )
916 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
917 }
918 }
919 /*===========================================================================*/
920 /* This function will render the current vertex buffer as Quads. The buffer*/
921 /* has to be able to be rendered directly. This means that we are filled, no*/
922 /* offsets, no culling and one sided rendering. Also we must be in render */
923 /* mode of cource. */
924 /* First I will fill the global D3D vertice buffer. Next I will set all the*/
925 /* states for D3D based on the current OGL state. Finally I pass the D3D VB */
926 /* to the wrapper that call DrawPrimitives. */
927 /*===========================================================================*/
928 /* RETURN: */
929 /*===========================================================================*/
930 static void RenderQuadVB( GLcontext *ctx, GLuint start, GLuint end )
931 {
932 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
933 struct vertex_buffer *VB = ctx->VB;
934 int index,
935 cVertex,
936 height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
937 DWORD dwPVColor;
938 GLfloat ex, ey,
939 fx, fy, c;
940 GLuint facing; /* 0=front, 1=back */
941
942 DPF(( DBG_FUNC, "RenderQuadVB();" ));
943
944 #define v1 (index)
945 #define v2 (index+1)
946 #define v3 (index+2)
947 #define v4 (index+3)
948
949 if ( !VB->ClipOrMask )
950 {
951 DPF(( DBG_PRIM_PROFILE, "DirectTriangles" ));
952
953 for( cVertex = 0, index = start; index < end; index += 4 )
954 {
955 if ( ctx->Light.ShadeModel == GL_FLAT )
956 dwPVColor = (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
957
958 /*=====================================*/
959 /* Populate the the triangle vertices. */
960 /*=====================================*/
961 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
962 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
963 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v1][2] );
964 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
965 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
966 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
967 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
968 dwPVColor :
969 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
970
971 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
972 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
973 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v2][2] );
974 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
975 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
976 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
977 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
978 dwPVColor :
979 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
980
981 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
982 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
983 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v3][2] );
984 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
985 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
986 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
987 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
988 dwPVColor :
989 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
990
991 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
992 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
993 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v1][2] );
994 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
995 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
996 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
997 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
998 dwPVColor :
999 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1000
1001 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
1002 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
1003 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v3][2] );
1004 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
1005 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
1006 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
1007 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1008 dwPVColor :
1009 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
1010
1011 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v4][0] );
1012 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v4][1]) );
1013 D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v4][2] );
1014 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v4][0] );
1015 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v4][1] );
1016 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v4][3]) );
1017 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1018 dwPVColor :
1019 (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
1020 }
1021 }
1022 else
1023 {
1024 for( cVertex = 0, index = start; index < end; index += 4 )
1025 {
1026 if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & VB->ClipMask[v4] & CLIP_ALL_BITS )
1027 {
1028 continue;
1029 }
1030 else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] | VB->ClipMask[v4] )
1031 {
1032 VList[0] = v1;
1033 VList[1] = v2;
1034 VList[2] = v3;
1035 VList[3] = v4;
1036 RenderClippedPolygon( ctx, 4, VList );
1037 continue;
1038 }
1039
1040 /* Compute orientation of triangle */
1041 ex = VB->Win[v2][0] - VB->Win[v1][0];
1042 ey = VB->Win[v2][1] - VB->Win[v1][1];
1043 fx = VB->Win[v3][0] - VB->Win[v1][0];
1044 fy = VB->Win[v3][1] - VB->Win[v1][1];
1045 c = (ex * fy) - (ey * fx);
1046
1047 /* polygon is perpindicular to view plane, don't draw it */
1048 if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
1049 continue;
1050
1051 /* Backface culling. */
1052 facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
1053 if ( (facing + 1) & ctx->Polygon.CullBits )
1054 continue;
1055
1056 if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
1057 {
1058 if ( facing == 1 )
1059 {
1060 /* use back color */
1061 VB->Color = VB->Bcolor;
1062 VB->Specular= VB->Bspec;
1063 }
1064 else
1065 {
1066 /* use front color */
1067 VB->Color = VB->Fcolor;
1068 VB->Specular= VB->Fspec;
1069 }
1070 }
1071
1072 if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
1073 {
1074 /* Finish computing plane equation of polygon, compute offset */
1075 GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
1076 GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
1077 GLfloat a = (ey * fz) - (ez * fy);
1078 GLfloat b = (ez * fx) - (ex * fz);
1079 OffsetPolygon( ctx, a, b, c );
1080 }
1081
1082 if ( ctx->Light.ShadeModel == GL_FLAT )
1083 dwPVColor = (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
1084
1085 /*=====================================*/
1086 /* Populate the the triangle vertices. */
1087 /*=====================================*/
1088 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
1089 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
1090 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
1091 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
1092 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
1093 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
1094 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1095 dwPVColor :
1096 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1097
1098 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
1099 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
1100 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
1101 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
1102 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
1103 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
1104 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1105 dwPVColor :
1106 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
1107
1108 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
1109 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
1110 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
1111 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
1112 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
1113 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
1114 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1115 dwPVColor :
1116 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
1117
1118 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
1119 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
1120 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
1121 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
1122 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
1123 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
1124 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1125 dwPVColor :
1126 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1127
1128 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
1129 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
1130 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
1131 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
1132 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
1133 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
1134 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1135 dwPVColor :
1136 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
1137
1138 D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v4][0] );
1139 D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v4][1]) );
1140 D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v4][2] + ctx->PolygonZoffset) );
1141 D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v4][0] );
1142 D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v4][1] );
1143 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v4][3]) );
1144 D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
1145 dwPVColor :
1146 (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
1147 }
1148 }
1149
1150 #undef v4
1151 #undef v3
1152 #undef v2
1153 #undef v1
1154
1155 /* Render the converted vertex buffer. */
1156 if ( cVertex )
1157 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
1158 }
1159 /*===========================================================================*/
1160 /* */
1161 /*===========================================================================*/
1162 /* RETURN: TRUE, FALSE. */
1163 /*===========================================================================*/
1164 static void RenderQuad( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv )
1165 {
1166 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1167 struct vertex_buffer *VB = ctx->VB;
1168 int height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
1169 DWORD dwPVColor;
1170 GLfloat ex, ey,
1171 fx, fy, c;
1172 GLuint facing; /* 0=front, 1=back */
1173 static D3DTLVERTEX TLVertices[6];
1174
1175 DPF(( DBG_FUNC, "RenderQuad" ));
1176 DPF(( DBG_PRIM_INFO, "RenderQuad( 1 )" ));
1177
1178 /* Compute orientation of triangle */
1179 ex = VB->Win[v2][0] - VB->Win[v1][0];
1180 ey = VB->Win[v2][1] - VB->Win[v1][1];
1181 fx = VB->Win[v3][0] - VB->Win[v1][0];
1182 fy = VB->Win[v3][1] - VB->Win[v1][1];
1183 c = (ex * fy) - (ey * fx);
1184
1185 /* polygon is perpindicular to view plane, don't draw it */
1186 if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
1187 return;
1188
1189 /* Backface culling. */
1190 facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
1191 if ( (facing + 1) & ctx->Polygon.CullBits )
1192 return;
1193
1194 if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
1195 {
1196 if ( facing == 1 )
1197 {
1198 /* use back color */
1199 VB->Color = VB->Bcolor;
1200 VB->Specular= VB->Bspec;
1201 }
1202 else
1203 {
1204 /* use front color */
1205 VB->Color = VB->Fcolor;
1206 VB->Specular= VB->Fspec;
1207 }
1208 }
1209
1210 if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
1211 {
1212 /* Finish computing plane equation of polygon, compute offset */
1213 GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
1214 GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
1215 GLfloat a = (ey * fz) - (ez * fy);
1216 GLfloat b = (ez * fx) - (ex * fz);
1217 OffsetPolygon( ctx, a, b, c );
1218 }
1219
1220 if ( ctx->Light.ShadeModel == GL_FLAT )
1221 dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
1222
1223 /*=====================================*/
1224 /* Populate the the triangle vertices. */
1225 /*=====================================*/
1226 TLVertices[0].sx = D3DVAL( VB->Win[v1][0] );
1227 TLVertices[0].sy = D3DVAL( (height - VB->Win[v1][1]) );
1228 TLVertices[0].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
1229 TLVertices[0].tu = D3DVAL( VB->TexCoord[v1][0] );
1230 TLVertices[0].tv = D3DVAL( VB->TexCoord[v1][1] );
1231 TLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
1232 TLVertices[0].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1233 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1234
1235 TLVertices[1].sx = D3DVAL( VB->Win[v2][0] );
1236 TLVertices[1].sy = D3DVAL( (height - VB->Win[v2][1]) );
1237 TLVertices[1].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
1238 TLVertices[1].tu = D3DVAL( VB->TexCoord[v2][0] );
1239 TLVertices[1].tv = D3DVAL( VB->TexCoord[v2][1] );
1240 TLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
1241 TLVertices[1].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1242 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
1243
1244 TLVertices[2].sx = D3DVAL( VB->Win[v3][0] );
1245 TLVertices[2].sy = D3DVAL( (height - VB->Win[v3][1]) );
1246 TLVertices[2].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
1247 TLVertices[2].tu = D3DVAL( VB->TexCoord[v3][0] );
1248 TLVertices[2].tv = D3DVAL( VB->TexCoord[v3][1] );
1249 TLVertices[2].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
1250 TLVertices[2].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1251 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
1252
1253 TLVertices[3].sx = D3DVAL( VB->Win[v3][0] );
1254 TLVertices[3].sy = D3DVAL( (height - VB->Win[v3][1]) );
1255 TLVertices[3].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
1256 TLVertices[3].tu = D3DVAL( VB->TexCoord[v3][0] );
1257 TLVertices[3].tv = D3DVAL( VB->TexCoord[v3][1] );
1258 TLVertices[3].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
1259 TLVertices[3].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1260 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
1261
1262 TLVertices[4].sx = D3DVAL( VB->Win[v4][0] );
1263 TLVertices[4].sy = D3DVAL( (height - VB->Win[v4][1]) );
1264 TLVertices[4].sz = D3DVAL( (VB->Win[v4][2] + ctx->PolygonZoffset) );
1265 TLVertices[4].tu = D3DVAL( VB->TexCoord[v4][0] );
1266 TLVertices[4].tv = D3DVAL( VB->TexCoord[v4][1] );
1267 TLVertices[4].rhw = D3DVAL( (1.0 / VB->Clip[v4][3]) );
1268 TLVertices[4].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1269 (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
1270
1271 TLVertices[5].sx = D3DVAL( VB->Win[v1][0] );
1272 TLVertices[5].sy = D3DVAL( (height - VB->Win[v1][1]) );
1273 TLVertices[5].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
1274 TLVertices[5].tu = D3DVAL( VB->TexCoord[v1][0] );
1275 TLVertices[5].tv = D3DVAL( VB->TexCoord[v1][1] );
1276 TLVertices[5].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
1277 TLVertices[5].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1278 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1279
1280 /* Draw the two triangles. */
1281 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &TLVertices[0], 6 );
1282 }
1283 /*===========================================================================*/
1284 /* */
1285 /*===========================================================================*/
1286 /* RETURN: TRUE, FALSE. */
1287 /*===========================================================================*/
1288 void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv )
1289 {
1290 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1291 struct vertex_buffer *VB = ctx->VB;
1292 int height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
1293 DWORD dwPVColor;
1294 static D3DTLVERTEX TLVertices[3];
1295
1296 DPF(( DBG_FUNC, "RenderOneTriangle" ));
1297 DPF(( DBG_PRIM_INFO, "RenderTriangle( 1 )" ));
1298
1299 /*=====================================*/
1300 /* Populate the the triangle vertices. */
1301 /*=====================================*/
1302 if ( ctx->Light.ShadeModel == GL_FLAT )
1303 dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
1304
1305 TLVertices[0].sx = D3DVAL( VB->Win[v1][0] );
1306 TLVertices[0].sy = D3DVAL( (height - VB->Win[v1][1]) );
1307 TLVertices[0].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
1308 TLVertices[0].tu = D3DVAL( VB->TexCoord[v1][0] );
1309 TLVertices[0].tv = D3DVAL( VB->TexCoord[v1][1] );
1310 TLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
1311 TLVertices[0].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1312 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1313 DPF(( DBG_PRIM_INFO, "V1 -> x:%f y:%f z:%f c:%x",
1314 TLVertices[0].sx,
1315 TLVertices[0].sy,
1316 TLVertices[0].sz,
1317 TLVertices[0].color ));
1318
1319 TLVertices[1].sx = D3DVAL( VB->Win[v2][0] );
1320 TLVertices[1].sy = D3DVAL( (height - VB->Win[v2][1]) );
1321 TLVertices[1].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
1322 TLVertices[1].tu = D3DVAL( VB->TexCoord[v2][0] );
1323 TLVertices[1].tv = D3DVAL( VB->TexCoord[v2][1] );
1324 TLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
1325 TLVertices[1].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1326 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
1327 DPF(( DBG_PRIM_INFO, "V2 -> x:%f y:%f z:%f c:%x",
1328 TLVertices[1].sx,
1329 TLVertices[1].sy,
1330 TLVertices[1].sz,
1331 TLVertices[1].color ));
1332
1333 TLVertices[2].sx = D3DVAL( VB->Win[v3][0] );
1334 TLVertices[2].sy = D3DVAL( (height - VB->Win[v3][1]) );
1335 TLVertices[2].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
1336 TLVertices[2].tu = D3DVAL( VB->TexCoord[v3][0] );
1337 TLVertices[2].tv = D3DVAL( VB->TexCoord[v3][1] );
1338 TLVertices[2].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
1339 TLVertices[2].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1340 (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
1341 DPF(( DBG_PRIM_INFO, "V3 -> x:%f y:%f z:%f c:%x",
1342 TLVertices[2].sx,
1343 TLVertices[2].sy,
1344 TLVertices[2].sz,
1345 TLVertices[2].color ));
1346
1347 /* Draw the triangle. */
1348 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &TLVertices[0], 3 );
1349 }
1350 /*===========================================================================*/
1351 /* */
1352 /*===========================================================================*/
1353 /* RETURN: TRUE, FALSE. */
1354 /*===========================================================================*/
1355 void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
1356 {
1357 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1358 struct vertex_buffer *VB = ctx->VB;
1359 int height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
1360 DWORD dwPVColor;
1361 static D3DTLVERTEX TLVertices[2];
1362
1363 DPF(( DBG_FUNC, "RenderOneLine" ));
1364 DPF(( DBG_PRIM_INFO, "RenderLine( 1 )" ));
1365
1366 if ( VB->MonoColor )
1367 dwPVColor = (pContext->aCurrent<<24) | (pContext->rCurrent<<16) | (pContext->gCurrent<<8) | pContext->bCurrent;
1368 else
1369 dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
1370
1371 TLVertices[0].sx = D3DVAL( VB->Win[v1][0] );
1372 TLVertices[0].sy = D3DVAL( (height - VB->Win[v1][1]) );
1373 TLVertices[0].sz = D3DVAL( (VB->Win[v1][2] + ctx->LineZoffset) );
1374 TLVertices[0].tu = D3DVAL( VB->TexCoord[v1][0] );
1375 TLVertices[0].tv = D3DVAL( VB->TexCoord[v1][1] );
1376 TLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
1377 TLVertices[0].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1378 (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
1379
1380 TLVertices[1].sx = D3DVAL( VB->Win[v2][0] );
1381 TLVertices[1].sy = D3DVAL( (height - VB->Win[v2][1]) );
1382 TLVertices[1].sz = D3DVAL( (VB->Win[v2][2] + ctx->LineZoffset) );
1383 TLVertices[1].tu = D3DVAL( VB->TexCoord[v2][0] );
1384 TLVertices[1].tv = D3DVAL( VB->TexCoord[v2][1] );
1385 TLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
1386 TLVertices[1].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
1387 (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
1388
1389 /* Draw line from (x0,y0) to (x1,y1) with current pixel color/index */
1390 DrawPrimitiveHAL( pContext->pShared, D3DPT_LINELIST, &TLVertices[0], 2 );
1391 }
1392 /*===========================================================================*/
1393 /* This function was written to convert points into triangles. I did this */
1394 /* as all card accelerate triangles and most drivers do this anyway. In hind*/
1395 /* thought this might be a bad idea as some cards do better. */
1396 /*===========================================================================*/
1397 /* RETURN: */
1398 /*===========================================================================*/
1399 static void RenderPointsVB( GLcontext *ctx, GLuint start, GLuint end )
1400 {
1401 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1402 struct vertex_buffer *VB = ctx->VB;
1403 struct pixel_buffer *PB = ctx->PB;
1404 GLuint index;
1405 GLfloat radius, z,
1406 xmin, ymin,
1407 xmax, ymax;
1408 GLint cVertex,
1409 height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
1410 DWORD dwPVColor;
1411
1412 DPF(( DBG_FUNC, "RenderPointsVB();" ));
1413
1414 radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
1415
1416 for( index = start, cVertex = 0; index <= end; index++ )
1417 {
1418 if ( VB->ClipMask[index] == 0 )
1419 {
1420 xmin = D3DVAL( VB->Win[index][0] - radius );
1421 xmax = D3DVAL( VB->Win[index][0] + radius );
1422 ymin = D3DVAL( height - VB->Win[index][1] - radius );
1423 ymax = D3DVAL( height - VB->Win[index][1] + radius );
1424 z = D3DVAL( (VB->Win[index][2] + ctx->PointZoffset) );
1425
1426 dwPVColor = (VB->Color[index][3]<<24) |
1427 (VB->Color[index][0]<<16) |
1428 (VB->Color[index][1]<<8) |
1429 VB->Color[index][2];
1430
1431 D3DTLVertices[cVertex].sx = xmin;
1432 D3DTLVertices[cVertex].sy = ymax;
1433 D3DTLVertices[cVertex].sz = z;
1434 D3DTLVertices[cVertex].tu = 0.0;
1435 D3DTLVertices[cVertex].tv = 0.0;
1436 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
1437 D3DTLVertices[cVertex++].color = dwPVColor;
1438
1439 D3DTLVertices[cVertex].sx = xmin;
1440 D3DTLVertices[cVertex].sy = ymin;
1441 D3DTLVertices[cVertex].sz = z;
1442 D3DTLVertices[cVertex].tu = 0.0;
1443 D3DTLVertices[cVertex].tv = 0.0;
1444 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
1445 D3DTLVertices[cVertex++].color = dwPVColor;
1446
1447 D3DTLVertices[cVertex].sx = xmax;
1448 D3DTLVertices[cVertex].sy = ymin;
1449 D3DTLVertices[cVertex].sz = z;
1450 D3DTLVertices[cVertex].tu = 0.0;
1451 D3DTLVertices[cVertex].tv = 0.0;
1452 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
1453 D3DTLVertices[cVertex++].color = dwPVColor;
1454
1455 D3DTLVertices[cVertex].sx = xmax;
1456 D3DTLVertices[cVertex].sy = ymin;
1457 D3DTLVertices[cVertex].sz = z;
1458 D3DTLVertices[cVertex].tu = 0.0;
1459 D3DTLVertices[cVertex].tv = 0.0;
1460 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
1461 D3DTLVertices[cVertex++].color = dwPVColor;
1462
1463 D3DTLVertices[cVertex].sx = xmax;
1464 D3DTLVertices[cVertex].sy = ymax;
1465 D3DTLVertices[cVertex].sz = z;
1466 D3DTLVertices[cVertex].tu = 0.0;
1467 D3DTLVertices[cVertex].tv = 0.0;
1468 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
1469 D3DTLVertices[cVertex++].color = dwPVColor;
1470
1471 D3DTLVertices[cVertex].sx = xmin;
1472 D3DTLVertices[cVertex].sy = ymax;
1473 D3DTLVertices[cVertex].sz = z;
1474 D3DTLVertices[cVertex].tu = 0.0;
1475 D3DTLVertices[cVertex].tv = 0.0;
1476 D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
1477 D3DTLVertices[cVertex++].color = dwPVColor;
1478 }
1479 }
1480
1481 /* Render the converted vertex buffer. */
1482 if ( cVertex )
1483 DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
1484 }
1485 /*===========================================================================*/
1486 /* This gets call before we render any primitives so that the current OGL */
1487 /* states will be mapped the D3D context. I'm still not sure how D3D works */
1488 /* but I'm finding that it doesn't act like a state machine as OGL is. It */
1489 /* looks like the state gets set back to the defaults after a DrawPrimitives */
1490 /* or an EndScene. Also I set states that are the default even though this */
1491 /* is redundant as the defaults seem screwed up. */
1492 /* TODO: make a batch call. */
1493 /*===========================================================================*/
1494 /* RETURN: */
1495 /*===========================================================================*/
1496 static void SetRenderStates( GLcontext *ctx )
1497 {
1498 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1499 DWORD dwFunc;
1500 static BOOL bTexture = FALSE;
1501 static int texName = -1;
1502
1503 DPF(( DBG_FUNC, "SetRenderStates();" ));
1504
1505 if ( g_DBGMask & DBG_STATES )
1506 DebugRenderStates( ctx, FALSE );
1507
1508 SetStateHAL( pContext->pShared, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
1509 SetStateHAL( pContext->pShared, D3DRENDERSTATE_DITHERENABLE, (ctx->Color.DitherFlag) ? TRUE : FALSE );
1510
1511 /*================================================*/
1512 /* Check too see if there are new TEXTURE states. */
1513 /*================================================*/
1514 if ( ctx->Texture._EnabledUnits )
1515 {
1516 switch( ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode )
1517 {
1518 case GL_MODULATE:
1519 if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Format == GL_RGBA )
1520 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_modulatealpha];
1521 else
1522 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_modulate];
1523 break;
1524
1525 case GL_BLEND:
1526 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decalalpha];
1527 break;
1528
1529 case GL_REPLACE:
1530 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decal];
1531 break;
1532
1533 case GL_DECAL:
1534 if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Format == GL_RGBA )
1535 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decalalpha];
1536 else
1537 dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decal];
1538 break;
1539 }
1540 SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMAPBLEND, dwFunc );
1541
1542 switch( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter )
1543 {
1544 case GL_NEAREST:
1545 dwFunc = D3DFILTER_NEAREST;
1546 break;
1547 case GL_LINEAR:
1548 dwFunc = D3DFILTER_LINEAR;
1549 break;
1550 case GL_NEAREST_MIPMAP_NEAREST:
1551 dwFunc = D3DFILTER_MIPNEAREST;
1552 break;
1553 case GL_LINEAR_MIPMAP_NEAREST:
1554 dwFunc = D3DFILTER_LINEARMIPNEAREST;
1555 break;
1556 case GL_NEAREST_MIPMAP_LINEAR:
1557 dwFunc = D3DFILTER_MIPLINEAR;
1558 break;
1559 case GL_LINEAR_MIPMAP_LINEAR:
1560 dwFunc = D3DFILTER_LINEARMIPLINEAR;
1561 break;
1562 }
1563 SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMAG, dwFunc );
1564
1565 switch( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter )
1566 {
1567 case GL_NEAREST:
1568 dwFunc = D3DFILTER_NEAREST;
1569 break;
1570 case GL_LINEAR:
1571 dwFunc = D3DFILTER_LINEAR;
1572 break;
1573 case GL_NEAREST_MIPMAP_NEAREST:
1574 dwFunc = D3DFILTER_MIPNEAREST;
1575 break;
1576 case GL_LINEAR_MIPMAP_NEAREST:
1577 dwFunc = D3DFILTER_LINEARMIPNEAREST;
1578 break;
1579 case GL_NEAREST_MIPMAP_LINEAR:
1580 dwFunc = D3DFILTER_MIPLINEAR;
1581 break;
1582 case GL_LINEAR_MIPMAP_LINEAR:
1583 dwFunc = D3DFILTER_LINEARMIPLINEAR;
1584 break;
1585 }
1586 SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMIN, dwFunc );
1587
1588 /* Another hack to cut down on redundant texture binding. */
1589 // if ( texName != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name )
1590 // {
1591 texName = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name;
1592 CreateTMgrHAL( pContext->pShared,
1593 texName,
1594 0,
1595 ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Format,
1596 (RECT *)NULL,
1597 ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Width,
1598 ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Height,
1599 TM_ACTION_BIND,
1600 (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Data );
1601 // }
1602 bTexture = TRUE;
1603 }
1604 else
1605 {
1606 /* This is nasty but should cut down on the number of redundant calls. */
1607 if ( bTexture == TRUE )
1608 {
1609 DisableTMgrHAL( pContext->pShared );
1610 bTexture = FALSE;
1611 }
1612 }
1613
1614 /*===============================================*/
1615 /* Check too see if there are new RASTER states. */
1616 /*===============================================*/
1617
1618 // TODO: no concept of front & back.
1619 switch( ctx->Polygon.FrontMode )
1620 {
1621 case GL_POINT:
1622 SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_POINT );
1623 break;
1624 case GL_LINE:
1625 SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME );
1626 break;
1627 case GL_FILL:
1628 SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID );
1629 break;
1630 }
1631
1632 /*************/
1633 /* Z-Buffer. */
1634 /*************/
1635 if ( ctx->Depth.Test == GL_TRUE )
1636 {
1637 switch( ctx->Depth.Func )
1638 {
1639 case GL_NEVER:
1640 dwFunc = D3DCMP_NEVER;
1641 break;
1642 case GL_LESS:
1643 dwFunc = D3DCMP_LESS;
1644 break;
1645 case GL_GEQUAL:
1646 dwFunc = D3DCMP_GREATEREQUAL;
1647 break;
1648 case GL_LEQUAL:
1649 dwFunc = D3DCMP_LESSEQUAL;
1650 break;
1651 case GL_GREATER:
1652 dwFunc = D3DCMP_GREATER;
1653 break;
1654 case GL_NOTEQUAL:
1655 dwFunc = D3DCMP_NOTEQUAL;
1656 break;
1657 case GL_EQUAL:
1658 dwFunc = D3DCMP_EQUAL;
1659 break;
1660 case GL_ALWAYS:
1661 dwFunc = D3DCMP_ALWAYS;
1662 break;
1663 }
1664 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZFUNC, dwFunc );
1665 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZENABLE, TRUE );
1666 }
1667 else
1668 {
1669 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZENABLE, FALSE );
1670 }
1671
1672 /*******************/
1673 /* Z-Write Enable. */
1674 /*******************/
1675 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZWRITEENABLE , (ctx->Depth.Mask == GL_TRUE) ? TRUE : FALSE );
1676
1677 /***************/
1678 /* Alpha test. */
1679 /***************/
1680 if ( ctx->Color.AlphaEnabled == GL_TRUE )
1681 {
1682 switch( ctx->Color.AlphaFunc )
1683 {
1684 case GL_NEVER:
1685 dwFunc = D3DCMP_NEVER;
1686 break;
1687 case GL_LESS:
1688 dwFunc = D3DCMP_LESS;
1689 break;
1690 case GL_GEQUAL:
1691 dwFunc = D3DCMP_GREATEREQUAL;
1692 break;
1693 case GL_LEQUAL:
1694 dwFunc = D3DCMP_LESSEQUAL;
1695 break;
1696 case GL_GREATER:
1697 dwFunc = D3DCMP_GREATER;
1698 break;
1699 case GL_NOTEQUAL:
1700 dwFunc = D3DCMP_NOTEQUAL;
1701 break;
1702 case GL_EQUAL:
1703 dwFunc = D3DCMP_EQUAL;
1704 break;
1705 case GL_ALWAYS:
1706 dwFunc = D3DCMP_ALWAYS;
1707 break;
1708 }
1709 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHAFUNC , dwFunc );
1710 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
1711 }
1712 else
1713 {
1714 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
1715 }
1716
1717 /****************/
1718 /* Alpha blend. */
1719 /****************/
1720 if ( ctx->Color.BlendEnabled == GL_TRUE )
1721 {
1722 switch( ctx->Color.BlendSrc )
1723 {
1724 case GL_ZERO:
1725 dwFunc = pContext->pShared->dwSrcBlendCaps[s_zero];
1726 break;
1727 case GL_ONE:
1728 dwFunc = pContext->pShared->dwSrcBlendCaps[s_one];
1729 break;
1730 case GL_DST_COLOR:
1731 dwFunc = pContext->pShared->dwSrcBlendCaps[s_dst_color];
1732 break;
1733 case GL_ONE_MINUS_DST_COLOR:
1734 dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_dst_color];
1735 break;
1736 case GL_SRC_ALPHA:
1737 dwFunc = pContext->pShared->dwSrcBlendCaps[s_src_alpha];
1738 break;
1739 case GL_ONE_MINUS_SRC_ALPHA:
1740 dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_src_alpha];
1741 break;
1742 case GL_DST_ALPHA:
1743 dwFunc = pContext->pShared->dwSrcBlendCaps[s_dst_alpha];
1744 break;
1745 case GL_ONE_MINUS_DST_ALPHA:
1746 dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_dst_alpha];
1747 break;
1748 case GL_SRC_ALPHA_SATURATE:
1749 dwFunc = pContext->pShared->dwSrcBlendCaps[s_src_alpha_saturate];
1750 break;
1751 case GL_CONSTANT_COLOR:
1752 dwFunc = pContext->pShared->dwSrcBlendCaps[s_constant_color];
1753 break;
1754 case GL_ONE_MINUS_CONSTANT_COLOR:
1755 dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_constant_color];
1756 break;
1757 case GL_CONSTANT_ALPHA:
1758 dwFunc = pContext->pShared->dwSrcBlendCaps[s_constant_alpha];
1759 break;
1760 case GL_ONE_MINUS_CONSTANT_ALPHA:
1761 dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_constant_alpha];
1762 break;
1763 }
1764 SetStateHAL( pContext->pShared, D3DRENDERSTATE_SRCBLEND, dwFunc );
1765
1766 switch( ctx->Color.BlendDst )
1767 {
1768 case GL_ZERO:
1769 dwFunc = pContext->pShared->dwDestBlendCaps[d_zero];
1770 break;
1771 case GL_ONE:
1772 dwFunc = pContext->pShared->dwDestBlendCaps[d_one];
1773 break;
1774 case GL_SRC_COLOR:
1775 dwFunc = pContext->pShared->dwDestBlendCaps[d_src_color];
1776 break;
1777 case GL_ONE_MINUS_SRC_COLOR:
1778 dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_src_color];
1779 break;
1780 case GL_SRC_ALPHA:
1781 dwFunc = pContext->pShared->dwDestBlendCaps[d_src_alpha];
1782 break;
1783 case GL_ONE_MINUS_SRC_ALPHA:
1784 dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_src_alpha];
1785 break;
1786 case GL_DST_ALPHA:
1787 dwFunc = pContext->pShared->dwDestBlendCaps[d_dst_alpha];
1788 break;
1789 case GL_ONE_MINUS_DST_ALPHA:
1790 dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_dst_alpha];
1791 break;
1792 case GL_CONSTANT_COLOR:
1793 dwFunc = pContext->pShared->dwDestBlendCaps[d_constant_color];
1794 break;
1795 case GL_ONE_MINUS_CONSTANT_COLOR:
1796 dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_constant_color];
1797 break;
1798 case GL_CONSTANT_ALPHA:
1799 dwFunc = pContext->pShared->dwDestBlendCaps[d_constant_alpha];
1800 break;
1801 case GL_ONE_MINUS_CONSTANT_ALPHA:
1802 dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_constant_alpha];
1803 break;
1804 }
1805 SetStateHAL( pContext->pShared, D3DRENDERSTATE_DESTBLEND, dwFunc );
1806 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
1807 }
1808 else
1809 {
1810 SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
1811 }
1812 }
1813 /*===========================================================================*/
1814 /* If this function is called it will track the changes to the current */
1815 /* states that I'm setting in Direct3D. I did this so that the DPF's would */
1816 /* be under control! */
1817 /*===========================================================================*/
1818 /* RETURN: */
1819 /*===========================================================================*/
1820 static void DebugRenderStates( GLcontext *ctx, BOOL bForce )
1821 {
1822 D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
1823 DWORD dwFunc;
1824 static int dither = -1,
1825 texture = -1,
1826 textName = -1,
1827 textEnv = -1,
1828 textMin = -1,
1829 textMag = -1,
1830 polyMode = -1,
1831 depthTest = -1,
1832 depthFunc = -1,
1833 depthMask = -1,
1834 alphaTest = -1,
1835 alphaFunc = -1,
1836 blend = -1,
1837 blendSrc = -1,
1838 blendDest = -1;
1839
1840 /* Force a displayed update of all current states. */
1841 if ( bForce )
1842 {
1843 dither = texture = textName = textEnv = textMin = textMag = -1;
1844 polyMode = depthTest = depthFunc = depthMask = -1;
1845 alphaTest = alphaFunc = blend = blendSrc = blendDest = -1;
1846 }
1847
1848 if ( dither != ctx->Color.DitherFlag )
1849 {
1850 dither = ctx->Color.DitherFlag;
1851 DPF(( 0, "\tDither\t\t%s", (dither) ? "ENABLED" : "--------" ));
1852 }
1853 if ( depthTest != ctx->Depth.Test )
1854 {
1855 depthTest = ctx->Depth.Test;
1856 DPF(( 0, "\tDepth Test\t%s", (depthTest) ? "ENABLED" : "--------" ));
1857 }
1858 if ( alphaTest != ctx->Color.AlphaEnabled )
1859 {
1860 alphaTest = ctx->Color.AlphaEnabled;
1861
1862 DPF(( 0, "\tAlpha Test\t%s", (alphaTest) ? "ENABLED" : "--------" ));
1863 }
1864 if ( blend != ctx->Color.BlendEnabled )
1865 {
1866 blend = ctx->Color.BlendEnabled;
1867
1868 DPF(( 0, "\tBlending\t%s", (blend) ? "ENABLED" : "--------" ));
1869 }
1870
1871 /*================================================*/
1872 /* Check too see if there are new TEXTURE states. */
1873 /*================================================*/
1874 if ( texture != ctx->Texture._EnabledUnits )
1875 {
1876 texture = ctx->Texture._EnabledUnits;
1877 DPF(( 0, "\tTexture\t\t%s", (texture) ? "ENABLED" : "--------" ));
1878 }
1879
1880 if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current )
1881 {
1882 if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name != textName )
1883 {
1884 textName = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name;
1885 DPF(( 0, "\tTexture Name:\t%d", textName ));
1886 DPF(( 0, "\tTexture Format:\t%s",
1887 (ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0][0]->Format == GL_RGBA) ?
1888 "GL_RGBA" : "GLRGB" ));
1889 }
1890
1891 if ( textEnv != ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode )
1892 {
1893 textEnv = ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode;
1894
1895 switch( textEnv )
1896 {
1897 case GL_MODULATE:
1898 DPF(( 0, "\tTexture\tMode\tGL_MODULATE" ));
1899 break;
1900 case GL_BLEND:
1901 DPF(( 0, "\tTexture\tMode\tGL_BLEND" ));
1902 break;
1903 case GL_REPLACE:
1904 DPF(( 0, "\tTexture\tMode\tGL_REPLACE" ));
1905 break;
1906 case GL_DECAL:
1907 DPF(( 0, "\tTexture\tMode\tGL_DECAL" ));
1908 break;
1909 }
1910 }
1911
1912 if ( textMag != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter )
1913 {
1914 textMag = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter;
1915
1916 switch( textMag )
1917 {
1918 case GL_NEAREST:
1919 DPF(( 0, "\tTexture MAG\tGL_NEAREST" ));
1920 break;
1921 case GL_LINEAR:
1922 DPF(( 0, "\tTexture MAG\tGL_LINEAR" ));
1923 break;
1924 case GL_NEAREST_MIPMAP_NEAREST:
1925 DPF(( 0, "\tTexture MAG\tGL_NEAREST_MIPMAP_NEAREST" ));
1926 break;
1927 case GL_LINEAR_MIPMAP_NEAREST:
1928 DPF(( 0, "\tTexture MAG\tGL_LINEAR_MIPMAP_NEAREST" ));
1929 break;
1930 case GL_NEAREST_MIPMAP_LINEAR:
1931 DPF(( 0, "\tTexture MAG\tGL_NEAREST_MIPMAP_LINEAR" ));
1932 break;
1933 case GL_LINEAR_MIPMAP_LINEAR:
1934 DPF(( 0, "\tTexture MAG\tGL_LINEAR_MIPMAP_LINEAR" ));
1935 break;
1936 }
1937 }
1938
1939 if ( textMin != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter )
1940 {
1941 textMin = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter;
1942
1943 switch( textMin )
1944 {
1945 case GL_NEAREST:
1946 DPF(( 0, "\tTexture MIN\tGL_NEAREST" ));
1947 break;
1948 case GL_LINEAR:
1949 DPF(( 0, "\tTexture MIN\tGL_LINEAR" ));
1950 break;
1951 case GL_NEAREST_MIPMAP_NEAREST:
1952 DPF(( 0, "\tTexture MIN\tGL_NEAREST_MIPMAP_NEAREST" ));
1953 break;
1954 case GL_LINEAR_MIPMAP_NEAREST:
1955 DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_NEAREST" ));
1956 break;
1957 case GL_NEAREST_MIPMAP_LINEAR:
1958 DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_LINEAR" ));
1959 break;
1960 case GL_LINEAR_MIPMAP_LINEAR:
1961 DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_LINEAR" ));
1962 break;
1963 }
1964 }
1965 }
1966
1967 if ( ctx->Polygon.FrontMode != polyMode )
1968 {
1969 polyMode = ctx->Polygon.FrontMode;
1970
1971 switch( polyMode )
1972 {
1973 case GL_POINT:
1974 DPF(( 0, "\tMode\t\tGL_POINT" ));
1975 break;
1976 case GL_LINE:
1977 DPF(( 0, "\tMode\t\tGL_LINE" ));
1978 break;
1979 case GL_FILL:
1980 DPF(( 0, "\tMode\t\tGL_FILL" ));
1981 break;
1982 }
1983 }
1984
1985 if ( depthFunc != ctx->Depth.Func )
1986 {
1987 depthFunc = ctx->Depth.Func;
1988
1989 switch( depthFunc )
1990 {
1991 case GL_NEVER:
1992 DPF(( 0, "\tDepth Func\tGL_NEVER" ));
1993 break;
1994 case GL_LESS:
1995 DPF(( 0, "\tDepth Func\tGL_LESS" ));
1996 break;
1997 case GL_GEQUAL:
1998 DPF(( 0, "\tDepth Func\tGL_GEQUAL" ));
1999 break;
2000 case GL_LEQUAL:
2001 DPF(( 0, "\tDepth Func\tGL_LEQUAL" ));
2002 break;
2003 case GL_GREATER:
2004 DPF(( 0, "\tDepth Func\tGL_GREATER" ));
2005 break;
2006 case GL_NOTEQUAL:
2007 DPF(( 0, "\tDepth Func\tGL_NOTEQUAL" ));
2008 break;
2009 case GL_EQUAL:
2010 DPF(( 0, "\tDepth Func\tGL_EQUAL" ));
2011 break;
2012 case GL_ALWAYS:
2013 DPF(( 0, "\tDepth Func\tGL_ALWAYS" ));
2014 break;
2015 }
2016 }
2017
2018 if ( depthMask != ctx->Depth.Mask )
2019 {
2020 depthMask = ctx->Depth.Mask;
2021 DPF(( 0, "\tZWrite\t\t%s", (depthMask) ? "ENABLED" : "--------" ));
2022 }
2023
2024 if ( alphaFunc != ctx->Color.AlphaFunc )
2025 {
2026 alphaFunc = ctx->Color.AlphaFunc;
2027
2028 switch( alphaFunc )
2029 {
2030 case GL_NEVER:
2031 DPF(( 0, "\tAlpha Func\tGL_NEVER" ));
2032 break;
2033 case GL_LESS:
2034 DPF(( 0, "\tAlpha Func\tGL_LESS" ));
2035 break;
2036 case GL_GEQUAL:
2037 DPF(( 0, "\tAlpha Func\tGL_GEQUAL" ));
2038 break;
2039 case GL_LEQUAL:
2040 DPF(( 0, "\tAlpha Func\tGL_LEQUAL" ));
2041 break;
2042 case GL_GREATER:
2043 DPF(( 0, "\tAlpha Func\tGL_GREATER" ));
2044 break;
2045 case GL_NOTEQUAL:
2046 DPF(( 0, "\tAlpha Func\tGL_NOTEQUAL" ));
2047 break;
2048 case GL_EQUAL:
2049 DPF(( 0, "\tAlpha Func\tGL_EQUAL" ));
2050 break;
2051 case GL_ALWAYS:
2052 DPF(( 0, "\tAlpha Func\tGL_ALWAYS" ));
2053 break;
2054 }
2055 }
2056
2057 if ( blendSrc != ctx->Color.BlendSrc )
2058 {
2059 blendSrc = ctx->Color.BlendSrc;
2060
2061 switch( blendSrc )
2062 {
2063 case GL_ZERO:
2064 DPF(( 0, "\tSRC Blend\tGL_ZERO" ));
2065 break;
2066 case GL_ONE:
2067 DPF(( 0, "\tSRC Blend\tGL_ONE" ));
2068 break;
2069 case GL_DST_COLOR:
2070 DPF(( 0, "\tSRC Blend\tGL_DST_COLOR" ));
2071 break;
2072 case GL_ONE_MINUS_DST_COLOR:
2073 DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_DST_COLOR" ));
2074 break;
2075 case GL_SRC_ALPHA:
2076 DPF(( 0, "\tSRC Blend\tGL_SRC_ALPHA" ));
2077 break;
2078 case GL_ONE_MINUS_SRC_ALPHA:
2079 DPF(( 0, "\tSRC Blend\tGL_MINUS_SRC_ALPHA" ));
2080 break;
2081 case GL_DST_ALPHA:
2082 DPF(( 0, "\tSRC Blend\tGL_DST_ALPHA" ));
2083 break;
2084 case GL_ONE_MINUS_DST_ALPHA:
2085 DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_DST_ALPHA" ));
2086 break;
2087 case GL_SRC_ALPHA_SATURATE:
2088 DPF(( 0, "\tSRC Blend\tGL_SRC_ALPHA_SATURATE" ));
2089 break;
2090 case GL_CONSTANT_COLOR:
2091 DPF(( 0, "\tSRC Blend\tGL_CONSTANT_COLOR" ));
2092 break;
2093 case GL_ONE_MINUS_CONSTANT_COLOR:
2094 DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_CONSTANT_COLOR" ));
2095 break;
2096 case GL_CONSTANT_ALPHA:
2097 DPF(( 0, "\tSRC Blend\tGL_CONSTANT_ALPHA" ));
2098 break;
2099 case GL_ONE_MINUS_CONSTANT_ALPHA:
2100 DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_CONSTANT_ALPHA" ));
2101 break;
2102 }
2103 }
2104
2105 if ( blendDest != ctx->Color.BlendDst )
2106 {
2107 blendDest = ctx->Color.BlendDst;
2108
2109 switch( blendDest )
2110 {
2111 case GL_ZERO:
2112 DPF(( 0, "\tDST Blend\tGL_ZERO" ));
2113 break;
2114 case GL_ONE:
2115 DPF(( 0, "\tDST Blend\tGL_ONE" ));
2116 break;
2117 case GL_SRC_COLOR:
2118 DPF(( 0, "\tDST Blend\tGL_SRC_COLOR" ));
2119 break;
2120 case GL_ONE_MINUS_SRC_COLOR:
2121 DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_SRC_COLOR" ));
2122 break;
2123 case GL_SRC_ALPHA:
2124 DPF(( 0, "\tDST Blend\tGL_SRC_ALPHA" ));
2125 break;
2126 case GL_ONE_MINUS_SRC_ALPHA:
2127 DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_SRC_ALPHA" ));
2128 break;
2129 case GL_DST_ALPHA:
2130 DPF(( 0, "\tDST Blend\tGL_DST_ALPHA" ));
2131 break;
2132 case GL_ONE_MINUS_DST_ALPHA:
2133 DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_DST_ALPHA" ));
2134 break;
2135 case GL_CONSTANT_COLOR:
2136 DPF(( 0, "\tDST Blend\tGL_CONSTANT_COLOR" ));
2137 break;
2138 case GL_ONE_MINUS_CONSTANT_COLOR:
2139 DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_CONSTANT_COLOR" ));
2140 break;
2141 case GL_CONSTANT_ALPHA:
2142 DPF(( 0, "\tDST Blend\tGL_CONSTANT_ALPHA" ));
2143 break;
2144 case GL_ONE_MINUS_CONSTANT_ALPHA:
2145 DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_CONSTANT_ALPHA" ));
2146 break;
2147 }
2148 }
2149 }