Game Development Community

dev|Pro Game Development Curriculum

SkySphere

by Mike Kuklinski · 12/01/2004 (6:18 pm) · 41 comments

Download Code File

This resource is designed to allow the user to utilize a SkySphere instead of a SkyBox.

By default, the TGE utilizes a 6 sided box in order to render the background. For many applications, this is sufficient, however, in many space simulations, the SkyBox can have a detrimental effect on the background by causing stretching of the texture near the edges. A sphere works to repair this issue by having the majority of the edges of the polygons closer to being the same distance from the camera. Spheres have the small issue of often requiring a mapped texture. I have attached an example polar mapped texture.

I would recommend you use this resource with the Star Rendering resource by James Lupiani.

//SKY.CC

Around Line 28

#define RAD             (2 * M_PI)
//SkySphere
#define PID2            (M_PI / 2)
//SkySphere

Around Line 57

mRenderStars     = true;
//SkySphere
mSkySphere       = false;
mSkyDepth        = false;
//SkySphere

Around Line 332

addField("noRenderBans",            TypeBool,      Offset(mNoRenderBans, Sky));
//SkySphere
addField("SkySphere",               TypeBool,      Offset(mSkySphere, Sky));
addField("SkyDepth",                TypeBool,      Offset(mSkyDepth, Sky));
addField("sphereList",              TypeFilename,  Offset(mSphereListName,Sky));
//SkySphere
Around Line 362

stream->read(&mRenderBoxBottom);
//SkySphere
stream->read(&mSkySphere);
stream->read(&mSkyDepth);
mSphereListName = stream->readSTString();
//SkySphere

Around Line 524

stream->write(mRenderBoxBottom);
//SkySphere
stream->write(mSkySphere);
stream->write(mSkyDepth);
stream->writeString(mSphereListName);
//SkySphere

In Sky::renderObject(SceneState* state, SceneRenderImage*), after    

render(state);   
glDisable(GL_TEXTURE_2D);

put:

glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glDepthMask(GL_FALSE);
rendersphere();
glDisable(GL_TEXTURE_2D);


"If you are using the star generation resource, put that after the star rendering code"

Then, replace Sky::renderSkyBox with this:

void Sky::renderSkyBox(F32 lowerBanHeight, F32 alphaBanUpper)
{
   if(!mSkyTexturesOn || !smSkyOn)
   {
      glDisable(GL_TEXTURE_2D);
      glColor3ub(mRealSkyColor.red, mRealSkyColor.green, mRealSkyColor.blue);
   }
   if (!mSkySphere) {
   S32 side, index=0, val;
   U32 numPoints;
   Point3F renderPoints[4]; 
   Point2F texCoords[4];
   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();      
         }
         
      }
   }
   }
   else {
      int i,j,n = 0;
	  if (mFirstRun != 1)
		 spherearray();
      for (j=0;j<20;j++) {
		 
         glBindTexture(GL_TEXTURE_2D,mSkyHandle[1].getGLName());
         glBegin(GL_TRIANGLE_STRIP);
         for (i=0;i<=40;i++,n++) {
            glNormal3f(Sphere[n].x,Sphere[n].y,Sphere[n].z);
            glTexCoord2f(Sphere3[n].x,Sphere3[n].y);
            glVertex3f(Sphere[n].x,Sphere[n].y,Sphere[n].z);
            glNormal3f(Sphere2[n].x,Sphere2[n].y,Sphere2[n].z);
            glTexCoord2f(Sphere4[n].x,Sphere4[n].y);
            glVertex3f(Sphere2[n].x,Sphere2[n].y,Sphere2[n].z);
         }
      glEnd();
      }
   }
   if(!mSkyTexturesOn)
      glEnable(GL_TEXTURE_2D);
}

Put this code above renderSkyBox:

void Sky::spherearray()
{

   char path[1024], *p;
   dStrcpy(path, mSphereListName);
   if ((p = dStrrchr(path, '/')) != NULL)
      *p = 0;
      Stream *stream = ResourceManager->openStream(mSphereListName);
      char buffer[512];
	U32 count;
      stream->readLine( (U8*)buffer, 512 );
      count = dAtoi( buffer );
      if( count > 820 )
         count = 820;
      for(int i=0; i<count; ++i)
      {
         if( stream->getStatus() == Stream::EOS )
            break;
         stream->readLine( (U8*)buffer, 512 );
         F32 aa,bb,cc,dd,ee,ff,gg,hh,ii,jj;
	   aa=bb=cc=dd=ee=ff=gg=hh=ii=jj=0;
         dSscanf( buffer, "%f %f %f %f %f %f %f %f %f %f",&aa,&bb,&cc,&dd,&ee,&ff,&gg,&hh,&ii,&jj);
	   Sphere[i] = Point3F(aa,bb,cc);
	   Sphere2[i] = Point3F(dd,ee,ff);
	   Sphere3[i]= Point2F(gg,hh);
         Sphere4[i] = Point2F(ii,jj);
      }
      mNumVerts = count;
      ResourceManager->closeStream(stream);		
	mFirstRun = 1;
}

Put this after renderSkyBox:

void Sky::rendersphere()
{
   if (mSkyDepth) {
   if(!mSkyTexturesOn || !smSkyOn)
   {
      glDisable(GL_TEXTURE_2D);
      glColor3ub(mRealSkyColor.red, mRealSkyColor.green, mRealSkyColor.blue);
   }
   if (mSkySphere) {
      int i,j,n = 0;
	  if (mFirstRun != 1)
		 spherearray();
      for (j=0;j<20;j++) {
		 
         glBindTexture(GL_TEXTURE_2D,mSkyHandle[4].getGLName());
         glBegin(GL_TRIANGLE_STRIP);
         for (i=0;i<=40;i++,n++) {
            glNormal3f(Sphere[n].x,Sphere[n].y,Sphere[n].z);
            glTexCoord2f(Sphere3[n].x,Sphere3[n].y);
            glVertex3f(Sphere[n].x,Sphere[n].y,Sphere[n].z);
            glNormal3f(Sphere2[n].x,Sphere2[n].y,Sphere2[n].z);
            glTexCoord2f(Sphere4[n].x,Sphere4[n].y);
            glVertex3f(Sphere2[n].x,Sphere2[n].y,Sphere2[n].z);
         }
      glEnd();
      }
   }
   if(!mSkyTexturesOn)
      glEnable(GL_TEXTURE_2D);
	   }
}

//Sky.h

Around Line 157, in Private:

MaterialList mMaterialList;
//SkySphere
F32 mod1;
F32 mod2;
F32 sLastTime;
bool mSkySphere;
bool mSkyDepth;
bool mFirstRun;
Point3F Sphere[820];
Point3F Sphere2[820];
Point2F Sphere3[820];
Point2F Sphere4[820];
U16 mNumVerts;
StringTableEntry mSphereListName;
//SkySphere

Around Line 220

void calcAlphas_Heights(F32 zCamPos, F32 *banHeights, F32 *alphaBan, F32 DepthInFog);
//SkySphere
void spherearray();
void rendersphere();
//SkySphere

//In Mission File

Add "SkySphere = "1";" to the Sky object. It should map the sky using the first texture in the sky DML. Unless it is a polar mapped texture, it will NOT look right.
Also, you must define the location of sphere.arr using
sphereList = "~/data/sphere.arr";
SkyDepth = "1"; //Use this to render two spheres.
Page«First 1 2 3 Next»
#41
02/18/2012 (4:27 pm)
Mike @ How about a T3D version ?
Page«First 1 2 3 Next»