📄 s_triangle.c
字号:
break; } break; } ASSERT(span->arrayMask & SPAN_RGBA); _swrast_write_rgba_span(ctx, span);#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_RGB 1#define INTERP_ALPHA 1#define INTERP_ATTRIBS 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]->_BaseFormat; \ 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_TYPE != GL_FLOAT*//* * Render an RGBA triangle with arbitrary attributes. */#define NAME general_triangle#define INTERP_Z 1#define INTERP_RGB 1#define INTERP_ALPHA 1#define INTERP_ATTRIBS 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->_DepthBuffer; \ struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; \ ASSERT(ctx->Depth.Test); \ ASSERT(!ctx->Depth.Mask); \ ASSERT(ctx->Depth.Func == GL_LESS); \ if (!q) { \ return; \ }#define RENDER_SPAN( span ) \ if (rb->DepthBits <= 16) { \ GLuint i; \ const GLushort *zRow = (const GLushort *) \ rb->GetPointer(ctx, rb, span.x, span.y); \ for (i = 0; i < span.end; i++) { \ GLuint z = FixedToDepth(span.z); \ if (z < zRow[i]) { \ q->Result++; \ } \ 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]) { \ q->Result++; \ } \ span.z += span.zStep; \ } \ }#include "s_tritemp.h"static voidnodraw_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; GLfloat rSum, gSum, bSum; GLchan cSave[3][4]; /* save original colors */ COPY_CHAN4( cSave[0], ncv0->color ); COPY_CHAN4( cSave[1], ncv1->color ); COPY_CHAN4( cSave[2], ncv2->color ); /* sum v0 */ rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); /* sum v1 */ rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0]; gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1]; bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2]; UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); /* sum v2 */ rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0]; gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1]; bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2]; UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum); UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum); UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum); /* draw */ SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 ); /* restore original colors */ COPY_CHAN4( ncv0->color, cSave[0] ); COPY_CHAN4( ncv1->color, cSave[1] ); COPY_CHAN4( ncv2->color, cSave[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->Query.CurrentOcclusionObject && 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 (!rgbmode) { USE(ci_triangle); return; } /* * XXX should examine swrast->_ActiveAttribMask to determine what * needs to be interpolated. */ if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled || NEED_SECONDARY_COLOR(ctx) || swrast->_FogEnabled) { /* 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._Current && !ctx->ATIFragmentShader._Enabled && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && texObj2D->WrapS == GL_REPEAT && texObj2D->WrapT == GL_REPEAT && texImg->_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 && !swrast->_FogEnabled && 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->DrawBuffer->Visual.depthBits <= 16) { if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) { USE(simple_z_textured_triangle); } else { USE(simple_textured_triangle); } } else {#if CHAN_BITS != 8 USE(general_triangle);#else USE(affine_textured_triangle);#endif } } else {#if CHAN_BITS != 8 USE(general_triangle);#else USE(persp_textured_triangle);#endif } } else { /* general case textured triangles */ USE(general_triangle); } } else { ASSERT(!swrast->_FogEnabled); ASSERT(!NEED_SECONDARY_COLOR(ctx)); if (ctx->Light.ShadeModel==GL_SMOOTH) { /* smooth shaded, no texturing, stippled or some raster ops */#if CHAN_BITS != 8 USE(general_triangle);#else USE(smooth_rgba_triangle);#endif } else { /* flat shaded, no texturing, stippled or some raster ops */#if CHAN_BITS != 8 USE(general_triangle);#else USE(flat_rgba_triangle);#endif } } } 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 + -