New mipmap lambda calculation. Previously, trilinear filtering could
result in _very_ blurry textures. Still need to do some optimization of the new code in s_span.c
This commit is contained in:
parent
bc6b60c4ff
commit
31f12f504e
|
@ -1,10 +1,10 @@
|
||||||
/* $Id: s_aatriangle.c,v 1.22 2002/01/27 18:32:03 brianp Exp $ */
|
/* $Id: s_aatriangle.c,v 1.23 2002/03/16 18:02:07 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
* Version: 4.0.1
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -124,7 +124,6 @@ solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Solve plane and return clamped GLchan value.
|
* Solve plane and return clamped GLchan value.
|
||||||
*/
|
*/
|
||||||
|
@ -352,23 +351,36 @@ index_aa_tri(GLcontext *ctx,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute mipmap level of detail.
|
* 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
|
static INLINE GLfloat
|
||||||
compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
|
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;
|
const GLfloat s = solve_plane(cx, cy, sPlane);
|
||||||
GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width;
|
const GLfloat t = solve_plane(cx, cy, tPlane);
|
||||||
GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height;
|
const GLfloat invQ_x1 = solve_plane_recip(cx+1.0, cy, qPlane);
|
||||||
GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height;
|
const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0, qPlane);
|
||||||
GLfloat r1 = dudx * dudx + dudy * dudy;
|
const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
|
||||||
GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
|
const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
|
||||||
GLfloat rho2 = r1 + r2;
|
const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
|
||||||
/* return log base 2 of rho */
|
const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
|
||||||
if (rho2 == 0.0F)
|
GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
|
||||||
return 0.0;
|
GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
|
||||||
else
|
GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
|
||||||
return (GLfloat) (log(rho2) * 1.442695 * 0.5); /* 1.442695 = 1/log(2) */
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: s_aatritemp.h,v 1.26 2002/01/28 03:42:28 brianp Exp $ */
|
/* $Id: s_aatritemp.h,v 1.27 2002/03/16 18:02:07 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
|
@ -76,10 +76,10 @@
|
||||||
GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
|
GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
|
||||||
GLfloat texWidth, texHeight;
|
GLfloat texWidth, texHeight;
|
||||||
#elif defined(DO_MULTITEX)
|
#elif defined(DO_MULTITEX)
|
||||||
GLfloat sPlane[MAX_TEXTURE_UNITS][4];
|
GLfloat sPlane[MAX_TEXTURE_UNITS][4]; /* texture S */
|
||||||
GLfloat tPlane[MAX_TEXTURE_UNITS][4];
|
GLfloat tPlane[MAX_TEXTURE_UNITS][4]; /* texture T */
|
||||||
GLfloat uPlane[MAX_TEXTURE_UNITS][4];
|
GLfloat uPlane[MAX_TEXTURE_UNITS][4]; /* texture R */
|
||||||
GLfloat vPlane[MAX_TEXTURE_UNITS][4];
|
GLfloat vPlane[MAX_TEXTURE_UNITS][4]; /* texture Q */
|
||||||
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
|
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
|
||||||
#endif
|
#endif
|
||||||
GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign;
|
GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign;
|
||||||
|
@ -316,7 +316,8 @@
|
||||||
span.texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
|
span.texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
|
||||||
span.texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
|
span.texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
|
||||||
span.texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
|
span.texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
|
||||||
span.lambda[0][count] = compute_lambda(sPlane, tPlane, invQ,
|
span.lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane,
|
||||||
|
cx, cy, invQ,
|
||||||
texWidth, texHeight);
|
texWidth, texHeight);
|
||||||
}
|
}
|
||||||
#elif defined(DO_MULTITEX)
|
#elif defined(DO_MULTITEX)
|
||||||
|
@ -329,7 +330,8 @@
|
||||||
span.texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
|
span.texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
|
||||||
span.texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
|
span.texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
|
||||||
span.lambda[unit][count] = compute_lambda(sPlane[unit],
|
span.lambda[unit][count] = compute_lambda(sPlane[unit],
|
||||||
tPlane[unit], invQ, texWidth[unit], texHeight[unit]);
|
tPlane[unit], vPlane[unit], cx, cy, invQ,
|
||||||
|
texWidth[unit], texHeight[unit]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,8 +421,8 @@
|
||||||
span.texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
|
span.texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
|
||||||
span.texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
|
span.texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
|
||||||
span.texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
|
span.texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
|
||||||
span.lambda[0][ix] = compute_lambda(sPlane, tPlane, invQ,
|
span.lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane,
|
||||||
texWidth, texHeight);
|
cx, cy, invQ, texWidth, texHeight);
|
||||||
}
|
}
|
||||||
#elif defined(DO_MULTITEX)
|
#elif defined(DO_MULTITEX)
|
||||||
{
|
{
|
||||||
|
@ -433,7 +435,8 @@
|
||||||
span.texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
|
span.texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
|
||||||
span.lambda[unit][ix] = compute_lambda(sPlane[unit],
|
span.lambda[unit][ix] = compute_lambda(sPlane[unit],
|
||||||
tPlane[unit],
|
tPlane[unit],
|
||||||
invQ,
|
vPlane[unit],
|
||||||
|
cx, cy, invQ,
|
||||||
texWidth[unit],
|
texWidth[unit],
|
||||||
texHeight[unit]);
|
texHeight[unit]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: s_pointtemp.h,v 1.12 2002/02/02 17:24:11 brianp Exp $ */
|
/* $Id: s_pointtemp.h,v 1.13 2002/03/16 18:02:08 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
|
@ -120,7 +120,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
|
||||||
#endif
|
#endif
|
||||||
#if FLAGS & TEXTURE
|
#if FLAGS & TEXTURE
|
||||||
span.interpMask |= SPAN_TEXTURE;
|
span.interpMask |= SPAN_TEXTURE;
|
||||||
span.arrayMask |= SPAN_LAMBDA;
|
|
||||||
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
||||||
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||||
const GLfloat q = vert->texcoord[u][3];
|
const GLfloat q = vert->texcoord[u][3];
|
||||||
|
@ -129,11 +128,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
|
||||||
span.tex[u][1] = vert->texcoord[u][1] * invQ;
|
span.tex[u][1] = vert->texcoord[u][1] * invQ;
|
||||||
span.tex[u][2] = vert->texcoord[u][2] * invQ;
|
span.tex[u][2] = vert->texcoord[u][2] * invQ;
|
||||||
span.tex[u][3] = q;
|
span.tex[u][3] = q;
|
||||||
span.texStep[u][0] = 0.0;
|
span.texStepX[u][0] = span.texStepY[u][0] = 0.0;
|
||||||
span.texStep[u][1] = 0.0;
|
span.texStepX[u][1] = span.texStepY[u][1] = 0.0;
|
||||||
span.texStep[u][2] = 0.0;
|
span.texStepX[u][2] = span.texStepY[u][2] = 0.0;
|
||||||
span.texStep[u][3] = 0.0;
|
span.texStepX[u][3] = span.texStepY[u][3] = 0.0;
|
||||||
span.rho[u] = 0.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: s_span.c,v 1.36 2002/02/17 17:30:57 brianp Exp $ */
|
/* $Id: s_span.c,v 1.37 2002/03/16 18:02:08 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
|
@ -36,6 +36,7 @@
|
||||||
#include "colormac.h"
|
#include "colormac.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
#include "mmath.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
#include "s_alpha.h"
|
#include "s_alpha.h"
|
||||||
|
@ -263,52 +264,51 @@ _mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return log_base_2(x) / 2.
|
* This the ideal solution, as given in the OpenGL spec.
|
||||||
* We divide by two here since we didn't square rho in the triangle function.
|
|
||||||
*/
|
*/
|
||||||
#ifdef USE_IEEE
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* This is pretty fast, but not accurate enough (only 2 fractional bits).
|
static GLfloat
|
||||||
* Based on code from http://www.stereopsis.com/log2.html
|
compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
|
||||||
*/
|
GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
|
||||||
static INLINE GLfloat HALF_LOG2(GLfloat x)
|
GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
|
||||||
{
|
{
|
||||||
const GLfloat y = x * x * x * x;
|
GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
|
||||||
const GLuint ix = *((GLuint *) &y);
|
GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
|
||||||
const GLuint exp = (ix >> 23) & 0xFF;
|
GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
|
||||||
const GLint log2 = ((GLint) exp) - 127;
|
GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
|
||||||
return (GLfloat) log2 * (0.5 / 4.0); /* 4, because of x^4 above */
|
GLfloat x = sqrt(dudx * dudx + dvdx * dvdx);
|
||||||
|
GLfloat y = sqrt(dudy * dudy + dvdy * dvdy);
|
||||||
|
GLfloat rho = MAX2(x, y);
|
||||||
|
GLfloat lambda = LOG2(rho);
|
||||||
|
return lambda;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Pretty fast, and accurate.
|
|
||||||
* Based on code from http://www.flipcode.com/totd/
|
/*
|
||||||
|
* This is a faster approximation
|
||||||
*/
|
*/
|
||||||
static INLINE GLfloat HALF_LOG2(GLfloat val)
|
static GLfloat
|
||||||
|
compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
|
||||||
|
GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
|
||||||
|
GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
|
||||||
{
|
{
|
||||||
GLint *exp_ptr = (GLint *) &val;
|
GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
|
||||||
GLint x = *exp_ptr;
|
GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
|
||||||
const GLint log_2 = ((x >> 23) & 255) - 128;
|
GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
|
||||||
x &= ~(255 << 23);
|
GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
|
||||||
x += 127 << 23;
|
GLfloat maxU, maxV, rho, lambda;
|
||||||
*exp_ptr = x;
|
dsdx2 = FABSF(dsdx2);
|
||||||
val = ((-1.0f/3) * val + 2) * val - 2.0f/3;
|
dsdy2 = FABSF(dsdy2);
|
||||||
return 0.5F * (val + log_2);
|
dtdx2 = FABSF(dtdx2);
|
||||||
|
dtdy2 = FABSF(dtdy2);
|
||||||
|
maxU = MAX2(dsdx2, dsdy2) * texW;
|
||||||
|
maxV = MAX2(dtdx2, dtdy2) * texH;
|
||||||
|
rho = MAX2(maxU, maxV);
|
||||||
|
lambda = LOG2(rho);
|
||||||
|
return lambda;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* USE_IEEE */
|
|
||||||
|
|
||||||
/* Slow, portable solution.
|
|
||||||
* NOTE: log_base_2(x) = log(x) / log(2)
|
|
||||||
* NOTE: 1.442695 = 1/log(2).
|
|
||||||
*/
|
|
||||||
#define HALF_LOG2(x) ((GLfloat) (log(x) * (1.442695F * 0.5F)))
|
|
||||||
|
|
||||||
#endif /* USE_IEEE */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill in the span.texcoords array from the interpolation values.
|
* Fill in the span.texcoords array from the interpolation values.
|
||||||
* XXX We could optimize here for the case when dq = 0. That would
|
* XXX We could optimize here for the case when dq = 0. That would
|
||||||
|
@ -320,76 +320,64 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
||||||
ASSERT(span->interpMask & SPAN_TEXTURE);
|
ASSERT(span->interpMask & SPAN_TEXTURE);
|
||||||
|
|
||||||
if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
|
if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
|
||||||
if (span->interpMask & SPAN_LAMBDA) {
|
/* multitexture */
|
||||||
/* multitexture, lambda */
|
|
||||||
GLuint u;
|
GLuint u;
|
||||||
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
||||||
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||||
const GLfloat rho = span->rho[u];
|
const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
|
||||||
const GLfloat ds = span->texStep[u][0];
|
const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
|
||||||
const GLfloat dt = span->texStep[u][1];
|
GLboolean needLambda = (obj->MinFilter != obj->MagFilter);
|
||||||
const GLfloat dr = span->texStep[u][2];
|
if (needLambda) {
|
||||||
const GLfloat dq = span->texStep[u][3];
|
const GLfloat texW = (GLfloat) img->Width;
|
||||||
|
const GLfloat texH = (GLfloat) img->Height;
|
||||||
|
const GLfloat dsdx = span->texStepX[u][0];
|
||||||
|
const GLfloat dsdy = span->texStepY[u][0];
|
||||||
|
const GLfloat dtdx = span->texStepX[u][1];
|
||||||
|
const GLfloat dtdy = span->texStepY[u][1];
|
||||||
|
const GLfloat drdx = span->texStepX[u][2];
|
||||||
|
const GLfloat dqdx = span->texStepX[u][3];
|
||||||
|
const GLfloat dqdy = span->texStepY[u][3];
|
||||||
GLfloat s = span->tex[u][0];
|
GLfloat s = span->tex[u][0];
|
||||||
GLfloat t = span->tex[u][1];
|
GLfloat t = span->tex[u][1];
|
||||||
GLfloat r = span->tex[u][2];
|
GLfloat r = span->tex[u][2];
|
||||||
GLfloat q = span->tex[u][3];
|
GLfloat q = span->tex[u][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (dq == 0.0) {
|
|
||||||
/* Ortho projection or polygon's parallel to window X axis */
|
|
||||||
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
|
||||||
const GLfloat lambda = HALF_LOG2(rho * invQ * invQ);
|
|
||||||
for (i = 0; i < span->end; i++) {
|
|
||||||
span->texcoords[u][i][0] = s * invQ;
|
|
||||||
span->texcoords[u][i][1] = t * invQ;
|
|
||||||
span->texcoords[u][i][2] = r * invQ;
|
|
||||||
span->lambda[u][i] = lambda;
|
|
||||||
s += ds;
|
|
||||||
t += dt;
|
|
||||||
r += dr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (i = 0; i < span->end; i++) {
|
for (i = 0; i < span->end; i++) {
|
||||||
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
||||||
span->texcoords[u][i][0] = s * invQ;
|
span->texcoords[u][i][0] = s * invQ;
|
||||||
span->texcoords[u][i][1] = t * invQ;
|
span->texcoords[u][i][1] = t * invQ;
|
||||||
span->texcoords[u][i][2] = r * invQ;
|
span->texcoords[u][i][2] = r * invQ;
|
||||||
span->lambda[u][i] = HALF_LOG2(rho * invQ * invQ);
|
span->lambda[u][i] = compute_lambda(dsdx, dsdy, dtdx, dtdy,
|
||||||
s += ds;
|
dqdx, dqdy, texW, texH,
|
||||||
t += dt;
|
s, t, q, invQ);
|
||||||
r += dr;
|
s += dsdx;
|
||||||
q += dq;
|
t += dtdx;
|
||||||
}
|
r += drdx;
|
||||||
}
|
q += dqdx;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
span->arrayMask |= SPAN_LAMBDA;
|
span->arrayMask |= SPAN_LAMBDA;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* multitexture, no lambda */
|
const GLfloat dsdx = span->texStepX[u][0];
|
||||||
GLuint u;
|
const GLfloat dtdx = span->texStepX[u][1];
|
||||||
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
const GLfloat drdx = span->texStepX[u][2];
|
||||||
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
const GLfloat dqdx = span->texStepX[u][3];
|
||||||
const GLfloat ds = span->texStep[u][0];
|
|
||||||
const GLfloat dt = span->texStep[u][1];
|
|
||||||
const GLfloat dr = span->texStep[u][2];
|
|
||||||
const GLfloat dq = span->texStep[u][3];
|
|
||||||
GLfloat s = span->tex[u][0];
|
GLfloat s = span->tex[u][0];
|
||||||
GLfloat t = span->tex[u][1];
|
GLfloat t = span->tex[u][1];
|
||||||
GLfloat r = span->tex[u][2];
|
GLfloat r = span->tex[u][2];
|
||||||
GLfloat q = span->tex[u][3];
|
GLfloat q = span->tex[u][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (dq == 0.0) {
|
if (dqdx == 0.0) {
|
||||||
/* Ortho projection or polygon's parallel to window X axis */
|
/* Ortho projection or polygon's parallel to window X axis */
|
||||||
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
||||||
for (i = 0; i < span->end; i++) {
|
for (i = 0; i < span->end; i++) {
|
||||||
span->texcoords[u][i][0] = s * invQ;
|
span->texcoords[u][i][0] = s * invQ;
|
||||||
span->texcoords[u][i][1] = t * invQ;
|
span->texcoords[u][i][1] = t * invQ;
|
||||||
span->texcoords[u][i][2] = r * invQ;
|
span->texcoords[u][i][2] = r * invQ;
|
||||||
s += ds;
|
span->lambda[u][i] = 0.0;
|
||||||
t += dt;
|
s += dsdx;
|
||||||
r += dr;
|
t += dtdx;
|
||||||
|
r += drdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -398,79 +386,74 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
||||||
span->texcoords[u][i][0] = s * invQ;
|
span->texcoords[u][i][0] = s * invQ;
|
||||||
span->texcoords[u][i][1] = t * invQ;
|
span->texcoords[u][i][1] = t * invQ;
|
||||||
span->texcoords[u][i][2] = r * invQ;
|
span->texcoords[u][i][2] = r * invQ;
|
||||||
s += ds;
|
span->lambda[u][i] = 0.0;
|
||||||
t += dt;
|
s += dsdx;
|
||||||
r += dr;
|
t += dtdx;
|
||||||
q += dq;
|
r += drdx;
|
||||||
}
|
q += dqdx;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} /* lambda */
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (span->interpMask & SPAN_LAMBDA) {
|
/* single texture */
|
||||||
|
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
|
||||||
|
const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
|
||||||
|
GLboolean needLambda = (obj->MinFilter != obj->MagFilter);
|
||||||
|
if (needLambda) {
|
||||||
/* just texture unit 0, with lambda */
|
/* just texture unit 0, with lambda */
|
||||||
const GLfloat rho = span->rho[0];
|
const GLfloat texW = (GLfloat) img->Width;
|
||||||
const GLfloat ds = span->texStep[0][0];
|
const GLfloat texH = (GLfloat) img->Height;
|
||||||
const GLfloat dt = span->texStep[0][1];
|
const GLfloat dsdx = span->texStepX[0][0];
|
||||||
const GLfloat dr = span->texStep[0][2];
|
const GLfloat dsdy = span->texStepY[0][0];
|
||||||
const GLfloat dq = span->texStep[0][3];
|
const GLfloat dtdx = span->texStepX[0][1];
|
||||||
|
const GLfloat dtdy = span->texStepY[0][1];
|
||||||
|
const GLfloat drdx = span->texStepX[0][2];
|
||||||
|
const GLfloat dqdx = span->texStepX[0][3];
|
||||||
|
const GLfloat dqdy = span->texStepY[0][3];
|
||||||
GLfloat s = span->tex[0][0];
|
GLfloat s = span->tex[0][0];
|
||||||
GLfloat t = span->tex[0][1];
|
GLfloat t = span->tex[0][1];
|
||||||
GLfloat r = span->tex[0][2];
|
GLfloat r = span->tex[0][2];
|
||||||
GLfloat q = span->tex[0][3];
|
GLfloat q = span->tex[0][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (dq == 0.0) {
|
|
||||||
/* Ortho projection or polygon's parallel to window X axis */
|
|
||||||
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
|
||||||
const GLfloat lambda = HALF_LOG2(rho * invQ * invQ);
|
|
||||||
for (i = 0; i < span->end; i++) {
|
for (i = 0; i < span->end; i++) {
|
||||||
|
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
||||||
|
span->lambda[0][i] = compute_lambda(dsdx, dsdy, dtdx, dtdy,
|
||||||
|
dqdx, dqdy, texW, texH,
|
||||||
|
s, t, q, invQ);
|
||||||
span->texcoords[0][i][0] = s * invQ;
|
span->texcoords[0][i][0] = s * invQ;
|
||||||
span->texcoords[0][i][1] = t * invQ;
|
span->texcoords[0][i][1] = t * invQ;
|
||||||
span->texcoords[0][i][2] = r * invQ;
|
span->texcoords[0][i][2] = r * invQ;
|
||||||
span->lambda[0][i] = lambda;
|
s += dsdx;
|
||||||
s += ds;
|
t += dtdx;
|
||||||
t += dt;
|
r += drdx;
|
||||||
r += dr;
|
q += dqdx;
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (i = 0; i < span->end; i++) {
|
|
||||||
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
|
||||||
span->texcoords[0][i][0] = s * invQ;
|
|
||||||
span->texcoords[0][i][1] = t * invQ;
|
|
||||||
span->texcoords[0][i][2] = r * invQ;
|
|
||||||
span->lambda[0][i] = HALF_LOG2(rho * invQ * invQ);
|
|
||||||
s += ds;
|
|
||||||
t += dt;
|
|
||||||
r += dr;
|
|
||||||
q += dq;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
span->arrayMask |= SPAN_LAMBDA;
|
span->arrayMask |= SPAN_LAMBDA;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* just texture 0, without lambda */
|
/* just texture 0, without lambda */
|
||||||
const GLfloat ds = span->texStep[0][0];
|
const GLfloat dsdx = span->texStepX[0][0];
|
||||||
const GLfloat dt = span->texStep[0][1];
|
const GLfloat dtdx = span->texStepX[0][1];
|
||||||
const GLfloat dr = span->texStep[0][2];
|
const GLfloat drdx = span->texStepX[0][2];
|
||||||
const GLfloat dq = span->texStep[0][3];
|
const GLfloat dqdx = span->texStepX[0][3];
|
||||||
GLfloat s = span->tex[0][0];
|
GLfloat s = span->tex[0][0];
|
||||||
GLfloat t = span->tex[0][1];
|
GLfloat t = span->tex[0][1];
|
||||||
GLfloat r = span->tex[0][2];
|
GLfloat r = span->tex[0][2];
|
||||||
GLfloat q = span->tex[0][3];
|
GLfloat q = span->tex[0][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (dq == 0.0) {
|
if (dqdx == 0.0) {
|
||||||
/* Ortho projection or polygon's parallel to window X axis */
|
/* Ortho projection or polygon's parallel to window X axis */
|
||||||
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
|
||||||
for (i = 0; i < span->end; i++) {
|
for (i = 0; i < span->end; i++) {
|
||||||
span->texcoords[0][i][0] = s * invQ;
|
span->texcoords[0][i][0] = s * invQ;
|
||||||
span->texcoords[0][i][1] = t * invQ;
|
span->texcoords[0][i][1] = t * invQ;
|
||||||
span->texcoords[0][i][2] = r * invQ;
|
span->texcoords[0][i][2] = r * invQ;
|
||||||
s += ds;
|
s += dsdx;
|
||||||
t += dt;
|
t += dtdx;
|
||||||
r += dr;
|
r += drdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -479,10 +462,10 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
||||||
span->texcoords[0][i][0] = s * invQ;
|
span->texcoords[0][i][0] = s * invQ;
|
||||||
span->texcoords[0][i][1] = t * invQ;
|
span->texcoords[0][i][1] = t * invQ;
|
||||||
span->texcoords[0][i][2] = r * invQ;
|
span->texcoords[0][i][2] = r * invQ;
|
||||||
s += ds;
|
s += dsdx;
|
||||||
t += dt;
|
t += dtdx;
|
||||||
r += dr;
|
r += drdx;
|
||||||
q += dq;
|
q += dqdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: s_texture.c,v 1.55 2002/03/08 00:09:18 brianp Exp $ */
|
/* $Id: s_texture.c,v 1.56 2002/03/16 18:02:08 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
|
@ -310,18 +310,22 @@ compute_min_mag_ranges( GLfloat minMagThresh, GLuint n, const GLfloat lambda[],
|
||||||
GLuint *magStart, GLuint *magEnd )
|
GLuint *magStart, GLuint *magEnd )
|
||||||
{
|
{
|
||||||
ASSERT(lambda != NULL);
|
ASSERT(lambda != NULL);
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
/* verify that lambda[] is monotonous */
|
/* Verify that lambda[] is monotonous.
|
||||||
|
* We can't really use this because the inaccuracy in the LOG2 function
|
||||||
|
* causes this test to fail, yet the resulting texturing is correct.
|
||||||
|
*/
|
||||||
if (n > 1) {
|
if (n > 1) {
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
|
||||||
if (lambda[0] >= lambda[n-1]) { /* decreasing */
|
if (lambda[0] >= lambda[n-1]) { /* decreasing */
|
||||||
for (i = 0; i < n - 1; i++) {
|
for (i = 0; i < n - 1; i++) {
|
||||||
ASSERT((GLint) (lambda[i] * 100) >= (GLint) (lambda[i+1] * 100));
|
ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* increasing */
|
else { /* increasing */
|
||||||
for (i = 0; i < n - 1; i++) {
|
for (i = 0; i < n - 1; i++) {
|
||||||
ASSERT((GLint) (lambda[i] * 100) <= (GLint) (lambda[i+1] * 100));
|
ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,8 +371,10 @@ compute_min_mag_ranges( GLfloat minMagThresh, GLuint n, const GLfloat lambda[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#if 0
|
||||||
/* Verify the min/mag Start/End values */
|
/* Verify the min/mag Start/End values
|
||||||
|
* We don't use this either (see above)
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
GLint i;
|
GLint i;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
@ -3280,6 +3286,18 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n,
|
||||||
GLchan texel[MAX_WIDTH][4];
|
GLchan texel[MAX_WIDTH][4];
|
||||||
|
|
||||||
if (lambda) {
|
if (lambda) {
|
||||||
|
#if 0
|
||||||
|
float min, max;
|
||||||
|
int i;
|
||||||
|
min = max = lambda[0];
|
||||||
|
for (i = 1; i < n; i++) {
|
||||||
|
if (lambda[i] > max)
|
||||||
|
max = lambda[i];
|
||||||
|
if (lambda[i] < min)
|
||||||
|
min = lambda[i];
|
||||||
|
}
|
||||||
|
printf("min/max %g / %g\n", min, max);
|
||||||
|
#endif
|
||||||
if (textureUnit->LodBias != 0.0F) {
|
if (textureUnit->LodBias != 0.0F) {
|
||||||
/* apply LOD bias, but don't clamp yet */
|
/* apply LOD bias, but don't clamp yet */
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: s_triangle.c,v 1.54 2002/02/02 17:24:11 brianp Exp $ */
|
/* $Id: s_triangle.c,v 1.55 2002/03/16 18:02:08 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
|
@ -722,13 +722,13 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
|
||||||
GLfloat tex_coord[3], tex_step[3];
|
GLfloat tex_coord[3], tex_step[3];
|
||||||
GLchan *dest = span->color.rgba[0];
|
GLchan *dest = span->color.rgba[0];
|
||||||
|
|
||||||
tex_coord[0] = span->tex[0][0] * (info->smask + 1),
|
tex_coord[0] = span->tex[0][0] * (info->smask + 1);
|
||||||
tex_step[0] = span->texStep[0][0] * (info->smask + 1);
|
tex_step[0] = span->texStepX[0][0] * (info->smask + 1);
|
||||||
tex_coord[1] = span->tex[0][1] * (info->tmask + 1),
|
tex_coord[1] = span->tex[0][1] * (info->tmask + 1);
|
||||||
tex_step[1] = span->texStep[0][1] * (info->tmask + 1);
|
tex_step[1] = span->texStepX[0][1] * (info->tmask + 1);
|
||||||
/* span->tex[0][2] only if 3D-texturing, here only 2D */
|
/* span->tex[0][2] only if 3D-texturing, here only 2D */
|
||||||
tex_coord[2] = span->tex[0][3],
|
tex_coord[2] = span->tex[0][3];
|
||||||
tex_step[2] = span->texStep[0][3];
|
tex_step[2] = span->texStepX[0][3];
|
||||||
|
|
||||||
switch (info->filter) {
|
switch (info->filter) {
|
||||||
case GL_NEAREST:
|
case GL_NEAREST:
|
||||||
|
@ -934,41 +934,13 @@ static void general_textured_triangle( GLcontext *ctx,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Render a smooth-shaded, textured, RGBA triangle.
|
|
||||||
* Interpolate S,T,R with perspective correction and compute lambda for
|
|
||||||
* each fragment. Lambda is used to determine whether to use the
|
|
||||||
* minification or magnification filter. If minification and using
|
|
||||||
* mipmaps, lambda is also used to select the texture level of detail.
|
|
||||||
*/
|
|
||||||
static void lambda_textured_triangle( GLcontext *ctx,
|
|
||||||
const SWvertex *v0,
|
|
||||||
const SWvertex *v1,
|
|
||||||
const SWvertex *v2 )
|
|
||||||
{
|
|
||||||
#define INTERP_Z 1
|
|
||||||
#define INTERP_FOG 1
|
|
||||||
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
|
|
||||||
#define INTERP_RGB 1
|
|
||||||
#define INTERP_SPEC 1
|
|
||||||
#define INTERP_ALPHA 1
|
|
||||||
#define INTERP_TEX 1
|
|
||||||
#define INTERP_LAMBDA 1
|
|
||||||
|
|
||||||
#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span, GL_POLYGON);
|
|
||||||
|
|
||||||
#include "s_tritemp.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the big one!
|
* This is the big one!
|
||||||
* Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates
|
* Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
|
||||||
* with lambda (LOD).
|
|
||||||
* Yup, it's slow.
|
* Yup, it's slow.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lambda_multitextured_triangle( GLcontext *ctx,
|
multitextured_triangle( GLcontext *ctx,
|
||||||
const SWvertex *v0,
|
const SWvertex *v0,
|
||||||
const SWvertex *v1,
|
const SWvertex *v1,
|
||||||
const SWvertex *v2 )
|
const SWvertex *v2 )
|
||||||
|
@ -981,7 +953,6 @@ lambda_multitextured_triangle( GLcontext *ctx,
|
||||||
#define INTERP_ALPHA 1
|
#define INTERP_ALPHA 1
|
||||||
#define INTERP_SPEC 1
|
#define INTERP_SPEC 1
|
||||||
#define INTERP_MULTITEX 1
|
#define INTERP_MULTITEX 1
|
||||||
#define INTERP_LAMBDA 1
|
|
||||||
|
|
||||||
#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span, GL_POLYGON);
|
#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span, GL_POLYGON);
|
||||||
|
|
||||||
|
@ -1201,27 +1172,15 @@ _swrast_choose_triangle( GLcontext *ctx )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* More complicated textures (mipmap, multi-tex, sep specular) */
|
/* general case textured triangles */
|
||||||
GLboolean needLambda;
|
|
||||||
/* if mag filter != min filter we need to compute lambda */
|
|
||||||
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
|
|
||||||
if (obj && obj->MinFilter != obj->MagFilter)
|
|
||||||
needLambda = GL_TRUE;
|
|
||||||
else
|
|
||||||
needLambda = GL_FALSE;
|
|
||||||
if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
|
if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) {
|
||||||
USE(lambda_multitextured_triangle);
|
USE(multitextured_triangle);
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (needLambda) {
|
|
||||||
USE(lambda_textured_triangle);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
USE(general_textured_triangle);
|
USE(general_textured_triangle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
ASSERT(!ctx->Texture._ReallyEnabled);
|
ASSERT(!ctx->Texture._ReallyEnabled);
|
||||||
if (ctx->Light.ShadeModel==GL_SMOOTH) {
|
if (ctx->Light.ShadeModel==GL_SMOOTH) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: s_tritemp.h,v 1.34 2002/03/01 04:28:32 brianp Exp $ */
|
/* $Id: s_tritemp.h,v 1.35 2002/03/16 18:02:08 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
|
@ -43,8 +43,6 @@
|
||||||
* INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords
|
* INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords
|
||||||
* NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
|
* NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
|
||||||
* INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
|
* INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
|
||||||
* INTERP_LAMBDA - if defined, compute lambda value (for mipmapping)
|
|
||||||
* a lambda value for every texture unit
|
|
||||||
* INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
|
* INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
|
||||||
* INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
|
* INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
|
||||||
*
|
*
|
||||||
|
@ -317,20 +315,16 @@
|
||||||
GLfloat dtdx, dtdy;
|
GLfloat dtdx, dtdy;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INTERP_TEX
|
#ifdef INTERP_TEX
|
||||||
GLfloat dsdy;
|
GLfloat dsdx, dsdy;
|
||||||
GLfloat dtdy;
|
GLfloat dtdx, dtdy;
|
||||||
GLfloat dudy;
|
GLfloat dudx, dudy;
|
||||||
GLfloat dvdy;
|
GLfloat dvdx, dvdy;
|
||||||
#endif
|
#endif
|
||||||
#ifdef INTERP_MULTITEX
|
#ifdef INTERP_MULTITEX
|
||||||
GLfloat dsdy[MAX_TEXTURE_UNITS];
|
GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS];
|
||||||
GLfloat dtdy[MAX_TEXTURE_UNITS];
|
GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS];
|
||||||
GLfloat dudy[MAX_TEXTURE_UNITS];
|
GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS];
|
||||||
GLfloat dvdy[MAX_TEXTURE_UNITS];
|
GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(INTERP_LAMBDA) && !defined(INTERP_TEX) && !defined(INTERP_MULTITEX)
|
|
||||||
#error "Mipmapping without texturing doesn't make sense."
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -578,50 +572,35 @@
|
||||||
|
|
||||||
eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
|
eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
|
||||||
eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
|
eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
|
||||||
span.texStep[0][0] = oneOverArea * (eMaj_ds * eBot.dy
|
dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
|
||||||
- eMaj.dy * eBot_ds);
|
|
||||||
dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
|
dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
|
||||||
|
span.texStepX[0][0] = dsdx;
|
||||||
|
span.texStepY[0][0] = dsdy;
|
||||||
|
|
||||||
eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
|
eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
|
||||||
eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
|
eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
|
||||||
span.texStep[0][1] = oneOverArea * (eMaj_dt * eBot.dy
|
dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
|
||||||
- eMaj.dy * eBot_dt);
|
|
||||||
dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
|
dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
|
||||||
|
span.texStepX[0][1] = dtdx;
|
||||||
|
span.texStepY[0][1] = dtdy;
|
||||||
|
|
||||||
eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
|
eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
|
||||||
eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
|
eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
|
||||||
span.texStep[0][2] = oneOverArea * (eMaj_du * eBot.dy
|
dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
|
||||||
- eMaj.dy * eBot_du);
|
|
||||||
dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
|
dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
|
||||||
|
span.texStepX[0][2] = dudx;
|
||||||
|
span.texStepY[0][2] = dudy;
|
||||||
|
|
||||||
eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
|
eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
|
||||||
eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
|
eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
|
||||||
span.texStep[0][3] = oneOverArea * (eMaj_dv * eBot.dy
|
dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
|
||||||
- eMaj.dy * eBot_dv);
|
|
||||||
dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
|
dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
|
||||||
|
span.texStepX[0][3] = dvdx;
|
||||||
|
span.texStepY[0][3] = dvdy;
|
||||||
}
|
}
|
||||||
# ifdef INTERP_LAMBDA
|
|
||||||
{
|
|
||||||
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
|
|
||||||
const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
|
|
||||||
const GLfloat texWidth = (GLfloat) texImage->Width;
|
|
||||||
const GLfloat texHeight = (GLfloat) texImage->Height;
|
|
||||||
GLfloat dudx = span.texStep[0][0] * texWidth;
|
|
||||||
GLfloat dudy = dsdy * texWidth;
|
|
||||||
GLfloat dvdx = span.texStep[0][1] * texHeight;
|
|
||||||
GLfloat dvdy = dtdy * texHeight;
|
|
||||||
GLfloat r1 = dudx * dudx + dudy * dudy;
|
|
||||||
GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
|
|
||||||
span.rho[0] = r1 + r2; /* was rho2 = MAX2(r1,r2) */
|
|
||||||
span.interpMask |= SPAN_LAMBDA;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef INTERP_MULTITEX
|
#ifdef INTERP_MULTITEX
|
||||||
span.interpMask |= SPAN_TEXTURE;
|
span.interpMask |= SPAN_TEXTURE;
|
||||||
# ifdef INTERP_LAMBDA
|
|
||||||
span.interpMask |= SPAN_LAMBDA;
|
|
||||||
# endif
|
|
||||||
{
|
{
|
||||||
GLfloat wMax = vMax->win[3];
|
GLfloat wMax = vMax->win[3];
|
||||||
GLfloat wMin = vMin->win[3];
|
GLfloat wMin = vMin->win[3];
|
||||||
|
@ -637,50 +616,37 @@
|
||||||
- vMin->texcoord[u][0] * wMin;
|
- vMin->texcoord[u][0] * wMin;
|
||||||
eBot_ds = vMid->texcoord[u][0] * wMid
|
eBot_ds = vMid->texcoord[u][0] * wMid
|
||||||
- vMin->texcoord[u][0] * wMin;
|
- vMin->texcoord[u][0] * wMin;
|
||||||
span.texStep[u][0] = oneOverArea * (eMaj_ds * eBot.dy
|
dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
|
||||||
- eMaj.dy * eBot_ds);
|
|
||||||
dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
|
dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
|
||||||
|
span.texStepX[u][0] = dsdx[u];
|
||||||
|
span.texStepY[u][0] = dsdy[u];
|
||||||
|
|
||||||
eMaj_dt = vMax->texcoord[u][1] * wMax
|
eMaj_dt = vMax->texcoord[u][1] * wMax
|
||||||
- vMin->texcoord[u][1] * wMin;
|
- vMin->texcoord[u][1] * wMin;
|
||||||
eBot_dt = vMid->texcoord[u][1] * wMid
|
eBot_dt = vMid->texcoord[u][1] * wMid
|
||||||
- vMin->texcoord[u][1] * wMin;
|
- vMin->texcoord[u][1] * wMin;
|
||||||
span.texStep[u][1] = oneOverArea * (eMaj_dt * eBot.dy
|
dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
|
||||||
- eMaj.dy * eBot_dt);
|
|
||||||
dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
|
dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
|
||||||
|
span.texStepX[u][1] = dtdx[u];
|
||||||
|
span.texStepY[u][1] = dtdy[u];
|
||||||
|
|
||||||
eMaj_du = vMax->texcoord[u][2] * wMax
|
eMaj_du = vMax->texcoord[u][2] * wMax
|
||||||
- vMin->texcoord[u][2] * wMin;
|
- vMin->texcoord[u][2] * wMin;
|
||||||
eBot_du = vMid->texcoord[u][2] * wMid
|
eBot_du = vMid->texcoord[u][2] * wMid
|
||||||
- vMin->texcoord[u][2] * wMin;
|
- vMin->texcoord[u][2] * wMin;
|
||||||
span.texStep[u][2] = oneOverArea * (eMaj_du * eBot.dy
|
dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
|
||||||
- eMaj.dy * eBot_du);
|
|
||||||
dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
|
dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
|
||||||
|
span.texStepX[u][2] = dudx[u];
|
||||||
|
span.texStepY[u][2] = dudy[u];
|
||||||
|
|
||||||
eMaj_dv = vMax->texcoord[u][3] * wMax
|
eMaj_dv = vMax->texcoord[u][3] * wMax
|
||||||
- vMin->texcoord[u][3] * wMin;
|
- vMin->texcoord[u][3] * wMin;
|
||||||
eBot_dv = vMid->texcoord[u][3] * wMid
|
eBot_dv = vMid->texcoord[u][3] * wMid
|
||||||
- vMin->texcoord[u][3] * wMin;
|
- vMin->texcoord[u][3] * wMin;
|
||||||
span.texStep[u][3] = oneOverArea * (eMaj_dv * eBot.dy
|
dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
|
||||||
- eMaj.dy * eBot_dv);
|
|
||||||
dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
|
dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
|
||||||
# ifdef INTERP_LAMBDA
|
span.texStepX[u][3] = dvdx[u];
|
||||||
{
|
span.texStepY[u][3] = dvdy[u];
|
||||||
const struct gl_texture_object *obj
|
|
||||||
= ctx->Texture.Unit[u]._Current;
|
|
||||||
const struct gl_texture_image *texImage
|
|
||||||
= obj->Image[obj->BaseLevel];
|
|
||||||
const GLfloat texWidth = (GLfloat) texImage->Width;
|
|
||||||
const GLfloat texHeight = (GLfloat) texImage->Height;
|
|
||||||
GLfloat dudx = span.texStep[u][0] * texWidth;
|
|
||||||
GLfloat dudy = dsdy[u] * texWidth;
|
|
||||||
GLfloat dvdx = span.texStep[u][1] * texHeight;
|
|
||||||
GLfloat dvdy = dtdy[u] * texHeight;
|
|
||||||
GLfloat r1 = dudx * dudx + dudy * dudy;
|
|
||||||
GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
|
|
||||||
span.rho[u] = r1 + r2; /* was rho2 = MAX2(r1,r2) */
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1040,21 +1006,21 @@
|
||||||
GLfloat invW = vLower->win[3];
|
GLfloat invW = vLower->win[3];
|
||||||
GLfloat s0, t0, u0, v0;
|
GLfloat s0, t0, u0, v0;
|
||||||
s0 = vLower->texcoord[0][0] * invW;
|
s0 = vLower->texcoord[0][0] * invW;
|
||||||
sLeft = s0 + (span.texStep[0][0] * adjx + dsdy * adjy)
|
sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)
|
||||||
* (1.0F/FIXED_SCALE);
|
* (1.0F/FIXED_SCALE);
|
||||||
dsOuter = dsdy + dxOuter * span.texStep[0][0];
|
dsOuter = dsdy + dxOuter * span.texStepX[0][0];
|
||||||
t0 = vLower->texcoord[0][1] * invW;
|
t0 = vLower->texcoord[0][1] * invW;
|
||||||
tLeft = t0 + (span.texStep[0][1] * adjx + dtdy * adjy)
|
tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)
|
||||||
* (1.0F/FIXED_SCALE);
|
* (1.0F/FIXED_SCALE);
|
||||||
dtOuter = dtdy + dxOuter * span.texStep[0][1];
|
dtOuter = dtdy + dxOuter * span.texStepX[0][1];
|
||||||
u0 = vLower->texcoord[0][2] * invW;
|
u0 = vLower->texcoord[0][2] * invW;
|
||||||
uLeft = u0 + (span.texStep[0][2] * adjx + dudy * adjy)
|
uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)
|
||||||
* (1.0F/FIXED_SCALE);
|
* (1.0F/FIXED_SCALE);
|
||||||
duOuter = dudy + dxOuter * span.texStep[0][2];
|
duOuter = dudy + dxOuter * span.texStepX[0][2];
|
||||||
v0 = vLower->texcoord[0][3] * invW;
|
v0 = vLower->texcoord[0][3] * invW;
|
||||||
vLeft = v0 + (span.texStep[0][3] * adjx + dvdy * adjy)
|
vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)
|
||||||
* (1.0F/FIXED_SCALE);
|
* (1.0F/FIXED_SCALE);
|
||||||
dvOuter = dvdy + dxOuter * span.texStep[0][3];
|
dvOuter = dvdy + dxOuter * span.texStepX[0][3];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef INTERP_MULTITEX
|
#ifdef INTERP_MULTITEX
|
||||||
|
@ -1065,21 +1031,21 @@
|
||||||
GLfloat invW = vLower->win[3];
|
GLfloat invW = vLower->win[3];
|
||||||
GLfloat s0, t0, u0, v0;
|
GLfloat s0, t0, u0, v0;
|
||||||
s0 = vLower->texcoord[u][0] * invW;
|
s0 = vLower->texcoord[u][0] * invW;
|
||||||
sLeft[u] = s0 + (span.texStep[u][0] * adjx + dsdy[u]
|
sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u]
|
||||||
* adjy) * (1.0F/FIXED_SCALE);
|
* adjy) * (1.0F/FIXED_SCALE);
|
||||||
dsOuter[u] = dsdy[u] + dxOuter * span.texStep[u][0];
|
dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0];
|
||||||
t0 = vLower->texcoord[u][1] * invW;
|
t0 = vLower->texcoord[u][1] * invW;
|
||||||
tLeft[u] = t0 + (span.texStep[u][1] * adjx + dtdy[u]
|
tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u]
|
||||||
* adjy) * (1.0F/FIXED_SCALE);
|
* adjy) * (1.0F/FIXED_SCALE);
|
||||||
dtOuter[u] = dtdy[u] + dxOuter * span.texStep[u][1];
|
dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1];
|
||||||
u0 = vLower->texcoord[u][2] * invW;
|
u0 = vLower->texcoord[u][2] * invW;
|
||||||
uLeft[u] = u0 + (span.texStep[u][2] * adjx + dudy[u]
|
uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u]
|
||||||
* adjy) * (1.0F/FIXED_SCALE);
|
* adjy) * (1.0F/FIXED_SCALE);
|
||||||
duOuter[u] = dudy[u] + dxOuter * span.texStep[u][2];
|
duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2];
|
||||||
v0 = vLower->texcoord[u][3] * invW;
|
v0 = vLower->texcoord[u][3] * invW;
|
||||||
vLeft[u] = v0 + (span.texStep[u][3] * adjx + dvdy[u]
|
vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u]
|
||||||
* adjy) * (1.0F/FIXED_SCALE);
|
* adjy) * (1.0F/FIXED_SCALE);
|
||||||
dvOuter[u] = dvdy[u] + dxOuter * span.texStep[u][3];
|
dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1132,20 +1098,20 @@
|
||||||
fdtInner = fdtOuter + span.intTexStep[1];
|
fdtInner = fdtOuter + span.intTexStep[1];
|
||||||
#endif
|
#endif
|
||||||
#ifdef INTERP_TEX
|
#ifdef INTERP_TEX
|
||||||
dsInner = dsOuter + span.texStep[0][0];
|
dsInner = dsOuter + span.texStepX[0][0];
|
||||||
dtInner = dtOuter + span.texStep[0][1];
|
dtInner = dtOuter + span.texStepX[0][1];
|
||||||
duInner = duOuter + span.texStep[0][2];
|
duInner = duOuter + span.texStepX[0][2];
|
||||||
dvInner = dvOuter + span.texStep[0][3];
|
dvInner = dvOuter + span.texStepX[0][3];
|
||||||
#endif
|
#endif
|
||||||
#ifdef INTERP_MULTITEX
|
#ifdef INTERP_MULTITEX
|
||||||
{
|
{
|
||||||
GLuint u;
|
GLuint u;
|
||||||
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
||||||
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||||
dsInner[u] = dsOuter[u] + span.texStep[u][0];
|
dsInner[u] = dsOuter[u] + span.texStepX[u][0];
|
||||||
dtInner[u] = dtOuter[u] + span.texStep[u][1];
|
dtInner[u] = dtOuter[u] + span.texStepX[u][1];
|
||||||
duInner[u] = duOuter[u] + span.texStep[u][2];
|
duInner[u] = duOuter[u] + span.texStepX[u][2];
|
||||||
dvInner[u] = dvOuter[u] + span.texStep[u][3];
|
dvInner[u] = dvOuter[u] + span.texStepX[u][3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1428,7 +1394,6 @@
|
||||||
#undef INTERP_INT_TEX
|
#undef INTERP_INT_TEX
|
||||||
#undef INTERP_TEX
|
#undef INTERP_TEX
|
||||||
#undef INTERP_MULTITEX
|
#undef INTERP_MULTITEX
|
||||||
#undef INTERP_LAMBDA
|
|
||||||
#undef INTERP_FLOAT_RGBA
|
#undef INTERP_FLOAT_RGBA
|
||||||
#undef INTERP_FLOAT_SPEC
|
#undef INTERP_FLOAT_SPEC
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue