static void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { GLchan *c = (GLchan *)v; (void) a; UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); c[2] = 0; c[3] = CHAN_MAX; }
static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { GLchan *c = (GLchan *)v; DEBUG_INSERT; (void) a; UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]); }
/** * Convert GLfloat[n][4] colors to GLchan[n][4]. * XXX maybe move into image.c */ static void float_span_to_chan(GLuint n, CONST GLfloat in[][4], GLchan out[][4]) { GLuint i; for (i = 0; i < n; i++) { UNCLAMPED_FLOAT_TO_CHAN(out[i][RCOMP], in[i][RCOMP]); UNCLAMPED_FLOAT_TO_CHAN(out[i][GCOMP], in[i][GCOMP]); UNCLAMPED_FLOAT_TO_CHAN(out[i][BCOMP], in[i][BCOMP]); UNCLAMPED_FLOAT_TO_CHAN(out[i][ACOMP], in[i][ACOMP]); } }
__inline DWORD _gldComputeFog( GLcontext *ctx, SWvertex *swv) { // Full fog calculation. // Based on Mesa code. GLchan rFog, gFog, bFog; GLchan fR, fG, fB; const GLfloat f = swv->fog; const GLfloat g = 1.0f - f; UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]); UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]); UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]); fR = f * swv->color[0] + g * rFog; fG = f * swv->color[1] + g * gFog; fB = f * swv->color[2] + g * bFog; return D3DCOLOR_RGBA(fR, fG, fB, swv->color[3]); }
/** * Add specular color to primary color, draw point, restore original * primary color. */ void _swrast_add_spec_terms_point(GLcontext *ctx, const SWvertex *v0) { SWvertex *ncv0 = (SWvertex *) v0; /* cast away const */ GLfloat rSum, gSum, bSum; GLchan cSave[4]; /* save */ COPY_CHAN4(cSave, ncv0->color); /* sum */ 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); /* draw */ SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0); /* restore */ COPY_CHAN4(ncv0->color, cSave); }
void _swrast_add_spec_terms_line(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1) { SWvertex *ncv0 = (SWvertex *)v0; SWvertex *ncv1 = (SWvertex *)v1; GLfloat rSum, gSum, bSum; GLchan cSave[2][4]; /* save original colors */ COPY_CHAN4(cSave[0], ncv0->color); COPY_CHAN4(cSave[1], ncv1->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); /* draw */ SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 ); /* restore original colors */ COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] ); COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[1] ); }
/** * Adaptor for fetching a GLchan texel from a float-valued texture. */ static void fetch_texel_float_to_chan(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texelOut) { GLfloat temp[4]; GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat); ASSERT(texImage->FetchTexelf); texImage->FetchTexelf(texImage, i, j, k, temp); if (baseFormat == GL_DEPTH_COMPONENT || baseFormat == GL_DEPTH_STENCIL_EXT) { /* just one channel */ UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]); } else { /* four channels */ UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]); UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]); UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]); UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]); } }
/** * Execute the current fragment program, operating on the given span. */ void _swrast_exec_fragment_shader(GLcontext * ctx, struct sw_span *span) { const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; GLuint i; ctx->_CurrentProgram = GL_FRAGMENT_SHADER_ATI; for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { init_machine(ctx, &ctx->ATIFragmentShader.Machine, ctx->ATIFragmentShader.Current, span, i); if (execute_shader(ctx, shader, ~0, &ctx->ATIFragmentShader.Machine, span, i)) { span->array->mask[i] = GL_FALSE; } { const GLfloat *colOut = ctx->ATIFragmentShader.Machine.Registers[0]; /*fprintf(stderr,"outputs %f %f %f %f\n", colOut[0], colOut[1], colOut[2], colOut[3]); */ UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]); UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], colOut[1]); UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]); UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]); } } } ctx->_CurrentProgram = 0; }
/** * Do texture application for: * GL_EXT_texture_env_combine * GL_ARB_texture_env_combine * GL_EXT_texture_env_dot3 * GL_ARB_texture_env_dot3 * GL_ATI_texture_env_combine3 * GL_NV_texture_env_combine4 * conventional GL texture env modes * * \param ctx rendering context * \param unit the texture combiner unit * \param primary_rgba incoming fragment color array * \param texelBuffer pointer to texel colors for all texture units * * \param span two fields are used in this function: * span->end: number of fragments to process * span->array->rgba: incoming/result fragment colors */ static void texture_combine( struct gl_context *ctx, GLuint unit, const float4_array primary_rgba, const GLfloat *texelBuffer, SWspan *span ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine; float4_array argRGB[MAX_COMBINER_TERMS]; float4_array argA[MAX_COMBINER_TERMS]; const GLfloat scaleRGB = (GLfloat) (1 << combine->ScaleShiftRGB); const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA); const GLuint numArgsRGB = combine->_NumArgsRGB; const GLuint numArgsA = combine->_NumArgsA; float4_array ccolor[4], rgba; GLuint i, term; GLuint n = span->end; GLchan (*rgbaChan)[4] = span->array->rgba; /* alloc temp pixel buffers */ rgba = malloc(4 * n * sizeof(GLfloat)); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); return; } for (i = 0; i < numArgsRGB || i < numArgsA; i++) { ccolor[i] = malloc(4 * n * sizeof(GLfloat)); if (!ccolor[i]) { while (i) { free(ccolor[i]); i--; } _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); free(rgba); return; } } for (i = 0; i < n; i++) { rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]); rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]); rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]); rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]); } /* printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n", combine->ModeRGB, combine->ModeA, combine->SourceRGB[0], combine->SourceA[0], combine->SourceRGB[1], combine->SourceA[1]); */ /* * Do operand setup for up to 4 operands. Loop over the terms. */ for (term = 0; term < numArgsRGB; term++) { const GLenum srcRGB = combine->SourceRGB[term]; const GLenum operandRGB = combine->OperandRGB[term]; switch (srcRGB) { case GL_TEXTURE: argRGB[term] = get_texel_array(swrast, unit); break; case GL_PRIMARY_COLOR: argRGB[term] = primary_rgba; break; case GL_PREVIOUS: argRGB[term] = rgba; break; case GL_CONSTANT: { float4_array c = ccolor[term]; GLfloat red = textureUnit->EnvColor[0]; GLfloat green = textureUnit->EnvColor[1]; GLfloat blue = textureUnit->EnvColor[2]; GLfloat alpha = textureUnit->EnvColor[3]; for (i = 0; i < n; i++) { ASSIGN_4V(c[i], red, green, blue, alpha); } argRGB[term] = ccolor[term]; } break; /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. */ case GL_ZERO: { float4_array c = ccolor[term]; for (i = 0; i < n; i++) { ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F); } argRGB[term] = ccolor[term]; } break; case GL_ONE: { float4_array c = ccolor[term]; for (i = 0; i < n; i++) { ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F); } argRGB[term] = ccolor[term]; } break; default: /* ARB_texture_env_crossbar source */ { const GLuint srcUnit = srcRGB - GL_TEXTURE0; ASSERT(srcUnit < ctx->Const.MaxTextureUnits); if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) goto end; argRGB[term] = get_texel_array(swrast, srcUnit); } } if (operandRGB != GL_SRC_COLOR) { float4_array src = argRGB[term]; float4_array dst = ccolor[term]; /* point to new arg[term] storage */ argRGB[term] = ccolor[term]; switch (operandRGB) { case GL_ONE_MINUS_SRC_COLOR: for (i = 0; i < n; i++) { dst[i][RCOMP] = 1.0F - src[i][RCOMP]; dst[i][GCOMP] = 1.0F - src[i][GCOMP]; dst[i][BCOMP] = 1.0F - src[i][BCOMP]; } break; case GL_SRC_ALPHA: for (i = 0; i < n; i++) { dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = src[i][ACOMP]; } break; case GL_ONE_MINUS_SRC_ALPHA: for (i = 0; i < n; i++) { dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = 1.0F - src[i][ACOMP]; } break; default: _mesa_problem(ctx, "Bad operandRGB"); } } } /* * Set up the argA[term] pointers */ for (term = 0; term < numArgsA; term++) { const GLenum srcA = combine->SourceA[term]; const GLenum operandA = combine->OperandA[term]; switch (srcA) { case GL_TEXTURE: argA[term] = get_texel_array(swrast, unit); break; case GL_PRIMARY_COLOR: argA[term] = primary_rgba; break; case GL_PREVIOUS: argA[term] = rgba; break; case GL_CONSTANT: { float4_array c = ccolor[term]; GLfloat alpha = textureUnit->EnvColor[3]; for (i = 0; i < n; i++) c[i][ACOMP] = alpha; argA[term] = ccolor[term]; } break; /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. */ case GL_ZERO: { float4_array c = ccolor[term]; for (i = 0; i < n; i++) c[i][ACOMP] = 0.0F; argA[term] = ccolor[term]; } break; case GL_ONE: { float4_array c = ccolor[term]; for (i = 0; i < n; i++) c[i][ACOMP] = 1.0F; argA[term] = ccolor[term]; } break; default: /* ARB_texture_env_crossbar source */ { const GLuint srcUnit = srcA - GL_TEXTURE0; ASSERT(srcUnit < ctx->Const.MaxTextureUnits); if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) goto end; argA[term] = get_texel_array(swrast, srcUnit); } } if (operandA == GL_ONE_MINUS_SRC_ALPHA) { float4_array src = argA[term]; float4_array dst = ccolor[term]; argA[term] = ccolor[term]; for (i = 0; i < n; i++) { dst[i][ACOMP] = 1.0F - src[i][ACOMP]; } } } /* RGB channel combine */ { float4_array arg0 = argRGB[0]; float4_array arg1 = argRGB[1]; float4_array arg2 = argRGB[2]; float4_array arg3 = argRGB[3]; switch (combine->ModeRGB) { case GL_REPLACE: for (i = 0; i < n; i++) { rgba[i][RCOMP] = arg0[i][RCOMP] * scaleRGB; rgba[i][GCOMP] = arg0[i][GCOMP] * scaleRGB; rgba[i][BCOMP] = arg0[i][BCOMP] * scaleRGB; } break; case GL_MODULATE: for (i = 0; i < n; i++) { rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * scaleRGB; rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * scaleRGB; rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * scaleRGB; } break; case GL_ADD: if (textureUnit->EnvMode == GL_COMBINE4_NV) { /* (a * b) + (c * d) */ for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + arg2[i][RCOMP] * arg3[i][RCOMP]) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + arg2[i][GCOMP] * arg3[i][GCOMP]) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + arg2[i][BCOMP] * arg3[i][BCOMP]) * scaleRGB; } } else { /* 2-term addition */ for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * scaleRGB; } } break; case GL_ADD_SIGNED: if (textureUnit->EnvMode == GL_COMBINE4_NV) { /* (a * b) + (c * d) - 0.5 */ for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5F) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5F) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5F) * scaleRGB; } } else { for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5F) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5F) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5F) * scaleRGB; } } break; case GL_INTERPOLATE: for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * scaleRGB; } break; case GL_SUBTRACT: for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * scaleRGB; } break; case GL_DOT3_RGB_EXT: case GL_DOT3_RGBA_EXT: /* Do not scale the result by 1 2 or 4 */ for (i = 0; i < n; i++) { GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) + (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) * 4.0F; dot = CLAMP(dot, 0.0F, 1.0F); rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; } break; case GL_DOT3_RGB: case GL_DOT3_RGBA: /* DO scale the result by 1 2 or 4 */ for (i = 0; i < n; i++) { GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) + (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) * 4.0F * scaleRGB; dot = CLAMP(dot, 0.0F, 1.0F); rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; } break; case GL_MODULATE_ADD_ATI: for (i = 0; i < n; i++) { rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * scaleRGB; rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * scaleRGB; rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * scaleRGB; } break; case GL_MODULATE_SIGNED_ADD_ATI: for (i = 0; i < n; i++) { rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5F) * scaleRGB; rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5F) * scaleRGB; rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5F) * scaleRGB; } break; case GL_MODULATE_SUBTRACT_ATI: for (i = 0; i < n; i++) { rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * scaleRGB; rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * scaleRGB; rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * scaleRGB; } break; case GL_BUMP_ENVMAP_ATI: /* this produces a fixed rgba color, and the coord calc is done elsewhere */ for (i = 0; i < n; i++) { /* rgba result is 0,0,0,1 */ rgba[i][RCOMP] = 0.0; rgba[i][GCOMP] = 0.0; rgba[i][BCOMP] = 0.0; rgba[i][ACOMP] = 1.0; } goto end; /* no alpha processing */ default: _mesa_problem(ctx, "invalid combine mode"); } } /* Alpha channel combine */ { float4_array arg0 = argA[0]; float4_array arg1 = argA[1]; float4_array arg2 = argA[2]; float4_array arg3 = argA[3]; switch (combine->ModeA) { case GL_REPLACE: for (i = 0; i < n; i++) { rgba[i][ACOMP] = arg0[i][ACOMP] * scaleA; } break; case GL_MODULATE: for (i = 0; i < n; i++) { rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * scaleA; } break; case GL_ADD: if (textureUnit->EnvMode == GL_COMBINE4_NV) { /* (a * b) + (c * d) */ for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + arg2[i][ACOMP] * arg3[i][ACOMP]) * scaleA; } } else { /* two-term add */ for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * scaleA; } } break; case GL_ADD_SIGNED: if (textureUnit->EnvMode == GL_COMBINE4_NV) { /* (a * b) + (c * d) - 0.5 */ for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + arg2[i][ACOMP] * arg3[i][ACOMP] - 0.5F) * scaleA; } } else { /* a + b - 0.5 */ for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * scaleA; } } break; case GL_INTERPOLATE: for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP])) * scaleA; } break; case GL_SUBTRACT: for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * scaleA; } break; case GL_MODULATE_ADD_ATI: for (i = 0; i < n; i++) { rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * scaleA; } break; case GL_MODULATE_SIGNED_ADD_ATI: for (i = 0; i < n; i++) { rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * scaleA; } break; case GL_MODULATE_SUBTRACT_ATI: for (i = 0; i < n; i++) { rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * scaleA; } break; default: _mesa_problem(ctx, "invalid combine mode"); } } /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining. * This is kind of a kludge. It would have been better if the spec * were written such that the GL_COMBINE_ALPHA value could be set to * GL_DOT3. */ if (combine->ModeRGB == GL_DOT3_RGBA_EXT || combine->ModeRGB == GL_DOT3_RGBA) { for (i = 0; i < n; i++) { rgba[i][ACOMP] = rgba[i][RCOMP]; } } for (i = 0; i < n; i++) { UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]); UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]); UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]); UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]); } /* The span->array->rgba values are of CHAN type so set * span->array->ChanType field accordingly. */ span->array->ChanType = CHAN_TYPE; end: for (i = 0; i < numArgsRGB || i < numArgsA; i++) { free(ccolor[i]); } free(rgba); }
/** Set a float-valued texture parameter */ static void set_tex_parameterf(GLcontext *ctx, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params) { switch (pname) { case GL_TEXTURE_MIN_LOD: if (texObj->MinLod == params[0]) return; flush(ctx, texObj); texObj->MinLod = params[0]; return; case GL_TEXTURE_MAX_LOD: if (texObj->MaxLod == params[0]) return; flush(ctx, texObj); texObj->MaxLod = params[0]; return; case GL_TEXTURE_PRIORITY: flush(ctx, texObj); texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); return; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { if (texObj->MaxAnisotropy == params[0]) return; if (params[0] < 1.0) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); return; } flush(ctx, texObj); /* clamp to max, that's what NVIDIA does */ texObj->MaxAnisotropy = MIN2(params[0], ctx->Const.MaxTextureMaxAnisotropy); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); } return; case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: if (ctx->Extensions.SGIX_shadow_ambient) { if (texObj->ShadowAmbient != params[0]) { flush(ctx, texObj); texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F); } } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)"); } return; case GL_TEXTURE_LOD_BIAS: /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */ if (ctx->Extensions.EXT_texture_lod_bias) { if (texObj->LodBias != params[0]) { flush(ctx, texObj); texObj->LodBias = params[0]; } } break; case GL_TEXTURE_BORDER_COLOR: flush(ctx, texObj); texObj->BorderColor[RCOMP] = params[0]; texObj->BorderColor[GCOMP] = params[1]; texObj->BorderColor[BCOMP] = params[2]; texObj->BorderColor[ACOMP] = params[3]; UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]); UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]); UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]); UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]); return; default: _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); } }
/** * Set default fragment attributes for the span using the * current raster values. Used prior to glDraw/CopyPixels * and glBitmap. */ void _swrast_span_default_attribs(struct gl_context *ctx, SWspan *span) { GLchan r, g, b, a; /* Z*/ { const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; if (ctx->DrawBuffer->Visual.depthBits <= 16) span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); else { GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; tmpf = MIN2(tmpf, depthMax); span->z = (GLint)tmpf; } span->zStep = 0; span->interpMask |= SPAN_Z; } /* W (for perspective correction) */ span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0; span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0; span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; /* primary color, or color index */ UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); #if CHAN_TYPE == GL_FLOAT span->red = r; span->green = g; span->blue = b; span->alpha = a; #else span->red = IntToFixed(r); span->green = IntToFixed(g); span->blue = IntToFixed(b); span->alpha = IntToFixed(a); #endif span->redStep = 0; span->greenStep = 0; span->blueStep = 0; span->alphaStep = 0; span->interpMask |= SPAN_RGBA; COPY_4V(span->attrStart[FRAG_ATTRIB_COL], ctx->Current.RasterColor); ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL], 0.0, 0.0, 0.0, 0.0); ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL], 0.0, 0.0, 0.0, 0.0); /* fog */ { const SWcontext *swrast = SWRAST_CONTEXT(ctx); GLfloat fogVal; /* a coord or a blend factor */ if (swrast->_PreferPixelFog) { /* fog blend factors will be computed from fog coordinates per pixel */ fogVal = ctx->Current.RasterDistance; } else { /* fog blend factor should be computed from fogcoord now */ fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); } span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; } /* texcoords */ { const GLuint attr = FRAG_ATTRIB_TEX; const GLfloat *tc = ctx->Current.RasterTexCoords; if (tc[3] > 0.0F) { /* use (s/q, t/q, r/q, 1) */ span->attrStart[attr][0] = tc[0] / tc[3]; span->attrStart[attr][1] = tc[1] / tc[3]; span->attrStart[attr][2] = tc[2] / tc[3]; span->attrStart[attr][3] = 1.0; } else { ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); } ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); } }
static GLboolean check_vtx_fmt( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint ind = RADEON_CP_VC_FRMT_Z; GLuint unit; if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))) return GL_FALSE; if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); /* Make all this event-driven: */ if (ctx->Light.Enabled) { ind |= RADEON_CP_VC_FRMT_N0; /* TODO: make this data driven: If we receive only ubytes, send * color as ubytes. Also check if converting (with free * checking for overflow) is cheaper than sending floats * directly. */ if (ctx->Light.ColorMaterialEnabled) { ind |= (RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA); } else ind |= RADEON_CP_VC_FRMT_PKCOLOR; /* for alpha? */ } else { /* TODO: make this data driven? */ ind |= RADEON_CP_VC_FRMT_PKCOLOR; if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { ind |= RADEON_CP_VC_FRMT_PKSPEC; } } if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { ind |= RADEON_CP_VC_FRMT_PKSPEC; } for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { if (ctx->Texture.Unit[unit].TexGenEnabled) { if (rmesa->TexGenNeedNormals[unit]) { ind |= RADEON_CP_VC_FRMT_N0; } } else { if (ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] != 1.0) { if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) fprintf(stderr, "%s: q%u\n", __FUNCTION__, unit); return GL_FALSE; } ind |= RADEON_ST_BIT(unit); } } } if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind ); RADEON_NEWPRIM(rmesa); rmesa->vb.vertex_format = ind; rmesa->vb.vertex_size = 3; rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; rmesa->vb.colorptr = NULL; rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; rmesa->vb.specptr = NULL; rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ /* Run through and initialize the vertex components in the order * the hardware understands: */ if (ind & RADEON_CP_VC_FRMT_N0) { rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 3; rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; } if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; rmesa->vb.vertex_size += 1; UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); } if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR)); rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 3; rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; if (ind & RADEON_CP_VC_FRMT_FPALPHA) { rmesa->vb.vertex_size += 1; rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; } } if (ind & RADEON_CP_VC_FRMT_PKSPEC) { rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; rmesa->vb.vertex_size += 1; UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); /* fog ??? */ /* UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha, radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */ } for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { if (ind & RADEON_ST_BIT(unit)) { rmesa->vb.texcoordptr[unit] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 2; rmesa->vb.texcoordptr[unit][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0]; rmesa->vb.texcoordptr[unit][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1]; } } if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) { if (RADEON_DEBUG & DEBUG_VFMT) fprintf(stderr, "reinstall on vertex_format change\n"); _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format; } if (RADEON_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s -- success\n", __FUNCTION__); return GL_TRUE; }
/** * Determines the hardware vertex format based on the current state vector. * * \returns * If the hardware TCL unit is capable of handling the current state vector, * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. * * \todo * Make this color format selection data driven. If we receive only ubytes, * send color as ubytes. Also check if converting (with free checking for * overflow) is cheaper than sending floats directly. * * \todo * When intializing texture coordinates, it might be faster to just copy the * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that * some of the data (i.e., the last texture coordinate components) get copied * over, but that still may be faster than the conditional branching. If * nothing else, the code will be smaller and easier to follow. */ static GLboolean check_vtx_fmt( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint ind0 = R200_VTX_Z0; GLuint ind1 = 0; GLuint i; GLuint count[R200_MAX_TEXTURE_UNITS]; if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag) return GL_FALSE; if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); /* Make all this event-driven: */ if (ctx->Light.Enabled) { ind0 |= R200_VTX_N0; if (ctx->Light.ColorMaterialEnabled) ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; else ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; } else { /* TODO: make this data driven? */ ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; } } if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { ind0 |= R200_VTX_DISCRETE_FOG; } for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { count[i] = 0; if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { ind0 |= R200_VTX_N0; } else { switch( ctx->Texture.Unit[i]._ReallyEnabled ) { case TEXTURE_CUBE_BIT: case TEXTURE_3D_BIT: count[i] = 3; break; case TEXTURE_2D_BIT: case TEXTURE_RECT_BIT: count[i] = 2; break; case TEXTURE_1D_BIT: count[i] = 1; break; } ind1 |= count[i] << (3 * i); } } } if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); R200_NEWPRIM(rmesa); rmesa->vb.vtxfmt_0 = ind0; rmesa->vb.vtxfmt_1 = ind1; rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; rmesa->vb.vertex_size = 3; rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; rmesa->vb.colorptr = NULL; rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG]; rmesa->vb.specptr = NULL; rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3]; rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4]; rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5]; rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ /* Run through and initialize the vertex components in the order * the hardware understands: */ if (ind0 & R200_VTX_N0) { rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 3; rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; } if (ind0 & R200_VTX_DISCRETE_FOG) { rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 1; rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; } if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; rmesa->vb.vertex_size += 1; UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 4; rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; } else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; rmesa->vb.vertex_size += 3; rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; } if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; rmesa->vb.vertex_size += 1; UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); } for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { if ( count[i] != 0 ) { float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i]; unsigned j; rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; for ( j = 0 ; j < count[i] ; j++ ) { rmesa->vb.texcoordptr[i][j] = attr[j]; } rmesa->vb.vertex_size += count[i]; } } if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) { if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "reinstall on vertex_format change\n"); _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0; } if (R200_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s -- success\n", __FUNCTION__); return GL_TRUE; }