home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
System
/
Mesa-3.1
/
src
/
fog_tmp.h
< prev
next >
Wrap
Text File
|
2000-01-07
|
12KB
|
436 lines
/* $Id: fog_tmp.h,v 1.2.2.1 1999/11/25 16:51:24 keithw Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.1
*
* Copyright (C) 1999 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"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* For 3.2: Add a helper function for drivers to do fog coordinate
* calculation. Not called from standard pipelines.
*/
static void TAG(make_fog_coord)( struct vertex_buffer *VB,
const GLvector4f *eye,
GLubyte flag)
{
const GLcontext *ctx = VB->ctx;
GLfloat end = ctx->Fog.End;
GLubyte *cullmask = VB->CullMask + VB->Start;
GLfloat *v = eye->start;
GLuint stride = eye->stride;
GLuint n = VB->Count - VB->Start;
GLubyte (*out)[4];
GLfloat d;
GLuint i;
(void) cullmask;
(void) flag;
/* Use specular alpha (front side) as fog coordinate.
*/
out = VB->Spec[0] + VB->Start;
if (VB->EyePtr->size > 2) {
switch (ctx->Fog.Mode) {
case GL_LINEAR:
d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
CULLCHECK {
GLfloat f = (end - ABSF(v[2])) * d;
FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
}
}
break;
case GL_EXP:
d = -ctx->Fog.Density;
for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
CULLCHECK {
GLfloat f = exp( d*ABSF(v[2]) ); /* already clamped */
FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
}
}
break;
case GL_EXP2:
d = -(ctx->Fog.Density*ctx->Fog.Density);
for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
CULLCHECK {
GLfloat z = v[2];
GLfloat f = exp( d*z*z ); /* already clamped */
FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
}
}
break;
default:
gl_problem(ctx, "Bad fog mode in make_fog_coord");
return;
}
}
else
{
GLubyte r = 0;
if (ctx->Fog.Mode == GL_LINEAR) {
GLfloat f = ctx->Fog.End * (ctx->Fog.End - ctx->Fog.Start);
CLAMP_FLOAT_COLOR( f );
f = 1.0 - f;
FLOAT_COLOR_TO_UBYTE_COLOR(r, f);
}
for (i = 0 ; i < n ; i++)
out[i][3] = r;
}
}
#if 0
/* For 3.3: use fog coordinates as intermediate step in all fog
* calculations.
*/
static void TAG(fog_rgba_vertices)( struct vertex_buffer *VB,
GLuint side,
GLubyte flag)
{
const GLcontext *ctx = VB->ctx;
const GLubyte rFog = ctx->Fog.ByteColor[0];
const GLubyte gFog = ctx->Fog.ByteColor[1];
const GLubyte bFog = ctx->Fog.ByteColor[2];
GLfloat end = ctx->Fog.End;
GLubyte *cullmask = VB->CullMask + VB->Start;
GLubyte (*fcoord)[4] = VB->SpecPtr[0]->start;
GLuint stride = VB->SpecPtr[0]->stride;
GLuint n = VB->Count - VB->Start;
GLubyte *in;
GLuint in_stride;
GLubyte (*out)[4];
GLfloat d,t;
GLuint i;
(void) cullmask;
(void) flag;
/* Get correct source and destination for fogged colors.
*/
in_stride = VB->Color[side]->stride;
in = VB->Color[side]->start;
VB->Color[side] = VB->FoggedColor[side];
VB->ColorPtr = VB->Color[0];
out = (GLubyte (*)[4])VB->Color[side]->start;
FLOAT_COLOR_TO_UBYTE_COLOR( rFog, ctx->Fog.Color[0] );
for ( i = 0 ; i < n ; i++, STRIDE_F(spec, sp_stride), in += in_stride) {
CULLCHECK {
GLint fc = (GLint) spec[3], ifc = 255 - fc;
out[i][0] = (fc * in[0] + ifc * rFog) >> 8;
out[i][1] = (fc * in[1] + ifc * gFog) >> 8;
out[i][2] = (fc * in[2] + ifc * bFog) >> 8;
}
}
}
static void TAG(fog_ci_vertices)( struct vertex_buffer *VB,
GLuint side,
GLubyte flag )
{
GLcontext *ctx = VB->ctx;
GLubyte *cullmask = VB->CullMask + VB->Start;
GLfloat *v = VB->EyePtr->start;
GLuint stride = VB->EyePtr->stride;
GLuint vertex_size = VB->EyePtr->size;
GLuint n = VB->EyePtr->count;
GLuint *in;
GLuint in_stride;
GLuint *out;
GLuint i;
(void) flag;
(void) cullmask;
in = VB->Index[side]->start;
in_stride = VB->Index[side]->stride;
VB->IndexPtr = VB->FoggedIndex[side];
out = VB->IndexPtr->start;
/* NOTE: the extensive use of casts generates better/faster code for MIPS */
for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
CULLCHECK {
GLfloat f = (fogend - ABSF(v[2])) * d;
f = CLAMP( f, 0.0, 1.0 );
*out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
}
}
#endif
static void TAG(fog_rgba_vertices)( struct vertex_buffer *VB,
GLuint side,
GLubyte flag)
{
const GLcontext *ctx = VB->ctx;
GLfloat rFog = ctx->Fog.Color[0];
GLfloat gFog = ctx->Fog.Color[1];
GLfloat bFog = ctx->Fog.Color[2];
GLfloat end = ctx->Fog.End;
GLubyte *cullmask = VB->CullMask + VB->Start;
GLfloat *v = VB->EyePtr->start;
GLuint stride = VB->EyePtr->stride;
GLuint n = VB->EyePtr->count;
GLubyte *in;
GLuint in_stride;
GLubyte (*out)[4];
GLfloat d,t;
GLuint i;
(void) cullmask;
(void) flag;
/* Get correct source and destination for fogged colors.
*/
in_stride = VB->Color[side]->stride;
in = VB->Color[side]->start;
VB->Color[side] = VB->FoggedColor[side];
VB->ColorPtr = VB->Color[0];
out = (GLubyte (*)[4])VB->Color[side]->start;
if (VB->EyePtr->size > 2) {
switch (ctx->Fog.Mode) {
case GL_LINEAR:
d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride), in += in_stride) {
CULLCHECK {
GLfloat f = (end - ABSF(v[2])) * d;
if (f >= 1.0) continue;
if (f < 0) {
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], rFog);
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], gFog);
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], bFog);
} else {
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
}
}
}
break;
case GL_EXP:
d = -ctx->Fog.Density;
for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride), in += in_stride) {
CULLCHECK {
GLfloat f = exp( d*ABSF(v[2]) ); /* already clamped */
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
}
}
break;
case GL_EXP2:
d = -(ctx->Fog.Density*ctx->Fog.Density);
for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride), in += in_stride) {
CULLCHECK {
GLfloat z = v[2];
GLfloat f = exp( d*z*z ); /* already clamped */
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
}
}
break;
default:
gl_problem(ctx, "Bad fog mode in gl_fog_rgba_vertices");
return;
}
}
else if (ctx->Fog.Mode == GL_LINEAR)
{
/* 2-vector vertices */
GLubyte r,g,b;
GLfloat f = ctx->Fog.End * (ctx->Fog.End - ctx->Fog.Start);
CLAMP_FLOAT_COLOR( f );
f = 1.0 - f;
rFog *= f;
bFog *= f;
gFog *= f;
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(r, rFog);
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(g, gFog);
CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b, bFog);
for (i = 0 ; i < n ; i++) {
/* CULLCHECK */ {
out[i][0] = r;
out[i][1] = g;
out[i][2] = b;
}
}
}
}
/*
* Compute the fogged color indexes for an array of vertices.
* Input: n - number of vertices
* v - array of vertices
* In/Out: indx - array of vertex color indexes
*/
static void TAG(fog_ci_vertices)( struct vertex_buffer *VB,
GLuint side,
GLubyte flag )
{
GLcontext *ctx = VB->ctx;
GLubyte *cullmask = VB->CullMask + VB->Start;
GLfloat *v = VB->EyePtr->start;
GLuint stride = VB->EyePtr->stride;
GLuint vertex_size = VB->EyePtr->size;
GLuint n = VB->EyePtr->count;
GLuint *in;
GLuint in_stride;
GLuint *out;
GLuint i;
(void) flag;
(void) cullmask;
in = VB->Index[side]->start;
in_stride = VB->Index[side]->stride;
VB->IndexPtr = VB->FoggedIndex[side];
out = VB->IndexPtr->start;
/* NOTE: the extensive use of casts generates better/faster code for MIPS */
if (vertex_size > 2) {
switch (ctx->Fog.Mode) {
case GL_LINEAR:
{
GLfloat d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
GLfloat fogindex = ctx->Fog.Index;
GLfloat fogend = ctx->Fog.End;
for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
{
CULLCHECK {
GLfloat f = (fogend - ABSF(v[2])) * d;
f = CLAMP( f, 0.0, 1.0 );
*out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
}
}
break;
}
case GL_EXP:
{
GLfloat d = -ctx->Fog.Density;
GLfloat fogindex = ctx->Fog.Index;
for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
{
CULLCHECK {
GLfloat f = exp( d * ABSF(v[2]) );
*out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
}
}
break;
}
case GL_EXP2:
{
GLfloat d = -(ctx->Fog.Density*ctx->Fog.Density);
GLfloat fogindex = ctx->Fog.Index;
for ( i = 0; i < n ; i++, STRIDE_F(v,stride),STRIDE_UI(in,in_stride))
{
CULLCHECK {
GLfloat z = v[2]; /*ABSF(v[i][2]);*/
GLfloat f = exp( d * z*z ); /* was -d ??? */
out[i] = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
}
}
break;
}
default:
gl_problem(ctx, "Bad fog mode in gl_fog_ci_vertices");
return;
}
} else if (ctx->Fog.Mode == GL_LINEAR) {
GLuint fogindex;
GLfloat f = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start);
f = 1.0 - CLAMP( f, 0.0F, 1.0F );
fogindex = (GLuint)(f * ctx->Fog.Index);
if (fogindex) {
for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
{
CULLCHECK {
*out = *in + fogindex;
}
}
}
}
}
static void TAG(init_fog_tab)(void)
{
fog_ci_tab[IDX] = TAG(fog_ci_vertices);
fog_rgba_tab[IDX] = TAG(fog_rgba_vertices);
make_fog_coord_tab[IDX] = TAG(make_fog_coord);
}
#undef TAG
#undef CULLCHECK
#undef IDX