-/* $Id: s_aatriangle.c,v 1.15 2001/05/15 16:18:13 brianp Exp $ */
+/* $Id: s_aatriangle.c,v 1.23 2002/03/16 18:02:07 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*/
+#include "macros.h"
+#include "mem.h"
#include "mmath.h"
#include "s_aatriangle.h"
#include "s_context.h"
/*
* Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
* vertices and the given Z values.
+ * A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
*/
static INLINE void
compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
const GLfloat qy = v2[1] - v0[1];
const GLfloat qz = z2 - z0;
+ /* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
const GLfloat a = py * qz - pz * qy;
const GLfloat b = pz * qx - px * qz;
const GLfloat c = px * qy - py * qx;
+ /* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
+ on the distance of plane from origin and arbitrary "w" parallel
+ to the plane. */
+ /* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
+ which is equal to "-d" below. */
const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
plane[0] = a;
static INLINE GLfloat
solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
{
- const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
- return z;
+ ASSERT(plane[2] != 0.0F);
+ return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
}
}
-
/*
* Solve plane and return clamped GLchan value.
*/
compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
const GLfloat v2[3], GLint winx, GLint winy)
{
-#define B 0.125
+ /* Given a position [0,3]x[0,3] return the sub-pixel sample position.
+ * Contributed by Ray Tice.
+ *
+ * Jitter sample positions -
+ * - average should be .5 in x & y for each column
+ * - each of the 16 rows and columns should be used once
+ * - the rectangle formed by the first four points
+ * should contain the other points
+ * - the distrubition should be fairly even in any given direction
+ *
+ * The pattern drawn below isn't optimal, but it's better than a regular
+ * grid. In the drawing, the center of each subpixel is surrounded by
+ * four dots. The "x" marks the jittered position relative to the
+ * subpixel center.
+ */
+#define POS(a, b) (0.5+a*4+b)/16
static const GLfloat samples[16][2] = {
/* start with the four corners */
- { 0.00+B, 0.00+B },
- { 0.75+B, 0.00+B },
- { 0.00+B, 0.75+B },
- { 0.75+B, 0.75+B },
+ { POS(0, 2), POS(0, 0) },
+ { POS(3, 3), POS(0, 2) },
+ { POS(0, 0), POS(3, 1) },
+ { POS(3, 1), POS(3, 3) },
/* continue with interior samples */
- { 0.25+B, 0.00+B },
- { 0.50+B, 0.00+B },
- { 0.00+B, 0.25+B },
- { 0.25+B, 0.25+B },
- { 0.50+B, 0.25+B },
- { 0.75+B, 0.25+B },
- { 0.00+B, 0.50+B },
- { 0.25+B, 0.50+B },
- { 0.50+B, 0.50+B },
- { 0.75+B, 0.50+B },
- { 0.25+B, 0.75+B },
- { 0.50+B, 0.75+B }
+ { POS(1, 1), POS(0, 1) },
+ { POS(2, 0), POS(0, 3) },
+ { POS(0, 3), POS(1, 3) },
+ { POS(1, 2), POS(1, 0) },
+ { POS(2, 3), POS(1, 2) },
+ { POS(3, 2), POS(1, 1) },
+ { POS(0, 1), POS(2, 2) },
+ { POS(1, 0), POS(2, 1) },
+ { POS(2, 1), POS(2, 3) },
+ { POS(3, 0), POS(2, 0) },
+ { POS(1, 3), POS(3, 0) },
+ { POS(2, 2), POS(3, 2) }
};
+
const GLfloat x = (GLfloat) winx;
const GLfloat y = (GLfloat) winy;
const GLfloat dx0 = v1[0] - v0[0];
#ifdef DEBUG
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
- assert(area >= 0.0);
+ ASSERT(area >= 0.0);
}
#endif
compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
const GLfloat v2[3], GLint winx, GLint winy)
{
- /* NOTE: 15 samples instead of 16.
- * A better sample distribution could be used.
- */
+ /* NOTE: 15 samples instead of 16. */
static const GLfloat samples[15][2] = {
/* start with the four corners */
- { 0.00+B, 0.00+B },
- { 0.75+B, 0.00+B },
- { 0.00+B, 0.75+B },
- { 0.75+B, 0.75+B },
+ { POS(0, 2), POS(0, 0) },
+ { POS(3, 3), POS(0, 2) },
+ { POS(0, 0), POS(3, 1) },
+ { POS(3, 1), POS(3, 3) },
/* continue with interior samples */
- { 0.25+B, 0.00+B },
- { 0.50+B, 0.00+B },
- { 0.00+B, 0.25+B },
- { 0.25+B, 0.25+B },
- { 0.50+B, 0.25+B },
- { 0.75+B, 0.25+B },
- { 0.00+B, 0.50+B },
- { 0.25+B, 0.50+B },
- /*{ 0.50, 0.50 },*/
- { 0.75+B, 0.50+B },
- { 0.25+B, 0.75+B },
- { 0.50+B, 0.75+B }
+ { POS(1, 1), POS(0, 1) },
+ { POS(2, 0), POS(0, 3) },
+ { POS(0, 3), POS(1, 3) },
+ { POS(1, 2), POS(1, 0) },
+ { POS(2, 3), POS(1, 2) },
+ { POS(3, 2), POS(1, 1) },
+ { POS(0, 1), POS(2, 2) },
+ { POS(1, 0), POS(2, 1) },
+ { POS(2, 1), POS(2, 3) },
+ { POS(3, 0), POS(2, 0) },
+ { POS(1, 3), POS(3, 0) }
};
const GLfloat x = (GLfloat) winx;
const GLfloat y = (GLfloat) winy;
#ifdef DEBUG
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
- assert(area >= 0.0);
+ ASSERT(area >= 0.0);
}
#endif
/*
* Compute mipmap level of detail.
+ * XXX we should really include the R coordinate in this computation
+ * in order to do 3-D texture mipmapping.
*/
static INLINE GLfloat
compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
- GLfloat invQ, GLfloat width, GLfloat height)
+ const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
+ GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
{
- GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width;
- GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width;
- GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height;
- GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height;
- GLfloat r1 = dudx * dudx + dudy * dudy;
- GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
- GLfloat rho2 = r1 + r2;
- /* return log base 2 of rho */
- if (rho2 == 0.0F)
- return 0.0;
- else
- return log(rho2) * 1.442695 * 0.5; /* 1.442695 = 1/log(2) */
+ const GLfloat s = solve_plane(cx, cy, sPlane);
+ const GLfloat t = solve_plane(cx, cy, tPlane);
+ const GLfloat invQ_x1 = solve_plane_recip(cx+1.0, cy, qPlane);
+ const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0, qPlane);
+ const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
+ const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
+ const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
+ const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
+ GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
+ GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
+ GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
+ GLfloat dtdy = t_y1 * invQ_y1 - t * invQ;
+ GLfloat maxU, maxV, rho, lambda;
+ dsdx = FABSF(dsdx);
+ dsdy = FABSF(dsdy);
+ dtdx = FABSF(dtdx);
+ dtdy = FABSF(dtdy);
+ maxU = MAX2(dsdx, dsdy) * texWidth;
+ maxV = MAX2(dtdx, dtdy) * texHeight;
+ rho = MAX2(maxU, maxV);
+ lambda = LOG2(rho);
+ return lambda;
}
void
_mesa_set_aa_triangle_function(GLcontext *ctx)
{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
ASSERT(ctx->Polygon.SmoothFlag);
if (ctx->Texture._ReallyEnabled) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
- if (swrast->_MultiTextureEnabled) {
+ if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri;
}
else {
}
}
else {
- if (swrast->_MultiTextureEnabled) {
+ if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri;
}
else {