summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/d3d/D3Dvbrender.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/d3d/D3Dvbrender.c')
-rw-r--r--src/mesa/drivers/d3d/D3Dvbrender.c2150
1 files changed, 2150 insertions, 0 deletions
diff --git a/src/mesa/drivers/d3d/D3Dvbrender.c b/src/mesa/drivers/d3d/D3Dvbrender.c
new file mode 100644
index 0000000000..57c1306d60
--- /dev/null
+++ b/src/mesa/drivers/d3d/D3Dvbrender.c
@@ -0,0 +1,2150 @@
+/*===========================================================================*/
+/* */
+/* Mesa-3.0 DirectX 6 Driver */
+/* */
+/* By Leigh McRae */
+/* */
+/* http://www.altsoftware.com/ */
+/* */
+/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */
+/*===========================================================================*/
+#include <stdio.h>
+#include "clip.h"
+#include "context.h"
+#include "light.h"
+#include "lines.h"
+#include "macros.h"
+#include "matrix.h"
+#include "pb.h"
+#include "points.h"
+#include "types.h"
+#include "vb.h"
+#include "vbrender.h"
+#include "xform.h"
+#include "D3DMesa.h"
+
+static void SetRenderStates( GLcontext *ctx );
+static void DebugRenderStates( GLcontext *ctx, BOOL bForce );
+
+static void RenderPointsVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderTriangleVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderTriangleFanVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderTriangleStripVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderQuadVB( GLcontext *ctx, GLuint start, GLuint end );
+static void RenderQuad( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv );
+void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv );
+void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv );
+
+/* I went with a D3D vertex buffer that is 6 times that of the Mesa one */
+/* instead of having the D3D one flush when its full. This way Mesa will*/
+/* handle all the flushing. I need x6 as points can use 4 vertex each. */
+D3DTLVERTEX D3DTLVertices[ (VB_MAX*6) ];
+GLuint VList[VB_SIZE];
+/*===========================================================================*/
+/* Compute Z offsets for a polygon with plane defined by (A,B,C,D) */
+/* D is not needed. TODO: Currently we are calculating this but not using it.*/
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void OffsetPolygon( GLcontext *ctx, GLfloat a, GLfloat b, GLfloat c )
+{
+ GLfloat ac,
+ bc,
+ m,
+ offset;
+
+ DPF(( DBG_FUNC, "OffsetPolygon();" ));
+
+ if ( (c < 0.001F) && (c > - 0.001F) )
+ {
+ /* Prevents underflow problems. */
+ ctx->PointZoffset = 0.0F;
+ ctx->LineZoffset = 0.0F;
+ ctx->PolygonZoffset = 0.0F;
+ }
+ else
+ {
+ ac = a / c;
+ bc = b / c;
+ if ( ac < 0.0F )
+ ac = -ac;
+ if ( bc<0.0F )
+ bc = -bc;
+ m = MAX2( ac, bc ); /* m = sqrt( ac*ac + bc*bc ); */
+
+ offset = (m * ctx->Polygon.OffsetFactor + ctx->Polygon.OffsetUnits);
+ ctx->PointZoffset = ctx->Polygon.OffsetPoint ? offset : 0.0F;
+ ctx->LineZoffset = ctx->Polygon.OffsetLine ? offset : 0.0F;
+ ctx->PolygonZoffset = ctx->Polygon.OffsetFill ? offset : 0.0F;
+ }
+
+ DPF(( DBG_PRIM_INFO, "OffsetPolygon: %f", offset ));
+}
+/*===========================================================================*/
+/* Compute signed area of the n-sided polgyon specified by vertices */
+/* vb->Win[] and vertex list vlist[]. */
+/* A clockwise polygon will return a negative area. A counter-clockwise */
+/* polygon will return a positive area. I have changed this function to */
+/* actually calculate twice the area as its faster and still gives the sign. */
+/*===========================================================================*/
+/* RETURN: signed area of the polgon. */
+/*===========================================================================*/
+static GLfloat PolygonArea( const struct vertex_buffer *vb, GLuint n, const GLuint vlist[] )
+{
+ GLfloat area;
+ GLuint i;
+
+ DPF(( DBG_FUNC, "PolygonArea();" ));
+
+#define j0 vlist[i]
+#define j1 vlist[(i+1)%n]
+#define x0 vb->Win[j0][0]
+#define y0 vb->Win[j0][1]
+#define x1 vb->Win[j1][0]
+#define y1 vb->Win[j1][1]
+
+ /* area = sum of trapezoids */
+ for( i = 0, area = 0.0; i < n; i++ )
+ area += ((x0 - x1) * (y0 + y1)); /* Note: no divide by two here! */
+
+#undef x0
+#undef y0
+#undef x1
+#undef y1
+#undef j1
+#undef j0
+
+ // TODO: I don't see the point or * 0.5 as we just want the sign...
+ return area;
+}
+/*===========================================================================*/
+/* Render a polygon that needs clipping on at least one vertex. The function*/
+/* will first clip the polygon to any user clipping planes then clip to the */
+/* viewing volume. The final polygon will be draw as single triangles that */
+/* first need minor proccessing (culling, offset, etc) before we draw the */
+/* polygon as a fan. NOTE: the fan is draw as single triangles as its not */
+/* formed sequentaly in the VB but is in the vlist[]. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void RenderClippedPolygon( GLcontext *ctx, GLuint n, GLuint vlist[] )
+{
+ struct vertex_buffer *VB = ctx->VB;
+ GLfloat (*win)[3] = VB->Win,
+ *proj = ctx->ProjectionMatrix,
+ ex, ey,
+ fx, fy, c,
+ wInv;
+ GLuint index,
+ pv,
+ facing;
+
+ DPF(( DBG_FUNC, "RenderClippedPolygon();" ));
+
+ DPF(( DBG_PRIM_INFO, "RenderClippedtPolygon( %d )", n ));
+
+ /* Which vertex dictates the color when flat shading. */
+ pv = (ctx->Primitive==GL_POLYGON) ? vlist[0] : vlist[n-1];
+
+ /* Clipping may introduce new vertices. New vertices will be stored in */
+ /* the vertex buffer arrays starting with location VB->Free. After we've*/
+ /* rendered the polygon, these extra vertices can be overwritten. */
+ VB->Free = VB_MAX;
+
+ /* Clip against user clipping planes in eye coord space. */
+ if ( ctx->Transform.AnyClip )
+ {
+ n = gl_userclip_polygon( ctx, n, vlist );
+ if ( n < 3 )
+ return;
+
+ /* Transform vertices from eye to clip coordinates: clip = Proj * eye */
+ for( index = 0; index < n; index++ )
+ {
+ TRANSFORM_POINT( VB->Clip[vlist[index]], proj, VB->Eye[vlist[index]] );
+ }
+ }
+
+ /* Clip against view volume in clip coord space */
+ n = gl_viewclip_polygon( ctx, n, vlist );
+ if ( n < 3 )
+ return;
+
+ /* Transform new vertices from clip to ndc to window coords. */
+ /* ndc = clip / W window = viewport_mapping(ndc) */
+ /* Note that window Z values are scaled to the range of integer */
+ /* depth buffer values. */
+
+ /* Only need to compute window coords for new vertices */
+ for( index = VB_MAX; index < VB->Free; index++ )
+ {
+ if ( VB->Clip[index][3] != 0.0F )
+ {
+ wInv = 1.0F / VB->Clip[index][3];
+
+ win[index][0] = VB->Clip[index][0] * wInv * ctx->Viewport.Sx + ctx->Viewport.Tx;
+ win[index][1] = VB->Clip[index][1] * wInv * ctx->Viewport.Sy + ctx->Viewport.Ty;
+ win[index][2] = VB->Clip[index][2] * wInv * ctx->Viewport.Sz + ctx->Viewport.Tz;
+ }
+ else
+ {
+ /* Can't divide by zero, so... */
+ win[index][0] = win[index][1] = win[index][2] = 0.0F;
+ }
+ }
+
+ /* Draw filled polygon as a triangle fan */
+ for( index = 2; index < n; index++ )
+ {
+ /* Compute orientation of triangle */
+ ex = win[vlist[index-1]][0] - win[vlist[0]][0];
+ ey = win[vlist[index-1]][1] - win[vlist[0]][1];
+ fx = win[vlist[index]][0] - win[vlist[0]][0];
+ fy = win[vlist[index]][1] - win[vlist[0]][1];
+ c = (ex * fy) - (ey * fx);
+
+ /* polygon is perpindicular to view plane, don't draw it */
+ if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+ continue;
+
+ /* Backface culling. */
+ facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+ if ( (facing + 1) & ctx->Polygon.CullBits )
+ continue;
+
+ if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
+ {
+ if ( facing == 1 )
+ {
+ /* use back color */
+ VB->Color = VB->Bcolor;
+ VB->Specular= VB->Bspec;
+ }
+ else
+ {
+ /* use front color */
+ VB->Color = VB->Fcolor;
+ VB->Specular= VB->Fspec;
+ }
+ }
+
+ if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
+ {
+ /* finish computing plane equation of polygon, compute offset */
+ GLfloat fz = win[vlist[index]][2] - win[vlist[0]][2];
+ GLfloat ez = win[vlist[index-1]][2] - win[vlist[0]][2];
+ GLfloat a = (ey * fz) - (ez * fy);
+ GLfloat b = (ez * fx) - (ex * fz);
+ OffsetPolygon( ctx, a, b, c );
+ }
+ RenderOneTriangle( ctx, vlist[0], vlist[index-1], vlist[index], pv );
+ }
+}
+/*===========================================================================*/
+/* This function gets called when either the vertex buffer is full or glEnd */
+/* has been called. If the we aren't in rendering mode (FEEDBACK) then I */
+/* pass the vertex buffer back to Mesa to deal with by returning FALSE. */
+/* If I can render the primitive types in the buffer directly then I will */
+/* return TRUE after I render the vertex buffer and reset the vertex buffer. */
+/* */
+/* TODO: I don't handle the special case of when the vertex buffer is full */
+/* and we have a primitive that bounds this buffer and the next one to */
+/* come. I'm not sure right now if Mesa handles this for me... */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+GLboolean RenderVertexBuffer( GLcontext *ctx, GLboolean allDone )
+{
+ struct vertex_buffer *VB = ctx->VB;
+ GLuint index,
+ vlist[VB_SIZE];
+
+ DPF(( DBG_FUNC, "RenderVertexBuffer();" ));
+
+ /* We only need to hook actual tri's that need rendering. */
+ if ( ctx->RenderMode != GL_RENDER )
+ {
+ // (ctx->Visual->AccumBits > 0) )
+ // (ctx->Visual->StencilBits > 0) )
+ DPF(( DBG_PRIM_INFO, "Passing VB back to Mesa" ));
+ return FALSE;
+ }
+
+ /* I'm going to set the states here so that all functions will */
+ /* be assured to have the right states. If Mesa's vertex bufefr */
+ /* function calls one of my primitive functions (TRI,POINT,LINE) */
+ /* it will need the right states. So instead of doing it in the */
+ /* primitive function I will always do it here at risk of some */
+ /* slow down to some cases... */
+ SetRenderStates( ctx );
+
+ switch( ctx->Primitive )
+ {
+ case GL_POINTS:
+ DPF(( DBG_PRIM_INFO, "GL_POINTS( %d )", VB->Count ));
+ RenderPointsVB( ctx, 0, VB->Count );
+ break;
+
+ case GL_LINES:
+ case GL_LINE_STRIP:
+ case GL_LINE_LOOP:
+ /* Not supported functions yet so pass back that we failed to */
+ /* render the vertex buffer and Mesa will have to do it. */
+ DPF(( DBG_PRIM_INFO, "GL_LINE_?( %d )", VB->Count ));
+ return FALSE;
+
+ case GL_TRIANGLES:
+ if ( VB->Count < 3 )
+ {
+ DPF(( DBG_PRIM_WARN, "GL_TRIANGLES( %d )", VB->Count ));
+ return FALSE;
+ }
+
+ DPF(( DBG_PRIM_INFO, "GL_TRIANGLES( %d )", VB->Count ));
+ RenderTriangleVB( ctx, 0, VB->Count );
+ break;
+
+ case GL_TRIANGLE_STRIP:
+ if ( VB->Count < 3 )
+ {
+ DPF(( DBG_PRIM_WARN, "GL_TRIANGLE_STRIP( %d )", VB->Count ));
+ return FALSE;
+ }
+
+ DPF(( DBG_PRIM_INFO, "GL_TRIANGLE_STRIP( %d )", VB->Count ));
+ RenderTriangleStripVB( ctx, 0, VB->Count );
+ break;
+
+ case GL_TRIANGLE_FAN:
+ if ( VB->Count < 3 )
+ {
+ DPF(( DBG_PRIM_WARN, "GL_TRIANGLE_FAN( %d )", VB->Count ));
+ return FALSE;
+ }
+
+ DPF(( DBG_PRIM_INFO, "GL_TRIANGLE_FAN( %d )", VB->Count ));
+ RenderTriangleFanVB( ctx, 0, VB->Count );
+ break;
+
+ case GL_QUADS:
+ if ( VB->Count < 4 )
+ {
+ DPF(( DBG_PRIM_WARN, "GL_QUADS( %d )", VB->Count ));
+ return FALSE;
+ }
+
+ DPF(( DBG_PRIM_INFO, "GL_QUADS( %d )", VB->Count ));
+ RenderQuadVB( ctx, 0, VB->Count );
+ break;
+
+ case GL_QUAD_STRIP:
+ if ( VB->Count < 4 )
+ {
+ DPF(( DBG_PRIM_WARN, "GL_QUAD_STRIP( %d )", VB->Count ));
+ return FALSE;
+ }
+
+ DPF(( DBG_PRIM_INFO, "GL_QUAD_STRIP( %d )", VB->Count ));
+
+ if ( VB->ClipOrMask )
+ {
+ for( index = 3; index < VB->Count; index += 2 )
+ {
+ if ( VB->ClipMask[index-3] & VB->ClipMask[index-2] & VB->ClipMask[index-1] & VB->ClipMask[index] & CLIP_ALL_BITS )
+ {
+ /* All points clipped by common plane */
+ DPF(( DBG_PRIM_WARN, "GL_QUAD_STRIP( %d )", VB->Count ));
+ continue;
+ }
+ else if ( VB->ClipMask[index-3] | VB->ClipMask[index-2] | VB->ClipMask[index-1] | VB->ClipMask[index] )
+ {
+ vlist[0] = index - 3;
+ vlist[1] = index - 2;
+ vlist[2] = index;
+ vlist[3] = index - 1;
+ RenderClippedPolygon( ctx, 4, vlist );
+ }
+ else
+ {
+ RenderQuad( ctx, (index-3), (index-2), index, (index-1), index );
+ }
+ }
+ }
+ else
+ {
+ /* No clipping needed */
+ for( index = 3; index < VB->Count; index += 2 )
+ RenderQuad( ctx, (index-3), (index-2), index, (index-1), index );
+ }
+ break;
+
+ case GL_POLYGON:
+ if ( VB->Count < 3 )
+ {
+ DPF(( DBG_PRIM_WARN, "GL_POLYGON( %d )", VB->Count ));
+ return FALSE;
+ }
+
+ DPF(( DBG_PRIM_INFO, "GL_POLYGON( %d )", VB->Count ));
+
+ /* All points clipped by common plane, draw nothing */
+ if ( !(VB->ClipAndMask & CLIP_ALL_BITS) )
+ RenderTriangleFanVB( ctx, 0, VB->Count );
+ break;
+
+ default:
+ /* should never get here */
+ gl_problem( ctx, "invalid mode in gl_render_vb" );
+ }
+
+ DPF(( DBG_PRIM_INFO, "ResetVB" ));
+
+ /* We return TRUE to indicate we rendered the VB. */
+ gl_reset_vb( ctx, allDone );
+ return TRUE;
+}
+/*===========================================================================*/
+/* This function will render the current vertex buffer as triangles. The */
+/* buffer has to be able to be rendered directly. This means that we are */
+/* filled, no offsets, no culling and one sided rendering. Also we must be */
+/* in render mode of course. */
+/* First I will fill the global D3D vertice buffer. Next I will set all the*/
+/* states for D3D based on the current OGL state. Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void RenderTriangleVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int index,
+ cVertex,
+ height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ DWORD dwPVColor;
+ GLfloat ex, ey,
+ fx, fy, c;
+ GLuint facing;
+
+ DPF(( DBG_FUNC, "RenderTriangleVB" ));
+
+ if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask )
+ {
+ DPF(( DBG_PRIM_INFO, "DirectTriangles( %d )", (end-start) ));
+ for( index = start, cVertex = 0; index < end; )
+ {
+ dwPVColor = (VB->Color[(index+2)][3]<<24) | (VB->Color[(index+2)][0]<<16) | (VB->Color[(index+2)][1]<<8) | VB->Color[(index+2)][2];
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+ index++;
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+ index++;
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color= dwPVColor;
+ index++;
+ }
+ }
+ else
+ {
+#define v1 index
+#define v2 (index+1)
+#define v3 (index+2)
+
+ for( index = start, cVertex = 0; index < end; index += 3 )
+ {
+ if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS )
+ {
+ continue;
+ }
+ else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] )
+ {
+ VList[0] = v1;
+ VList[1] = v2;
+ VList[2] = v3;
+ RenderClippedPolygon( ctx, 3, VList );
+ continue;
+ }
+
+ /* Compute orientation of triangle */
+ ex = VB->Win[v2][0] - VB->Win[v1][0];
+ ey = VB->Win[v2][1] - VB->Win[v1][1];
+ fx = VB->Win[v3][0] - VB->Win[v1][0];
+ fy = VB->Win[v3][1] - VB->Win[v1][1];
+ c = (ex * fy) - (ey * fx);
+
+ /* polygon is perpindicular to view plane, don't draw it */
+ if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+ continue;
+
+ /* Backface culling. */
+ facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+ if ( (facing + 1) & ctx->Polygon.CullBits )
+ continue;
+
+ if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
+ {
+ if ( facing == 1 )
+ {
+ /* use back color */
+ VB->Color = VB->Bcolor;
+ VB->Specular= VB->Bspec;
+ }
+ else
+ {
+ /* use front color */
+ VB->Color = VB->Fcolor;
+ VB->Specular= VB->Fspec;
+ }
+ }
+
+ if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
+ {
+ /* Finish computing plane equation of polygon, compute offset */
+ GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
+ GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+ GLfloat a = (ey * fz) - (ez * fy);
+ GLfloat b = (ez * fx) - (ex * fz);
+ OffsetPolygon( ctx, a, b, c );
+ }
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ /* Solve the prevoking vertex color as we need it for the 3rd triangle and flat shading. */
+ dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= dwPVColor;
+ }
+#undef v1
+#undef v2
+#undef v3
+ }
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex > 2 )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+}
+/*===========================================================================*/
+/* This function will render the current vertex buffer as a triangle fan. */
+/* The buffer has to be able to be rendered directly. This means that we are*/
+/* filled, no offsets, no culling and one sided rendering. Also we must be */
+/* in render mode of course. */
+/* First I will fill the global D3D vertice buffer. Next I will set all the*/
+/* states for D3D based on the current OGL state. Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void RenderTriangleFanVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int index,
+ cVertex,
+ height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ GLfloat ex, ey,
+ fx, fy, c;
+ GLuint facing;
+ DWORD dwPVColor;
+
+ DPF(( DBG_FUNC, "RenderTriangleFanVB();" ));
+
+ /* Special case that we can blast the fan without culling, offset, etc... */
+ if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask && (ctx->Light.ShadeModel != GL_FLAT) )
+ {
+ DPF(( DBG_PRIM_INFO, "DirectTriangles( %d )", (end-start) ));
+
+ /* Seed the the fan. */
+ D3DTLVertices[0].sx = D3DVAL( VB->Win[start][0] );
+ D3DTLVertices[0].sy = D3DVAL( (height - VB->Win[start][1]) );
+ D3DTLVertices[0].sz = D3DVAL( VB->Win[start][2] );
+ D3DTLVertices[0].tu = D3DVAL( VB->TexCoord[start][0] );
+ D3DTLVertices[0].tv = D3DVAL( VB->TexCoord[start][1] );
+ D3DTLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[start][3]) );
+ D3DTLVertices[0].color= (VB->Color[start][3]<<24) | (VB->Color[start][0]<<16) | (VB->Color[start][1]<<8) | VB->Color[start][2];
+
+ /* Seed the the fan. */
+ D3DTLVertices[1].sx = D3DVAL( VB->Win[(start+1)][0] );
+ D3DTLVertices[1].sy = D3DVAL( (height - VB->Win[(start+1)][1]) );
+ D3DTLVertices[1].sz = D3DVAL( VB->Win[(start+1)][2] );
+ D3DTLVertices[1].tu = D3DVAL( VB->TexCoord[(start+1)][0] );
+ D3DTLVertices[1].tv = D3DVAL( VB->TexCoord[(start+1)][1] );
+ D3DTLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[(start+1)][3]) );
+ 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];
+
+ for( index = (start+2), cVertex = 2; index < end; index++, cVertex++ )
+ {
+ /*=================================*/
+ /* Add the next vertex to the fan. */
+ /*=================================*/
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex].color = (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+ }
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLEFAN, &D3DTLVertices[0], cVertex );
+ }
+ else
+ {
+#define v1 start
+#define v2 (index-1)
+#define v3 index
+
+ for( index = (start+2), cVertex = 0; index < end; index++ )
+ {
+ if ( VB->ClipOrMask )
+ {
+ /* All points clipped by common plane */
+ if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS )
+ {
+ continue;
+ }
+ else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] )
+ {
+ VList[0] = v1;
+ VList[1] = v2;
+ VList[2] = v3;
+ RenderClippedPolygon( ctx, 3, VList );
+ continue;
+ }
+ }
+
+ /* Compute orientation of triangle */
+ ex = VB->Win[v2][0] - VB->Win[v1][0];
+ ey = VB->Win[v2][1] - VB->Win[v1][1];
+ fx = VB->Win[v3][0] - VB->Win[v1][0];
+ fy = VB->Win[v3][1] - VB->Win[v1][1];
+ c = (ex * fy) - (ey * fx);
+
+ /* polygon is perpindicular to view plane, don't draw it */
+ if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+ continue;
+
+ /* Backface culling. */
+ facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+ if ( (facing + 1) & ctx->Polygon.CullBits )
+ continue;
+
+ if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
+ {
+ /* Finish computing plane equation of polygon, compute offset */
+ GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
+ GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+ GLfloat a = (ey * fz) - (ez * fy);
+ GLfloat b = (ez * fx) - (ex * fz);
+ OffsetPolygon( ctx, a, b, c );
+ }
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= dwPVColor;
+ }
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+#undef v1
+#undef v2
+#undef v3
+ }
+}
+/*===========================================================================*/
+/* This function will render the current vertex buffer as a triangle strip. */
+/* The buffer has to be able to be rendered directly. This means that we are*/
+/* filled, no offsets, no culling and one sided rendering. Also we must be */
+/* in render mode of course. */
+/* First I will fill the global D3D vertice buffer. Next I will set all the*/
+/* states for D3D based on the current OGL state. Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void RenderTriangleStripVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int index,
+ cVertex = 0,
+ v1, v2, v3,
+ height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ GLfloat ex, ey,
+ fx, fy, c;
+ GLuint facing;
+ DWORD dwPVColor;
+
+ DPF(( DBG_FUNC, "RenderTriangleStripVB();" ));
+
+ /* Special case that we can blast the fan without culling, offset, etc... */
+ if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask && (ctx->Light.ShadeModel != GL_FLAT) )
+ {
+ DPF(( DBG_PRIM_PROFILE, "DirectTriangles" ));
+
+ /* Seed the the strip. */
+ D3DTLVertices[0].sx = D3DVAL( VB->Win[start][0] );
+ D3DTLVertices[0].sy = D3DVAL( (height - VB->Win[start][1]) );
+ D3DTLVertices[0].sz = D3DVAL( VB->Win[start][2] );
+ D3DTLVertices[0].tu = D3DVAL( VB->TexCoord[start][0] );
+ D3DTLVertices[0].tv = D3DVAL( VB->TexCoord[start][1] );
+ D3DTLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[start][3]) );
+ D3DTLVertices[0].color= (VB->Color[start][3]<<24) | (VB->Color[start][0]<<16) | (VB->Color[start][1]<<8) | VB->Color[start][2];
+
+ /* Seed the the strip. */
+ D3DTLVertices[1].sx = D3DVAL( VB->Win[(start+1)][0] );
+ D3DTLVertices[1].sy = D3DVAL( (height - VB->Win[(start+1)][1]) );
+ D3DTLVertices[1].sz = D3DVAL( VB->Win[(start+1)][2] );
+ D3DTLVertices[1].tu = D3DVAL( VB->TexCoord[(start+1)][0] );
+ D3DTLVertices[1].tv = D3DVAL( VB->TexCoord[(start+1)][1] );
+ D3DTLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[(start+1)][3]) );
+ 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];
+
+ for( index = (start+2), cVertex = 2; index < end; index++, cVertex++ )
+ {
+ /*===================================*/
+ /* Add the next vertex to the strip. */
+ /*===================================*/
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[index][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[index][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[index][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[index][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[index][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex].color = (VB->Color[index][3]<<24) | (VB->Color[index][0]<<16) | (VB->Color[index][1]<<8) | VB->Color[index][2];
+ }
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLESTRIP, &D3DTLVertices[0], cVertex );
+ }
+ else
+ {
+ for( index = (start+2); index < end; index++ )
+ {
+ /* We need to switch order so that winding won't be a problem. */
+ if ( index & 1 )
+ {
+ v1 = index - 1;
+ v2 = index - 2;
+ v3 = index - 0;
+ }
+ else
+ {
+ v1 = index - 2;
+ v2 = index - 1;
+ v3 = index - 0;
+ }
+
+ /* All vertices clipped by common plane */
+ if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & CLIP_ALL_BITS )
+ continue;
+
+ /* Check if any vertices need clipping. */
+ if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] )
+ {
+ VList[0] = v1;
+ VList[1] = v2;
+ VList[2] = v3;
+ RenderClippedPolygon( ctx, 3, VList );
+ }
+ else
+ {
+ /* Compute orientation of triangle */
+ ex = VB->Win[v2][0] - VB->Win[v1][0];
+ ey = VB->Win[v2][1] - VB->Win[v1][1];
+ fx = VB->Win[v3][0] - VB->Win[v1][0];
+ fy = VB->Win[v3][1] - VB->Win[v1][1];
+ c = (ex * fy) - (ey * fx);
+
+ /* Polygon is perpindicular to view plane, don't draw it */
+ if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+ continue;
+
+ /* Backface culling. */
+ facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+ if ( (facing + 1) & ctx->Polygon.CullBits )
+ continue;
+
+ /* Need right color if we have two sided lighting. */
+ if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
+ {
+ if ( facing == 1 )
+ {
+ /* use back color */
+ VB->Color = VB->Bcolor;
+ VB->Specular= VB->Bspec;
+ }
+ else
+ {
+ /* use front color */
+ VB->Color = VB->Fcolor;
+ VB->Specular= VB->Fspec;
+ }
+ }
+
+ if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
+ {
+ /* Finish computing plane equation of polygon, compute offset */
+ GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
+ GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+ GLfloat a = (ey * fz) - (ez * fy);
+ GLfloat b = (ez * fx) - (ex * fz);
+ OffsetPolygon( ctx, a, b, c );
+ }
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+
+ /* Solve the prevoking vertex color as we need it for the 3rd triangle and flat shading. */
+ dwPVColor = (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= dwPVColor;
+ }
+ }
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+ }
+}
+/*===========================================================================*/
+/* This function will render the current vertex buffer as Quads. The buffer*/
+/* has to be able to be rendered directly. This means that we are filled, no*/
+/* offsets, no culling and one sided rendering. Also we must be in render */
+/* mode of cource. */
+/* First I will fill the global D3D vertice buffer. Next I will set all the*/
+/* states for D3D based on the current OGL state. Finally I pass the D3D VB */
+/* to the wrapper that call DrawPrimitives. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void RenderQuadVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int index,
+ cVertex,
+ height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ DWORD dwPVColor;
+ GLfloat ex, ey,
+ fx, fy, c;
+ GLuint facing; /* 0=front, 1=back */
+
+ DPF(( DBG_FUNC, "RenderQuadVB();" ));
+
+#define v1 (index)
+#define v2 (index+1)
+#define v3 (index+2)
+#define v4 (index+3)
+
+ if ( (!(ctx->IndirectTriangles & DD_SW_SETUP)) && !VB->ClipOrMask )
+ {
+ DPF(( DBG_PRIM_PROFILE, "DirectTriangles" ));
+
+ for( cVertex = 0, index = start; index < end; index += 4 )
+ {
+ if ( ctx->Light.ShadeModel == GL_FLAT )
+ dwPVColor = (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v1][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v2][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v3][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v1][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v3][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v4][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v4][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( VB->Win[v4][2] );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v4][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v4][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v4][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+ }
+ }
+ else
+ {
+ for( cVertex = 0, index = start; index < end; index += 4 )
+ {
+ if ( VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3] & VB->ClipMask[v4] & CLIP_ALL_BITS )
+ {
+ continue;
+ }
+ else if ( VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3] | VB->ClipMask[v4] )
+ {
+ VList[0] = v1;
+ VList[1] = v2;
+ VList[2] = v3;
+ VList[3] = v4;
+ RenderClippedPolygon( ctx, 4, VList );
+ continue;
+ }
+
+ /* Compute orientation of triangle */
+ ex = VB->Win[v2][0] - VB->Win[v1][0];
+ ey = VB->Win[v2][1] - VB->Win[v1][1];
+ fx = VB->Win[v3][0] - VB->Win[v1][0];
+ fy = VB->Win[v3][1] - VB->Win[v1][1];
+ c = (ex * fy) - (ey * fx);
+
+ /* polygon is perpindicular to view plane, don't draw it */
+ if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+ continue;
+
+ /* Backface culling. */
+ facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+ if ( (facing + 1) & ctx->Polygon.CullBits )
+ continue;
+
+ if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
+ {
+ if ( facing == 1 )
+ {
+ /* use back color */
+ VB->Color = VB->Bcolor;
+ VB->Specular= VB->Bspec;
+ }
+ else
+ {
+ /* use front color */
+ VB->Color = VB->Fcolor;
+ VB->Specular= VB->Fspec;
+ }
+ }
+
+ if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
+ {
+ /* Finish computing plane equation of polygon, compute offset */
+ GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
+ GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+ GLfloat a = (ey * fz) - (ez * fy);
+ GLfloat b = (ez * fx) - (ex * fz);
+ OffsetPolygon( ctx, a, b, c );
+ }
+
+ if ( ctx->Light.ShadeModel == GL_FLAT )
+ dwPVColor = (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v2][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v2][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v2][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v1][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v1][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v1][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v3][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v3][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v3][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ D3DTLVertices[cVertex].sx = D3DVAL( VB->Win[v4][0] );
+ D3DTLVertices[cVertex].sy = D3DVAL( (height - VB->Win[v4][1]) );
+ D3DTLVertices[cVertex].sz = D3DVAL( (VB->Win[v4][2] + ctx->PolygonZoffset) );
+ D3DTLVertices[cVertex].tu = D3DVAL( VB->TexCoord[v4][0] );
+ D3DTLVertices[cVertex].tv = D3DVAL( VB->TexCoord[v4][1] );
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[v4][3]) );
+ D3DTLVertices[cVertex++].color= (ctx->Light.ShadeModel == GL_FLAT) ?
+ dwPVColor :
+ (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+ }
+ }
+
+#undef v4
+#undef v3
+#undef v2
+#undef v1
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+}
+/*===========================================================================*/
+/* */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+static void RenderQuad( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ DWORD dwPVColor;
+ GLfloat ex, ey,
+ fx, fy, c;
+ GLuint facing; /* 0=front, 1=back */
+ static D3DTLVERTEX TLVertices[6];
+
+ DPF(( DBG_FUNC, "RenderQuad" ));
+ DPF(( DBG_PRIM_INFO, "RenderQuad( 1 )" ));
+
+ /* Compute orientation of triangle */
+ ex = VB->Win[v2][0] - VB->Win[v1][0];
+ ey = VB->Win[v2][1] - VB->Win[v1][1];
+ fx = VB->Win[v3][0] - VB->Win[v1][0];
+ fy = VB->Win[v3][1] - VB->Win[v1][1];
+ c = (ex * fy) - (ey * fx);
+
+ /* polygon is perpindicular to view plane, don't draw it */
+ if ( (c == 0.0F) && !ctx->Polygon.Unfilled )
+ return;
+
+ /* Backface culling. */
+ facing = (c < 0.0F) ^ ctx->Polygon.FrontBit;
+ if ( (facing + 1) & ctx->Polygon.CullBits )
+ return;
+
+ if ( ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE )
+ {
+ if ( facing == 1 )
+ {
+ /* use back color */
+ VB->Color = VB->Bcolor;
+ VB->Specular= VB->Bspec;
+ }
+ else
+ {
+ /* use front color */
+ VB->Color = VB->Fcolor;
+ VB->Specular= VB->Fspec;
+ }
+ }
+
+ if ( ctx->IndirectTriangles & DD_TRI_OFFSET )
+ {
+ /* Finish computing plane equation of polygon, compute offset */
+ GLfloat fz = VB->Win[v3][2] - VB->Win[v1][2];
+ GLfloat ez = VB->Win[v2][2] - VB->Win[v1][2];
+ GLfloat a = (ey * fz) - (ez * fy);
+ GLfloat b = (ez * fx) - (ex * fz);
+ OffsetPolygon( ctx, a, b, c );
+ }
+
+ if ( ctx->Light.ShadeModel == GL_FLAT )
+ dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ TLVertices[0].sx = D3DVAL( VB->Win[v1][0] );
+ TLVertices[0].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ TLVertices[0].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ TLVertices[0].tu = D3DVAL( VB->TexCoord[v1][0] );
+ TLVertices[0].tv = D3DVAL( VB->TexCoord[v1][1] );
+ TLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ TLVertices[0].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ TLVertices[1].sx = D3DVAL( VB->Win[v2][0] );
+ TLVertices[1].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ TLVertices[1].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+ TLVertices[1].tu = D3DVAL( VB->TexCoord[v2][0] );
+ TLVertices[1].tv = D3DVAL( VB->TexCoord[v2][1] );
+ TLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ TLVertices[1].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ TLVertices[2].sx = D3DVAL( VB->Win[v3][0] );
+ TLVertices[2].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ TLVertices[2].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ TLVertices[2].tu = D3DVAL( VB->TexCoord[v3][0] );
+ TLVertices[2].tv = D3DVAL( VB->TexCoord[v3][1] );
+ TLVertices[2].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ TLVertices[2].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ TLVertices[3].sx = D3DVAL( VB->Win[v3][0] );
+ TLVertices[3].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ TLVertices[3].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ TLVertices[3].tu = D3DVAL( VB->TexCoord[v3][0] );
+ TLVertices[3].tv = D3DVAL( VB->TexCoord[v3][1] );
+ TLVertices[3].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ TLVertices[3].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+
+ TLVertices[4].sx = D3DVAL( VB->Win[v4][0] );
+ TLVertices[4].sy = D3DVAL( (height - VB->Win[v4][1]) );
+ TLVertices[4].sz = D3DVAL( (VB->Win[v4][2] + ctx->PolygonZoffset) );
+ TLVertices[4].tu = D3DVAL( VB->TexCoord[v4][0] );
+ TLVertices[4].tv = D3DVAL( VB->TexCoord[v4][1] );
+ TLVertices[4].rhw = D3DVAL( (1.0 / VB->Clip[v4][3]) );
+ TLVertices[4].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v4][3]<<24) | (VB->Color[v4][0]<<16) | (VB->Color[v4][1]<<8) | VB->Color[v4][2];
+
+ TLVertices[5].sx = D3DVAL( VB->Win[v1][0] );
+ TLVertices[5].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ TLVertices[5].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ TLVertices[5].tu = D3DVAL( VB->TexCoord[v1][0] );
+ TLVertices[5].tv = D3DVAL( VB->TexCoord[v1][1] );
+ TLVertices[5].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ TLVertices[5].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ /* Draw the two triangles. */
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &TLVertices[0], 6 );
+}
+/*===========================================================================*/
+/* */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+void RenderOneTriangle( GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ DWORD dwPVColor;
+ static D3DTLVERTEX TLVertices[3];
+
+ DPF(( DBG_FUNC, "RenderOneTriangle" ));
+ DPF(( DBG_PRIM_INFO, "RenderTriangle( 1 )" ));
+
+ /*=====================================*/
+ /* Populate the the triangle vertices. */
+ /*=====================================*/
+ if ( ctx->Light.ShadeModel == GL_FLAT )
+ dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
+
+ TLVertices[0].sx = D3DVAL( VB->Win[v1][0] );
+ TLVertices[0].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ TLVertices[0].sz = D3DVAL( (VB->Win[v1][2] + ctx->PolygonZoffset) );
+ TLVertices[0].tu = D3DVAL( VB->TexCoord[v1][0] );
+ TLVertices[0].tv = D3DVAL( VB->TexCoord[v1][1] );
+ TLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ TLVertices[0].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+ DPF(( DBG_PRIM_INFO, "V1 -> x:%f y:%f z:%f c:%x",
+ TLVertices[0].sx,
+ TLVertices[0].sy,
+ TLVertices[0].sz,
+ TLVertices[0].color ));
+
+ TLVertices[1].sx = D3DVAL( VB->Win[v2][0] );
+ TLVertices[1].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ TLVertices[1].sz = D3DVAL( (VB->Win[v2][2] + ctx->PolygonZoffset) );
+ TLVertices[1].tu = D3DVAL( VB->TexCoord[v2][0] );
+ TLVertices[1].tv = D3DVAL( VB->TexCoord[v2][1] );
+ TLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ TLVertices[1].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+ DPF(( DBG_PRIM_INFO, "V2 -> x:%f y:%f z:%f c:%x",
+ TLVertices[1].sx,
+ TLVertices[1].sy,
+ TLVertices[1].sz,
+ TLVertices[1].color ));
+
+ TLVertices[2].sx = D3DVAL( VB->Win[v3][0] );
+ TLVertices[2].sy = D3DVAL( (height - VB->Win[v3][1]) );
+ TLVertices[2].sz = D3DVAL( (VB->Win[v3][2] + ctx->PolygonZoffset) );
+ TLVertices[2].tu = D3DVAL( VB->TexCoord[v3][0] );
+ TLVertices[2].tv = D3DVAL( VB->TexCoord[v3][1] );
+ TLVertices[2].rhw = D3DVAL( (1.0 / VB->Clip[v3][3]) );
+ TLVertices[2].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v3][3]<<24) | (VB->Color[v3][0]<<16) | (VB->Color[v3][1]<<8) | VB->Color[v3][2];
+ DPF(( DBG_PRIM_INFO, "V3 -> x:%f y:%f z:%f c:%x",
+ TLVertices[2].sx,
+ TLVertices[2].sy,
+ TLVertices[2].sz,
+ TLVertices[2].color ));
+
+ /* Draw the triangle. */
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &TLVertices[0], 3 );
+}
+/*===========================================================================*/
+/* */
+/*===========================================================================*/
+/* RETURN: TRUE, FALSE. */
+/*===========================================================================*/
+void RenderOneLine( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ int height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ DWORD dwPVColor;
+ static D3DTLVERTEX TLVertices[2];
+
+ DPF(( DBG_FUNC, "RenderOneLine" ));
+ DPF(( DBG_PRIM_INFO, "RenderLine( 1 )" ));
+
+ if ( VB->MonoColor )
+ dwPVColor = (pContext->aCurrent<<24) | (pContext->rCurrent<<16) | (pContext->gCurrent<<8) | pContext->bCurrent;
+ else
+ dwPVColor = (VB->Color[pv][3]<<24) | (VB->Color[pv][0]<<16) | (VB->Color[pv][1]<<8) | VB->Color[pv][2];
+
+ TLVertices[0].sx = D3DVAL( VB->Win[v1][0] );
+ TLVertices[0].sy = D3DVAL( (height - VB->Win[v1][1]) );
+ TLVertices[0].sz = D3DVAL( (VB->Win[v1][2] + ctx->LineZoffset) );
+ TLVertices[0].tu = D3DVAL( VB->TexCoord[v1][0] );
+ TLVertices[0].tv = D3DVAL( VB->TexCoord[v1][1] );
+ TLVertices[0].rhw = D3DVAL( (1.0 / VB->Clip[v1][3]) );
+ TLVertices[0].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v1][3]<<24) | (VB->Color[v1][0]<<16) | (VB->Color[v1][1]<<8) | VB->Color[v1][2];
+
+ TLVertices[1].sx = D3DVAL( VB->Win[v2][0] );
+ TLVertices[1].sy = D3DVAL( (height - VB->Win[v2][1]) );
+ TLVertices[1].sz = D3DVAL( (VB->Win[v2][2] + ctx->LineZoffset) );
+ TLVertices[1].tu = D3DVAL( VB->TexCoord[v2][0] );
+ TLVertices[1].tv = D3DVAL( VB->TexCoord[v2][1] );
+ TLVertices[1].rhw = D3DVAL( (1.0 / VB->Clip[v2][3]) );
+ TLVertices[1].color = (ctx->Light.ShadeModel == GL_FLAT) ? dwPVColor :
+ (VB->Color[v2][3]<<24) | (VB->Color[v2][0]<<16) | (VB->Color[v2][1]<<8) | VB->Color[v2][2];
+
+ /* Draw line from (x0,y0) to (x1,y1) with current pixel color/index */
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_LINELIST, &TLVertices[0], 2 );
+}
+/*===========================================================================*/
+/* This function was written to convert points into triangles. I did this */
+/* as all card accelerate triangles and most drivers do this anyway. In hind*/
+/* thought this might be a bad idea as some cards do better. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void RenderPointsVB( GLcontext *ctx, GLuint start, GLuint end )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ struct vertex_buffer *VB = ctx->VB;
+ struct pixel_buffer *PB = ctx->PB;
+ GLuint index;
+ GLfloat radius, z,
+ xmin, ymin,
+ xmax, ymax;
+ GLint cVertex,
+ height = (pContext->pShared->rectW.bottom - pContext->pShared->rectW.top);
+ DWORD dwPVColor;
+
+ DPF(( DBG_FUNC, "RenderPointsVB();" ));
+
+ radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
+
+ for( index = start, cVertex = 0; index <= end; index++ )
+ {
+ if ( VB->ClipMask[index] == 0 )
+ {
+ xmin = D3DVAL( VB->Win[index][0] - radius );
+ xmax = D3DVAL( VB->Win[index][0] + radius );
+ ymin = D3DVAL( height - VB->Win[index][1] - radius );
+ ymax = D3DVAL( height - VB->Win[index][1] + radius );
+ z = D3DVAL( (VB->Win[index][2] + ctx->PointZoffset) );
+
+ dwPVColor = (VB->Color[index][3]<<24) |
+ (VB->Color[index][0]<<16) |
+ (VB->Color[index][1]<<8) |
+ VB->Color[index][2];
+
+ D3DTLVertices[cVertex].sx = xmin;
+ D3DTLVertices[cVertex].sy = ymax;
+ D3DTLVertices[cVertex].sz = z;
+ D3DTLVertices[cVertex].tu = 0.0;
+ D3DTLVertices[cVertex].tv = 0.0;
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color = dwPVColor;
+
+ D3DTLVertices[cVertex].sx = xmin;
+ D3DTLVertices[cVertex].sy = ymin;
+ D3DTLVertices[cVertex].sz = z;
+ D3DTLVertices[cVertex].tu = 0.0;
+ D3DTLVertices[cVertex].tv = 0.0;
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color = dwPVColor;
+
+ D3DTLVertices[cVertex].sx = xmax;
+ D3DTLVertices[cVertex].sy = ymin;
+ D3DTLVertices[cVertex].sz = z;
+ D3DTLVertices[cVertex].tu = 0.0;
+ D3DTLVertices[cVertex].tv = 0.0;
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color = dwPVColor;
+
+ D3DTLVertices[cVertex].sx = xmax;
+ D3DTLVertices[cVertex].sy = ymin;
+ D3DTLVertices[cVertex].sz = z;
+ D3DTLVertices[cVertex].tu = 0.0;
+ D3DTLVertices[cVertex].tv = 0.0;
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color = dwPVColor;
+
+ D3DTLVertices[cVertex].sx = xmax;
+ D3DTLVertices[cVertex].sy = ymax;
+ D3DTLVertices[cVertex].sz = z;
+ D3DTLVertices[cVertex].tu = 0.0;
+ D3DTLVertices[cVertex].tv = 0.0;
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color = dwPVColor;
+
+ D3DTLVertices[cVertex].sx = xmin;
+ D3DTLVertices[cVertex].sy = ymax;
+ D3DTLVertices[cVertex].sz = z;
+ D3DTLVertices[cVertex].tu = 0.0;
+ D3DTLVertices[cVertex].tv = 0.0;
+ D3DTLVertices[cVertex].rhw = D3DVAL( (1.0 / VB->Clip[index][3]) );
+ D3DTLVertices[cVertex++].color = dwPVColor;
+ }
+ }
+
+ /* Render the converted vertex buffer. */
+ if ( cVertex )
+ DrawPrimitiveHAL( pContext->pShared, D3DPT_TRIANGLELIST, &D3DTLVertices[0], cVertex );
+}
+/*===========================================================================*/
+/* This gets call before we render any primitives so that the current OGL */
+/* states will be mapped the D3D context. I'm still not sure how D3D works */
+/* but I'm finding that it doesn't act like a state machine as OGL is. It */
+/* looks like the state gets set back to the defaults after a DrawPrimitives */
+/* or an EndScene. Also I set states that are the default even though this */
+/* is redundant as the defaults seem screwed up. */
+/* TODO: make a batch call. */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void SetRenderStates( GLcontext *ctx )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ DWORD dwFunc;
+ static BOOL bTexture = FALSE;
+ static int texName = -1;
+
+ DPF(( DBG_FUNC, "SetRenderStates();" ));
+
+ if ( g_DBGMask & DBG_STATES )
+ DebugRenderStates( ctx, FALSE );
+
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE );
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_DITHERENABLE, (ctx->Color.DitherFlag) ? TRUE : FALSE );
+
+ /*================================================*/
+ /* Check too see if there are new TEXTURE states. */
+ /*================================================*/
+ if ( ctx->Texture.Enabled )
+ {
+ switch( ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode )
+ {
+ case GL_MODULATE:
+ if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format == GL_RGBA )
+ dwFunc = pContext->pShared->dwTexFunc[d3dtblend_modulatealpha];
+ else
+ dwFunc = pContext->pShared->dwTexFunc[d3dtblend_modulate];
+ break;
+
+ case GL_BLEND:
+ dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decalalpha];
+ break;
+
+ case GL_REPLACE:
+ dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decal];
+ break;
+
+ case GL_DECAL:
+ if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format == GL_RGBA )
+ dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decalalpha];
+ else
+ dwFunc = pContext->pShared->dwTexFunc[d3dtblend_decal];
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMAPBLEND, dwFunc );
+
+ switch( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter )
+ {
+ case GL_NEAREST:
+ dwFunc = D3DFILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ dwFunc = D3DFILTER_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ dwFunc = D3DFILTER_MIPNEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ dwFunc = D3DFILTER_LINEARMIPNEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ dwFunc = D3DFILTER_MIPLINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ dwFunc = D3DFILTER_LINEARMIPLINEAR;
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMAG, dwFunc );
+
+ switch( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter )
+ {
+ case GL_NEAREST:
+ dwFunc = D3DFILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ dwFunc = D3DFILTER_LINEAR;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ dwFunc = D3DFILTER_MIPNEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ dwFunc = D3DFILTER_LINEARMIPNEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ dwFunc = D3DFILTER_MIPLINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ dwFunc = D3DFILTER_LINEARMIPLINEAR;
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_TEXTUREMIN, dwFunc );
+
+ /* Another hack to cut down on redundant texture binding. */
+ // if ( texName != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name )
+ // {
+ texName = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name;
+ CreateTMgrHAL( pContext->pShared,
+ texName,
+ 0,
+ ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format,
+ (RECT *)NULL,
+ ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Width,
+ ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Height,
+ TM_ACTION_BIND,
+ (void *)ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Data );
+ // }
+ bTexture = TRUE;
+ }
+ else
+ {
+ /* This is nasty but should cut down on the number of redundant calls. */
+ if ( bTexture == TRUE )
+ {
+ DisableTMgrHAL( pContext->pShared );
+ bTexture = FALSE;
+ }
+ }
+
+ /*===============================================*/
+ /* Check too see if there are new RASTER states. */
+ /*===============================================*/
+
+ // TODO: no concept of front & back.
+ switch( ctx->Polygon.FrontMode )
+ {
+ case GL_POINT:
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_POINT );
+ break;
+ case GL_LINE:
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME );
+ break;
+ case GL_FILL:
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID );
+ break;
+ }
+
+ /*************/
+ /* Z-Buffer. */
+ /*************/
+ if ( ctx->Depth.Test == GL_TRUE )
+ {
+ switch( ctx->Depth.Func )
+ {
+ case GL_NEVER:
+ dwFunc = D3DCMP_NEVER;
+ break;
+ case GL_LESS:
+ dwFunc = D3DCMP_LESS;
+ break;
+ case GL_GEQUAL:
+ dwFunc = D3DCMP_GREATEREQUAL;
+ break;
+ case GL_LEQUAL:
+ dwFunc = D3DCMP_LESSEQUAL;
+ break;
+ case GL_GREATER:
+ dwFunc = D3DCMP_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ dwFunc = D3DCMP_NOTEQUAL;
+ break;
+ case GL_EQUAL:
+ dwFunc = D3DCMP_EQUAL;
+ break;
+ case GL_ALWAYS:
+ dwFunc = D3DCMP_ALWAYS;
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZFUNC, dwFunc );
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZENABLE, TRUE );
+ }
+ else
+ {
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZENABLE, FALSE );
+ }
+
+ /*******************/
+ /* Z-Write Enable. */
+ /*******************/
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ZWRITEENABLE , (ctx->Depth.Mask == GL_TRUE) ? TRUE : FALSE );
+
+ /***************/
+ /* Alpha test. */
+ /***************/
+ if ( ctx->Color.AlphaEnabled == GL_TRUE )
+ {
+ switch( ctx->Color.AlphaFunc )
+ {
+ case GL_NEVER:
+ dwFunc = D3DCMP_NEVER;
+ break;
+ case GL_LESS:
+ dwFunc = D3DCMP_LESS;
+ break;
+ case GL_GEQUAL:
+ dwFunc = D3DCMP_GREATEREQUAL;
+ break;
+ case GL_LEQUAL:
+ dwFunc = D3DCMP_LESSEQUAL;
+ break;
+ case GL_GREATER:
+ dwFunc = D3DCMP_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ dwFunc = D3DCMP_NOTEQUAL;
+ break;
+ case GL_EQUAL:
+ dwFunc = D3DCMP_EQUAL;
+ break;
+ case GL_ALWAYS:
+ dwFunc = D3DCMP_ALWAYS;
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHAFUNC , dwFunc );
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
+ }
+ else
+ {
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
+ }
+
+ /****************/
+ /* Alpha blend. */
+ /****************/
+ if ( ctx->Color.BlendEnabled == GL_TRUE )
+ {
+ switch( ctx->Color.BlendSrc )
+ {
+ case GL_ZERO:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_zero];
+ break;
+ case GL_ONE:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_one];
+ break;
+ case GL_DST_COLOR:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_dst_color];
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_dst_color];
+ break;
+ case GL_SRC_ALPHA:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_src_alpha];
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_src_alpha];
+ break;
+ case GL_DST_ALPHA:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_dst_alpha];
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_dst_alpha];
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_src_alpha_saturate];
+ break;
+ case GL_CONSTANT_COLOR:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_constant_color];
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_constant_color];
+ break;
+ case GL_CONSTANT_ALPHA:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_constant_alpha];
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ dwFunc = pContext->pShared->dwSrcBlendCaps[s_one_minus_constant_alpha];
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_SRCBLEND, dwFunc );
+
+ switch( ctx->Color.BlendDst )
+ {
+ case GL_ZERO:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_zero];
+ break;
+ case GL_ONE:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_one];
+ break;
+ case GL_SRC_COLOR:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_src_color];
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_src_color];
+ break;
+ case GL_SRC_ALPHA:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_src_alpha];
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_src_alpha];
+ break;
+ case GL_DST_ALPHA:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_dst_alpha];
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_dst_alpha];
+ break;
+ case GL_CONSTANT_COLOR:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_constant_color];
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_constant_color];
+ break;
+ case GL_CONSTANT_ALPHA:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_constant_alpha];
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ dwFunc = pContext->pShared->dwDestBlendCaps[d_one_minus_constant_alpha];
+ break;
+ }
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_DESTBLEND, dwFunc );
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
+ }
+ else
+ {
+ SetStateHAL( pContext->pShared, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
+ }
+}
+/*===========================================================================*/
+/* If this function is called it will track the changes to the current */
+/* states that I'm setting in Direct3D. I did this so that the DPF's would */
+/* be under control! */
+/*===========================================================================*/
+/* RETURN: */
+/*===========================================================================*/
+static void DebugRenderStates( GLcontext *ctx, BOOL bForce )
+{
+ D3DMESACONTEXT *pContext = (D3DMESACONTEXT *)ctx->DriverCtx;
+ DWORD dwFunc;
+ static int dither = -1,
+ texture = -1,
+ textName = -1,
+ textEnv = -1,
+ textMin = -1,
+ textMag = -1,
+ polyMode = -1,
+ depthTest = -1,
+ depthFunc = -1,
+ depthMask = -1,
+ alphaTest = -1,
+ alphaFunc = -1,
+ blend = -1,
+ blendSrc = -1,
+ blendDest = -1;
+
+ /* Force a displayed update of all current states. */
+ if ( bForce )
+ {
+ dither = texture = textName = textEnv = textMin = textMag = -1;
+ polyMode = depthTest = depthFunc = depthMask = -1;
+ alphaTest = alphaFunc = blend = blendSrc = blendDest = -1;
+ }
+
+ if ( dither != ctx->Color.DitherFlag )
+ {
+ dither = ctx->Color.DitherFlag;
+ DPF(( 0, "\tDither\t\t%s", (dither) ? "ENABLED" : "--------" ));
+ }
+ if ( depthTest != ctx->Depth.Test )
+ {
+ depthTest = ctx->Depth.Test;
+ DPF(( 0, "\tDepth Test\t%s", (depthTest) ? "ENABLED" : "--------" ));
+ }
+ if ( alphaTest != ctx->Color.AlphaEnabled )
+ {
+ alphaTest = ctx->Color.AlphaEnabled;
+
+ DPF(( 0, "\tAlpha Test\t%s", (alphaTest) ? "ENABLED" : "--------" ));
+ }
+ if ( blend != ctx->Color.BlendEnabled )
+ {
+ blend = ctx->Color.BlendEnabled;
+
+ DPF(( 0, "\tBlending\t%s", (blend) ? "ENABLED" : "--------" ));
+ }
+
+ /*================================================*/
+ /* Check too see if there are new TEXTURE states. */
+ /*================================================*/
+ if ( texture != ctx->Texture.Enabled )
+ {
+ texture = ctx->Texture.Enabled;
+ DPF(( 0, "\tTexture\t\t%s", (texture) ? "ENABLED" : "--------" ));
+ }
+
+ if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current )
+ {
+ if ( ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name != textName )
+ {
+ textName = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Name;
+ DPF(( 0, "\tTexture Name:\t%d", textName ));
+ DPF(( 0, "\tTexture Format:\t%s",
+ (ctx->Texture.Set[ctx->Texture.CurrentSet].Current->Image[0]->Format == GL_RGBA) ?
+ "GL_RGBA" : "GLRGB" ));
+ }
+
+ if ( textEnv != ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode )
+ {
+ textEnv = ctx->Texture.Set[ctx->Texture.CurrentSet].EnvMode;
+
+ switch( textEnv )
+ {
+ case GL_MODULATE:
+ DPF(( 0, "\tTexture\tMode\tGL_MODULATE" ));
+ break;
+ case GL_BLEND:
+ DPF(( 0, "\tTexture\tMode\tGL_BLEND" ));
+ break;
+ case GL_REPLACE:
+ DPF(( 0, "\tTexture\tMode\tGL_REPLACE" ));
+ break;
+ case GL_DECAL:
+ DPF(( 0, "\tTexture\tMode\tGL_DECAL" ));
+ break;
+ }
+ }
+
+ if ( textMag != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter )
+ {
+ textMag = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MagFilter;
+
+ switch( textMag )
+ {
+ case GL_NEAREST:
+ DPF(( 0, "\tTexture MAG\tGL_NEAREST" ));
+ break;
+ case GL_LINEAR:
+ DPF(( 0, "\tTexture MAG\tGL_LINEAR" ));
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ DPF(( 0, "\tTexture MAG\tGL_NEAREST_MIPMAP_NEAREST" ));
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ DPF(( 0, "\tTexture MAG\tGL_LINEAR_MIPMAP_NEAREST" ));
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ DPF(( 0, "\tTexture MAG\tGL_NEAREST_MIPMAP_LINEAR" ));
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ DPF(( 0, "\tTexture MAG\tGL_LINEAR_MIPMAP_LINEAR" ));
+ break;
+ }
+ }
+
+ if ( textMin != ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter )
+ {
+ textMin = ctx->Texture.Set[ctx->Texture.CurrentSet].Current->MinFilter;
+
+ switch( textMin )
+ {
+ case GL_NEAREST:
+ DPF(( 0, "\tTexture MIN\tGL_NEAREST" ));
+ break;
+ case GL_LINEAR:
+ DPF(( 0, "\tTexture MIN\tGL_LINEAR" ));
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ DPF(( 0, "\tTexture MIN\tGL_NEAREST_MIPMAP_NEAREST" ));
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_NEAREST" ));
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_LINEAR" ));
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ DPF(( 0, "\tTexture MIN\tGL_LINEAR_MIPMAP_LINEAR" ));
+ break;
+ }
+ }
+ }
+
+ if ( ctx->Polygon.FrontMode != polyMode )
+ {
+ polyMode = ctx->Polygon.FrontMode;
+
+ switch( polyMode )
+ {
+ case GL_POINT:
+ DPF(( 0, "\tMode\t\tGL_POINT" ));
+ break;
+ case GL_LINE:
+ DPF(( 0, "\tMode\t\tGL_LINE" ));
+ break;
+ case GL_FILL:
+ DPF(( 0, "\tMode\t\tGL_FILL" ));
+ break;
+ }
+ }
+
+ if ( depthFunc != ctx->Depth.Func )
+ {
+ depthFunc = ctx->Depth.Func;
+
+ switch( depthFunc )
+ {
+ case GL_NEVER:
+ DPF(( 0, "\tDepth Func\tGL_NEVER" ));
+ break;
+ case GL_LESS:
+ DPF(( 0, "\tDepth Func\tGL_LESS" ));
+ break;
+ case GL_GEQUAL:
+ DPF(( 0, "\tDepth Func\tGL_GEQUAL" ));
+ break;
+ case GL_LEQUAL:
+ DPF(( 0, "\tDepth Func\tGL_LEQUAL" ));
+ break;
+ case GL_GREATER:
+ DPF(( 0, "\tDepth Func\tGL_GREATER" ));
+ break;
+ case GL_NOTEQUAL:
+ DPF(( 0, "\tDepth Func\tGL_NOTEQUAL" ));
+ break;
+ case GL_EQUAL:
+ DPF(( 0, "\tDepth Func\tGL_EQUAL" ));
+ break;
+ case GL_ALWAYS:
+ DPF(( 0, "\tDepth Func\tGL_ALWAYS" ));
+ break;
+ }
+ }
+
+ if ( depthMask != ctx->Depth.Mask )
+ {
+ depthMask = ctx->Depth.Mask;
+ DPF(( 0, "\tZWrite\t\t%s", (depthMask) ? "ENABLED" : "--------" ));
+ }
+
+ if ( alphaFunc != ctx->Color.AlphaFunc )
+ {
+ alphaFunc = ctx->Color.AlphaFunc;
+
+ switch( alphaFunc )
+ {
+ case GL_NEVER:
+ DPF(( 0, "\tAlpha Func\tGL_NEVER" ));
+ break;
+ case GL_LESS:
+ DPF(( 0, "\tAlpha Func\tGL_LESS" ));
+ break;
+ case GL_GEQUAL:
+ DPF(( 0, "\tAlpha Func\tGL_GEQUAL" ));
+ break;
+ case GL_LEQUAL:
+ DPF(( 0, "\tAlpha Func\tGL_LEQUAL" ));
+ break;
+ case GL_GREATER:
+ DPF(( 0, "\tAlpha Func\tGL_GREATER" ));
+ break;
+ case GL_NOTEQUAL:
+ DPF(( 0, "\tAlpha Func\tGL_NOTEQUAL" ));
+ break;
+ case GL_EQUAL:
+ DPF(( 0, "\tAlpha Func\tGL_EQUAL" ));
+ break;
+ case GL_ALWAYS:
+ DPF(( 0, "\tAlpha Func\tGL_ALWAYS" ));
+ break;
+ }
+ }
+
+ if ( blendSrc != ctx->Color.BlendSrc )
+ {
+ blendSrc = ctx->Color.BlendSrc;
+
+ switch( blendSrc )
+ {
+ case GL_ZERO:
+ DPF(( 0, "\tSRC Blend\tGL_ZERO" ));
+ break;
+ case GL_ONE:
+ DPF(( 0, "\tSRC Blend\tGL_ONE" ));
+ break;
+ case GL_DST_COLOR:
+ DPF(( 0, "\tSRC Blend\tGL_DST_COLOR" ));
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_DST_COLOR" ));
+ break;
+ case GL_SRC_ALPHA:
+ DPF(( 0, "\tSRC Blend\tGL_SRC_ALPHA" ));
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ DPF(( 0, "\tSRC Blend\tGL_MINUS_SRC_ALPHA" ));
+ break;
+ case GL_DST_ALPHA:
+ DPF(( 0, "\tSRC Blend\tGL_DST_ALPHA" ));
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_DST_ALPHA" ));
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ DPF(( 0, "\tSRC Blend\tGL_SRC_ALPHA_SATURATE" ));
+ break;
+ case GL_CONSTANT_COLOR:
+ DPF(( 0, "\tSRC Blend\tGL_CONSTANT_COLOR" ));
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_CONSTANT_COLOR" ));
+ break;
+ case GL_CONSTANT_ALPHA:
+ DPF(( 0, "\tSRC Blend\tGL_CONSTANT_ALPHA" ));
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ DPF(( 0, "\tSRC Blend\tGL_ONE_MINUS_CONSTANT_ALPHA" ));
+ break;
+ }
+ }
+
+ if ( blendDest != ctx->Color.BlendDst )
+ {
+ blendDest = ctx->Color.BlendDst;
+
+ switch( blendDest )
+ {
+ case GL_ZERO:
+ DPF(( 0, "\tDST Blend\tGL_ZERO" ));
+ break;
+ case GL_ONE:
+ DPF(( 0, "\tDST Blend\tGL_ONE" ));
+ break;
+ case GL_SRC_COLOR:
+ DPF(( 0, "\tDST Blend\tGL_SRC_COLOR" ));
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_SRC_COLOR" ));
+ break;
+ case GL_SRC_ALPHA:
+ DPF(( 0, "\tDST Blend\tGL_SRC_ALPHA" ));
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_SRC_ALPHA" ));
+ break;
+ case GL_DST_ALPHA:
+ DPF(( 0, "\tDST Blend\tGL_DST_ALPHA" ));
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_DST_ALPHA" ));
+ break;
+ case GL_CONSTANT_COLOR:
+ DPF(( 0, "\tDST Blend\tGL_CONSTANT_COLOR" ));
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_CONSTANT_COLOR" ));
+ break;
+ case GL_CONSTANT_ALPHA:
+ DPF(( 0, "\tDST Blend\tGL_CONSTANT_ALPHA" ));
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ DPF(( 0, "\tDST Blend\tGL_ONE_MINUS_CONSTANT_ALPHA" ));
+ break;
+ }
+ }
+}
+