3D planet is now antialiased, from PhracturedBlue
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@336 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -64,7 +64,13 @@ DWORD **getpixelarray(FRAME FramePtr,int width, int height);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DWORD phong[DIAMETER][DIAMETER];
|
DWORD phong[DIAMETER][DIAMETER];
|
||||||
POINT map_rotate[DIAMETER][DIAMETER];
|
typedef struct
|
||||||
|
{
|
||||||
|
POINT p[4];
|
||||||
|
DWORD m[4];
|
||||||
|
} MAP3D_POINT;
|
||||||
|
MAP3D_POINT map_rotate[DIAMETER][DIAMETER];
|
||||||
|
//POINT map_rotate[DIAMETER][DIAMETER];
|
||||||
|
|
||||||
void
|
void
|
||||||
RenderTopography (BOOLEAN Reconstruct)
|
RenderTopography (BOOLEAN Reconstruct)
|
||||||
@@ -109,7 +115,7 @@ RenderTopography (BOOLEAN Reconstruct)
|
|||||||
pBatch = &BatchArray[0];
|
pBatch = &BatchArray[0];
|
||||||
for (i = 0; i < NUM_BATCH_POINTS; ++i, ++pBatch)
|
for (i = 0; i < NUM_BATCH_POINTS; ++i, ++pBatch)
|
||||||
{
|
{
|
||||||
SetPrimNextLink (pBatch, i + 1);
|
SetPrimNextLink (pBatch, (COUNT)(i + 1));
|
||||||
SetPrimType (pBatch, POINT_PRIM);
|
SetPrimType (pBatch, POINT_PRIM);
|
||||||
}
|
}
|
||||||
SetPrimNextLink (&pBatch[-1], END_OF_LIST);
|
SetPrimNextLink (&pBatch[-1], END_OF_LIST);
|
||||||
@@ -196,7 +202,7 @@ RenderPhongMask (POINT loc)
|
|||||||
POINT pt,light;
|
POINT pt,light;
|
||||||
double lrad;
|
double lrad;
|
||||||
int lmag;
|
int lmag;
|
||||||
int step;
|
DWORD step;
|
||||||
double lmag2;
|
double lmag2;
|
||||||
|
|
||||||
#define LIGHT_MULT 0.8
|
#define LIGHT_MULT 0.8
|
||||||
@@ -247,6 +253,99 @@ RenderPhongMask (POINT loc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//create_aa_points creates weighted averages for
|
||||||
|
// 4 points around the 'ideal' point at x,y
|
||||||
|
// the concept is to compute the weight based on the
|
||||||
|
// distance from the integer location poinnts to the ideal point
|
||||||
|
void create_aa_points(MAP3D_POINT *ppt, double x, double y)
|
||||||
|
{
|
||||||
|
double deltax=0,deltay=0,inv_deltax,inv_deltay;
|
||||||
|
COORD nextx,nexty;
|
||||||
|
COUNT i;
|
||||||
|
double d1,d2,d3,d4,m[4];
|
||||||
|
// get the integer value of this point
|
||||||
|
ppt->p[0].x=(COORD)(0.5+x);
|
||||||
|
ppt->p[0].y=(COORD)(0.5+y);
|
||||||
|
if(ppt->p[0].x > TWORADIUS) {
|
||||||
|
ppt->p[0].x=TWORADIUS;
|
||||||
|
} else if(ppt->p[0].x != 0) {
|
||||||
|
deltax=x-ppt->p[0].x;
|
||||||
|
}
|
||||||
|
if(ppt->p[0].y > TWORADIUS) {
|
||||||
|
ppt->p[0].y=TWORADIUS;
|
||||||
|
} else if(ppt->p[0].y != 0) {
|
||||||
|
deltay=y-ppt->p[0].y;
|
||||||
|
}
|
||||||
|
//if this point doesn't need modificaton, set m[0]=0
|
||||||
|
if(deltax==0 && deltay==0) {
|
||||||
|
ppt->m[0]=0;
|
||||||
|
} else {
|
||||||
|
//get the neighbboring points surrounding the 'ideal' poinnt
|
||||||
|
if(deltax!=0) {
|
||||||
|
nextx=ppt->p[0].x+((deltax >0) ?1 : -1);
|
||||||
|
} else {
|
||||||
|
nextx=ppt->p[0].x;
|
||||||
|
}
|
||||||
|
if(deltay!=0) {
|
||||||
|
nexty=ppt->p[0].y+((deltay >0) ?1 : -1);
|
||||||
|
} else {
|
||||||
|
nexty=ppt->p[0].y;
|
||||||
|
}
|
||||||
|
//(x1,y)
|
||||||
|
ppt->p[1].x=nextx;
|
||||||
|
ppt->p[1].y=ppt->p[0].y;
|
||||||
|
//(x,y1)
|
||||||
|
ppt->p[2].x=ppt->p[0].x;
|
||||||
|
ppt->p[2].y=nexty;
|
||||||
|
//(x1y1)
|
||||||
|
ppt->p[3].x=nextx;
|
||||||
|
ppt->p[3].y=nexty;
|
||||||
|
//the square 1x1, so opposite poinnts are at 1-delta
|
||||||
|
inv_deltax=1.0-fabs(deltax);
|
||||||
|
inv_deltax*=inv_deltax;
|
||||||
|
inv_deltay=1.0-fabs(deltay);
|
||||||
|
inv_deltay*=inv_deltay;
|
||||||
|
deltax*=deltax;
|
||||||
|
deltay*=deltay;
|
||||||
|
//d1-d4 contain the distances from the poinnts to the ideal point
|
||||||
|
d1=sqrt(deltax+deltay);
|
||||||
|
d2=sqrt(inv_deltax+deltay);
|
||||||
|
d3=sqrt(deltax+inv_deltay);
|
||||||
|
d4=sqrt(inv_deltax+inv_deltay);
|
||||||
|
//compute the weights. the sum(ppt->m[])=65536
|
||||||
|
m[0]=1/(1+d1*(1/d2+1/d3+1/d4));
|
||||||
|
m[1]=m[0]*d1/d2;
|
||||||
|
m[2]=m[0]*d1/d3;
|
||||||
|
m[3]=m[0]*d1/d4;
|
||||||
|
for(i=0;i<4;i++)
|
||||||
|
ppt->m[i]=(DWORD)((1<<16)*m[i]+0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//get_avg_rgb creates either a red, green, or blue value by
|
||||||
|
//computing the weightd averages of the 4 points in p1
|
||||||
|
UBYTE get_avg_rgb(DWORD p1[4],DWORD mult[4],COUNT offset) {
|
||||||
|
COUNT i,j;
|
||||||
|
UBYTE c;
|
||||||
|
DWORD ci;
|
||||||
|
|
||||||
|
i=offset<<3;
|
||||||
|
ci=0;
|
||||||
|
//sum(mult[])==65536
|
||||||
|
//c is the red/green/blue value of this pixel
|
||||||
|
for(j=0;j<4;j++)
|
||||||
|
{
|
||||||
|
c=(UBYTE)(p1[j] >> i);
|
||||||
|
ci+=c*mult[j];
|
||||||
|
}
|
||||||
|
ci=ci>>16;
|
||||||
|
//check for overflow
|
||||||
|
if (ci> 255)
|
||||||
|
ci=255;
|
||||||
|
return((UBYTE)ci);
|
||||||
|
}
|
||||||
|
|
||||||
// SetPlanetTilt creates 'map_rotate' to map the topo data
|
// SetPlanetTilt creates 'map_rotate' to map the topo data
|
||||||
// for a tilted planet. It also does the sphere->plane mapping
|
// for a tilted planet. It also does the sphere->plane mapping
|
||||||
void
|
void
|
||||||
@@ -261,9 +360,9 @@ SetPlanetTilt (int angle)
|
|||||||
y_2=y*y;
|
y_2=y*y;
|
||||||
for(x=-RADIUS;x<=RADIUS;x++)
|
for(x=-RADIUS;x<=RADIUS;x++)
|
||||||
{
|
{
|
||||||
double dx, dy;
|
double dx, dy, newx, newy;
|
||||||
double da,rad,rad2;
|
double da,rad,rad2;
|
||||||
POINT *ppt=&map_rotate[y+RADIUS][x+RADIUS];
|
MAP3D_POINT *ppt=&map_rotate[y+RADIUS][x+RADIUS];
|
||||||
rad2=x*x+y_2;
|
rad2=x*x+y_2;
|
||||||
if(rad2<=RADIUS_2) {
|
if(rad2<=RADIUS_2) {
|
||||||
rad=sqrt(rad2);
|
rad=sqrt(rad2);
|
||||||
@@ -277,15 +376,13 @@ SetPlanetTilt (int angle)
|
|||||||
dy=y;
|
dy=y;
|
||||||
}
|
}
|
||||||
//Map the sphere onto a plane
|
//Map the sphere onto a plane
|
||||||
ppt->x=(int)(0.5+RADIUS*(multx*acos(-dx/RADIUS)));
|
newx=RADIUS*(multx*acos(-dx/RADIUS));
|
||||||
if(ppt->x > TWORADIUS)
|
newy=RADIUS*(multy*acos(-dy/RADIUS));
|
||||||
ppt->x=TWORADIUS;
|
create_aa_points(ppt,newx,newy);
|
||||||
ppt->y=(int)(0.5+RADIUS*(multy*acos(-dy/RADIUS)));
|
|
||||||
if(ppt->y > TWORADIUS)
|
|
||||||
ppt->y=TWORADIUS;
|
|
||||||
} else {
|
} else {
|
||||||
ppt->x=x+RADIUS;
|
ppt->p[0].x=x+RADIUS;
|
||||||
ppt->y=y+RADIUS;
|
ppt->p[0].y=y+RADIUS;
|
||||||
|
ppt->m[0]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +401,8 @@ SetPlanetTilt (int angle)
|
|||||||
#define SHIELD_RADIUS_2 SHIELD_RADIUS*SHIELD_RADIUS
|
#define SHIELD_RADIUS_2 SHIELD_RADIUS*SHIELD_RADIUS
|
||||||
void CreateShieldMask()
|
void CreateShieldMask()
|
||||||
{
|
{
|
||||||
DWORD rad2,red,red_nt,clear,**rgba,p;
|
DWORD rad2,clear,**rgba,p;
|
||||||
|
UBYTE red_nt;
|
||||||
int x,y;
|
int x,y;
|
||||||
FRAME ShieldFrame;
|
FRAME ShieldFrame;
|
||||||
DWORD aa_delta,aa_delta2;
|
DWORD aa_delta,aa_delta2;
|
||||||
@@ -313,8 +411,6 @@ void CreateShieldMask()
|
|||||||
CreateDrawable (WANT_PIXMAP, SHIELD_DIAM, SHIELD_DIAM, 1)
|
CreateDrawable (WANT_PIXMAP, SHIELD_DIAM, SHIELD_DIAM, 1)
|
||||||
);
|
);
|
||||||
rgba=(DWORD **)malloc(sizeof(DWORD *)*(SHIELD_DIAM));
|
rgba=(DWORD **)malloc(sizeof(DWORD *)*(SHIELD_DIAM));
|
||||||
// This is a 'transparent' red for the planet mask.
|
|
||||||
red=frame_mapRGBA (ShieldFrame,255,0,0,200);
|
|
||||||
// This is a non-transparent red for the halo
|
// This is a non-transparent red for the halo
|
||||||
red_nt=180;
|
red_nt=180;
|
||||||
// This is 100% transparent.
|
// This is 100% transparent.
|
||||||
@@ -335,16 +431,16 @@ void CreateShieldMask()
|
|||||||
p=frame_mapRGBA(ShieldFrame,0,0,0,255);
|
p=frame_mapRGBA(ShieldFrame,0,0,0,255);
|
||||||
} else {
|
} else {
|
||||||
// The halo itself
|
// The halo itself
|
||||||
DWORD red=red_nt;
|
UBYTE red=red_nt;
|
||||||
if(rad2>(SHIELD_RADIUS-1)*(SHIELD_RADIUS-1))
|
if(rad2>(SHIELD_RADIUS-1)*(SHIELD_RADIUS-1))
|
||||||
{
|
{
|
||||||
DWORD r;
|
DWORD r;
|
||||||
r=rad2-(SHIELD_RADIUS-1)*(SHIELD_RADIUS-1);
|
r=rad2-(SHIELD_RADIUS-1)*(SHIELD_RADIUS-1);
|
||||||
red=red_nt-red_nt*r/aa_delta;
|
red=red_nt-(UBYTE)(red_nt*r/aa_delta);
|
||||||
} else if (rad2 < (RADIUS+3)*(RADIUS+3)) {
|
} else if (rad2 < (RADIUS+3)*(RADIUS+3)) {
|
||||||
DWORD r;
|
DWORD r;
|
||||||
r = rad2 - (RADIUS+2)*(RADIUS+2);
|
r = rad2 - (RADIUS+2)*(RADIUS+2);
|
||||||
red = red_nt*r/aa_delta2;
|
red = (UBYTE)(red_nt*r/aa_delta2);
|
||||||
}
|
}
|
||||||
p=frame_mapRGBA (ShieldFrame,red,0,0,255);
|
p=frame_mapRGBA (ShieldFrame,red,0,0,255);
|
||||||
|
|
||||||
@@ -394,28 +490,40 @@ RenderLevelMasks (int offset)
|
|||||||
rgba[pt.y]=malloc(sizeof(DWORD)*(DIAMETER));
|
rgba[pt.y]=malloc(sizeof(DWORD)*(DIAMETER));
|
||||||
for (pt.x = 0, x=-RADIUS; pt.x <= TWORADIUS; ++pt.x,++x)
|
for (pt.x = 0, x=-RADIUS; pt.x <= TWORADIUS; ++pt.x,++x)
|
||||||
{
|
{
|
||||||
int c1,c2,c3;
|
UBYTE c[3];
|
||||||
int ph;
|
int ph;
|
||||||
|
COUNT i;
|
||||||
|
DWORD p1[4];
|
||||||
|
MAP3D_POINT *ppt=&map_rotate[pt.y][pt.x];
|
||||||
rgba[pt.y][pt.x]=0;
|
rgba[pt.y][pt.x]=0;
|
||||||
ph=phong[pt.y][pt.x];
|
ph=phong[pt.y][pt.x];
|
||||||
p=pixels[map_rotate[pt.y][pt.x].y][map_rotate[pt.y][pt.x].x+offset];
|
if(ph < 1<<PHONG_BITS) {
|
||||||
c1=(p&0xff000000)>>24;
|
if(ppt->m[0]==0) {
|
||||||
c2=(p&0x00ff0000)>>16;
|
p=pixels[ppt->p[0].y][ppt->p[0].x+offset];
|
||||||
c3=(p&0x0000ff00)>>8;
|
c[0]=(UBYTE)(p>>8);
|
||||||
|
c[1]=(UBYTE)(p>>16);
|
||||||
|
c[2]=(UBYTE)(p>>24);
|
||||||
|
} else {
|
||||||
|
for(i=0;i<4;i++) {
|
||||||
|
p1[i]=pixels[ppt->p[i].y][ppt->p[i].x+offset];
|
||||||
|
}
|
||||||
|
for(i=1;i<4;i++) {
|
||||||
|
c[i-1]=get_avg_rgb(p1,ppt->m,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
// fixed planet surfaces being too dark
|
// fixed planet surfaces being too dark
|
||||||
// ctab shifts were previously >> 3 .. -Mika
|
// ctab shifts were previously >> 3 .. -Mika
|
||||||
// Apply the lightinng model. This also bounds the sphere to make it circular
|
// Apply the lightinng model. This also bounds the sphere to make it circular
|
||||||
if(ph < 1<<PHONG_BITS) {
|
|
||||||
if(pSolarSysState->ShieldFrame) {
|
if(pSolarSysState->ShieldFrame) {
|
||||||
c1=GET_PHONG(255,ph);
|
c[2]=GET_PHONG(255,ph);
|
||||||
c2=GET_PHONG(c2>>1,ph);
|
c[1]=GET_PHONG(c[1]>>1,ph);
|
||||||
c3=GET_PHONG(c3>>1,ph);
|
c[0]=GET_PHONG(c[0]>>1,ph);
|
||||||
} else {
|
} else {
|
||||||
c1=GET_PHONG(c1,ph);
|
c[2]=GET_PHONG(c[2],ph);
|
||||||
c2=GET_PHONG(c2,ph);
|
c[1]=GET_PHONG(c[1],ph);
|
||||||
c3=GET_PHONG(c3,ph);
|
c[0]=GET_PHONG(c[0],ph);
|
||||||
}
|
}
|
||||||
rgba[pt.y][pt.x]=frame_mapRGBA (MaskFrame,(UBYTE)c1,(UBYTE)c2,(UBYTE)c3,(UBYTE)255);
|
rgba[pt.y][pt.x]=frame_mapRGBA (MaskFrame,c[2],c[1],c[0],(UBYTE)255);
|
||||||
} else {
|
} else {
|
||||||
rgba[pt.y][pt.x]=frame_mapRGBA (MaskFrame,0,0,0,0);
|
rgba[pt.y][pt.x]=frame_mapRGBA (MaskFrame,0,0,0,0);
|
||||||
}
|
}
|
||||||
@@ -899,7 +1007,7 @@ MakeGasGiant (COUNT num_bands, PSBYTE DepthArray, PRECT pRect, SIZE
|
|||||||
& (((1 << RANGE_SHIFT) * NUM_BAND_COLORS) - 1);
|
& (((1 << RANGE_SHIFT) * NUM_BAND_COLORS) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeStorms (4 + ((COUNT)Random () & 3) + 1, DepthArray);
|
MakeStorms ((COUNT)(4 + ((COUNT)Random () & 3) + 1), DepthArray);
|
||||||
|
|
||||||
DitherMap (DepthArray);
|
DitherMap (DepthArray);
|
||||||
}
|
}
|
||||||
@@ -1136,7 +1244,7 @@ GeneratePlanetMask (PPLANET_DESC pPlanetDesc, BOOLEAN IsEarth)
|
|||||||
|
|
||||||
SeedRandom (old_seed);
|
SeedRandom (old_seed);
|
||||||
|
|
||||||
SetPlanetMusic (pPlanetDesc->data_index & ~PLANET_SHIELDED);
|
SetPlanetMusic ((UBYTE)(pPlanetDesc->data_index & ~PLANET_SHIELDED));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user