📄 s_triangle.c
字号:
#undef SPAN_NEAREST
#undef SPAN_LINEAR
/* restore state */
ctx->Texture._EnabledUnits = savedTexEnable;
}
/*
* Render an perspective corrected RGB/RGBA textured triangle.
* The Q (aka V in Mesa) coordinate must be zero such that the divide
* by interpolated Q/W comes out right.
*
*/
#define NAME persp_textured_triangle
#define INTERP_Z 1
#define INTERP_W 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
#define SETUP_CODE \
struct persp_info info; \
const struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
const struct gl_texture_object *obj = unit->Current2D; \
const GLint b = obj->BaseLevel; \
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; \
\
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 persp_textured_triangle");\
return; \
} \
info.tsize = obj->Image[0][b]->Height * info.tbytesline;
#define RENDER_SPAN( span ) \
span.interpMask &= ~SPAN_RGBA; \
span.arrayMask |= SPAN_RGBA; \
fast_persp_span(ctx, &span, &info);
#include "s_tritemp.h"
#endif /* CHAN_BITS != GL_FLOAT */
/*
* Render a smooth-shaded, textured, RGBA triangle.
* Interpolate S,T,R with perspective correction, w/out mipmapping.
*/
#define NAME general_textured_triangle
#define INTERP_Z 1
#define INTERP_W 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
/*
* This is the big one!
* Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
* Yup, it's slow.
*/
#define NAME multitextured_triangle
#define INTERP_Z 1
#define INTERP_W 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_SPEC 1
#define INTERP_MULTITEX 1
#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"
/*
* Special tri function for occlusion testing
*/
#define NAME occlusion_zless_triangle
#define INTERP_Z 1
#define SETUP_CODE \
struct gl_renderbuffer *rb \
= ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; \
ASSERT(ctx->Depth.Test); \
ASSERT(!ctx->Depth.Mask); \
ASSERT(ctx->Depth.Func == GL_LESS); \
if (ctx->OcclusionResult && !ctx->Occlusion.Active) { \
return; \
}
#define RENDER_SPAN( span ) \
if (ctx->Visual.depthBits <= 16) { \
GLuint i; \
const GLushort *zRow = (const GLushort *) \
rb->GetPointer(ctx, rb, span.x, span.y); \
for (i = 0; i < span.end; i++) { \
GLdepth z = FixedToDepth(span.z); \
if (z < zRow[i]) { \
ctx->OcclusionResult = GL_TRUE; \
ctx->Occlusion.PassedCounter++; \
} \
span.z += span.zStep; \
} \
} \
else { \
GLuint i; \
const GLuint *zRow = (const GLuint *) \
rb->GetPointer(ctx, rb, span.x, span.y); \
for (i = 0; i < span.end; i++) { \
if ((GLuint)span.z < zRow[i]) { \
ctx->OcclusionResult = GL_TRUE; \
ctx->Occlusion.PassedCounter++; \
} \
span.z += span.zStep; \
} \
}
#include "s_tritemp.h"
static void
nodraw_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
(void) (ctx && v0 && v1 && v2);
}
/*
* This is used when separate specular color is enabled, but not
* texturing. We add the specular color to the primary color,
* draw the triangle, then restore the original primary color.
* Inefficient, but seldom needed.
*/
void _swrast_add_spec_terms_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
SWvertex *ncv1 = (SWvertex *)v1;
SWvertex *ncv2 = (SWvertex *)v2;
#if CHAN_TYPE == GL_FLOAT
GLfloat rSum, gSum, bSum;
#else
GLint rSum, gSum, bSum;
#endif
GLchan c[3][4];
/* save original colors */
COPY_CHAN4( c[0], ncv0->color );
COPY_CHAN4( c[1], ncv1->color );
COPY_CHAN4( c[2], ncv2->color );
/* sum v0 */
rSum = ncv0->color[0] + ncv0->specular[0];
gSum = ncv0->color[1] + ncv0->specular[1];
bSum = ncv0->color[2] + ncv0->specular[2];
ncv0->color[0] = MIN2(rSum, CHAN_MAX);
ncv0->color[1] = MIN2(gSum, CHAN_MAX);
ncv0->color[2] = MIN2(bSum, CHAN_MAX);
/* sum v1 */
rSum = ncv1->color[0] + ncv1->specular[0];
gSum = ncv1->color[1] + ncv1->specular[1];
bSum = ncv1->color[2] + ncv1->specular[2];
ncv1->color[0] = MIN2(rSum, CHAN_MAX);
ncv1->color[1] = MIN2(gSum, CHAN_MAX);
ncv1->color[2] = MIN2(bSum, CHAN_MAX);
/* sum v2 */
rSum = ncv2->color[0] + ncv2->specular[0];
gSum = ncv2->color[1] + ncv2->specular[1];
bSum = ncv2->color[2] + ncv2->specular[2];
ncv2->color[0] = MIN2(rSum, CHAN_MAX);
ncv2->color[1] = MIN2(gSum, CHAN_MAX);
ncv2->color[2] = MIN2(bSum, CHAN_MAX);
/* draw */
SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
/* restore original colors */
COPY_CHAN4( ncv0->color, c[0] );
COPY_CHAN4( ncv1->color, c[1] );
COPY_CHAN4( ncv2->color, c[2] );
}
#ifdef DEBUG
/* record the current triangle function name */
const char *_mesa_triFuncName = NULL;
#define USE(triFunc) \
do { \
_mesa_triFuncName = #triFunc; \
/*printf("%s\n", _mesa_triFuncName);*/ \
swrast->Triangle = triFunc; \
} while (0)
#else
#define USE(triFunc) swrast->Triangle = triFunc;
#endif
/*
* Determine which triangle rendering function to use given the current
* rendering context.
*
* Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or
* remove tests to this code.
*/
void
_swrast_choose_triangle( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
USE(nodraw_triangle);
return;
}
if (ctx->RenderMode==GL_RENDER) {
if (ctx->Polygon.SmoothFlag) {
_swrast_set_aa_triangle_function(ctx);
ASSERT(swrast->Triangle);
return;
}
/* special case for occlusion testing */
if ((ctx->Depth.OcclusionTest || ctx->Occlusion.Active) &&
ctx->Depth.Test &&
ctx->Depth.Mask == GL_FALSE &&
ctx->Depth.Func == GL_LESS &&
!ctx->Stencil.Enabled) {
if ((rgbmode &&
ctx->Color.ColorMask[0] == 0 &&
ctx->Color.ColorMask[1] == 0 &&
ctx->Color.ColorMask[2] == 0 &&
ctx->Color.ColorMask[3] == 0)
||
(!rgbmode && ctx->Color.IndexMask == 0)) {
USE(occlusion_zless_triangle);
return;
}
}
if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Active) {
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
const struct gl_texture_object *texObj2D;
const struct gl_texture_image *texImg;
GLenum minFilter, magFilter, envMode;
GLint format;
texObj2D = ctx->Texture.Unit[0].Current2D;
texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
format = texImg ? texImg->TexFormat->MesaFormat : -1;
minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
envMode = ctx->Texture.Unit[0].EnvMode;
/* First see if we can use an optimized 2-D texture function */
if (ctx->Texture._EnabledCoordUnits == 0x1
&& !ctx->FragmentProgram._Active
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS == GL_REPEAT
&& texObj2D->WrapT == GL_REPEAT
&& texObj2D->_IsPowerOfTwo
&& texImg->Border == 0
&& texImg->Width == texImg->RowStride
&& (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
&& ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
if (minFilter == GL_NEAREST
&& format == MESA_FORMAT_RGB
&& (envMode == GL_REPLACE || envMode == GL_DECAL)
&& ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)
&& ctx->Depth.Func == GL_LESS
&& ctx->Depth.Mask == GL_TRUE)
|| swrast->_RasterMask == TEXTURE_BIT)
&& ctx->Polygon.StippleFlag == GL_FALSE
&& ctx->Visual.depthBits <= 16) {
if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) {
USE(simple_z_textured_triangle);
}
else {
USE(simple_textured_triangle);
}
}
else {
#if (CHAN_BITS == 16 || CHAN_BITS == 32)
USE(general_textured_triangle);
#else
USE(affine_textured_triangle);
#endif
}
}
else {
#if (CHAN_BITS == 16 || CHAN_BITS == 32)
USE(general_textured_triangle);
#else
USE(persp_textured_triangle);
#endif
}
}
else {
/* general case textured triangles */
if (ctx->Texture._EnabledCoordUnits > 1) {
USE(multitextured_triangle);
}
else {
USE(general_textured_triangle);
}
}
}
else {
ASSERT(!ctx->Texture._EnabledCoordUnits);
if (ctx->Light.ShadeModel==GL_SMOOTH) {
/* smooth shaded, no texturing, stippled or some raster ops */
if (rgbmode) {
USE(smooth_rgba_triangle);
}
else {
USE(smooth_ci_triangle);
}
}
else {
/* flat shaded, no texturing, stippled or some raster ops */
if (rgbmode) {
USE(flat_rgba_triangle);
}
else {
USE(flat_ci_triangle);
}
}
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
USE(_swrast_feedback_triangle);
}
else {
/* GL_SELECT mode */
USE(_swrast_select_triangle);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -