Initial work for supporting different renderbuffer color depths at runtime.
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 4.1
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -37,188 +36,125 @@
|
||||
#include "s_context.h"
|
||||
|
||||
|
||||
#define ALPHA_TEST(ALPHA, LOOP_CODE) \
|
||||
do { \
|
||||
switch (ctx->Color.AlphaFunc) { \
|
||||
case GL_LESS: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
mask[i] &= (ALPHA < ref); \
|
||||
LOOP_CODE; \
|
||||
} \
|
||||
break; \
|
||||
case GL_LEQUAL: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
mask[i] &= (ALPHA <= ref); \
|
||||
LOOP_CODE; \
|
||||
} \
|
||||
break; \
|
||||
case GL_GEQUAL: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
mask[i] &= (ALPHA >= ref); \
|
||||
LOOP_CODE; \
|
||||
} \
|
||||
break; \
|
||||
case GL_GREATER: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
mask[i] &= (ALPHA > ref); \
|
||||
LOOP_CODE; \
|
||||
} \
|
||||
break; \
|
||||
case GL_NOTEQUAL: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
mask[i] &= (ALPHA != ref); \
|
||||
LOOP_CODE; \
|
||||
} \
|
||||
break; \
|
||||
case GL_EQUAL: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
mask[i] &= (ALPHA == ref); \
|
||||
LOOP_CODE; \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
_mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \
|
||||
return 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \fn GLint _swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
|
||||
* \brief Apply the alpha test to a span of pixels.
|
||||
* \return
|
||||
* - "0" = all pixels in the span failed the alpha test.
|
||||
* - "1" = one or more pixels passed the alpha test.
|
||||
* Perform the alpha test for an array of pixels.
|
||||
* For pixels that fail the test, mask[i] will be set to 0.
|
||||
* \return 0 if all pixels in the span failed the alpha test,
|
||||
* 1 if one or more pixels passed the alpha test.
|
||||
*/
|
||||
GLint
|
||||
_swrast_alpha_test(const GLcontext *ctx, struct sw_span *span)
|
||||
{
|
||||
const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
|
||||
GLchan ref;
|
||||
const GLuint n = span->end;
|
||||
GLubyte *mask = span->array->mask;
|
||||
GLuint i;
|
||||
|
||||
CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
|
||||
|
||||
if (span->arrayMask & SPAN_RGBA) {
|
||||
/* Use the array values */
|
||||
switch (ctx->Color.AlphaFunc) {
|
||||
case GL_LESS:
|
||||
for (i = 0; i < n; i++)
|
||||
mask[i] &= (rgba[i][ACOMP] < ref);
|
||||
break;
|
||||
case GL_LEQUAL:
|
||||
for (i = 0; i < n; i++)
|
||||
mask[i] &= (rgba[i][ACOMP] <= ref);
|
||||
break;
|
||||
case GL_GEQUAL:
|
||||
for (i = 0; i < n; i++)
|
||||
mask[i] &= (rgba[i][ACOMP] >= ref);
|
||||
break;
|
||||
case GL_GREATER:
|
||||
for (i = 0; i < n; i++)
|
||||
mask[i] &= (rgba[i][ACOMP] > ref);
|
||||
break;
|
||||
case GL_NOTEQUAL:
|
||||
for (i = 0; i < n; i++)
|
||||
mask[i] &= (rgba[i][ACOMP] != ref);
|
||||
break;
|
||||
case GL_EQUAL:
|
||||
for (i = 0; i < n; i++)
|
||||
mask[i] &= (rgba[i][ACOMP] == ref);
|
||||
break;
|
||||
case GL_ALWAYS:
|
||||
if (ctx->Color.AlphaFunc == GL_ALWAYS) {
|
||||
/* do nothing */
|
||||
return 1;
|
||||
case GL_NEVER:
|
||||
/* caller should check for zero! */
|
||||
}
|
||||
else if (ctx->Color.AlphaFunc == GL_NEVER) {
|
||||
/* All pixels failed - caller should check for this return value and
|
||||
* act accordingly.
|
||||
*/
|
||||
span->writeAll = GL_FALSE;
|
||||
return 0;
|
||||
default:
|
||||
_mesa_problem( ctx, "Invalid alpha test in _swrast_alpha_test" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (span->arrayMask & SPAN_RGBA) {
|
||||
/* Use array's alpha values */
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
|
||||
GLubyte ref;
|
||||
CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
|
||||
ALPHA_TEST(rgba[i][ACOMP], ;);
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
GLushort (*rgba)[4] = span->array->color.sz2.rgba;
|
||||
GLushort ref;
|
||||
CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
|
||||
ALPHA_TEST(rgba[i][ACOMP], ;);
|
||||
}
|
||||
else {
|
||||
GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
|
||||
const GLfloat ref = ctx->Color.AlphaRef;
|
||||
ALPHA_TEST(rgba[i][ACOMP], ;);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use the interpolation values */
|
||||
#if CHAN_TYPE == GL_FLOAT
|
||||
const GLfloat alphaStep = span->alphaStep;
|
||||
GLfloat alpha = span->alpha;
|
||||
/* Interpolate alpha values */
|
||||
ASSERT(span->interpMask & SPAN_RGBA);
|
||||
switch (ctx->Color.AlphaFunc) {
|
||||
case GL_LESS:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (alpha < ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_LEQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (alpha <= ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_GEQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (alpha >= ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_GREATER:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (alpha > ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_NOTEQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (alpha != ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_EQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (alpha == ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_ALWAYS:
|
||||
/* do nothing */
|
||||
return 1;
|
||||
case GL_NEVER:
|
||||
/* caller should check for zero! */
|
||||
span->writeAll = GL_FALSE;
|
||||
return 0;
|
||||
default:
|
||||
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* 8 or 16-bit channel interpolation */
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
const GLfixed alphaStep = span->alphaStep;
|
||||
GLfixed alpha = span->alpha;
|
||||
ASSERT(span->interpMask & SPAN_RGBA);
|
||||
switch (ctx->Color.AlphaFunc) {
|
||||
case GL_LESS:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (FixedToChan(alpha) < ref);
|
||||
alpha += alphaStep;
|
||||
GLubyte ref;
|
||||
CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
|
||||
ALPHA_TEST(alpha, alpha += alphaStep);
|
||||
}
|
||||
break;
|
||||
case GL_LEQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (FixedToChan(alpha) <= ref);
|
||||
alpha += alphaStep;
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
const GLfixed alphaStep = span->alphaStep;
|
||||
GLfixed alpha = span->alpha;
|
||||
GLushort ref;
|
||||
CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
|
||||
ALPHA_TEST(alpha, alpha += alphaStep);
|
||||
}
|
||||
break;
|
||||
case GL_GEQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (FixedToChan(alpha) >= ref);
|
||||
alpha += alphaStep;
|
||||
else {
|
||||
const GLfloat alphaStep = span->alphaStep;
|
||||
GLfloat alpha = span->alpha;
|
||||
const GLfloat ref = ctx->Color.AlphaRef;
|
||||
ALPHA_TEST(alpha, alpha += alphaStep);
|
||||
}
|
||||
break;
|
||||
case GL_GREATER:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (FixedToChan(alpha) > ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_NOTEQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (FixedToChan(alpha) != ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_EQUAL:
|
||||
for (i = 0; i < n; i++) {
|
||||
mask[i] &= (FixedToChan(alpha) == ref);
|
||||
alpha += alphaStep;
|
||||
}
|
||||
break;
|
||||
case GL_ALWAYS:
|
||||
/* do nothing */
|
||||
return 1;
|
||||
case GL_NEVER:
|
||||
/* caller should check for zero! */
|
||||
span->writeAll = GL_FALSE;
|
||||
return 0;
|
||||
default:
|
||||
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
|
||||
return 0;
|
||||
}
|
||||
#endif /* CHAN_TYPE */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXXX This causes conformance failures!!!! */
|
||||
while ((span->start <= span->end) &&
|
||||
(mask[span->start] == 0))
|
||||
span->start ++;
|
||||
|
||||
while ((span->end >= span->start) &&
|
||||
(mask[span->end] == 0))
|
||||
span->end --;
|
||||
#endif
|
||||
|
||||
span->writeAll = GL_FALSE;
|
||||
|
||||
if (span->start >= span->end)
|
||||
return 0;
|
||||
else
|
||||
/* XXX examine mask[] values? */
|
||||
return 1;
|
||||
}
|
||||
|
@@ -51,12 +51,12 @@
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Special case for glBlendFunc(GL_ZERO, GL_ONE)
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
blend_noop_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
|
||||
@@ -73,12 +73,12 @@ blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Special case for glBlendFunc(GL_ONE, GL_ZERO)
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_replace(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
|
||||
{
|
||||
ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
|
||||
ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
|
||||
@@ -92,18 +92,21 @@ blend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Common transparency blending mode.
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
blend_transparency_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4],
|
||||
GLenum chanType)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
|
||||
ASSERT(ctx->Color.BlendEquationA == GL_FUNC_ADD);
|
||||
ASSERT(ctx->Color.BlendSrcRGB == GL_SRC_ALPHA);
|
||||
ASSERT(ctx->Color.BlendSrcA == GL_SRC_ALPHA);
|
||||
ASSERT(ctx->Color.BlendDstRGB == GL_ONE_MINUS_SRC_ALPHA);
|
||||
ASSERT(ctx->Color.BlendDstA == GL_ONE_MINUS_SRC_ALPHA);
|
||||
(void) ctx;
|
||||
|
||||
for (i=0;i<n;i++) {
|
||||
@@ -180,12 +183,12 @@ blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Add src and dest.
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
blend_add_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Color.BlendEquationRGB == GL_FUNC_ADD);
|
||||
@@ -219,12 +222,12 @@ blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Blend min function (for GL_EXT_blend_minmax)
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
blend_min_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Color.BlendEquationRGB == GL_MIN);
|
||||
@@ -248,12 +251,12 @@ blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Blend max function (for GL_EXT_blend_minmax)
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
blend_max_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
|
||||
{
|
||||
GLuint i;
|
||||
ASSERT(ctx->Color.BlendEquationRGB == GL_MAX);
|
||||
@@ -277,12 +280,12 @@ blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Modulate: result = src * dest
|
||||
*/
|
||||
static void _BLENDAPI
|
||||
blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
blend_modulate_ubyte(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4], GLenum chanType)
|
||||
{
|
||||
GLuint i;
|
||||
(void) ctx;
|
||||
@@ -318,17 +321,435 @@ blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* General case blend pixels.
|
||||
* Input: n - number of pixels
|
||||
* mask - the usual write mask
|
||||
* In/Out: rgba - the incoming and modified pixels
|
||||
* Input: dest - the pixels from the dest color buffer
|
||||
#if 0
|
||||
/**
|
||||
* Do any blending operation, using floating point.
|
||||
* \param n number of pixels
|
||||
* \param mask fragment writemask array
|
||||
* \param src array of incoming (and modified) pixels
|
||||
* \param dst array of pixels from the dest color buffer
|
||||
*/
|
||||
static void
|
||||
blend_general_float(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLvoid *src, const GLvoid *dst, GLenum chanType)
|
||||
{
|
||||
GLfloat (*rgba)[4] = (GLfloat (*)[4]) src;
|
||||
const GLfloat (*dest)[4] = (const GLfloat (*)[4]) dst;
|
||||
GLuint i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (mask[i]) {
|
||||
/* Incoming/source Color */
|
||||
const GLfloat Rs = rgba[i][RCOMP];
|
||||
const GLfloat Gs = rgba[i][GCOMP];
|
||||
const GLfloat Bs = rgba[i][BCOMP];
|
||||
const GLfloat As = rgba[i][ACOMP];
|
||||
|
||||
/* Frame buffer/dest color */
|
||||
const GLfloat Rd = dest[i][RCOMP];
|
||||
const GLfloat Gd = dest[i][GCOMP];
|
||||
const GLfloat Bd = dest[i][BCOMP];
|
||||
const GLfloat Ad = dest[i][ACOMP];
|
||||
|
||||
GLfloat sR, sG, sB, sA; /* Source factor */
|
||||
GLfloat dR, dG, dB, dA; /* Dest factor */
|
||||
GLfloat r, g, b, a; /* result color */
|
||||
|
||||
/* XXX for the case of constant blend terms we could init
|
||||
* the sX and dX variables just once before the loop.
|
||||
*/
|
||||
|
||||
/* Source RGB factor */
|
||||
switch (ctx->Color.BlendSrcRGB) {
|
||||
case GL_ZERO:
|
||||
sR = sG = sB = 0.0F;
|
||||
break;
|
||||
case GL_ONE:
|
||||
sR = sG = sB = 1.0F;
|
||||
break;
|
||||
case GL_DST_COLOR:
|
||||
sR = Rd;
|
||||
sG = Gd;
|
||||
sB = Bd;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_COLOR:
|
||||
sR = 1.0F - Rd;
|
||||
sG = 1.0F - Gd;
|
||||
sB = 1.0F - Bd;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
sR = sG = sB = As;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
sR = sG = sB = 1.0F - As;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
sR = sG = sB = Ad;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
sR = sG = sB = 1.0F - Ad;
|
||||
break;
|
||||
case GL_SRC_ALPHA_SATURATE:
|
||||
if (As < 1.0F - Ad) {
|
||||
sR = sG = sB = As;
|
||||
}
|
||||
else {
|
||||
sR = sG = sB = 1.0F - Ad;
|
||||
}
|
||||
break;
|
||||
case GL_CONSTANT_COLOR:
|
||||
sR = ctx->Color.BlendColor[0];
|
||||
sG = ctx->Color.BlendColor[1];
|
||||
sB = ctx->Color.BlendColor[2];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
sR = 1.0F - ctx->Color.BlendColor[0];
|
||||
sG = 1.0F - ctx->Color.BlendColor[1];
|
||||
sB = 1.0F - ctx->Color.BlendColor[2];
|
||||
break;
|
||||
case GL_CONSTANT_ALPHA:
|
||||
sR = sG = sB = ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_SRC_COLOR: /* GL_NV_blend_square */
|
||||
sR = Rs;
|
||||
sG = Gs;
|
||||
sB = Bs;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
|
||||
sR = 1.0F - Rs;
|
||||
sG = 1.0F - Gs;
|
||||
sB = 1.0F - Bs;
|
||||
break;
|
||||
default:
|
||||
/* this should never happen */
|
||||
_mesa_problem(ctx, "Bad blend source RGB factor in blend_general_float");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Source Alpha factor */
|
||||
switch (ctx->Color.BlendSrcA) {
|
||||
case GL_ZERO:
|
||||
sA = 0.0F;
|
||||
break;
|
||||
case GL_ONE:
|
||||
sA = 1.0F;
|
||||
break;
|
||||
case GL_DST_COLOR:
|
||||
sA = Ad;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_COLOR:
|
||||
sA = 1.0F - Ad;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
sA = As;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
sA = 1.0F - As;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
sA = Ad;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
sA = 1.0F - Ad;
|
||||
break;
|
||||
case GL_SRC_ALPHA_SATURATE:
|
||||
sA = 1.0;
|
||||
break;
|
||||
case GL_CONSTANT_COLOR:
|
||||
sA = ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
sA = 1.0F - ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_CONSTANT_ALPHA:
|
||||
sA = ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
sA = 1.0F - ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_SRC_COLOR: /* GL_NV_blend_square */
|
||||
sA = As;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
|
||||
sA = 1.0F - As;
|
||||
break;
|
||||
default:
|
||||
/* this should never happen */
|
||||
sA = 0.0F;
|
||||
_mesa_problem(ctx, "Bad blend source A factor in blend_general_float");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Dest RGB factor */
|
||||
switch (ctx->Color.BlendDstRGB) {
|
||||
case GL_ZERO:
|
||||
dR = dG = dB = 0.0F;
|
||||
break;
|
||||
case GL_ONE:
|
||||
dR = dG = dB = 1.0F;
|
||||
break;
|
||||
case GL_SRC_COLOR:
|
||||
dR = Rs;
|
||||
dG = Gs;
|
||||
dB = Bs;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_COLOR:
|
||||
dR = 1.0F - Rs;
|
||||
dG = 1.0F - Gs;
|
||||
dB = 1.0F - Bs;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
dR = dG = dB = As;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
dR = dG = dB = 1.0F - As;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
dR = dG = dB = Ad;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
dR = dG = dB = 1.0F - Ad;
|
||||
break;
|
||||
case GL_CONSTANT_COLOR:
|
||||
dR = ctx->Color.BlendColor[0];
|
||||
dG = ctx->Color.BlendColor[1];
|
||||
dB = ctx->Color.BlendColor[2];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
dR = 1.0F - ctx->Color.BlendColor[0];
|
||||
dG = 1.0F - ctx->Color.BlendColor[1];
|
||||
dB = 1.0F - ctx->Color.BlendColor[2];
|
||||
break;
|
||||
case GL_CONSTANT_ALPHA:
|
||||
dR = dG = dB = ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_DST_COLOR: /* GL_NV_blend_square */
|
||||
dR = Rd;
|
||||
dG = Gd;
|
||||
dB = Bd;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
|
||||
dR = 1.0F - Rd;
|
||||
dG = 1.0F - Gd;
|
||||
dB = 1.0F - Bd;
|
||||
break;
|
||||
default:
|
||||
/* this should never happen */
|
||||
dR = dG = dB = 0.0F;
|
||||
_mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Dest Alpha factor */
|
||||
switch (ctx->Color.BlendDstA) {
|
||||
case GL_ZERO:
|
||||
dA = 0.0F;
|
||||
break;
|
||||
case GL_ONE:
|
||||
dA = 1.0F;
|
||||
break;
|
||||
case GL_SRC_COLOR:
|
||||
dA = As;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_COLOR:
|
||||
dA = 1.0F - As;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
dA = As;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
dA = 1.0F - As;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
dA = Ad;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
dA = 1.0F - Ad;
|
||||
break;
|
||||
case GL_CONSTANT_COLOR:
|
||||
dA = ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
dA = 1.0F - ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_CONSTANT_ALPHA:
|
||||
dA = ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
dA = 1.0F - ctx->Color.BlendColor[3];
|
||||
break;
|
||||
case GL_DST_COLOR: /* GL_NV_blend_square */
|
||||
dA = Ad;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
|
||||
dA = 1.0F - Ad;
|
||||
break;
|
||||
default:
|
||||
/* this should never happen */
|
||||
dA = 0.0F;
|
||||
_mesa_problem(ctx, "Bad blend dest A factor in blend_general_float");
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute the blended RGB */
|
||||
switch (ctx->Color.BlendEquationRGB) {
|
||||
case GL_FUNC_ADD:
|
||||
r = Rs * sR + Rd * dR;
|
||||
g = Gs * sG + Gd * dG;
|
||||
b = Bs * sB + Bd * dB;
|
||||
a = As * sA + Ad * dA;
|
||||
break;
|
||||
case GL_FUNC_SUBTRACT:
|
||||
r = Rs * sR - Rd * dR;
|
||||
g = Gs * sG - Gd * dG;
|
||||
b = Bs * sB - Bd * dB;
|
||||
a = As * sA - Ad * dA;
|
||||
break;
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
r = Rd * dR - Rs * sR;
|
||||
g = Gd * dG - Gs * sG;
|
||||
b = Bd * dB - Bs * sB;
|
||||
a = Ad * dA - As * sA;
|
||||
break;
|
||||
case GL_MIN:
|
||||
r = MIN2( Rd, Rs );
|
||||
g = MIN2( Gd, Gs );
|
||||
b = MIN2( Bd, Bs );
|
||||
break;
|
||||
case GL_MAX:
|
||||
r = MAX2( Rd, Rs );
|
||||
g = MAX2( Gd, Gs );
|
||||
b = MAX2( Bd, Bs );
|
||||
break;
|
||||
default:
|
||||
/* should never get here */
|
||||
r = g = b = 0.0F; /* silence uninitialized var warning */
|
||||
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute the blended alpha */
|
||||
switch (ctx->Color.BlendEquationA) {
|
||||
case GL_FUNC_ADD:
|
||||
a = As * sA + Ad * dA;
|
||||
break;
|
||||
case GL_FUNC_SUBTRACT:
|
||||
a = As * sA - Ad * dA;
|
||||
break;
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
a = Ad * dA - As * sA;
|
||||
break;
|
||||
case GL_MIN:
|
||||
a = MIN2( Ad, As );
|
||||
break;
|
||||
case GL_MAX:
|
||||
a = MAX2( Ad, As );
|
||||
break;
|
||||
default:
|
||||
/* should never get here */
|
||||
a = 0.0F; /* silence uninitialized var warning */
|
||||
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* final clamping */
|
||||
#if 0
|
||||
rgba[i][RCOMP] = MAX2( r, 0.0F );
|
||||
rgba[i][GCOMP] = MAX2( g, 0.0F );
|
||||
rgba[i][BCOMP] = MAX2( b, 0.0F );
|
||||
rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
|
||||
#else
|
||||
ASSIGN_4V(rgba[i], r, g, b, a);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 /* not ready yet */
|
||||
static void
|
||||
blend_general2(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
void *src, const void *dst, GLenum chanType)
|
||||
{
|
||||
GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4];
|
||||
|
||||
if (chanType == GL_UNSIGNED_BYTE) {
|
||||
GLubyte (*rgba)[4] = (GLubyte (*)[4]) src;
|
||||
const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst;
|
||||
GLuint i;
|
||||
/* convert ubytes to floats */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (mask[i]) {
|
||||
rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]);
|
||||
rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]);
|
||||
rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]);
|
||||
rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]);
|
||||
destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]);
|
||||
destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]);
|
||||
destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]);
|
||||
destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]);
|
||||
}
|
||||
}
|
||||
/* do blend */
|
||||
blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
|
||||
/* convert back to ubytes */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (mask[i]) {
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (chanType == GL_UNSIGNED_SHORT) {
|
||||
GLushort (*rgba)[4] = (GLushort (*)[4]) src;
|
||||
const GLushort (*dest)[4] = (const GLushort (*)[4]) dst;
|
||||
GLuint i;
|
||||
/* convert ushorts to floats */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (mask[i]) {
|
||||
rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]);
|
||||
rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]);
|
||||
rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]);
|
||||
rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]);
|
||||
destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]);
|
||||
destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]);
|
||||
destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]);
|
||||
destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]);
|
||||
}
|
||||
}
|
||||
/* do blend */
|
||||
blend_general_float(ctx, n, mask, rgbaF, destF, chanType);
|
||||
/* convert back to ushorts */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (mask[i]) {
|
||||
UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]);
|
||||
UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]);
|
||||
UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]);
|
||||
UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
blend_general_float(ctx, n, mask, (GLfloat (*)[4]) rgbaF,
|
||||
(const GLfloat (*)[4]) destF, chanType);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void _BLENDAPI
|
||||
blend_general(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan rgba[][4], CONST GLchan dest[][4] )
|
||||
GLchan rgba[][4], CONST GLchan dest[][4],
|
||||
GLenum chanType)
|
||||
{
|
||||
const GLfloat rscale = 1.0F / CHAN_MAXF;
|
||||
const GLfloat gscale = 1.0F / CHAN_MAXF;
|
||||
@@ -441,7 +862,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
break;
|
||||
default:
|
||||
/* this should never happen */
|
||||
_mesa_problem(ctx, "Bad blend source RGB factor in do_blend");
|
||||
_mesa_problem(ctx, "Bad blend source RGB factor in blend_general");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -495,7 +916,8 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
default:
|
||||
/* this should never happen */
|
||||
sA = 0.0F;
|
||||
_mesa_problem(ctx, "Bad blend source A factor in do_blend");
|
||||
_mesa_problem(ctx, "Bad blend source A factor in blend_general");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Dest RGB factor */
|
||||
@@ -557,7 +979,8 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
default:
|
||||
/* this should never happen */
|
||||
dR = dG = dB = 0.0F;
|
||||
_mesa_problem(ctx, "Bad blend dest RGB factor in do_blend");
|
||||
_mesa_problem(ctx, "Bad blend dest RGB factor in blend_general");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Dest Alpha factor */
|
||||
@@ -607,7 +1030,7 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
default:
|
||||
/* this should never happen */
|
||||
dA = 0.0F;
|
||||
_mesa_problem(ctx, "Bad blend dest A factor in do_blend");
|
||||
_mesa_problem(ctx, "Bad blend dest A factor in blend_general");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -633,59 +1056,63 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
|
||||
/* compute blended color */
|
||||
#if CHAN_TYPE == GL_FLOAT
|
||||
if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) {
|
||||
switch (ctx->Color.BlendEquationRGB) {
|
||||
case GL_FUNC_ADD:
|
||||
r = Rs * sR + Rd * dR;
|
||||
g = Gs * sG + Gd * dG;
|
||||
b = Bs * sB + Bd * dB;
|
||||
a = As * sA + Ad * dA;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_SUBTRACT:
|
||||
r = Rs * sR - Rd * dR;
|
||||
g = Gs * sG - Gd * dG;
|
||||
b = Bs * sB - Bd * dB;
|
||||
a = As * sA - Ad * dA;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
r = Rd * dR - Rs * sR;
|
||||
g = Gd * dG - Gs * sG;
|
||||
b = Bd * dB - Bs * sB;
|
||||
a = Ad * dA - As * sA;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_MIN) {
|
||||
break;
|
||||
case GL_MIN:
|
||||
r = MIN2( Rd, Rs );
|
||||
g = MIN2( Gd, Gs );
|
||||
b = MIN2( Bd, Bs );
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_MAX) {
|
||||
break;
|
||||
case GL_MAX:
|
||||
r = MAX2( Rd, Rs );
|
||||
g = MAX2( Gd, Gs );
|
||||
b = MAX2( Bd, Bs );
|
||||
}
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
/* should never get here */
|
||||
r = g = b = 0.0F; /* silence uninitialized var warning */
|
||||
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->Color.BlendEquationA==GL_FUNC_ADD) {
|
||||
switch (ctx->Color.BlendEquationA) {
|
||||
case GL_FUNC_ADD:
|
||||
a = As * sA + Ad * dA;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_SUBTRACT:
|
||||
a = As * sA - Ad * dA;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
a = Ad * dA - As * sA;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_MIN) {
|
||||
break;
|
||||
case GL_MIN:
|
||||
a = MIN2( Ad, As );
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_MAX) {
|
||||
break;
|
||||
case GL_MAX:
|
||||
a = MAX2( Ad, As );
|
||||
}
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
/* should never get here */
|
||||
a = 0.0F; /* silence uninitialized var warning */
|
||||
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* final clamping */
|
||||
@@ -694,56 +1121,60 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
rgba[i][BCOMP] = MAX2( b, 0.0F );
|
||||
rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
|
||||
#else
|
||||
if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) {
|
||||
switch (ctx->Color.BlendEquationRGB) {
|
||||
case GL_FUNC_ADD:
|
||||
r = Rs * sR + Rd * dR + 0.5F;
|
||||
g = Gs * sG + Gd * dG + 0.5F;
|
||||
b = Bs * sB + Bd * dB + 0.5F;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_SUBTRACT:
|
||||
r = Rs * sR - Rd * dR + 0.5F;
|
||||
g = Gs * sG - Gd * dG + 0.5F;
|
||||
b = Bs * sB - Bd * dB + 0.5F;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
r = Rd * dR - Rs * sR + 0.5F;
|
||||
g = Gd * dG - Gs * sG + 0.5F;
|
||||
b = Bd * dB - Bs * sB + 0.5F;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_MIN) {
|
||||
break;
|
||||
case GL_MIN:
|
||||
r = MIN2( Rd, Rs );
|
||||
g = MIN2( Gd, Gs );
|
||||
b = MIN2( Bd, Bs );
|
||||
}
|
||||
else if (ctx->Color.BlendEquationRGB==GL_MAX) {
|
||||
break;
|
||||
case GL_MAX:
|
||||
r = MAX2( Rd, Rs );
|
||||
g = MAX2( Gd, Gs );
|
||||
b = MAX2( Bd, Bs );
|
||||
}
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
/* should never get here */
|
||||
r = g = b = 0.0F; /* silence uninitialized var warning */
|
||||
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->Color.BlendEquationA==GL_FUNC_ADD) {
|
||||
switch (ctx->Color.BlendEquationA) {
|
||||
case GL_FUNC_ADD:
|
||||
a = As * sA + Ad * dA + 0.5F;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_SUBTRACT:
|
||||
a = As * sA - Ad * dA + 0.5F;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) {
|
||||
break;
|
||||
case GL_FUNC_REVERSE_SUBTRACT:
|
||||
a = Ad * dA - As * sA + 0.5F;
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_MIN) {
|
||||
break;
|
||||
case GL_MIN:
|
||||
a = MIN2( Ad, As );
|
||||
}
|
||||
else if (ctx->Color.BlendEquationA==GL_MAX) {
|
||||
break;
|
||||
case GL_MAX:
|
||||
a = MAX2( Ad, As );
|
||||
}
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
/* should never get here */
|
||||
a = 0.0F; /* silence uninitialized var warning */
|
||||
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* final clamping */
|
||||
@@ -757,12 +1188,13 @@ blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Analyze current blending parameters to pick fastest blending function.
|
||||
* Result: the ctx->Color.BlendFunc pointer is updated.
|
||||
*/
|
||||
void _swrast_choose_blend_func( GLcontext *ctx )
|
||||
{
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
const GLenum eq = ctx->Color.BlendEquationRGB;
|
||||
const GLenum srcRGB = ctx->Color.BlendSrcRGB;
|
||||
const GLenum dstRGB = ctx->Color.BlendDstRGB;
|
||||
@@ -770,49 +1202,49 @@ void _swrast_choose_blend_func( GLcontext *ctx )
|
||||
const GLenum dstA = ctx->Color.BlendDstA;
|
||||
|
||||
if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
|
||||
swrast->BlendFunc = blend_general;
|
||||
}
|
||||
else if (eq == GL_MIN) {
|
||||
/* Note: GL_MIN ignores the blending weight factors */
|
||||
#if defined(USE_MMX_ASM)
|
||||
if ( cpu_has_mmx ) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min;
|
||||
swrast->BlendFunc = _mesa_mmx_blend_min;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
|
||||
swrast->BlendFunc = blend_min_ubyte;
|
||||
}
|
||||
else if (eq == GL_MAX) {
|
||||
/* Note: GL_MAX ignores the blending weight factors */
|
||||
#if defined(USE_MMX_ASM)
|
||||
if ( cpu_has_mmx ) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max;
|
||||
swrast->BlendFunc = _mesa_mmx_blend_max;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
|
||||
swrast->BlendFunc = blend_max_ubyte;
|
||||
}
|
||||
else if (srcRGB != srcA || dstRGB != dstA) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
|
||||
swrast->BlendFunc = blend_general;
|
||||
}
|
||||
else if (eq == GL_FUNC_ADD && srcRGB == GL_SRC_ALPHA
|
||||
&& dstRGB == GL_ONE_MINUS_SRC_ALPHA) {
|
||||
#if defined(USE_MMX_ASM)
|
||||
if ( cpu_has_mmx ) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
|
||||
swrast->BlendFunc = _mesa_mmx_blend_transparency;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
|
||||
swrast->BlendFunc = blend_transparency_ubyte;
|
||||
}
|
||||
else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {
|
||||
#if defined(USE_MMX_ASM)
|
||||
if ( cpu_has_mmx ) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add;
|
||||
swrast->BlendFunc = _mesa_mmx_blend_add;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
|
||||
swrast->BlendFunc = blend_add_ubyte;
|
||||
}
|
||||
else if (((eq == GL_FUNC_ADD || eq == GL_FUNC_REVERSE_SUBTRACT)
|
||||
&& (srcRGB == GL_ZERO && dstRGB == GL_SRC_COLOR))
|
||||
@@ -821,26 +1253,26 @@ void _swrast_choose_blend_func( GLcontext *ctx )
|
||||
&& (srcRGB == GL_DST_COLOR && dstRGB == GL_ZERO))) {
|
||||
#if defined(USE_MMX_ASM)
|
||||
if ( cpu_has_mmx ) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate;
|
||||
swrast->BlendFunc = _mesa_mmx_blend_modulate;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
|
||||
swrast->BlendFunc = blend_modulate_ubyte;
|
||||
}
|
||||
else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop;
|
||||
swrast->BlendFunc = blend_noop_ubyte;
|
||||
}
|
||||
else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace;
|
||||
swrast->BlendFunc = blend_replace;
|
||||
}
|
||||
else {
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
|
||||
swrast->BlendFunc = blend_general;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Apply the blending operator to a span of pixels.
|
||||
* We can handle horizontal runs of pixels (spans) or arrays of x/y
|
||||
* pixel coordinates.
|
||||
@@ -849,25 +1281,17 @@ void
|
||||
_swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
struct sw_span *span)
|
||||
{
|
||||
GLchan framebuffer[MAX_WIDTH][4];
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
void *rbPixels;
|
||||
|
||||
ASSERT(span->end <= MAX_WIDTH);
|
||||
ASSERT(span->arrayMask & SPAN_RGBA);
|
||||
ASSERT(rb->DataType == span->array->ChanType);
|
||||
ASSERT(!ctx->Color._LogicOpEnabled);
|
||||
|
||||
/* Read span of current frame buffer pixels */
|
||||
if (span->arrayMask & SPAN_XY) {
|
||||
/* array of x/y pixel coords */
|
||||
_swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
|
||||
framebuffer, 4 * sizeof(GLchan));
|
||||
}
|
||||
else {
|
||||
/* horizontal run of pixels */
|
||||
_swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y,
|
||||
framebuffer);
|
||||
}
|
||||
rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
|
||||
|
||||
SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask,
|
||||
span->array->rgba,
|
||||
(const GLchan (*)[4]) framebuffer );
|
||||
swrast->BlendFunc(ctx, span->end, span->array->mask,
|
||||
span->array->rgba, (const GLchan (*)[4]) rbPixels,
|
||||
span->array->ChanType);
|
||||
}
|
||||
|
@@ -199,11 +199,6 @@ _swrast_update_fog_state( GLcontext *ctx )
|
||||
{
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
|
||||
/* convert fog color to GLchan values */
|
||||
CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[RCOMP], ctx->Fog.Color[RCOMP]);
|
||||
CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[GCOMP], ctx->Fog.Color[GCOMP]);
|
||||
CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[BCOMP], ctx->Fog.Color[BCOMP]);
|
||||
|
||||
/* determine if fog is needed, and if so, which fog mode */
|
||||
swrast->_FogEnabled = GL_FALSE;
|
||||
if (ctx->FragmentProgram._Enabled) {
|
||||
@@ -359,17 +354,16 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
|
||||
* function, then call it.
|
||||
*/
|
||||
static void _ASMAPI
|
||||
_swrast_validate_blend_func( GLcontext *ctx, GLuint n,
|
||||
const GLubyte mask[],
|
||||
GLchan src[][4],
|
||||
CONST GLchan dst[][4] )
|
||||
_swrast_validate_blend_func(GLcontext *ctx, GLuint n, const GLubyte mask[],
|
||||
GLchan src[][4], CONST GLchan dst[][4],
|
||||
GLenum chanType )
|
||||
{
|
||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
|
||||
_swrast_validate_derived( ctx );
|
||||
_swrast_choose_blend_func( ctx );
|
||||
|
||||
swrast->BlendFunc( ctx, n, mask, src, dst );
|
||||
swrast->BlendFunc( ctx, n, mask, src, dst, chanType );
|
||||
}
|
||||
|
||||
|
||||
@@ -680,6 +674,17 @@ _swrast_CreateContext( GLcontext *ctx )
|
||||
FREE(swrast);
|
||||
return GL_FALSE;
|
||||
}
|
||||
swrast->SpanArrays->ChanType = CHAN_TYPE;
|
||||
#if CHAN_TYPE == GL_UNSIGNED_BYTE
|
||||
swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba;
|
||||
swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec;
|
||||
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
|
||||
swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba;
|
||||
swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec;
|
||||
#else
|
||||
swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz4.rgba;
|
||||
swrast->SpanArrays->spec = swrast->SpanArrays->color.sz4.spec;
|
||||
#endif
|
||||
|
||||
/* init point span buffer */
|
||||
swrast->PointSpan.primitive = GL_POINT;
|
||||
|
@@ -69,6 +69,22 @@
|
||||
#define SPAN_VARYING 0x2000
|
||||
/*@}*/
|
||||
|
||||
#if 0
|
||||
/* alternate arrangement for code below */
|
||||
struct arrays2 {
|
||||
union {
|
||||
GLubyte sz1[MAX_WIDTH][4]; /* primary color */
|
||||
GLushort sz2[MAX_WIDTH][4];
|
||||
GLfloat sz4[MAX_WIDTH][4];
|
||||
} rgba;
|
||||
union {
|
||||
GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */
|
||||
GLushort sz2[MAX_WIDTH][4];
|
||||
GLfloat sz4[MAX_WIDTH][4];
|
||||
} spec;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \struct span_arrays
|
||||
@@ -79,8 +95,25 @@
|
||||
* These arrays are separated out of sw_span to conserve memory.
|
||||
*/
|
||||
struct span_arrays {
|
||||
GLchan rgba[MAX_WIDTH][4];
|
||||
GLchan spec[MAX_WIDTH][4]; /* specular color */
|
||||
GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */
|
||||
union {
|
||||
struct {
|
||||
GLubyte rgba[MAX_WIDTH][4]; /**< primary color */
|
||||
GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */
|
||||
} sz1;
|
||||
struct {
|
||||
GLushort rgba[MAX_WIDTH][4];
|
||||
GLushort spec[MAX_WIDTH][4];
|
||||
} sz2;
|
||||
struct {
|
||||
GLfloat rgba[MAX_WIDTH][4];
|
||||
GLfloat spec[MAX_WIDTH][4];
|
||||
} sz4;
|
||||
} color;
|
||||
/** XXX these are temporary fields, pointing into above color arrays */
|
||||
GLchan (*rgba)[4];
|
||||
GLchan (*spec)[4];
|
||||
|
||||
GLuint index[MAX_WIDTH];
|
||||
GLint x[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
|
||||
GLint y[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
|
||||
@@ -218,7 +251,8 @@ typedef void (*texture_sample_func)(GLcontext *ctx,
|
||||
|
||||
typedef void (_ASMAPIP blend_func)( GLcontext *ctx, GLuint n,
|
||||
const GLubyte mask[],
|
||||
GLchan src[][4], CONST GLchan dst[][4] );
|
||||
GLchan src[][4], CONST GLchan dst[][4],
|
||||
GLenum chanType);
|
||||
|
||||
typedef void (*swrast_point_func)( GLcontext *ctx, const SWvertex *);
|
||||
|
||||
@@ -291,7 +325,6 @@ typedef struct
|
||||
GLfloat _BackfaceSign;
|
||||
GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */
|
||||
GLboolean _AnyTextureCombine;
|
||||
GLchan _FogColor[3];
|
||||
GLboolean _FogEnabled;
|
||||
GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 6.3
|
||||
* Version: 6.5.2
|
||||
*
|
||||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
||||
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@@ -30,7 +30,13 @@
|
||||
|
||||
#include "s_context.h"
|
||||
#include "s_fog.h"
|
||||
#include "s_span.h"
|
||||
|
||||
|
||||
/** XXX temporary */
|
||||
#define UBYTE_RGBA GLubyte (*rgba)[4] = span->array->color.sz1.rgba
|
||||
#define USHORT_RGBA GLushort (*rgba)[4] = span->array->color.sz2.rgba
|
||||
#define FLOAT_RGBA GLfloat (*rgba)[4] = span->array->color.sz4.rgba
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -66,6 +72,33 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template code for computing fog blend factor and applying it to colors.
|
||||
* \param TYPE either GLubyte, GLushort or GLfloat.
|
||||
* \param COMPUTE_F code to compute the fog blend factor, f.
|
||||
*/
|
||||
#define FOG_LOOP(TYPE, COMPUTE_F) \
|
||||
do { \
|
||||
const GLfloat fogStep = span->fogStep; \
|
||||
GLfloat fogCoord = span->fog; \
|
||||
const GLfloat wStep = haveW ? span->dwdx : 0.0F; \
|
||||
GLfloat w = haveW ? span->w : 1.0F; \
|
||||
GLuint i; \
|
||||
for (i = 0; i < span->end; i++) { \
|
||||
GLfloat f, oneMinusF; \
|
||||
COMPUTE_F; \
|
||||
f = CLAMP(f, 0.0F, 1.0F); \
|
||||
oneMinusF = 1.0F - f; \
|
||||
rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \
|
||||
rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \
|
||||
rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \
|
||||
fogCoord += fogStep; \
|
||||
w += wStep; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Apply fog to a span of RGBA pixels.
|
||||
* The fog value are either in the span->array->fog array or interpolated from
|
||||
@@ -77,11 +110,10 @@ void
|
||||
_swrast_fog_rgba_span( const GLcontext *ctx, struct sw_span *span )
|
||||
{
|
||||
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
const GLchan rFog = swrast->_FogColor[RCOMP];
|
||||
const GLchan gFog = swrast->_FogColor[GCOMP];
|
||||
const GLchan bFog = swrast->_FogColor[BCOMP];
|
||||
const GLfloat rFog = ctx->Fog.Color[RCOMP] * CHAN_MAX;
|
||||
const GLfloat gFog = ctx->Fog.Color[GCOMP] * CHAN_MAX;
|
||||
const GLfloat bFog = ctx->Fog.Color[BCOMP] * CHAN_MAX;
|
||||
const GLuint haveW = (span->interpMask & SPAN_W);
|
||||
GLchan (*rgba)[4] = (GLchan (*)[4]) span->array->rgba;
|
||||
|
||||
ASSERT(swrast->_FogEnabled);
|
||||
ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
|
||||
@@ -96,79 +128,71 @@ _swrast_fog_rgba_span( const GLcontext *ctx, struct sw_span *span )
|
||||
/* The span's fog values are fog coordinates, now compute blend factors
|
||||
* and blend the fragment colors with the fog color.
|
||||
*/
|
||||
switch (swrast->_FogMode) {
|
||||
case GL_LINEAR:
|
||||
{
|
||||
const GLfloat fogEnd = ctx->Fog.End;
|
||||
const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
|
||||
? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
|
||||
const GLfloat fogStep = span->fogStep;
|
||||
GLfloat fogCoord = span->fog;
|
||||
const GLfloat wStep = haveW ? span->dwdx : 0.0F;
|
||||
GLfloat w = haveW ? span->w : 1.0F;
|
||||
GLuint i;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
GLfloat f, oneMinusF;
|
||||
f = (fogEnd - FABSF(fogCoord) / w) * fogScale;
|
||||
f = CLAMP(f, 0.0F, 1.0F);
|
||||
oneMinusF = 1.0F - f;
|
||||
rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
fogCoord += fogStep;
|
||||
w += wStep;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_EXP:
|
||||
{
|
||||
const GLfloat density = -ctx->Fog.Density;
|
||||
const GLfloat fogStep = span->fogStep;
|
||||
GLfloat fogCoord = span->fog;
|
||||
const GLfloat wStep = haveW ? span->dwdx : 0.0F;
|
||||
GLfloat w = haveW ? span->w : 1.0F;
|
||||
GLuint i;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
GLfloat f, oneMinusF;
|
||||
f = EXPF(density * FABSF(fogCoord) / w);
|
||||
f = CLAMP(f, 0.0F, 1.0F);
|
||||
oneMinusF = 1.0F - f;
|
||||
rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
fogCoord += fogStep;
|
||||
w += wStep;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GL_EXP2:
|
||||
{
|
||||
const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
|
||||
const GLfloat fogStep = span->fogStep;
|
||||
GLfloat fogCoord = span->fog;
|
||||
const GLfloat wStep = haveW ? span->dwdx : 0.0F;
|
||||
GLfloat w = haveW ? span->w : 1.0F;
|
||||
GLuint i;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
const GLfloat coord = fogCoord / w;
|
||||
GLfloat tmp = negDensitySquared * coord * coord;
|
||||
GLfloat f, oneMinusF;
|
||||
#if defined(__alpha__) || defined(__alpha)
|
||||
/* XXX this underflow check may be needed for other systems*/
|
||||
if (tmp < FLT_MIN_10_EXP)
|
||||
tmp = FLT_MIN_10_EXP;
|
||||
#endif
|
||||
f = EXPF(tmp);
|
||||
f = CLAMP(f, 0.0F, 1.0F);
|
||||
oneMinusF = 1.0F - f;
|
||||
rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
fogCoord += fogStep;
|
||||
w += wStep;
|
||||
|
||||
switch (swrast->_FogMode) {
|
||||
case GL_LINEAR:
|
||||
#define COMPUTE_F f = (fogEnd - FABSF(fogCoord) / w) * fogScale;
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
UBYTE_RGBA;
|
||||
FOG_LOOP(GLubyte, COMPUTE_F);
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
USHORT_RGBA;
|
||||
FOG_LOOP(GLushort, COMPUTE_F);
|
||||
}
|
||||
else {
|
||||
FLOAT_RGBA;
|
||||
ASSERT(span->array->ChanType == GL_FLOAT);
|
||||
FOG_LOOP(GLfloat, COMPUTE_F);
|
||||
}
|
||||
#undef COMPUTE_F
|
||||
break;
|
||||
|
||||
case GL_EXP:
|
||||
#define COMPUTE_F f = EXPF(density * FABSF(fogCoord) / w);
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
UBYTE_RGBA;
|
||||
FOG_LOOP(GLubyte, COMPUTE_F);
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
USHORT_RGBA;
|
||||
FOG_LOOP(GLushort, COMPUTE_F);
|
||||
}
|
||||
else {
|
||||
FLOAT_RGBA;
|
||||
ASSERT(span->array->ChanType == GL_FLOAT);
|
||||
FOG_LOOP(GLfloat, COMPUTE_F);
|
||||
}
|
||||
#undef COMPUTE_F
|
||||
break;
|
||||
|
||||
case GL_EXP2:
|
||||
#define COMPUTE_F const GLfloat coord = fogCoord / w; \
|
||||
GLfloat tmp = negDensitySquared * coord * coord; \
|
||||
if (tmp < FLT_MIN_10_EXP) \
|
||||
tmp = FLT_MIN_10_EXP; \
|
||||
f = EXPF(tmp);
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
UBYTE_RGBA;
|
||||
FOG_LOOP(GLubyte, COMPUTE_F);
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
USHORT_RGBA;
|
||||
FOG_LOOP(GLushort, COMPUTE_F);
|
||||
}
|
||||
else {
|
||||
FLOAT_RGBA;
|
||||
ASSERT(span->array->ChanType == GL_FLOAT);
|
||||
FOG_LOOP(GLfloat, COMPUTE_F);
|
||||
}
|
||||
#undef COMPUTE_F
|
||||
break;
|
||||
|
||||
default:
|
||||
_mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span");
|
||||
return;
|
||||
@@ -179,33 +203,58 @@ _swrast_fog_rgba_span( const GLcontext *ctx, struct sw_span *span )
|
||||
* They were previously computed per-vertex.
|
||||
*/
|
||||
GLuint i;
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
UBYTE_RGBA;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
const GLfloat f = span->array->fog[i];
|
||||
const GLfloat oneMinusF = 1.0F - f;
|
||||
rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
}
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
USHORT_RGBA;
|
||||
for (i = 0; i < span->end; i++) {
|
||||
const GLfloat f = span->array->fog[i];
|
||||
const GLfloat oneMinusF = 1.0F - f;
|
||||
rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
}
|
||||
}
|
||||
else {
|
||||
FLOAT_RGBA;
|
||||
ASSERT(span->array->ChanType == GL_FLOAT);
|
||||
for (i = 0; i < span->end; i++) {
|
||||
const GLfloat f = span->array->fog[i];
|
||||
const GLfloat oneMinusF = 1.0F - f;
|
||||
rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog;
|
||||
rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog;
|
||||
rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* The span's fog start/step values are blend factors.
|
||||
* They were previously computed per-vertex.
|
||||
*/
|
||||
const GLfloat fogStep = span->fogStep;
|
||||
GLfloat fog = span->fog;
|
||||
const GLfloat wStep = haveW ? span->dwdx : 0.0F;
|
||||
GLfloat w = haveW ? span->w : 1.0F;
|
||||
GLuint i;
|
||||
ASSERT(span->interpMask & SPAN_FOG);
|
||||
for (i = 0; i < span->end; i++) {
|
||||
const GLfloat fact = fog / w;
|
||||
const GLfloat oneMinusF = 1.0F - fact;
|
||||
rgba[i][RCOMP] = (GLchan) (fact * rgba[i][RCOMP] + oneMinusF * rFog);
|
||||
rgba[i][GCOMP] = (GLchan) (fact * rgba[i][GCOMP] + oneMinusF * gFog);
|
||||
rgba[i][BCOMP] = (GLchan) (fact * rgba[i][BCOMP] + oneMinusF * bFog);
|
||||
fog += fogStep;
|
||||
w += wStep;
|
||||
#define COMPUTE_F f = fogCoord / w;
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
UBYTE_RGBA;
|
||||
FOG_LOOP(GLubyte, COMPUTE_F);
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
USHORT_RGBA;
|
||||
FOG_LOOP(GLushort, COMPUTE_F);
|
||||
}
|
||||
else {
|
||||
FLOAT_RGBA;
|
||||
ASSERT(span->array->ChanType == GL_FLOAT);
|
||||
FOG_LOOP(GLfloat, COMPUTE_F);
|
||||
}
|
||||
#undef COMPUTE_F
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,20 +33,25 @@
|
||||
#include "s_span.h"
|
||||
|
||||
|
||||
#define LOGIC_OP_LOOP(MODE) \
|
||||
/**
|
||||
* We do all logic ops on 4-byte GLuints.
|
||||
* Depending on bytes per pixel, the mask array elements correspond to
|
||||
* 1, 2 or 4 GLuints.
|
||||
*/
|
||||
#define LOGIC_OP_LOOP(MODE, MASKSTRIDE) \
|
||||
do { \
|
||||
GLuint i; \
|
||||
switch (MODE) { \
|
||||
case GL_CLEAR: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = 0; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_SET: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~0; \
|
||||
} \
|
||||
} \
|
||||
@@ -56,91 +61,91 @@ do { \
|
||||
break; \
|
||||
case GL_COPY_INVERTED: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~src[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_NOOP: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_INVERT: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_AND: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] &= dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_NAND: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~(src[i] & dest[i]); \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_OR: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] |= dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_NOR: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~(src[i] | dest[i]); \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_XOR: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] ^= dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_EQUIV: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~(src[i] ^ dest[i]); \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_AND_REVERSE: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = src[i] & ~dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_AND_INVERTED: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~src[i] & dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_OR_REVERSE: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = src[i] | ~dest[i]; \
|
||||
} \
|
||||
} \
|
||||
break; \
|
||||
case GL_OR_INVERTED: \
|
||||
for (i = 0; i < n; i++) { \
|
||||
if (mask[i]) { \
|
||||
if (mask[i / MASKSTRIDE]) { \
|
||||
src[i] = ~src[i] | dest[i]; \
|
||||
} \
|
||||
} \
|
||||
@@ -152,27 +157,27 @@ do { \
|
||||
|
||||
|
||||
|
||||
static void
|
||||
logicop_ubyte(GLcontext *ctx, GLuint n, GLubyte src[], const GLubyte dest[],
|
||||
static INLINE void
|
||||
logicop_uint1(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[],
|
||||
const GLubyte mask[])
|
||||
{
|
||||
LOGIC_OP_LOOP(ctx->Color.LogicOp);
|
||||
LOGIC_OP_LOOP(ctx->Color.LogicOp, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
logicop_ushort(GLcontext *ctx, GLuint n, GLushort src[], const GLushort dest[],
|
||||
static INLINE void
|
||||
logicop_uint2(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[],
|
||||
const GLubyte mask[])
|
||||
{
|
||||
LOGIC_OP_LOOP(ctx->Color.LogicOp);
|
||||
LOGIC_OP_LOOP(ctx->Color.LogicOp, 2);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
logicop_uint(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[],
|
||||
static INLINE void
|
||||
logicop_uint4(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[],
|
||||
const GLubyte mask[])
|
||||
{
|
||||
LOGIC_OP_LOOP(ctx->Color.LogicOp);
|
||||
LOGIC_OP_LOOP(ctx->Color.LogicOp, 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +205,7 @@ _swrast_logicop_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
rb->GetRow(ctx, rb, span->end, span->x, span->y, dest);
|
||||
}
|
||||
|
||||
logicop_uint(ctx, span->end, index, dest, span->array->mask);
|
||||
logicop_uint1(ctx, span->end, index, dest, span->array->mask);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,33 +218,29 @@ void
|
||||
_swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
struct sw_span *span)
|
||||
{
|
||||
GLchan dest[MAX_WIDTH][4];
|
||||
void *rbPixels;
|
||||
|
||||
ASSERT(span->end < MAX_WIDTH);
|
||||
ASSERT(span->arrayMask & SPAN_RGBA);
|
||||
ASSERT(rb->DataType == CHAN_TYPE);
|
||||
ASSERT(rb->DataType == span->array->ChanType);
|
||||
|
||||
if (span->arrayMask & SPAN_XY) {
|
||||
_swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
|
||||
dest, 4 * sizeof(GLchan));
|
||||
rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
|
||||
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
/* treat 4*GLubyte as GLuint */
|
||||
logicop_uint1(ctx, span->end,
|
||||
(GLuint *) span->array->color.sz1.rgba,
|
||||
(const GLuint *) rbPixels, span->array->mask);
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
/* treat 2*GLushort as GLuint */
|
||||
logicop_uint2(ctx, 2 * span->end,
|
||||
(GLuint *) span->array->color.sz2.rgba,
|
||||
(const GLuint *) rbPixels, span->array->mask);
|
||||
}
|
||||
else {
|
||||
_swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, dest);
|
||||
logicop_uint4(ctx, 4 * span->end,
|
||||
(GLuint *) span->array->color.sz4.rgba,
|
||||
(const GLuint *) rbPixels, span->array->mask);
|
||||
}
|
||||
|
||||
/* XXX make this a runtime test */
|
||||
#if CHAN_TYPE == GL_UNSIGNED_BYTE
|
||||
/* treat 4*GLubyte as GLuint */
|
||||
logicop_uint(ctx, span->end, (GLuint *) span->array->rgba,
|
||||
(const GLuint *) dest, span->array->mask);
|
||||
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
|
||||
logicop_ushort(ctx, 4 * span->end, (GLushort *) span->array->rgba,
|
||||
(const GLushort *) dest, span->array->mask);
|
||||
#elif CHAN_TYPE == GL_FLOAT
|
||||
logicop_uint(ctx, 4 * span->end, (GLuint *) span->array->rgba,
|
||||
(const GLuint *) dest, span->array->mask);
|
||||
#endif
|
||||
(void) logicop_ubyte;
|
||||
(void) logicop_ushort;
|
||||
(void) logicop_uint;
|
||||
}
|
||||
|
@@ -43,44 +43,63 @@ void
|
||||
_swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
struct sw_span *span)
|
||||
{
|
||||
GLchan dest[MAX_WIDTH][4];
|
||||
#if CHAN_BITS == 8
|
||||
GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
|
||||
GLuint dstMask = ~srcMask;
|
||||
GLuint *rgba32 = (GLuint *) span->array->rgba;
|
||||
GLuint *dest32 = (GLuint *) dest;
|
||||
#else
|
||||
const GLboolean rMask = ctx->Color.ColorMask[RCOMP];
|
||||
const GLboolean gMask = ctx->Color.ColorMask[GCOMP];
|
||||
const GLboolean bMask = ctx->Color.ColorMask[BCOMP];
|
||||
const GLboolean aMask = ctx->Color.ColorMask[ACOMP];
|
||||
#endif
|
||||
const GLuint n = span->end;
|
||||
GLuint i;
|
||||
void *rbPixels;
|
||||
|
||||
ASSERT(n < MAX_WIDTH);
|
||||
ASSERT(span->arrayMask & SPAN_RGBA);
|
||||
ASSERT(rb->DataType == span->array->ChanType);
|
||||
|
||||
if (span->arrayMask & SPAN_XY) {
|
||||
_swrast_get_values(ctx, rb, n, span->array->x, span->array->y,
|
||||
dest, 4 * sizeof(GLchan));
|
||||
rbPixels = _swrast_get_dest_rgba(ctx, rb, span);
|
||||
|
||||
/*
|
||||
* Do component masking.
|
||||
* Note that we're not using span->array->mask[] here. We could...
|
||||
*/
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
/* treat 4xGLubyte as 1xGLuint */
|
||||
const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
|
||||
const GLuint dstMask = ~srcMask;
|
||||
const GLuint *dst = (const GLuint *) rbPixels;
|
||||
GLuint *src = (GLuint *) span->array->color.sz1.rgba;
|
||||
GLuint i;
|
||||
for (i = 0; i < n; i++) {
|
||||
src[i] = (src[i] & srcMask) | (dst[i] & dstMask);
|
||||
}
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
/* 2-byte components */
|
||||
/* XXX try to use 64-bit arithmetic someday */
|
||||
const GLushort rMask = ctx->Color.ColorMask[RCOMP] ? 0xffff : 0x0;
|
||||
const GLushort gMask = ctx->Color.ColorMask[GCOMP] ? 0xffff : 0x0;
|
||||
const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
|
||||
const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
|
||||
const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
|
||||
GLushort (*src)[4] = span->array->color.sz2.rgba;
|
||||
GLuint i;
|
||||
for (i = 0; i < n; i++) {
|
||||
src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
|
||||
src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask);
|
||||
src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask);
|
||||
src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
_swrast_read_rgba_span(ctx, rb, n, span->x, span->y, dest);
|
||||
}
|
||||
|
||||
#if CHAN_BITS == 8
|
||||
/* 4-byte components */
|
||||
const GLuint rMask = ctx->Color.ColorMask[RCOMP] ? ~0x0 : 0x0;
|
||||
const GLuint gMask = ctx->Color.ColorMask[GCOMP] ? ~0x0 : 0x0;
|
||||
const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0;
|
||||
const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0;
|
||||
const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels;
|
||||
GLuint (*src)[4] = (GLuint (*)[4]) span->array->color.sz4.rgba;
|
||||
GLuint i;
|
||||
for (i = 0; i < n; i++) {
|
||||
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
|
||||
src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
|
||||
src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask);
|
||||
src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask);
|
||||
src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask);
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!rMask) span->array->rgba[i][RCOMP] = dest[i][RCOMP];
|
||||
if (!gMask) span->array->rgba[i][GCOMP] = dest[i][GCOMP];
|
||||
if (!bMask) span->array->rgba[i][BCOMP] = dest[i][BCOMP];
|
||||
if (!aMask) span->array->rgba[i][ACOMP] = dest[i][ACOMP];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@@ -933,7 +933,7 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
|
||||
*/
|
||||
{
|
||||
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
const GLuint output = 0; /* only frag progs can write to others */
|
||||
const GLuint output = 0; /* only frag progs can write to other outputs */
|
||||
const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
|
||||
GLuint indexSave[MAX_WIDTH];
|
||||
GLuint buf;
|
||||
@@ -1311,7 +1311,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
|
||||
*/
|
||||
{
|
||||
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||
const GLuint output = 0; /* only frag progs can write to others */
|
||||
const GLuint output = 0; /* only frag progs can write to other outputs */
|
||||
const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
|
||||
GLchan rgbaSave[MAX_WIDTH][4];
|
||||
GLuint buf;
|
||||
@@ -1322,6 +1322,8 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
|
||||
4 * span->end * sizeof(GLchan));
|
||||
}
|
||||
|
||||
/* XXX check that span's ChanType == rb's DataType, convert if needed */
|
||||
|
||||
for (buf = 0; buf < numDrawBuffers; buf++) {
|
||||
struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
|
||||
ASSERT(rb->_BaseFormat == GL_RGBA);
|
||||
@@ -1529,6 +1531,7 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
|
||||
/**
|
||||
* Wrapper for gl_renderbuffer::PutRow() which does clipping.
|
||||
* \param valueSize size of each value (pixel) in bytes
|
||||
*/
|
||||
void
|
||||
_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
@@ -1563,6 +1566,7 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
|
||||
/**
|
||||
* Wrapper for gl_renderbuffer::GetRow() which does clipping.
|
||||
* \param valueSize size of each value (pixel) in bytes
|
||||
*/
|
||||
void
|
||||
_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
@@ -1592,3 +1596,48 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
|
||||
rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get RGBA pixels from the given renderbuffer. Put the pixel colors into
|
||||
* the span's specular color arrays. The specular color arrays should no
|
||||
* longer be needed by time this function is called.
|
||||
* Used by blending, logicop and masking functions.
|
||||
* \return pointer to the colors we read.
|
||||
*/
|
||||
void *
|
||||
_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
struct sw_span *span)
|
||||
{
|
||||
GLuint pixelSize;
|
||||
void *rbPixels;
|
||||
|
||||
/*
|
||||
* Determine pixel size (in bytes).
|
||||
* Point rbPixels to a temporary space (use specular color arrays).
|
||||
*/
|
||||
if (span->array->ChanType == GL_UNSIGNED_BYTE) {
|
||||
pixelSize = 4 * sizeof(GLubyte);
|
||||
rbPixels = span->array->color.sz1.spec;
|
||||
}
|
||||
else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
|
||||
pixelSize = 4 * sizeof(GLushort);
|
||||
rbPixels = span->array->color.sz2.spec;
|
||||
}
|
||||
else {
|
||||
pixelSize = 4 * sizeof(GLfloat);
|
||||
rbPixels = span->array->color.sz4.spec;
|
||||
}
|
||||
|
||||
/* Get destination values from renderbuffer */
|
||||
if (span->arrayMask & SPAN_XY) {
|
||||
_swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y,
|
||||
rbPixels, pixelSize);
|
||||
}
|
||||
else {
|
||||
_swrast_get_row(ctx, rb, span->end, span->x, span->y,
|
||||
rbPixels, pixelSize);
|
||||
}
|
||||
|
||||
return rbPixels;
|
||||
}
|
||||
|
@@ -82,4 +82,9 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
GLuint count, GLint x, GLint y,
|
||||
GLvoid *values, GLuint valueSize);
|
||||
|
||||
|
||||
extern void *
|
||||
_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||
struct sw_span *span);
|
||||
|
||||
#endif
|
||||
|
@@ -144,6 +144,18 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const struct sw_span *span,
|
||||
zoomed.x = x0;
|
||||
zoomed.end = zoomedWidth;
|
||||
zoomed.array = &zoomed_arrays;
|
||||
zoomed_arrays.ChanType = CHAN_TYPE;
|
||||
#if CHAN_TYPE == GL_UNSIGNED_BYTE
|
||||
zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba;
|
||||
zoomed_arrays.spec = zoomed_arrays.color.sz1.spec;
|
||||
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
|
||||
zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba;
|
||||
zoomed_arrays.spec = zoomed_arrays.color.sz2.spec;
|
||||
#else
|
||||
zoomed_arrays.rgba = zoomed_arrays.color.sz4.rgba;
|
||||
zoomed_arrays.spec = zoomed_arrays.color.sz4.spec;
|
||||
#endif
|
||||
|
||||
|
||||
/* copy fog interp info */
|
||||
zoomed.fog = span->fog;
|
||||
|
Reference in New Issue
Block a user