📄 s_triangle.c
字号:
if (t == info->tmask) { \
tex10 -= info->tsize; \
tex11 -= info->tsize; \
} \
if (s == info->smask) { \
tex01 -= info->tbytesline; \
tex11 -= info->tbytesline; \
} \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
span->intTex[0] += span->intTexStep[0]; \
span->intTex[1] += span->intTexStep[1]; \
dest += 4; \
}
GLuint i;
GLchan *dest = span->array->rgba[0];
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
switch (info->filter) {
case GL_NEAREST:
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch(info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
return;
}
break;
}
break;
case GL_LINEAR:
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
return;
}
break;
}
break;
}
span->interpMask &= ~SPAN_RGBA;
ASSERT(span->arrayMask & SPAN_RGBA);
_swrast_write_rgba_span(ctx, span);
#undef SPAN_NEAREST
#undef SPAN_LINEAR
}
/*
* Render an RGB/RGBA textured triangle without perspective correction.
*/
#define NAME affine_textured_triangle
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_INT_TEX 1
#define S_SCALE twidth
#define T_SCALE theight
#define SETUP_CODE \
struct affine_info info; \
struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
struct gl_texture_object *obj = unit->Current2D; \
const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \
info.texture = (const GLchan *) obj->Image[0][b]->Data; \
info.twidth_log2 = obj->Image[0][b]->WidthLog2; \
info.smask = obj->Image[0][b]->Width - 1; \
info.tmask = obj->Image[0][b]->Height - 1; \
info.format = obj->Image[0][b]->Format; \
info.filter = obj->MinFilter; \
info.envmode = unit->EnvMode; \
span.arrayMask |= SPAN_RGBA; \
\
if (info.envmode == GL_BLEND) { \
/* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \
info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \
info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \
info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \
info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \
} \
if (!info.texture) { \
/* this shouldn't happen */ \
return; \
} \
\
switch (info.format) { \
case GL_ALPHA: \
case GL_LUMINANCE: \
case GL_INTENSITY: \
info.tbytesline = obj->Image[0][b]->Width; \
break; \
case GL_LUMINANCE_ALPHA: \
info.tbytesline = obj->Image[0][b]->Width * 2; \
break; \
case GL_RGB: \
info.tbytesline = obj->Image[0][b]->Width * 3; \
break; \
case GL_RGBA: \
info.tbytesline = obj->Image[0][b]->Width * 4; \
break; \
default: \
_mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
return; \
} \
info.tsize = obj->Image[0][b]->Height * info.tbytesline;
#define RENDER_SPAN( span ) affine_span(ctx, &span, &info);
#include "s_tritemp.h"
struct persp_info
{
GLenum filter;
GLenum format;
GLenum envmode;
GLint smask, tmask;
GLint twidth_log2;
const GLchan *texture;
GLfixed er, eg, eb, ea; /* texture env color */
GLint tbytesline, tsize;
};
static INLINE void
fast_persp_span(GLcontext *ctx, struct sw_span *span,
struct persp_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
/* Instead of defining a function for each mode, a test is done
* between the outer and inner loops. This is to reduce code size
* and complexity. Observe that an optimizing compiler kills
* unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
*/
#define SPAN_NEAREST(DO_TEX,COMP) \
for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \
GLint s = IFLOOR(s_tmp) & info->smask; \
GLint t = IFLOOR(t_tmp) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
tex_coord[0] += tex_step[0]; \
tex_coord[1] += tex_step[1]; \
tex_coord[2] += tex_step[2]; \
dest += 4; \
}
#define SPAN_LINEAR(DO_TEX,COMP) \
for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
const GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
const GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \
const GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF; \
const GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF; \
const GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \
const GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \
const GLfixed sf = s_fix & FIXED_FRAC_MASK; \
const GLfixed tf = t_fix & FIXED_FRAC_MASK; \
const GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
const GLchan *tex10 = tex00 + info->tbytesline; \
const GLchan *tex01 = tex00 + COMP; \
const GLchan *tex11 = tex10 + COMP; \
if (t == info->tmask) { \
tex10 -= info->tsize; \
tex11 -= info->tsize; \
} \
if (s == info->smask) { \
tex01 -= info->tbytesline; \
tex11 -= info->tbytesline; \
} \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
tex_coord[0] += tex_step[0]; \
tex_coord[1] += tex_step[1]; \
tex_coord[2] += tex_step[2]; \
dest += 4; \
}
GLuint i;
GLfloat tex_coord[3], tex_step[3];
GLchan *dest = span->array->rgba[0];
const GLuint savedTexEnable = ctx->Texture._EnabledUnits;
ctx->Texture._EnabledUnits = 0;
tex_coord[0] = span->tex[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_step[1] = span->texStepX[0][1] * (info->tmask + 1);
/* span->tex[0][2] only if 3D-texturing, here only 2D */
tex_coord[2] = span->tex[0][3];
tex_step[2] = span->texStepX[0][3];
switch (info->filter) {
case GL_NEAREST:
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch(info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
return;
}
break;
}
break;
case GL_LINEAR:
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
return;
}
break;
}
break;
}
ASSERT(span->arrayMask & SPAN_RGBA);
_swrast_write_rgba_span(ctx, span);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -