home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
REND
/
COLOR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-30
|
30KB
|
1,116 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include "reader.h"
#include "glib.h"
static Pointer(Atr*) patr ; /* アトリビュート */
static int shift[] = { 16, 24, 8 } ; /* r g b のシフト数 */
#define COLORBITS 8
/*
proto -s color.c > temp
*/
#ifdef XC
static void getposcolor();
static void lightcolor();
static const long lpow();
#else
#ifdef SPEC
static void getposcolor( ShadeTable *, Point, Vector, Frame* );
static void lightcolor( Color, Color, Light*, Vector, Point, Vector );
#else
static void getposcolor( Color, Point, Vector, Frame* );
static void lightcolor( Color, Light*, Vector, Point, Vector );
#endif
static const long lpow( long, long );
#endif
/*
光度計算
*/
int GetAtrTable( atrtable, frame, poly, world, worldit )
AtrTable *atrtable ;
Frame *frame ;
Poly *poly ; /* 対象ポリゴン */
Matrix world ; /* ワールド座標変換行列 */
Matrix worldit ; /* world の転置逆行列 */
{
int i, j, n, lockpoint ;
Point cm, pos ; /* 重心 */
Color col ; /* 面の明るさ */
#ifdef SPEC
Color spec ; /* 面のスペキュラー */
#endif
Point *point ;
Vector *vecp ;
Vector nvec ; /* 法線ベクトル */
Vector vec ;
Atr *atr ;
patr = poly->atr ;
n = poly->pointnum ;
/* 法線ベクトルを求める */
vec_mult_mat( &nvec, (Vector*)poly->coe, worldit, 1, FALSE );
v_copy( pos, *pointer( poly->point ) );
vec_mult_mat( &pos, &pos, world, 1, TRUE );
for( i = 0 ; i < 3 ; ++i )
vec[i] = frame->eye.mat[3][i] - pos[i] ;
#ifdef BACKFACE
if ( s_pro( nvec, vec ) < 0.0 ) {
extern int backface;
if (backface) {
return FALSE;
} else {
v_s_mult( nvec, nvec, -1.0 );
}
}
#else
if ( s_pro( nvec, vec ) < 0.0 )
v_s_mult( nvec, nvec, -1.0 );
#endif
v_unit( nvec, nvec );
if ( ShadingModel == GOURAUD_SHADE )
{
point = (Point*)pointer( poly->point );
lockpoint = datalock();
for( i = 0 ; i < n ; ++i )
{
v_copy( pos, point[i] );
vec_mult_mat( (Point*)pos, point+i, world, 1, TRUE );
if ( poly->type & SHADE )
{
vecp = (Vector*)pointer( poly->vec );
vec_mult_mat( (Vector*)vec, vecp+i, worldit, 1, FALSE );
v_unit( vec, vec );
if ( s_pro( nvec, vec ) < 0.0 )
v_s_mult( vec, vec, -1.0 );
#ifdef SPEC
getposcolor( &(atrtable[i].shade), pos, vec, frame );
#else
getposcolor( col, pos, vec, frame );
#endif
}
else
{
#ifdef SPEC
getposcolor( &(atrtable[i].shade), pos, nvec, frame );
#else
getposcolor( col, pos, nvec, frame );
#endif
}
#if 0
ColorToShadeTable( &(atrtable[i].shade), col );
ColorToShadeSpecularTable( &(atrtable[i].shade), spec );
#endif
#ifndef SPEC
ColorToShadeTable( &(atrtable[i].shade), col );
#endif
atrtable[i].map.map = NULL ;
}
dataunlock( lockpoint );
atr = pointer( patr );
if ( poly->type & UVPOLY && atr->maptype != NO_MAP )
SetMapTable( atrtable, poly->uv, n, patr );
}
else
{
/* 重心の計算 */
cm[0] = cm[1] = cm[2] = 0.0 ;
point = (Point*)pointer( poly->point );
for( i = 0 ; i < n ; ++i )
{
for( j = 0 ; j < 3 ; ++j )
cm[j] += point[i][j] ;
}
for( j = 0 ; j < 3 ; ++j )
cm[j] /= (Float)n ;
vec_mult_mat( (Point*)cm, (Point*)cm, world, 1, TRUE );
#ifdef SPEC
getposcolor( &(atrtable->shade), cm, nvec, frame);
for (i = 0; i < 3; ++i) {
long c;
c = (atrtable->shade.curcolor[i] + atrtable->shade.curspecular[i]);
if (atrtable->shade.depthrate > 0) {
c = (long)
((((Float)c * (SHADE_POINT - atrtable->shade.depthrate))+
((Float)atrtable->shade.depthcolor[i]
*atrtable->shade.depthrate)) / (Float) SHADE_POINT);
}
if (c >= SHADE_POINT) {
c = SHADE_POINT-1;
}
atrtable->shade.curcolor[i] = c;
}
#else
getposcolor( col, cm, nvec, frame );
ColorToShadeTable( &(atrtable->shade), col );
#endif
atrtable->map.map = NULL ;
}
return TRUE;
}
#ifdef SPEC
static void getrefdir(ShadeTable *shade, Vector nvec, Vector evec);
static void getposcolor( shade, pos, nvec, frame )
ShadeTable *shade;
Point pos ;
Vector nvec ;
Frame *frame ;
{
int i ;
Float r ;
Light *light ;
Vector evec, uevec ;
Atr *atr ;
Color spec;
Color col ;
/* 視線方向ベクトルを求める */
for( i = 0 ; i < 3 ; ++i )
evec[i] = frame->eye.mat[3][i] - pos[i] ;
v_unit( uevec, evec );
/* 光度計算 */
atr = pointer( patr );
c_mult( col, atr->col, atr->amb );
spec[0] = 0;spec[1] = 0; spec[2] = 0;
light = frame->light ;
for( i = 0 ; i < frame->lightnum ; ++i )
lightcolor( col, spec, light+i, uevec, pos, nvec );
ColorToShadeTable( shade, col );
ColorToShadeSpecularTable( shade, spec );
shade->depthrate = 0;
if ( frame->env.depth > 0.0 )
{
ColorToShadeDepthTable( shade, frame->env.depthcol );
#if 0
r = pow( 0.5, v_length( evec ) / frame->env.depth );
#else
r = exp(log(0.5) * v_length( evec ) / frame->env.depth );
#endif
shade->depthrate = (1.0 - r) * SHADE_POINT;
}
#ifdef REFMAP
if (RefMap && (atr->ref[0] > 0 || atr->ref[1] > 0 || atr->ref[2] > 0)) {
getrefdir(shade, nvec, uevec);
shade->refcolor[0] = (long)(atr->ref[0] * (Float)(SHADE_POINT/COLOR_POINT));
shade->refcolor[1] = (long)(atr->ref[1] * (Float)(SHADE_POINT/COLOR_POINT));
shade->refcolor[2] = (long)(atr->ref[2] * (Float)(SHADE_POINT/COLOR_POINT));
} else {
shade->refcolor[0] =
shade->refcolor[1] =
shade->refcolor[2] = 0;
}
#endif
}
#ifdef REFMAP
static void getrefdir(ShadeTable *shade, Vector nvec, Vector evec)
{
Vector y, r;
Float l;
int i;
v_pro(y, evec, nvec);
v_pro(r, nvec, y);
l = s_pro(nvec, evec);
for (i = 0; i < 3; ++i) {
shade->currefdir[i] = (long)((l * nvec[i]-r[i]) * (Float)SHADE_POINT);
}
#if 0
fprintf(stderr, "反射:");
/*
fprintf( errfp, "n:(%5.3lf %5.3lf %5.3lf)", nvec[0], nvec[1], nvec[2] ) ;
fprintf( errfp, "e:(%5.3lf %5.3lf %5.3lf)\n", evec[0], evec[1], evec[2] ) ;
*/
fprintf( errfp, "(%6.3lf %6.3lf %6.3lf\t",
(double)shade->currefdir[0]/(double)SHADE_POINT,
(double)shade->currefdir[1]/(double)SHADE_POINT,
(double)shade->currefdir[2]/(double)SHADE_POINT);
#endif
}
#endif
#else
static void getposcolor( col, pos, nvec, frame )
Color col ;
Point pos ;
Vector nvec ;
Frame *frame ;
{
int i ;
Float r ;
long dif ;
Light *light ;
Vector evec, uevec ;
Atr *atr ;
/* 視線方向ベクトルを求める */
for( i = 0 ; i < 3 ; ++i )
evec[i] = frame->eye.mat[3][i] - pos[i] ;
v_unit( uevec, evec );
/* 光度計算 */
atr = pointer( patr );
c_mult( col, atr->col, atr->amb );
light = frame->light ;
for( i = 0 ; i < frame->lightnum ; ++i )
lightcolor( col, light+i, uevec, pos, nvec );
if ( frame->env.depth > 0.0 )
{
#if 0
r = pow( 0.5, v_length( evec ) / frame->env.depth );
#else
r = exp(log(0.5) * v_length( evec ) / frame->env.depth );
#endif
for( i =0 ; i < 3 ; ++i )
{
dif = (long)( r * (Float)( col[i] - frame->env.depthcol[i] ) );
col[i] = dif + frame->env.depthcol[i] ;
}
}
}
#endif
#ifdef SPEC
static void lightcolor( color, spec, light, evec, pos, nvec )
Color spec;
#else
static void lightcolor( color, light, evec, pos, nvec )
#endif
Color color ;
Light *light ;
Vector evec ;
Point pos ;
Vector nvec ;
{
Float r ; /* 光源までの距離 */
Color lcol ; /* 光線の強さ */
Vector lvec ; /* 光源方向ベクトル */
Float co ; /* 余弦 */
Color cwork ;
Vector vwork ;
Float dwork ;
int j ;
long l, lco ;
Atr *atr ;
c_copy( lcol, light->col );
/* 光線方向のベクトル及び光線の強さを求める */
switch( light->type )
{
case LIGHT_POINT :
/* 光線方向ベクトル */
v_sub( lvec, light->point, pos );
r = v_length( lvec );
if ( fabs( r ) < minscale )
return;
v_unit( lvec, lvec );
/* 光線の強さ */
dwork = (light->dist*light->dist) / (r*r) ;
if ( dwork > 1.0 )
l = COLOR_POINT ;
else
l = (long)( dwork * (Float)COLOR_POINT );
c_s_mult( lcol, lcol, l );
break ;
case LIGHT_PAL :
v_s_mult( lvec, light->vec, -1.0 );
break ;
case LIGHT_SPOT :
v_sub( vwork, light->point, pos );
r = v_length( vwork );
if (light->dist > 0.0) {
dwork = (light->dist*light->dist) / (r*r) ;
} else {
dwork = 1.0;
}
v_unit( vwork, vwork );
v_s_mult( lvec, light->vec, -1.0 );
co = s_pro( vwork, lvec );
if ( co > 0.0 )
{
lco = (long)( co * (Float)COLOR_POINT );
l = lpow( lco, (long)( light->size * 100.0 ) );
if (dwork < 1.0) {
l *= dwork;
}
c_s_mult( lcol, lcol, l );
}
else
lcol[0] = lcol[1] = lcol[2] = 0L ;
break ;
default :
assert( FALSE );
}
atr = pointer( patr );
/* 影になっているかどうか */
co = s_pro( nvec, lvec ) ;
if ( co < 0.0 )
return;
/* ベクトル設定 */
v_add( vwork, evec, lvec );
v_unit( vwork, vwork );
if ( atr->rgbflag )
{
/* ディフューズ */
c_mult( cwork, lcol, atr->col );
c_mult( cwork, cwork, atr->dif );
lco = (long)( co * (Float)COLOR_POINT );
c_s_mult( cwork, cwork, lco );
c_add( color, color, cwork );
/* スペキュラー */
lco = (long)( s_pro( nvec, vwork ) * (Float)COLOR_POINT );
for( j = 0 ; j < 3 ; ++j )
{
l = atr->spc[j] * lpow( lco, atr->size[j] ) >> COLOR_SHIFT ;
cwork[j] = ( atr->h * atr->col[j] + ( COLOR_POINT - atr->h ) * lcol[j] )
>> COLOR_SHIFT ;
cwork[j] = ( l * cwork[j] ) >> COLOR_SHIFT ;
}
#ifdef SPEC
c_add( spec, spec, cwork ) ;
#else
c_add( color, color, cwork ) ;
#endif
}
else
{
/* ディフューズ */
c_mult( cwork, lcol, atr->col );
#if 1
l = ( (long)( co * (Float)COLOR_POINT ) * atr->dif[0] ) >> COLOR_SHIFT ;
#else
l = (long)( co * (Float)atr->dif[0] );
#endif
c_s_mult( cwork, cwork, l );
c_add( color, color, cwork );
/* スペキュラー */
lco = (long)( s_pro( nvec, vwork ) * (Float)COLOR_POINT );
lco = atr->spc[0] * lpow( lco, atr->size[0] ) >> COLOR_SHIFT ;
if ( atr->h == 0L )
c_s_mult( cwork, lcol, lco );
else
{
for( j = 0 ; j < 3 ; ++j )
{
l = ( atr->h * atr->col[j] + ( COLOR_POINT - atr->h ) * lcol[j] )
>> COLOR_SHIFT ;
cwork[j] = ( lco * l ) >> COLOR_SHIFT ;
}
}
#ifdef SPEC
c_add( spec, spec, cwork );
#else
c_add( color, color, cwork );
#endif
}
}
static const long lpow( a, n )
long a ;
long n ;
{
long ret ;
ret = COLOR_POINT ;
while( n > 0 )
{
if ( n & 1 )
ret = ( ret * a ) >> COLOR_SHIFT ;
n = n / 2 ;
a = ( a * a ) >> COLOR_SHIFT ;
}
return( ret );
}
ColorCode X68kcolorToColorCode( unsigned short color)
{
ColorCode code;
/*
-6 + 16 = 10
-11 + 24 = 13
-1 + 8 = 7
gggg grrr rrbb bbbt
gggg gggg rrrr rrrr bbbb bbbb 0000 000t
*/
#if 0
code = ((color & 0x07c0) << 13)
| ((color & 0xf800) << 16)
| ((color & 0x003e) << 10)
| ((color & 0x0001) ? 0xff : 0);
return code;
#else
code = ((unsigned long)(color & 0xf800) << 11L)
| ((unsigned long)(color & 0x07c0) << 8L)
| ((unsigned long)(color & 0x003e) << 5L);
return (code << 5L) | (code & 0x07070700L) | ((color & 0x0001) ? 0xff : 0);
#endif
}
ColorCode ColorCodeToX68kcolor( code )
ColorCode code;
{
unsigned short color;
/*
-6 + 16 = 10
-11 + 24 = 13
-1 + 8 = 7
*/
color = (unsigned short)
(((code >> 13) & 0x07c0)
| ((code >> 16) & 0xf800)
| ((code >> 10) & 0x003e)
| ((code & 0x0080) ? 1 : 0));
return color;
}
/* カラーコードの計算 */
const ColorCode ColorToCode( color )
Color color ;
{
ColorCode code, c ;
int i ;
code = 0 ;
for( i = 0 ; i < 3 ; ++i )
{
c = (ColorCode)( color[i] >> ( COLOR_SHIFT - COLORBITS ) );
if ( c >= (1 << COLORBITS) )
c = (1 << COLORBITS)-1 ;
code += c << shift[i] ;
}
return( code );
}
#ifdef MAPANTI
ColorCode ColorMix(ColorCode c11, ColorCode c12, ColorCode c21, ColorCode c22,
int urate, int vrate)
{
unsigned long r, g, b, t;
g = (unsigned long)
(( c11 >> 24 ) * (256 - urate) * (256 - vrate)
+ ( c12 >> 24 ) * (256 - urate) * vrate
+ ( c21 >> 24 ) * urate * (256 - vrate)
+ ( c22 >> 24 ) * urate * vrate );
r = (unsigned long)
(((c11 >> 16) & 255) * (256 - urate) * (256 - vrate)
+ ((c12 >> 16) & 255) * (256 - urate) * vrate
+ ((c21 >> 16) & 255) * urate * (256 - vrate)
+ ((c22 >> 16) & 255) * urate * vrate );
b = (unsigned long)
(((c11 >> 8) & 255) * (256 - urate) * (256 - vrate)
+ ((c12 >> 8) & 255) * (256 - urate) * vrate
+ ((c21 >> 8) & 255) * urate * (256 - vrate)
+ ((c22 >> 8) & 255) * urate * vrate );
t = (unsigned long)
(( c11 & 255) * (256 - urate) * (256 - vrate)
+ ( c12 & 255) * (256 - urate) * vrate
+ ( c21 & 255) * urate * (256 - vrate)
+ ( c22 & 255) * urate * vrate );
return ((g & 0xff0000L) << 8)
| (r & 0xff0000L)
| ((b & 0xff0000L) >> 8) | (t>>16);
}
#endif
/* カラーコードの計算 */
ColorCode GetColorCode( shade, maptable )
ShadeTable *shade ;
MapTable *maptable ;
{
unsigned long cc ;
long u, v ;
Map *map ;
REGISTER ColorCode code, c ;
REGISTER int i ;
if ( maptable == NULL || maptable->map == NULL )
{
/* マッピングなし */
code = 0 ;
for( i = 0 ; i < 3 ; ++i )
{
c = (ColorCode)( shade->curcolor[i] >> ( SHADE_SHIFT - COLORBITS ) );
if ( c >= (1 << COLORBITS) )
c = (1 << COLORBITS)-1 ;
code += c << shift[i] ;
}
}
else
{
#ifdef MAPANTI
extern int MapAntiFlag;
if (MapAntiFlag) {
int u1, u2, urate;
int v1, v2, vrate;
ColorCode c11, c12, c21, c22;
/* マッピングの処理 */
map = maptable->map ;
u = maptable->curuv[0];
v = maptable->curuv[1];
if (u >= 0) {
u = u % (map->h << 16);
} else {
u = (map->h << 16) - 1 - ( (-u) % (map->h << 16));
}
if (v >= 0) {
v = v % (map->v << 16);
} else {
v = (map->v << 16) - 1 - ( (-v) % (map->v << 16));
}
u1 = (int)(u >> 16);
u2 = (u1+1) % map->h;
v1 = (int)(v >> 16);
v2 = (v1+1) % map->v;
urate = (int)((u & 65535L) >> 8);
vrate = (int)((v & 65535L) >> 8);
if (map->fullcolor) {
c11 = ( (ColorCode*)pointer( map->buf[v1] ) )[u1] ;
c12 = ( (ColorCode*)pointer( map->buf[v2] ) )[u1] ;
c21 = ( (ColorCode*)pointer( map->buf[v1] ) )[u2] ;
c22 = ( (ColorCode*)pointer( map->buf[v2] ) )[u2] ;
} else {
c11 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v1] ) )[u1]) ;
c12 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v2] ) )[u1]) ;
c21 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v1] ) )[u2]) ;
c22 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v2] ) )[u2]) ;
}
c = ColorMix(c11, c12, c21, c22, urate, vrate);
} else
#endif
{
/* マッピングの処理 */
map = maptable->map ;
u = (int)( maptable->curuv[0] >> 16 );
v = (int)( maptable->curuv[1] >> 16 );
if ( u >= 0 )
u = u % map->h ;
else
u = map->h - 1 - ( ( - u ) % map->h ) ;
if ( v >= 0 )
v = v % map->v ;
else
v = map->v - 1 - ( ( - v ) % map->v );
if (map->fullcolor) {
c = ( (ColorCode*)pointer( map->buf[(int)v] ) )[(int)u] ;
} else {
c = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[(int)v] ) )[(int)u]) ;
}
}
if ((c & 0xff) == 0xff) {
return 0xff;
}
code = c & 255; ;
for( i = 0 ; i < 3 ; ++i )
{
cc = (ColorCode)(
( ( ( (long)c >> shift[i] ) & ((1 << COLORBITS)-1) ) * shade->curcolor[i] )
>> SHADE_SHIFT
) ;
if ( cc >= (1 << COLORBITS) )
cc = (1 << COLORBITS)-1 ;
code += cc << shift[i] ;
}
}
return( code );
}
#ifdef REFMAP
static ColorCode GetRefMapColor(long *direction)
{
extern int MapAntiFlag;
ColorCode c;
Map *map = RefMapData[0];
int u = 0, v = 0;
Float l;
if (RefMap == 1) {
l = sqrt((Float)(direction[0]) * (Float)(direction[0])
+ (Float)(direction[1]) * (Float)(direction[1]));
if (l <= 1) {
u = 0;
if (direction[2] > 0) {
v = 0;
} else {
v = (map->v-2)*256;
}
} else {
double fu, fv;
fu = atan2(-direction[1], direction[0]);
u = (int)(fu * (map->h-1) * (1.0 / 3.14159265 / 2.0 * 256.0)) + (map->h-1)*(256/2);
fv = atan(-direction[2]/ l);
v = (int)(fv * (map->v-1) * (1.0 / 3.14159265 * 256.0)) + (map->v-1)*(256/2);
}
} else if (RefMap == 2) {
l = sqrt((Float)(direction[0]) * (Float)(direction[0])
+ (Float)(direction[1]) * (Float)(direction[1])
+ (Float)(direction[2]) * (Float)(direction[2]));
if (l < 1.0) {
u = v = 0;
} else {
u = -(int)((Float)direction[1] / l * (Float)(map->h-1) * (256.0/2.0)) + (map->h-1)*(256/2) ;
v = (int)((Float)direction[0] / l * (Float)(map->v-1) * (256.0/2.0));
if (direction[2] > 0) {
v = (map->v-1)*(256/2) + v; /*上*/
} else {
map = RefMapData[1];
v = (map->v-1)*(256/2) - v; /*下*/
}
}
} else if (RefMap == 6) {
Float x, y, z;
x = direction[0] > 0 ? direction[0] : -direction[0];
y = direction[1] > 0 ? direction[1] : -direction[1];
z = direction[2] > 0 ? direction[2] : -direction[2];
if (x > y && x > z && x > 1.0) {
if (direction[0] > 0) {
u = (int)((Float)direction[1] / x * (Float)(map->h-1) * (256.0/2.0));
u = (map->h-1)*(256/2) - u; /*前(X+)*/
} else {
map = RefMapData[2];
u = (int)((Float)direction[1] / x * (Float)(map->h-1) * (256.0/2.0));
u = (map->h-1)*(256/2) + u; /*後(X-)*/
}
v = -(int)((Float)direction[2] / x * (Float)(map->v-1) * (256.0/2.0)) + (map->v-1)*256/2;
} else if (y > z && y > 1.0) {
if (direction[1] > 0) {
map = RefMapData[3];
u = (int)((Float)direction[0] / y * (Float)(map->h-1) * (256.0/2.0));
u = (map->h-1)*(256/2) + u; /*左(Y+)*/
} else {
map = RefMapData[1];
u = (int)((Float)direction[0] / y * (Float)(map->h-1) * (256.0/2.0));
u = (map->h-1)*(256/2) - u; /*右(Y-)*/
}
v = -(int)((Float)direction[2] / y * (Float)(map->v-1) * (256.0/2.0)) + (map->v-1)*(256/2);
} else if (z > 1.0) {
if (direction[2] > 0) {
map = RefMapData[4];
v = (int)((Float)direction[0] / z * (Float)(map->v-1) * (256.0/2.0));
v = (map->v-1)*(256/2) + v; /*上(Z+)*/
} else {
map = RefMapData[5];
v = (int)((Float)direction[0] / z * (Float)(map->v-1) * (256.0/2.0));
v = (map->v-1)*(256/2) - v; /*下(Z-)*/
}
u = -(int)((Float)direction[1] / z * (Float)(map->h-1) * (256.0/2.0)) + (map->h-1)*(256/2);
}
}
#ifdef MAPANTI
if (MapAntiFlag) {
int urate, vrate;
int u2, v2;
ColorCode c11, c12, c21, c22;
urate = u & 255;
vrate = v & 255;
u >>= 8;
u2 = (u < map->h-1) ? u+1 : u;
v >>= 8;
v2 = (v < map->v-1) ? v+1 : v;
if (map->fullcolor) {
c11 = ( (ColorCode*)pointer( map->buf[v ] ) )[u] ;
c12 = ( (ColorCode*)pointer( map->buf[v2] ) )[u] ;
c21 = ( (ColorCode*)pointer( map->buf[v ] ) )[u2] ;
c22 = ( (ColorCode*)pointer( map->buf[v2] ) )[u2] ;
} else {
c11 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v ] ) )[u]) ;
c12 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v2] ) )[u]) ;
c21 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v ] ) )[u2]) ;
c22 = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v2] ) )[u2]) ;
}
c = ColorMix(c11, c12, c21, c22, urate, vrate);
} else
#endif
if (map->fullcolor) {
c = ( (ColorCode*)pointer( map->buf[v>>8] ) )[u>>8] ;
} else {
c = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v>>8] ) )[u>>8]) ;
}
return c;
}
#endif
#ifdef SPEC
ColorCode GetColorAllCode( shade, maptable )
ShadeTable *shade ;
MapTable *maptable ;
{
unsigned long cc ;
int u, v ;
Map *map ;
REGISTER ColorCode code, c ;
REGISTER int i ;
#ifdef REFMAP
long refcolor[3];
refcolor[0] = refcolor[1] = refcolor[2] = 0;
if (RefMap && (shade->refcolor[0] > 0 || shade->refcolor[1] > 0 || shade->refcolor[2] > 0)) { c = GetRefMapColor(shade->currefdir);
for( i = 0 ; i < 3 ; ++i )
{
if (shade->refcolor[i] > 0) {
refcolor[i] =
( ( ( (unsigned long)c >> shift[i] ) & ((1 << COLORBITS)-1) ) * shade->refcolor[i] )
>> COLORBITS;
}
}
}
#endif
if ( maptable == NULL || maptable->map == NULL )
{
/* マッピングなし */
code = 0 ;
for( i = 0 ; i < 3 ; ++i )
{
#ifdef REFMAP
c = (ColorCode)(
(shade->curcolor[i]+shade->curspecular[i]+refcolor[i])
>> ( SHADE_SHIFT - COLORBITS ) );
#else
c = (ColorCode)(
(shade->curcolor[i]+shade->curspecular[i])
>> ( SHADE_SHIFT - COLORBITS ) );
#endif
if ( c >= (1 << COLORBITS) )
c = (1 << COLORBITS)-1 ;
if (shade->depthrate > 0) {
c = ( c * (SHADE_POINT - shade->depthrate)
+ (shade->depthcolor[i] >> (SHADE_SHIFT - COLORBITS))
* shade->depthrate) / SHADE_POINT;
}
code += c << shift[i] ;
}
}
/* ここから下にくることはない(マッピング時はGetColorCode, GetSpecularColorCode使用) */
else
{
/* マッピングの処理 */
map = maptable->map ;
u = (int)( maptable->curuv[0] >> 16 );
v = (int)( maptable->curuv[1] >> 16 );
if ( u >= 0 )
u = u % map->h ;
else
u = map->h - ( ( - u ) % map->h ) ;
if ( v >= 0 )
v = v % map->v ;
else
v = map->v - ( ( - v ) % map->v );
if (map->fullcolor) {
c = ( (ColorCode*)pointer( map->buf[v] ) )[u] ;
} else {
c = X68kcolorToColorCode(( (unsigned short *)pointer( map->buf[v] ) )[u]) ;
}
if ((c & 1) != 0) {
return 1;
}
code = 0 ;
for( i = 0 ; i < 3 ; ++i )
{
cc = (ColorCode)(
(
( ( ( (long)c >> shift[i] ) & ((1 << COLORBITS)-1) ) * shade->curcolor[i] )
>> SHADE_SHIFT
) + (
shade->curspecular[i] >> (SHADE_SHIFT - COLORBITS)
)) ;
if (shade->depthrate > 0) {
cc = ( cc * (SHADE_POINT - shade->depthrate)
+ (shade->depthcolor[i] >> (SHADE_SHIFT - COLORBITS))
* shade->depthrate) / SHADE_POINT;
}
if ( cc >= (1 << COLORBITS) )
cc = (1 << COLORBITS)-1 ;
code += cc << shift[i] ;
}
}
return( code );
}
/* カラーコードの計算 */
ColorCode GetSpecularColorCode( shade )
ShadeTable *shade ;
{
unsigned long cc ;
REGISTER ColorCode code, c ;
REGISTER int i ;
/* マッピングなし */
code = 0 ;
#ifdef REFMAP
c = 0;
if (RefMap) {
c = GetRefMapColor(shade->currefdir);
for( i = 0 ; i < 3 ; ++i )
{
cc = 0;
if (shade->refcolor[i] > 0) {
cc = (ColorCode)
(
( ( ( (unsigned long)c >> shift[i] ) & ((1 << COLORBITS)-1) ) * shade->refcolor[i] )
>> SHADE_SHIFT
);
}
if (shade->curspecular[i] > 0) {
cc += (ColorCode)( shade->curspecular[i] >> ( SHADE_SHIFT - COLORBITS ) );
}
if ( cc >= (1 << COLORBITS) )
cc = (1 << COLORBITS)-1 ;
code += cc << shift[i] ;
}
} else
#endif
for( i = 0 ; i < 3 ; ++i )
{
if (shade->curspecular[i] > 0) {
c = (ColorCode)( shade->curspecular[i] >> ( SHADE_SHIFT - COLORBITS ) );
if ( c >= (1 << COLORBITS) )
c = (1 << COLORBITS)-1 ;
code += c << shift[i] ;
}
}
return code;
}
#endif
/* アトリビュートデータの計算 */
void ColorToShadeTable( shade, col )
ShadeTable *shade ;
Color col ;
{
REGISTER int i ;
for( i = 0 ; i < 3 ; ++i )
{
if ( col[i] >= COLOR_POINT )
shade->curcolor[i] = SHADE_POINT - 1;
else
shade->curcolor[i] = col[i] << (SHADE_SHIFT - COLOR_SHIFT);
}
}
#ifdef SPEC
void ColorToShadeSpecularTable( shade, col )
ShadeTable *shade ;
Color col ;
{
REGISTER int i ;
for( i = 0 ; i < 3 ; ++i )
{
if ( col[i] >= COLOR_POINT )
shade->curspecular[i] = SHADE_POINT - 1;
else
shade->curspecular[i] = col[i] << (SHADE_SHIFT - COLOR_SHIFT);
}
}
void ColorToShadeDepthTable( shade, col )
ShadeTable *shade ;
Color col ;
{
REGISTER int i ;
for( i = 0 ; i < 3 ; ++i )
{
if ( col[i] >= COLOR_POINT )
shade->depthcolor[i] = SHADE_POINT - 1;
else
shade->depthcolor[i] = col[i] << (SHADE_SHIFT - COLOR_SHIFT);
}
}
#endif
/* アトリビュートデータの更新 */
void IncAtrTable( shade, map )
REGISTER ShadeTable *shade ;
REGISTER MapTable *map ;
{
shade->curcolor[0] += shade->stepcolor[0] ;
shade->curcolor[1] += shade->stepcolor[1] ;
shade->curcolor[2] += shade->stepcolor[2] ;
#ifdef SPEC
shade->curspecular[0] += shade->stepspecular[0] ;
shade->curspecular[1] += shade->stepspecular[1] ;
shade->curspecular[2] += shade->stepspecular[2] ;
shade->depthrate += shade->stepdepthrate;
#endif
if ( map != NULL && map->map != NULL )
{
map->curuv[0] += map->stepuv[0] ;
map->curuv[1] += map->stepuv[1] ;
#ifdef EXTENDMAP
map->stepuv[0] += map->stepstepuv[0];
map->stepuv[1] += map->stepstepuv[1];
#endif
}
#ifdef REFMAP
if (RefMap) {
shade->currefdir[0] += shade->steprefdir[0];
shade->currefdir[1] += shade->steprefdir[1];
shade->currefdir[2] += shade->steprefdir[2];
}
#endif
}
/* アトリビュートデータの更新 */
void AddAtrTable( shade, map, count )
REGISTER ShadeTable *shade ;
REGISTER MapTable *map ;
int count ;
{
shade->curcolor[0] += count * shade->stepcolor[0] ;
shade->curcolor[1] += count * shade->stepcolor[1] ;
shade->curcolor[2] += count * shade->stepcolor[2] ;
#ifdef SPEC
shade->curspecular[0] += count * shade->stepspecular[0] ;
shade->curspecular[1] += count * shade->stepspecular[1] ;
shade->curspecular[2] += count * shade->stepspecular[2] ;
shade->depthrate += count * shade->stepdepthrate;
#endif
if ( map != NULL && map->map != NULL )
{
#ifdef EXTENDMAP
int i;
for (i = count; i > 0; --i) {
map->curuv[0] += map->stepuv[0] ;
map->curuv[1] += map->stepuv[1] ;
map->stepuv[0] += map->stepstepuv[0];
map->stepuv[1] += map->stepstepuv[1];
}
#else
map->curuv[0] += count * map->stepuv[0] ;
map->curuv[1] += count * map->stepuv[1] ;
#endif
}
#ifdef REFMAP
if (RefMap &&
(shade->refcolor[0] > 0 || shade->refcolor[1] > 0 || shade->refcolor[2] > 0)) {
shade->currefdir[0] += count * shade->steprefdir[0];
shade->currefdir[1] += count * shade->steprefdir[1];
shade->currefdir[2] += count * shade->steprefdir[2];
}
#endif
}
/* アトリビュートデータの設定 */
void SetAtrStep( shade, toshade, map, tomap, step )
REGISTER ShadeTable *shade ;
ShadeTable *toshade ;
REGISTER MapTable *map ;
MapTable *tomap ;
int step ;
{
shade->stepcolor[0]
= (toshade->curcolor[0] - shade->curcolor[0] + step / 2) / step ;
shade->stepcolor[1]
= (toshade->curcolor[1] - shade->curcolor[1] + step / 2) / step ;
shade->stepcolor[2]
= (toshade->curcolor[2] - shade->curcolor[2] + step / 2) / step ;
#ifdef SPEC
shade->stepspecular[0]
= (toshade->curspecular[0] - shade->curspecular[0] + step / 2) / step ;
shade->stepspecular[1]
= (toshade->curspecular[1] - shade->curspecular[1] + step / 2) / step ;
shade->stepspecular[2]
= (toshade->curspecular[2] - shade->curspecular[2] + step / 2) / step ;
shade->stepdepthrate
= (toshade->depthrate - shade->depthrate + step / 2) / step ;
#endif
if ( map != NULL && map->map != NULL )
{
map->stepuv[0]
= ( tomap->curuv[0] - map->curuv[0] + step / 2 ) / step ;
map->stepuv[1]
= ( tomap->curuv[1] - map->curuv[1] + step / 2 ) / step ;
}
#ifdef REFMAP
if (RefMap && (shade->refcolor[0] > 0 || shade->refcolor[1] > 0 || shade->refcolor[2] > 0)) {
shade->steprefdir[0]
= (toshade->currefdir[0] - shade->currefdir[0] + step / 2) / step ;
shade->steprefdir[1]
= (toshade->currefdir[1] - shade->currefdir[1] + step / 2) / step ;
shade->steprefdir[2]
= (toshade->currefdir[2] - shade->currefdir[2] + step / 2) / step ;
}
#endif
}
void SetAtrStepMap( z1, z2, map, tomap, step )
long z1, z2;
MapTable *map, *tomap;
int step;
{
Float gamma;
gamma = (Float)z2 / ((Float)(z1)+(Float)(z2));
if (step == 1) {
map->stepuv[0] = tomap->curuv[0] - map->curuv[0];
map->stepuv[1] = tomap->curuv[1] - map->curuv[1];
map->stepstepuv[0] = 0;
map->stepstepuv[1] = 0;
} else if (gamma < 0.25) {
map->stepuv[0] = 0;
map->stepuv[1] = 0;
map->stepstepuv[0]
= 2 * ( tomap->curuv[0] - map->curuv[0] + step / 2 )
/ step / (step-1);
map->stepstepuv[1]
= 2 * ( tomap->curuv[1] - map->curuv[1] + step / 2 )
/ step / (step-1);
} else if (gamma > 0.75) {
map->stepuv[0]
= 2 * ( tomap->curuv[0] - map->curuv[0] + step / 2 )
/ (step+1);
map->stepuv[1]
= 2 * ( tomap->curuv[1] - map->curuv[1] + step / 2 )
/ (step+1);
map->stepstepuv[0] = -map->stepuv[0] / step;
map->stepstepuv[1] = -map->stepuv[1] / step;
} else {
map->stepuv[0]
= ( tomap->curuv[0] - map->curuv[0] + step / 2 )
* ( 4.0 * gamma - 1.0) / step;
map->stepuv[1]
= ( tomap->curuv[1] - map->curuv[1] + step / 2 )
* ( 4.0 * gamma - 1.0) / step;
map->stepstepuv[0]
= 4 * ( tomap->curuv[0] - map->curuv[0] + step / 2 )
* ( 1.0 - 2.0 * gamma ) / step / (step-1);
map->stepstepuv[1]
= 4 * ( tomap->curuv[1] - map->curuv[1] + step / 2 )
* ( 1.0 - 2.0 * gamma ) / step / (step-1);
map->stepuv[0] += map->stepstepuv[0];
map->stepuv[1] += map->stepstepuv[1];
}
}