📄 sky.cc
字号:
// Calculate upper, lower, and corner ban points
calcBans(banHeights, banPoints, cornerPoints);
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Renders the side, top, and corner bans
renderBans(alphaBan, banHeights, banPoints, cornerPoints);
}
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
}
if(mSetFog)
{
mSceneManager->setFogVolumes(mNumFogVolumes, mFogVolumes);
mSetFog = false;
}
if(mStormFogOn && mStormFogData.volume[mStormFogData.current].state != isDone)
updateFog();
if(mStormFogOn && mRealFog)
updateRealFog();
PROFILE_END();
}
//---------------------------------------------------------------------------
void Sky::calcAlphas_Heights(F32 zCamPos, F32 *banHeights,
F32 *alphaBan, F32 depthInFog)
{
F32 sideA, lower = 0.0f, upper = 0.0f;
F32 visValue, visDis = 0.0f;
F32 visRatio, ratioVal, setVis;
visDis = setVis = mVisibleDistance +
(mFogVolumes[mNumFogVolumes-1].visibleDistance - mVisibleDistance) *
mFogVolumes[mNumFogVolumes-1].percentage;
for(S32 x = 0; x < mNumFogVolumes-1; ++x)
{
F32 distance = mVisibleDistance +
(mFogVolumes[x].visibleDistance - mVisibleDistance) *
mFogVolumes[x].percentage;
if (distance < setVis)
{
visValue = (zCamPos < mFogVolumes[x].minHeight) ?
mFogVolumes[x].maxHeight - mFogVolumes[x].minHeight :
mFogVolumes[x].maxHeight - zCamPos;
if(visValue > 0.0f)
{
ratioVal = setVis / distance;
visRatio = visValue / distance;
visDis -= (distance * visRatio) * ratioVal;
}
}
}
//Calculate upper Height
if(visDis > 0.0f)
upper = (mSkyBoxPt.x*depthInFog)/(visDis * 0.2f);
banHeights[1] = mSpherePt.z;
if(upper < mSpherePt.z)
{
banHeights[1] = upper;
if(banHeights[1] < OFFSET_HEIGHT)
banHeights[1] = OFFSET_HEIGHT + HORIZON;
}
if(visDis > depthInFog)
{
sideA = mSqrt((visDis*visDis)-(depthInFog*depthInFog));
lower = (mSkyBoxPt.x*depthInFog)/sideA;
//Calculate lower Height
banHeights[0] = mSpherePt.z;
if(lower < mSpherePt.z)
banHeights[0] = lower;
if(banHeights[0] == mSpherePt.z && banHeights[1] == mSpherePt.z)
{
F32 temp = ((lower - mSpherePt.z) * (sideA/depthInFog));
if(temp <= mSkyBoxPt.x)
alphaBan[1] = temp/mSkyBoxPt.x;
else
alphaBan[1] = 1.0f;
alphaBan[0] = 1.0f;
}
else
{
alphaBan[0] = banHeights[0]/mSpherePt.z;
alphaBan[1] = 0.0f;
}
}
else
{
alphaBan[1] = alphaBan[0] = 1.0f;
banHeights[0] = banHeights[1] = mSpherePt.z;
}
banHeights[0] *= mFogVolumes[0].percentage;
banHeights[1] *= mFogVolumes[0].percentage;
if(banHeights[1] < OFFSET_HEIGHT)
banHeights[1] = OFFSET_HEIGHT + HORIZON;
}
void Sky::setRenderPoints(Point3F* renderPoints, S32 index)
{
renderPoints[0].set(mPoints[index].x, mPoints[index].y, mPoints[index].z);
renderPoints[1].set(mPoints[index+1].x, mPoints[index+1].y, mPoints[index+1].z);
renderPoints[2].set(mPoints[index+6].x, mPoints[index+6].y, mPoints[index+6].z);
renderPoints[3].set(mPoints[index+5].x, mPoints[index+5].y, mPoints[index+5].z);
}
void Sky::calcTexCoords(Point2F* texCoords, Point3F* renderPoints, S32 index)
{
for(S32 x = 0; x < 4; ++x)
texCoords[x].set(mTexCoord[x].x, mTexCoord[x].y);
S32 length = (S32)(mFabs(mPoints[index].z) + mFabs(mPoints[index + 5].z));
F32 per = mPoints[index].z - renderPoints[3].z;
texCoords[3].y = texCoords[2].y = (per / length);
}
//---------------------------------------------------------------------------
void Sky::renderSkyBox(F32 lowerBanHeight, F32 alphaBanUpper)
{
S32 side, index=0, val;
U32 numPoints;
Point3F renderPoints[4];
Point2F texCoords[4];
//celestial
if(gCelestials) // <sami>
{
ColorF dn = gCelestials->mCurrentColor;
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(dn.red, dn.green, dn.blue);
}
//celestial end
if(!mSkyTexturesOn || !smSkyOn)
{
glDisable(GL_TEXTURE_2D);
glColor3ub(mRealSkyColor.red, mRealSkyColor.green, mRealSkyColor.blue);
}
for(side = 0; side < ((mRenderBoxBottom) ? 6 : 5); ++side)
{
if((lowerBanHeight != mSpherePt.z || (side == 4 && alphaBanUpper < 1.0f)) && mSkyHandle[side])
{
glBindTexture(GL_TEXTURE_2D,mSkyHandle[side].getGLName());
if(side < 4)
{
numPoints = 4;
setRenderPoints(renderPoints, index);
if(!mNoRenderBans)
sgUtil_clipToPlane(renderPoints, numPoints, PlaneF(0.0f, 0.0f, 1.0f, -lowerBanHeight));
if(numPoints)
{
calcTexCoords(texCoords, renderPoints, index);
glBegin(GL_QUADS);
glTexCoord2f(texCoords[0].x, texCoords[0].y);
glVertex3f(renderPoints[0].x, renderPoints[0].y, renderPoints[0].z);
glTexCoord2f(texCoords[1].x, texCoords[1].y);
glVertex3f(renderPoints[1].x, renderPoints[1].y, renderPoints[1].z);
glTexCoord2f(texCoords[3].x, texCoords[3].y);
glVertex3f(renderPoints[2].x, renderPoints[2].y, renderPoints[2].z);
glTexCoord2f(texCoords[2].x, texCoords[2].y);
glVertex3f(renderPoints[3].x, renderPoints[3].y, renderPoints[3].z);
glEnd();
}
++index;
}
else
{
index = 3;
val = -1;
if(side == 5)
{
index = 5;
val = 1;
}
glBegin(GL_QUADS);
glTexCoord2f(mTexCoord[0].x, mTexCoord[0].y);
glVertex3f(mPoints[index].x, mPoints[index].y, mPoints[index].z);
glTexCoord2f(mTexCoord[1].x, mTexCoord[1].y);
glVertex3f(mPoints[index+(1*val)].x, mPoints[index+(1*val)].y, mPoints[index+(1*val)].z);
glTexCoord2f(mTexCoord[3].x, mTexCoord[3].y);
glVertex3f(mPoints[index+(2*val)].x, mPoints[index+(2*val)].y, mPoints[index+(2*val)].z);
glTexCoord2f(mTexCoord[2].x, mTexCoord[2].y);
glVertex3f(mPoints[index+(3*val)].x, mPoints[index+(3*val)].y, mPoints[index+(3*val)].z);
glEnd();
}
}
}
if(!mSkyTexturesOn)
glEnable(GL_TEXTURE_2D);
}
//---------------------------------------------------------------------------
void Sky::calcBans(F32 *banHeights, Point3F banPoints[][MAX_BAN_POINTS], Point3F *cornerPoints)
{
F32 incRad = RAD / F32(FOG_BAN_DETAIL*2);
MatrixF ban;
Point4F point;
S32 index, x;
F32 height = banHeights[0];
F32 value = banHeights[0] / mSkyBoxPt.z;
F32 mulVal = -(mSqrt(1-(value*value))); // lowerBan Multiple
index=0;
// Calculates the upper and lower bans
for(x=0; x < 2; ++x)
{
for(F32 angle=0.0f; angle <= RAD+incRad ; angle+=incRad)
{
ban.set(Point3F(0.0f, 0.0f, angle));
point.set(mulVal*mSkyBoxPt.x,0.0f,0.0f,1.0f);
ban.mul(point);
//celestial
// banPoints[x][index++].set(point.x,point.y,height);
if(gCelestials) // <sami>
banPoints[x][index++].set(point.x, point.y, height * gCelestials->mBandMod);
else
banPoints[x][index++].set(point.x, point.y, height);
//celestial end
}
height = banHeights[1];
value = banHeights[1] / mSkyBoxPt.x;
mulVal = -(mSqrt(1-(value*value))); // upperBan Multiple
index = 0;
}
// Calculates the filler points needed between the lower ban and the clipping plane
index = 2;
cornerPoints[0].set(mPoints[3].x, mPoints[3].y, banHeights[0]-1);
cornerPoints[1].set(mPoints[3].x, 0.0f, banHeights[0]-1);
for(x = 0; x < (FOG_BAN_DETAIL/2.0f) + 1.0f; ++x)
cornerPoints[index++].set(banPoints[0][x].x, banPoints[0][x].y, banPoints[0][x].z);
cornerPoints[index].set(0.0f, mPoints[3].y, banHeights[0]-1 );
}
//---------------------------------------------------------------------------
void Sky::renderBans(F32 *alphaBan, F32 *banHeights, Point3F banPoints[][MAX_BAN_POINTS], Point3F *cornerPoints)
{
S32 side, x, index = 0;
F32 angle;
U8 UalphaIn = U8(alphaBan[1]*255);
U8 UalphaOut = U8(alphaBan[0]*255);
//celestial
U8 c[3];
if(gCelestials) // <sami>
{
ColorF dn = gCelestials->mCurrentColor;
c[0]=U8(F32(mRealFogColor.red)*dn.red);
c[1]=U8(F32(mRealFogColor.green)*dn.green);
c[2]=U8(F32(mRealFogColor.blue)*dn.blue);
}
//celestial end
//Renders the side bans
if(banHeights[0] < mSpherePt.z)
{
glBegin(GL_TRIANGLE_STRIP);
for(x=0;x<FOG_BAN_DETAIL*2+1;++x)
{
//celestial
// glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), 255);
if(gCelestials) // <sami>
glColor4ub(c[0],c[1],c[2], U8(255.0f));
else
glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), 255);
//celestial end
glVertex3f(banPoints[0][index].x,banPoints[0][index].y,banPoints[0][index].z);
//celestial
// glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), UalphaOut);
if(gCelestials) // <sami>
glColor4ub(c[0],c[1],c[2], UalphaOut);
else
glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), UalphaOut);
//celestial end
glVertex3f(banPoints[1][index].x,banPoints[1][index].y,banPoints[1][index].z);
++index;
}
glEnd();
}
//Renders the top ban
glBegin(GL_TRIANGLE_FAN);
//celestial
// glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), UalphaIn);
if(gCelestials) // <sami>
glColor4ub(c[0],c[1],c[2], UalphaIn);
else
glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), UalphaIn);
//celestial end
glVertex3f(mTopCenterPt.x, mTopCenterPt.y, mTopCenterPt.z);
//celestial
// for(x=0;x<FOG_BAN_DETAIL*2+1;++x)
// {
// glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), UalphaOut);
// glVertex3f(banPoints[1][x].x, banPoints[1][x].y, banPoints[1][x].z);
// }
if(gCelestials)
for(x=0;x<FOG_BAN_DETAIL*2+1;++x)
{
glColor4ub(c[0],c[1],c[2], UalphaOut);
glVertex3f(banPoints[1][x].x, banPoints[1][x].y, banPoints[1][x].z);
}
else
for(x=0;x<FOG_BAN_DETAIL*2+1;++x)
{
glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), UalphaOut);
glVertex3f(banPoints[1][x].x, banPoints[1][x].y, banPoints[1][x].z);
}
//celestial end
glEnd();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
angle = 0.0f;
//Renders the filler
for(side=0;side<4;++side)
{
glRotatef(angle,0.0,0.0,1.0);
glBegin(GL_TRIANGLE_FAN);
if(gCelestials) //celestial just if statement
for(x=0;x<FOG_BAN_DETAIL;++x)
{
glColor4ub(c[0],c[1],c[2], 255);
glVertex3f(cornerPoints[x].x, cornerPoints[x].y, cornerPoints[x].z);
}
//celestial
else
for(x=0;x<FOG_BAN_DETAIL;++x)
{
glColor4ub(U8(mRealFogColor.red), U8(mRealFogColor.green), U8(mRealFogColor.blue), 255);
glVertex3f(cornerPoints[x].x, cornerPoints[x].y, cornerPoints[x].z);
}
//celestial end
glEnd();
angle += 90.0f;
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
//---------------------------------------------------------------------------
void Sky::startStorm()
{
mStormCloudsOn = true;
Cloud::startStorm(mStormCloudData.state);
for(int i = 0; i < mNumCloudLayers; ++i)
mCloudLayer[i].calcStorm(mStormCloudData.speed, mStormCloudData.fadeSpeed);
}
void Sky::stormCloudsShow(bool show)
{
mStormCloudsOn = show;
setMaskBits(StormCloudsOnMask);
}
void Sky::stormFogShow(bool show)
{
mStormFogOn = show;
setMaskBits(StormFogOnMask);
}
//---------------------------------------------------------------------------
void Sky::startStormFog()
{
if(mStormFogOn)
for(S32 x = 0; x < mNumFogVolumes; ++x)
mFogVolumes[x].percentage = mStormFogData.volume[x].endPercentage;
mStormFogOn = true;
if(mFogVolume < 0)
for(S32 x = 0; x < mNumFogVolumes; ++x)
{
mStormFogData.volume[x].speed = (mFogPercentage - mFogVolumes[x].percentage) / ((mStormFogData.time * 32.0f) / (F32)mNumFogVolumes);
mStormFogData.volume[x].state = (mStormFogData.volume[x].endPercentage > mFogPercentage) ? goingOut : comingIn;
mStormFogData.volume[x].endPercentage = mStormFogData.volume[x].active? mFogPercentage:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -