void gld_NEW_DEPTH( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZENABLE, ctx->Depth.Test ? D3DZB_TRUE : D3DZB_FALSE)); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZFUNC, _gldConvertCompareFunc(ctx->Depth.Func))); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZWRITEENABLE, ctx->Depth.Mask ? TRUE : FALSE)); }
void gld_NEW_FOG( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); D3DCOLOR d3dFogColour; D3DFOGMODE d3dFogMode = D3DFOG_LINEAR; // TODO: Fog is calculated seperately in the Mesa pipeline _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGENABLE, FALSE)); return; // Fog enable _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGENABLE, ctx->Fog.Enabled)); if (!ctx->Fog.Enabled) { _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE)); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE)); return; // If disabled, don't bother setting any fog state } // Fog colour d3dFogColour = D3DCOLOR_COLORVALUE( ctx->Fog.Color[0], ctx->Fog.Color[1], ctx->Fog.Color[2], ctx->Fog.Color[3]); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGCOLOR, d3dFogColour)); // Fog density _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGDENSITY, *((DWORD*) (&ctx->Fog.Density)))); // Fog start _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGSTART, *((DWORD*) (&ctx->Fog.Start)))); // Fog end _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGEND, *((DWORD*) (&ctx->Fog.End)))); // Fog mode switch (ctx->Fog.Mode) { case GL_LINEAR: d3dFogMode = D3DFOG_LINEAR; break; case GL_EXP: d3dFogMode = D3DFOG_EXP; break; case GL_EXP2: d3dFogMode = D3DFOG_EXP2; break; } _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGTABLEMODE, d3dFogMode)); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE)); }
void gld_Viewport_DX7( struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); D3DVIEWPORT7 d3dvp; if (!gld || !gld->pDev) return; // This is a hack. When the app is minimized, Mesa passes // w=1 and h=1 for viewport dimensions. Without this test // we get a GPF in gld_wgl_resize_buffers(). if ((w==1) && (h==1)) return; // Call ResizeBuffersMESA. This function will early-out // if no resize is needed. //ctx->Driver.ResizeBuffersMESA(ctx); // Mesa 5: Changed parameters ctx->Driver.ResizeBuffers(gldCtx->glBuffer); #if 0 ddlogPrintf(GLDLOG_SYSTEM, ">> Viewport x=%d y=%d w=%d h=%d", x,y,w,h); #endif // ** D3D viewport must not be outside the render target surface ** // Sanity check the GL viewport dimensions if (x < 0) x = 0; if (y < 0) y = 0; if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; // Ditto for D3D viewport dimensions if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; d3dvp.dwX = x; d3dvp.dwY = gldCtx->dwHeight - (y + h); d3dvp.dwWidth = w; d3dvp.dwHeight = h; if (ctx->Viewport.Near <= ctx->Viewport.Far) { d3dvp.dvMinZ = ctx->Viewport.Near; d3dvp.dvMaxZ = ctx->Viewport.Far; } else { d3dvp.dvMinZ = ctx->Viewport.Far; d3dvp.dvMaxZ = ctx->Viewport.Near; } // TODO: DEBUGGING // d3dvp.MinZ = 0.0f; // d3dvp.MaxZ = 1.0f; _GLD_DX7_DEV(SetViewport(gld->pDev, &d3dvp)); }
void gld_NEW_LIGHT( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); DWORD dwSpecularEnable; // Shademode _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SHADEMODE, (ctx->Light.ShadeModel == GL_SMOOTH) ? D3DSHADE_GOURAUD : D3DSHADE_FLAT)); // Separate specular colour if (ctx->Light.Enabled) dwSpecularEnable = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TRUE: FALSE; else dwSpecularEnable = FALSE; _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SPECULARENABLE, dwSpecularEnable)); }
void gld_NEW_COLOR( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); DWORD dwFlags = 0; D3DBLEND src; D3DBLEND dest; // Alpha func _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAFUNC, _gldConvertCompareFunc(ctx->Color.AlphaFunc))); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAREF, (DWORD)ctx->Color.AlphaRef)); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHATESTENABLE, ctx->Color.AlphaEnabled)); // Blend func _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHABLENDENABLE, ctx->Color.BlendEnabled)); src = _gldConvertBlendFunc(ctx->Color.BlendSrcRGB, GL_ONE); dest = _gldConvertBlendFunc(ctx->Color.BlendDstRGB, GL_ZERO); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SRCBLEND, src)); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_DESTBLEND, dest)); /* // Color mask - unsupported by DX7 if (ctx->Color.ColorMask[0][0]) dwFlags |= D3DCOLORWRITEENABLE_RED; if (ctx->Color.ColorMask[0][1]) dwFlags |= D3DCOLORWRITEENABLE_GREEN; if (ctx->Color.ColorMask[0][2]) dwFlags |= D3DCOLORWRITEENABLE_BLUE; if (ctx->Color.ColorMask[0][3]) dwFlags |= D3DCOLORWRITEENABLE_ALPHA; _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_COLORWRITEENABLE, dwFlags)); */ }
void gld_NEW_VIEWPORT( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); D3DVIEWPORT7 d3dvp; // GLint x, y; // GLsizei w, h; // Set depth range _GLD_DX7_DEV(GetViewport(gld->pDev, &d3dvp)); // D3D can't do Quake1/Quake2 z-trick if (ctx->Viewport.Near <= ctx->Viewport.Far) { d3dvp.dvMinZ = ctx->Viewport.Near; d3dvp.dvMaxZ = ctx->Viewport.Far; } else { d3dvp.dvMinZ = ctx->Viewport.Far; d3dvp.dvMaxZ = ctx->Viewport.Near; } /* x = ctx->Viewport.X; y = ctx->Viewport.Y; w = ctx->Viewport.Width; h = ctx->Viewport.Height; if (x < 0) x = 0; if (y < 0) y = 0; if (w > gldCtx->dwWidth) w = gldCtx->dwWidth; if (h > gldCtx->dwHeight) h = gldCtx->dwHeight; // Ditto for D3D viewport dimensions if (w+x > gldCtx->dwWidth) w = gldCtx->dwWidth-x; if (h+y > gldCtx->dwHeight) h = gldCtx->dwHeight-y; d3dvp.X = x; d3dvp.Y = gldCtx->dwHeight - (y + h); d3dvp.Width = w; d3dvp.Height = h;*/ _GLD_DX7_DEV(SetViewport(gld->pDev, &d3dvp)); // gld->fFlipWindowY = (float)gldCtx->dwHeight; }
void gld_NEW_STENCIL( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); // Two-sided stencil. New for Mesa 5 const GLuint uiFace = 0UL; struct gl_stencil_attrib *pStencil = &ctx->Stencil; _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILENABLE, pStencil->Enabled ? TRUE : FALSE)); if (pStencil->Enabled) { _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILFUNC, _gldConvertCompareFunc(pStencil->Function[uiFace]))); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILREF, pStencil->Ref[uiFace])); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILMASK, pStencil->ValueMask[uiFace])); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILWRITEMASK, pStencil->WriteMask[uiFace])); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILFAIL, _gldConvertStencilOp(pStencil->FailFunc[uiFace]))); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILZFAIL, _gldConvertStencilOp(pStencil->ZFailFunc[uiFace]))); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_STENCILPASS, _gldConvertStencilOp(pStencil->ZPassFunc[uiFace]))); } }
void gld_update_state_DX7( struct gl_context *ctx, GLuint new_state) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); TNLcontext *tnl = TNL_CONTEXT(ctx); GLD_pb_dx7 *gldPB; if (!gld || !gld->pDev) return; _swsetup_InvalidateState( ctx, new_state ); _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); // SetupIndex will be used in the pipelines for choosing setup function if ((ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_SEPARATE_SPECULAR)) || (ctx->Fog.Enabled)) { if (ctx->_TriangleCaps & DD_FLATSHADE) gld->iSetupFunc = GLD_SI_FLAT_EXTRAS; else gld->iSetupFunc = GLD_SI_SMOOTH_EXTRAS; } else { if (ctx->_TriangleCaps & DD_FLATSHADE) gld->iSetupFunc = GLD_SI_FLAT; // Setup flat shade + texture else gld->iSetupFunc = GLD_SI_SMOOTH; // Setup smooth shade + texture } gld->bUseMesaTnL = _gldChooseInternalPipeline(ctx, gld); if (gld->bUseMesaTnL) { gldPB = &gld->PB2d; // DX7 Does not implement D3DRS_SOFTWAREVERTEXPROCESSING // _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SOFTWAREVERTEXPROCESSING, TRUE)); _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_CLIPPING, FALSE)); // _GLD_DX7_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); } else { gldPB = &gld->PB3d; _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_CLIPPING, TRUE)); // if (gld->TnLPipeline == GLD_PIPELINE_D3D_VS_TWOSIDE) { // _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SOFTWAREVERTEXPROCESSING, !gld->VStwosidelight.bHardware)); // _GLD_DX7_DEV(SetVertexShader(gld->pDev, gld->VStwosidelight.hShader)); // } else { // DX7 Does not implement D3DRS_SOFTWAREVERTEXPROCESSING // _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_SOFTWAREVERTEXPROCESSING, !gld->bHasHWTnL)); // _GLD_DX7_DEV(SetVertexShader(gld->pDev, gldPB->dwFVF)); // } } #define _GLD_TEST_STATE(a) \ if (new_state & (a)) { \ gld##a(ctx); \ new_state &= ~(a); \ } #define _GLD_TEST_STATE_DX7(a) \ if (new_state & (a)) { \ gld##a##_DX7(ctx); \ new_state &= ~(a); \ } #define _GLD_IGNORE_STATE(a) new_state &= ~(a); // if (!gld->bUseMesaTnL) { // Not required if Mesa is doing the TnL. // Problem: If gld->bUseMesaTnL is TRUE when these are signaled, // then we'll miss updating the D3D TnL pipeline. // Therefore, don't test for gld->bUseMesaTnL _GLD_TEST_STATE(_NEW_MODELVIEW); _GLD_TEST_STATE(_NEW_PROJECTION); // } _GLD_TEST_STATE_DX7(_NEW_TEXTURE); // extern, so guard with _DX7 _GLD_TEST_STATE(_NEW_COLOR); _GLD_TEST_STATE(_NEW_DEPTH); _GLD_TEST_STATE(_NEW_POLYGON); _GLD_TEST_STATE(_NEW_STENCIL); _GLD_TEST_STATE(_NEW_FOG); _GLD_TEST_STATE(_NEW_LIGHT); _GLD_TEST_STATE(_NEW_VIEWPORT); _GLD_IGNORE_STATE(_NEW_TRANSFORM); // Stubs for future use. /* _GLD_TEST_STATE(_NEW_TEXTURE_MATRIX); _GLD_TEST_STATE(_NEW_COLOR_MATRIX); _GLD_TEST_STATE(_NEW_EVAL); _GLD_TEST_STATE(_NEW_HINT); _GLD_TEST_STATE(_NEW_LINE); _GLD_TEST_STATE(_NEW_PIXEL); _GLD_TEST_STATE(_NEW_POINT); _GLD_TEST_STATE(_NEW_POLYGONSTIPPLE); _GLD_TEST_STATE(_NEW_SCISSOR); _GLD_TEST_STATE(_NEW_PACKUNPACK); _GLD_TEST_STATE(_NEW_ARRAY); _GLD_TEST_STATE(_NEW_RENDERMODE); _GLD_TEST_STATE(_NEW_BUFFERS); _GLD_TEST_STATE(_NEW_MULTISAMPLE); */ // For debugging. #if 0 #define _GLD_TEST_UNHANDLED_STATE(a) \ if (new_state & (a)) { \ gldLogMessage(GLDLOG_ERROR, "Unhandled " #a "\n"); \ } _GLD_TEST_UNHANDLED_STATE(_NEW_TEXTURE_MATRIX); _GLD_TEST_UNHANDLED_STATE(_NEW_COLOR_MATRIX); _GLD_TEST_UNHANDLED_STATE(_NEW_EVAL); _GLD_TEST_UNHANDLED_STATE(_NEW_HINT); _GLD_TEST_UNHANDLED_STATE(_NEW_LINE); _GLD_TEST_UNHANDLED_STATE(_NEW_PIXEL); _GLD_TEST_UNHANDLED_STATE(_NEW_POINT); _GLD_TEST_UNHANDLED_STATE(_NEW_POLYGONSTIPPLE); _GLD_TEST_UNHANDLED_STATE(_NEW_SCISSOR); _GLD_TEST_UNHANDLED_STATE(_NEW_PACKUNPACK); _GLD_TEST_UNHANDLED_STATE(_NEW_ARRAY); _GLD_TEST_UNHANDLED_STATE(_NEW_RENDERMODE); _GLD_TEST_UNHANDLED_STATE(_NEW_BUFFERS); _GLD_TEST_UNHANDLED_STATE(_NEW_MULTISAMPLE); #undef _GLD_UNHANDLED_STATE #endif #undef _GLD_TEST_STATE }
void gld_NEW_POLYGON( struct gl_context *ctx) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); D3DFILLMODE d3dFillMode = D3DFILL_SOLID; D3DCULL d3dCullMode = D3DCULL_NONE; int iOffset = 0; // Fillmode switch (ctx->Polygon.FrontMode) { case GL_POINT: d3dFillMode = D3DFILL_POINT; break; case GL_LINE: d3dFillMode = D3DFILL_WIREFRAME; break; case GL_FILL: d3dFillMode = D3DFILL_SOLID; break; } _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_FILLMODE, d3dFillMode)); if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_BACK: if (ctx->Polygon.FrontFace == GL_CCW) d3dCullMode = D3DCULL_CW; else d3dCullMode = D3DCULL_CCW; break; case GL_FRONT: if (ctx->Polygon.FrontFace == GL_CCW) d3dCullMode = D3DCULL_CCW; else d3dCullMode = D3DCULL_CW; break; case GL_FRONT_AND_BACK: d3dCullMode = D3DCULL_NONE; break; default: break; } } else { d3dCullMode = D3DCULL_NONE; } // d3dCullMode = D3DCULL_NONE; // TODO: DEBUGGING _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_CULLMODE, d3dCullMode)); // Polygon offset // ZBIAS ranges from 0 to 16 and can only move towards the viewer // Mesa5: ctx->Polygon._OffsetAny removed if (ctx->Polygon.OffsetFill) { iOffset = (int)ctx->Polygon.OffsetUnits; if (iOffset < 0) iOffset = -iOffset; else iOffset = 0; // D3D can't push away } _GLD_DX7_DEV(SetRenderState(gld->pDev, D3DRENDERSTATE_ZBIAS, iOffset)); }
void gld_Clear_DX7( struct gl_context *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); DWORD dwFlags = 0; D3DCOLOR Color = 0; float Z = 0.0f; DWORD Stencil = 0; D3DRECT d3dClearRect; // TODO: Colourmask const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask[0]; if (!gld->pDev) return; if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { GLubyte col[4]; CLAMPED_FLOAT_TO_UBYTE(col[0], ctx->Color.ClearColor[0]); CLAMPED_FLOAT_TO_UBYTE(col[1], ctx->Color.ClearColor[1]); CLAMPED_FLOAT_TO_UBYTE(col[2], ctx->Color.ClearColor[2]); CLAMPED_FLOAT_TO_UBYTE(col[3], ctx->Color.ClearColor[3]); dwFlags |= D3DCLEAR_TARGET; Color = D3DCOLOR_RGBA(col[0], col[1], col[2], col[3]); // ctx->Color.ClearColor[1], // ctx->Color.ClearColor[2], // ctx->Color.ClearColor[3]); } if (mask & DD_DEPTH_BIT) { // D3D7 will fail the Clear call if we try and clear a // depth buffer and we haven't created one. // Also, some apps try and clear a depth buffer, // when a depth buffer hasn't been requested by the app. if (ctx->Visual.depthBits == 0) { mask &= ~DD_DEPTH_BIT; // Remove depth bit from mask } else { dwFlags |= D3DCLEAR_ZBUFFER; Z = ctx->Depth.Clear; } } if (mask & DD_STENCIL_BIT) { if (ctx->Visual.stencilBits == 0) { // No stencil bits in depth buffer mask &= ~DD_STENCIL_BIT; // Remove stencil bit from mask } else { dwFlags |= D3DCLEAR_STENCIL; Stencil = ctx->Stencil.Clear; } } // Some apps do really weird things with the rect, such as Quake3. if ((x < 0) || (y < 0) || (width <= 0) || (height <= 0)) { all = GL_TRUE; } if (!all) { // Calculate clear subrect d3dClearRect.x1 = x; d3dClearRect.y1 = gldCtx->dwHeight - (y + height); d3dClearRect.x2 = x + width; d3dClearRect.y2 = d3dClearRect.y1 + height; } // dwFlags will be zero if there's nothing to clear if (dwFlags) { _GLD_DX7_DEV(Clear( gld->pDev, all ? 0 : 1, all ? NULL : &d3dClearRect, dwFlags, Color, Z, Stencil)); } if (mask & DD_ACCUM_BIT) { // Clear accumulation buffer } }
static GLboolean _gld_mesa_render_stage_run( GLcontext *ctx, struct tnl_pipeline_stage *stage) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_render_func *tab; GLint pass = 0; GLD_pb_dx7 *gldPB; DWORD dwFlags; /* Allow the drivers to lock before projected verts are built so * that window coordinates are guarenteed not to change before * rendering. */ ASSERT(tnl->Driver.Render.Start); tnl->Driver.Render.Start( ctx ); gldPB = &gld->PB2d; tnl->Driver.Render.Points = _gldSetupPoints[gld->iSetupFunc]; tnl->Driver.Render.Line = _gldSetupLine[gld->iSetupFunc]; tnl->Driver.Render.Triangle = _gldSetupTriangle[gld->iSetupFunc]; tnl->Driver.Render.Quad = _gldSetupQuad[gld->iSetupFunc]; dwFlags = DDLOCK_DISCARDCONTENTS | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY; _GLD_DX7_VB(Lock(gldPB->pVB, dwFlags, &gldPB->pPoints, NULL)); gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; // Allocate primitive pointers - gldPB->pPoints is always first gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); ASSERT(tnl->Driver.Render.BuildVertices); ASSERT(tnl->Driver.Render.PrimitiveNotify); ASSERT(tnl->Driver.Render.Points); ASSERT(tnl->Driver.Render.Line); ASSERT(tnl->Driver.Render.Triangle); ASSERT(tnl->Driver.Render.Quad); ASSERT(tnl->Driver.Render.ResetLineStipple); ASSERT(tnl->Driver.Render.Interp); ASSERT(tnl->Driver.Render.CopyPV); ASSERT(tnl->Driver.Render.ClippedLine); ASSERT(tnl->Driver.Render.ClippedPolygon); ASSERT(tnl->Driver.Render.Finish); tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); if (VB->ClipOrMask) { tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; } else { tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); } do { GLuint i, length, flags = 0; for (i = 0 ; !(flags & PRIM_END) ; i += length) { flags = VB->Primitive[i].mode; length= VB->Primitive[i].count; ASSERT(length || (flags & PRIM_END)); ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); if (length) tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); } } while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass( ctx, ++pass )); // tnl->Driver.Render.Finish( ctx ); _GLD_DX7_VB(Unlock(gldPB->pVB)); if (gldPB->nPoints) { _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_POINTLIST, gldPB->pVB, 0, gldPB->nPoints, 0)); gldPB->nPoints = 0; } if (gldPB->nLines) { _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_LINELIST, gldPB->pVB, gldPB->iFirstLine, gldPB->nLines*2, 0)); gldPB->nLines = 0; } if (gldPB->nTriangles) { _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_TRIANGLELIST, gldPB->pVB, gldPB->iFirstTriangle, gldPB->nTriangles*3, 0)); gldPB->nTriangles = 0; } return GL_FALSE; /* finished the pipe */ }
static GLboolean gld_d3d_render_stage_run( GLcontext *ctx, struct tnl_pipeline_stage *stage) { GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx); TNLcontext *tnl; struct vertex_buffer *VB; tnl_render_func *tab; GLint pass; GLD_pb_dx7 *gldPB = &gld->PB3d; DWORD dwFlags; /* static int count = 0; count++; if (count != 2) return GL_FALSE; */ // The "check" function should disable this stage, // but we'll test gld->bUseMesaTnL anyway. if (gld->bUseMesaTnL) { // Do nothing in this stage, but continue pipeline return GL_TRUE; } tnl = TNL_CONTEXT(ctx); VB = &tnl->vb; pass = 0; tnl->Driver.Render.Start( ctx ); #if 0 // For debugging: Useful to see if an app passes colour data in // an unusual format. switch (VB->AttribPtr[_TNL_ATTRIB_COLOR0]->Type) { case GL_FLOAT: ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_FLOAT\n"); break; case GL_UNSIGNED_BYTE: ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: GL_UNSIGNED_BYTE\n"); break; default: ddlogMessage(GLDLOG_SYSTEM, "ColorPtr: *?*\n"); break; } #endif tnl->Driver.Render.Points = gld_Points3D_DX7; if (ctx->_TriangleCaps & DD_FLATSHADE) { tnl->Driver.Render.Line = gld_Line3DFlat_DX7; tnl->Driver.Render.Triangle = gld_Triangle3DFlat_DX7; tnl->Driver.Render.Quad = gld_Quad3DFlat_DX7; } else { tnl->Driver.Render.Line = gld_Line3DSmooth_DX7; tnl->Driver.Render.Triangle = gld_Triangle3DSmooth_DX7; tnl->Driver.Render.Quad = gld_Quad3DSmooth_DX7; } // _GLD_DX7_VB(Lock(gldPB->pVB, 0, 0, &gldPB->pPoints, D3DLOCK_DISCARD)); dwFlags = DDLOCK_DISCARDCONTENTS | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY; _GLD_DX7_VB(Lock(gldPB->pVB, dwFlags, &gldPB->pPoints, NULL)); gldPB->nPoints = gldPB->nLines = gldPB->nTriangles = 0; // Allocate primitive pointers // gldPB->pPoints is always first gldPB->pLines = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstLine); gldPB->pTriangles = gldPB->pPoints + (gldPB->dwStride * gldPB->iFirstTriangle); ASSERT(tnl->Driver.Render.BuildVertices); ASSERT(tnl->Driver.Render.PrimitiveNotify); ASSERT(tnl->Driver.Render.Points); ASSERT(tnl->Driver.Render.Line); ASSERT(tnl->Driver.Render.Triangle); ASSERT(tnl->Driver.Render.Quad); ASSERT(tnl->Driver.Render.ResetLineStipple); ASSERT(tnl->Driver.Render.Interp); ASSERT(tnl->Driver.Render.CopyPV); ASSERT(tnl->Driver.Render.ClippedLine); ASSERT(tnl->Driver.Render.ClippedPolygon); ASSERT(tnl->Driver.Render.Finish); tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); do { GLuint i, length, flags = 0; for (i = 0 ; !(flags & PRIM_END) ; i += length) { flags = VB->Primitive[i].mode; length= VB->Primitive[i].count; ASSERT(length || (flags & PRIM_END)); ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); if (length) tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); } } while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass( ctx, ++pass )); _GLD_DX7_VB(Unlock(gldPB->pVB)); // _GLD_DX7_DEV(SetStreamSource(gld->pDev, 0, gldPB->pVB, gldPB->dwStride)); _GLD_DX7_DEV(SetTransform(gld->pDev, D3DTRANSFORMSTATE_PROJECTION, &gld->matProjection)); _GLD_DX7_DEV(SetTransform(gld->pDev, D3DTRANSFORMSTATE_WORLD, &gld->matModelView)); if (gldPB->nPoints) { // _GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_POINTLIST, 0, gldPB->nPoints)); _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_POINTLIST, gldPB->pVB, 0, gldPB->nPoints, 0)); gldPB->nPoints = 0; } if (gldPB->nLines) { // _GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_LINELIST, gldPB->iFirstLine, gldPB->nLines)); _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_LINELIST, gldPB->pVB, gldPB->iFirstLine, gldPB->nLines, 0)); gldPB->nLines = 0; } if (gldPB->nTriangles) { // _GLD_DX7_DEV(DrawPrimitive(gld->pDev, D3DPT_TRIANGLELIST, gldPB->iFirstTriangle, gldPB->nTriangles)); _GLD_DX7_DEV(DrawPrimitiveVB(gld->pDev, D3DPT_TRIANGLELIST, gldPB->pVB, gldPB->iFirstTriangle, gldPB->nTriangles, 0)); gldPB->nTriangles = 0; } return GL_FALSE; /* finished the pipe */ }