📄 ffb_state.c
字号:
zmin = ((GLdouble)ctx->Viewport.Near * 0x0fffffff); zmax = ((GLdouble)ctx->Viewport.Far * 0x0fffffff); vcmin = ((ymin & 0xffff) << 16) | (xmin & 0xffff); vcmax = ((ymax & 0xffff) << 16) | (xmax & 0xffff); if (fmesa->vclipmin != vcmin || fmesa->vclipmax != vcmax || fmesa->vclipzmin != zmin || fmesa->vclipzmax != zmax) { fmesa->vclipmin = vcmin; fmesa->vclipmax = vcmax; fmesa->vclipzmin = zmin; fmesa->vclipzmax = zmax; FFB_MAKE_DIRTY(fmesa, FFB_STATE_CLIP, (4 + (4 * 2))); }}void ffbCalcViewport(GLcontext *ctx){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = fmesa->hw_viewport; __DRIdrawablePrivate *dPriv = fmesa->driDrawable; m[MAT_SX] = v[MAT_SX]; m[MAT_TX] = v[MAT_TX] + dPriv->x + SUBPIXEL_X; m[MAT_SY] = - v[MAT_SY]; m[MAT_TY] = - v[MAT_TY] + dPriv->h + dPriv->y + SUBPIXEL_Y; m[MAT_SZ] = v[MAT_SZ] * ((GLdouble)1.0 / (GLdouble)0x0fffffff); m[MAT_TZ] = v[MAT_TZ] * ((GLdouble)1.0 / (GLdouble)0x0fffffff); fmesa->depth_scale = ((GLdouble)1.0 / (GLdouble)0x0fffffff); ffbCalcViewportRegs(ctx); fmesa->setupnewinputs |= VERT_BIT_POS;}static void ffbDDViewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height){ ffbCalcViewport(ctx);}static void ffbDDDepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval){ ffbCalcViewport(ctx);}static void ffbDDScissor(GLcontext *ctx, GLint cx, GLint cy, GLsizei cw, GLsizei ch){ ffbCalcViewport(ctx);}static void ffbDDDrawBuffer(GLcontext *ctx, GLenum buffer){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); unsigned int fbc = fmesa->fbc;#ifdef STATE_TRACE fprintf(stderr, "ffbDDDrawBuffer: mode(%s)\n", _mesa_lookup_enum_by_nr(buffer));#endif fbc &= ~(FFB_FBC_WB_AB | FFB_FBC_RB_MASK); switch (buffer) { case GL_FRONT: if (fmesa->back_buffer == 0) fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B; else fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A; break; case GL_BACK: if (fmesa->back_buffer == 0) fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A; else fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B; break; case GL_FRONT_AND_BACK: fbc |= FFB_FBC_WB_AB; break; default: return; }; if (fbc != fmesa->fbc) { fmesa->fbc = fbc; FFB_MAKE_DIRTY(fmesa, FFB_STATE_FBC, 1); }}static void ffbDDReadBuffer(GLcontext *ctx, GLenum buffer){ /* no-op, unless you implement h/w glRead/CopyPixels */}/* * Specifies buffer for sw fallbacks (spans) */#if 000/* XXX * This function is obsolete. It's not clear how this really effected * span reading/writing above. The span functions should use the * incoming driRenderbuffer (gl_renderbuffer) pointer to determine how * to read from the specified bufer. */static void ffbDDSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); unsigned int fbc = fmesa->fbc;#ifdef STATE_TRACE fprintf(stderr, "ffbDDSetReadBuffer: mode(%s)\n", _mesa_lookup_enum_by_nr(buffer));#endif fbc &= ~(FFB_FBC_RB_MASK); switch (bufferBit) { case BUFFER_BIT_FRONT_LEFT: if (fmesa->back_buffer == 0) fbc |= FFB_FBC_RB_B; else fbc |= FFB_FBC_RB_A; break; case BUFFER_BIT_BACK_LEFT: if (fmesa->back_buffer == 0) fbc |= FFB_FBC_RB_A; else fbc |= FFB_FBC_RB_B; break; default: _mesa_problem(ctx, "Unexpected buffer in ffbDDSetBuffer()"); return; }; if (fbc != fmesa->fbc) { fmesa->fbc = fbc; FFB_MAKE_DIRTY(fmesa, FFB_STATE_FBC, 1); }}#endifstatic void ffbDDClearColor(GLcontext *ctx, const GLfloat color[4]){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); GLubyte c[4]; CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); fmesa->clear_pixel = ((c[0] << 0) | (c[1] << 8) | (c[2] << 16));}static void ffbDDClearDepth(GLcontext *ctx, GLclampd depth){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); fmesa->clear_depth = Z_FROM_MESA(depth * 4294967295.0f);}static void ffbDDClearStencil(GLcontext *ctx, GLint stencil){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); fmesa->clear_stencil = stencil & 0xf;}/* XXX Actually, should I be using FBC controls for this? -DaveM */static void ffbDDColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); unsigned int new_pmask = 0x0;#ifdef STATE_TRACE fprintf(stderr, "ffbDDColorMask: r(%d) g(%d) b(%d) a(%d)\n", r, g, b, a);#endif if (r) new_pmask |= 0x000000ff; if (g) new_pmask |= 0x0000ff00; if (b) new_pmask |= 0x00ff0000; if (a) new_pmask |= 0xff000000; if (fmesa->pmask != new_pmask) { fmesa->pmask = new_pmask; FFB_MAKE_DIRTY(fmesa, FFB_STATE_PMASK, 1); }}static void ffbDDLogicOp(GLcontext *ctx, GLenum op){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); unsigned int rop;#ifdef STATE_TRACE fprintf(stderr, "ffbDDLogicOp: op(%s)\n", _mesa_lookup_enum_by_nr(op));#endif switch (op) { case GL_CLEAR: rop = FFB_ROP_ZERO; break; case GL_SET: rop = FFB_ROP_ONES; break; case GL_COPY: rop = FFB_ROP_NEW; break; case GL_AND: rop = FFB_ROP_NEW_AND_OLD; break; case GL_NAND: rop = FFB_ROP_NEW_AND_NOLD; break; case GL_OR: rop = FFB_ROP_NEW_OR_OLD; break; case GL_NOR: rop = FFB_ROP_NEW_OR_NOLD; break; case GL_XOR: rop = FFB_ROP_NEW_XOR_OLD; break; case GL_NOOP: rop = FFB_ROP_OLD; break; case GL_COPY_INVERTED: rop = FFB_ROP_NNEW; break; case GL_INVERT: rop = FFB_ROP_NOLD; break; case GL_EQUIV: rop = FFB_ROP_NNEW_XOR_NOLD; break; case GL_AND_REVERSE: rop = FFB_ROP_NEW_AND_NOLD; break; case GL_AND_INVERTED: rop = FFB_ROP_NNEW_AND_OLD; break; case GL_OR_REVERSE: rop = FFB_ROP_NEW_OR_NOLD; break; case GL_OR_INVERTED: rop = FFB_ROP_NNEW_OR_OLD; break; default: return; }; rop |= fmesa->rop & ~0xff; if (rop != fmesa->rop) { fmesa->rop = rop; FFB_MAKE_DIRTY(fmesa, FFB_STATE_ROP, 1); if (op == GL_COPY) FALLBACK( ctx, FFB_BADATTR_BLENDROP, GL_FALSE ); }}#if 0/* XXX Also need to track near/far just like 3dfx driver. * XXX * XXX Actually, that won't work, because the 3dfx chip works by * XXX having 1/w coordinates fed to it for each primitive, and * XXX it uses this to index it's 64 entry fog table. */static void ffb_fog_linear(GLcontext *ctx, ffbContextPtr fmesa){ GLfloat c = ctx->ProjectionMatrix.m[10]; GLfloat d = ctx->ProjectionMatrix.m[14]; GLfloat tz = ctx->Viewport.WindowMap.m[MAT_TZ]; GLfloat szInv = 1.0F / ctx->Viewport.WindowMap.m[MAT_SZ]; GLfloat fogEnd = ctx->Fog.End; GLfloat fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start); GLfloat ndcz; GLfloat eyez; GLfloat Zzero, Zone; unsigned int zb, zf; /* Compute the Z at which f reaches 0.0, this is the full * saturation point. * * Thus compute Z (as seen by the chip during rendering), * such that: * * 0.0 = (fogEnd - eyez) * fogScale * * fogScale is usually not zero, thus we are looking for: * * fogEnd = eyez * * fogEnd = -d / (c + ((Z - tz) * szInv)) * fogEnd * (c + ((Z - tz) * szInv)) = -d * (c + ((Z - tz) * szInv)) = -d / fogEnd * (Z - tz) * szInv = (-d / fogEnd) - c * (Z - tz) = ((-d / fogEnd) - c) / szInv * Z = (((-d / fogEnd) - c) / szInv) + tz */ Zzero = (((-d / fogEnd) - c) / szInv) + tz; /* Compute the Z at which f reaches 1.0, this is where * the incoming frag's full intensity is shown. This * equation is: * * 1.0 = (fogEnd - eyez) * * We are looking for: * * 1.0 + eyez = fogEnd * * 1.0 + (-d / (c + ((Z - tz) * szInv))) = fogEnd * -d / (c + ((Z - tz) * szInv)) = fogEnd - 1.0 * -d / (FogEnd - 1.0) = (c + ((Z - tz) * szInv)) * (-d / (fogEnd - 1.0)) - c = ((Z - tz) * szInv) * ((-d / (fogEnd - 1.0)) - c) / szInv = (Z - tz) * (((-d / (fogEnd - 1.0)) - c) / szInv) + tz = Z */ Zone = (((-d / (fogEnd - 1.0)) - c) / szInv) + tz; /* FFB's Zfront must be less than Zback, thus we may have * to invert Sf/Sb to satisfy this constraint. */ if (Zzero < Zone) { sf = 0.0; sb = 1.0; zf = Z_FROM_MESA(Zzero); zb = Z_FROM_MESA(Zone); } else { sf = 1.0; sb = 0.0; zf = Z_FROM_MESA(Zone); zb = Z_FROM_MESA(Zzero); }}#endifstatic void ffbDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param){#ifdef STATE_TRACE fprintf(stderr, "ffbDDFogfv: pname(%s)\n", _mesa_lookup_enum_by_nr(pname));#endif}static void ffbDDLineStipple(GLcontext *ctx, GLint factor, GLushort pattern){ ffbContextPtr fmesa = FFB_CONTEXT(ctx);#ifdef STATE_TRACE fprintf(stderr, "ffbDDLineStipple: factor(%d) pattern(%04x)\n", factor, pattern);#endif if (ctx->Line.StippleFlag) { factor = ctx->Line.StippleFactor; pattern = ctx->Line.StipplePattern; if ((GLuint) factor > 15) { fmesa->lpat = FFB_LPAT_BAD; } else { fmesa->lpat = ((factor << FFB_LPAT_SCALEVAL_SHIFT) | (0 << FFB_LPAT_PATLEN_SHIFT) | ((pattern & 0xffff) << FFB_LPAT_PATTERN_SHIFT)); } } else { fmesa->lpat = 0; }}void ffbXformAreaPattern(ffbContextPtr fmesa, const GLubyte *mask){ __DRIdrawablePrivate *dPriv = fmesa->driDrawable; int i, lines, xoff; lines = 0; i = (dPriv->y + dPriv->h) & (32 - 1); xoff = dPriv->x & (32 - 1); while (lines++ < 32) { GLuint raw = (((GLuint)mask[0] << 24) | ((GLuint)mask[1] << 16) | ((GLuint)mask[2] << 8) | ((GLuint)mask[3] << 0)); fmesa->pattern[i] = (raw << xoff) | (raw >> (32 - xoff)); i = (i - 1) & (32 - 1); mask += 4; } FFB_MAKE_DIRTY(fmesa, FFB_STATE_APAT, 32);}static void ffbDDPolygonStipple(GLcontext *ctx, const GLubyte *mask){ ffbContextPtr fmesa = FFB_CONTEXT(ctx);#ifdef STATE_TRACE fprintf(stderr, "ffbDDPolygonStipple: state(%d)\n", ctx->Polygon.StippleFlag);#endif ffbXformAreaPattern(fmesa, mask);}static void ffbDDEnable(GLcontext *ctx, GLenum cap, GLboolean state){ ffbContextPtr fmesa = FFB_CONTEXT(ctx); unsigned int tmp;#ifdef STATE_TRACE fprintf(stderr, "ffbDDEnable: %s state(%d)\n", _mesa_lookup_enum_by_nr(cap), state);#endif switch (cap) { case GL_ALPHA_TEST: if (state) tmp = ffbComputeAlphaFunc(ctx); else tmp = FFB_XCLIP_TEST_ALWAYS; if (tmp != fmesa->xclip) { fmesa->xclip = tmp; FFB_MAKE_DIRTY(fmesa, FFB_STATE_XCLIP, 1); } break; case GL_BLEND:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -