The world is made of Chunks.
Each chunk is 16x16x16 blocks.
Just so you can get a feel for what I'm talking about:
I am now trying to utilize 2 threads to run the game. I am using the boost_thread library on Linux.
I have been trying to get this to work for the last 5 hours (yes I'm persistent)
I have been over and over the code and still can't locate the problem.
Chunk Management--
I have a class for the world called world with the instance used in the game being world0.
In that class I have 2 3d arrays which store pointers to chunks and bool exists.
chunk* chunks[7][7][7]; <- pointers to the chunks
bool chunkExists[7][7][7]; <- Weither a chunk has been created or loaded at that point.
world::world(int pName)
{
drawSkyBox=true;
name = pName;
time=1.000f;
timeAdd=0.000f;
//Make Chunks
//xChunks=CLIPDIST;
//yChunks=CLIPDIST;
//xOffset=((CLIPDIST-1)/2)+1;
//yOffset=((CLIPDIST-1)/2)+1;
//Set all the chunks to nonexisting
for (int a=0;a<CLIPDIST;a++)
{
for (int b=0;b<CLIPDIST;b++)
{
for (int c=0;c<CLIPDIST;c++)
{
chunkExists[a][c]=false;
}
}
}
init=true;
wait=WAITTIME;
running=false;
}
When the map is created it creates a chunk for each position before the game starts.
Then it creates a thread (~Thread 2) that will watch the chunks and create a new one as needed.
It basically for now loops checking the map and if it sees an exists==false it will create a new chunk.
So that when the map scrolls the new chunk will already be there.
It only exists this loop when the game ends.
void world::startThread()
{
//Create the Load chunk Thread
tMapLoading = boost::thread(boost::bind(&world::checkChunks, this));
running = true;
}
void world::checkChunks()
{
bool changed=false;
for (signed int iChunkY=0;iChunkY<CLIPDIST;iChunkY++)
{
for (signed int iChunkX=0;iChunkX<CLIPDIST;iChunkX++)
{
for (signed int iChunkZ=0;iChunkZ<CLIPDIST;iChunkZ++)
{
if (chunkExists[iChunkX][iChunkY][iChunkZ]==false)
{
signed int xCur=xOffset+iChunkX-HALFCLIPDIST;
signed int yCur=yOffset+iChunkY-HALFCLIPDIST;
signed int zCur=zOffset+iChunkZ-HALFCLIPDIST;
Chunk[iChunkX][iChunkY][iChunkZ] = new chunk(xCur,yCur,zCur);
chunkExists[iChunkX][iChunkY][iChunkZ]=true;
//cout << xCur << "\n" << yCur << "\n";
Writer->readChunk(xCur,yCur,zCur,iChunkX,iChunkY,iChunkZ);
//Writer->writeChunk(xCur,yCur,zCur,iChunkX,iChunkY,iChunkZ);
changed=true;
}
}
}
}
if (changed)
{
bufferInitAll();
cout << "New Chunks Created by Init\n";
}
while (running)
{
bool changed=false;
for (signed int iChunkY=0;iChunkY<CLIPDIST;iChunkY++)
{
for (signed int iChunkX=0;iChunkX<CLIPDIST;iChunkX++)
{
for (signed int iChunkZ=0;iChunkZ<CLIPDIST;iChunkZ++)
{
if (chunkExists[iChunkX][iChunkY][iChunkZ]==false)
{
signed int xCur=xOffset+iChunkX-HALFCLIPDIST;
signed int yCur=yOffset+iChunkY-HALFCLIPDIST;
signed int zCur=zOffset+iChunkZ-HALFCLIPDIST;
Chunk[iChunkX][iChunkY][iChunkZ] = new chunk(xCur,yCur,zCur);
chunkExists[iChunkX][iChunkY][iChunkZ]=true;
//cout << xCur << "\n" << yCur << "\n";
Writer->readChunk(xCur,yCur,zCur,iChunkX,iChunkY,iChunkZ);
//Writer->writeChunk(xCur,yCur,zCur,iChunkX,iChunkY,iChunkZ);
changed=true;
}
}
}
}
if (changed)
{
bufferInitAll();
cout << "-------------------------------------------------! New Chunks added by thread 2!-------------------------------------------------\n";
}
}
}
Map scrolling--
When the map scrolls it moves the pointers and sets the ones that need a new chunk to false in the chunkExists array.
This is so that ~thread 2 will see the false and create a new chunk in that position.
Player moves right on map (5 more simular to this exist):
void world::xOffsetAdd()
{
printf("Map->xOffset+=1\n");
xOffset+=1;
////Save Shifted
int x = 0;
for (int y=0;y<CLIPDIST;y++)
{
for (int z=0;z<CLIPDIST;z++)
{
if (chunkExists[x][y][z]==true)
{
Writer->writeChunk(Chunk[x][y][z]->location.x,Chunk[x][y][z]->location.y,Chunk[x][y][z]->location.z,x,y,z);
delete Chunk[x][y][z];
chunkExists[x][y][z]=false;
}
}
}
////Shift Map -x
for (int x=0;x<CLIPDIST-1;x++)
{
for (int y=0;y<CLIPDIST;y++)
{
for (int z=0;z<CLIPDIST;z++)
{
Chunk[x][y][z]=Chunk[x+1][y][z];
chunkExists[x][y][z]=true;
}
}
}
////Delete Old
x = CLIPDIST-1;
for (int y=0;y<CLIPDIST;y++)
{
for (int z=0;z<CLIPDIST;z++)
{
chunkExists[x][y][z]=false;
}
}
/*
////Delete Old
x = CLIPDIST-1;
for (int y=0;y<CLIPDIST;y++)
{
for (int z=0;z<CLIPDIST;z++)
{
signed int xCur=xOffset+x-HALFCLIPDIST;
signed int yCur=yOffset+y-HALFCLIPDIST;
signed int zCur=zOffset+z-HALFCLIPDIST;
Chunk[x][y][z] = new chunk(xCur,yCur,zCur);
chunkExists[x][y][z]=true;
Writer->readChunk(xCur,yCur,zCur,x,y,z);
}
}
//Fix Buffers
x = CLIPDIST-1;
for (int y=0;y<CLIPDIST;y++)
{
for (int z=0;z<CLIPDIST;z++)
{
Chunk[x][y][z]->bufferInit();
Chunk[x-1][y][z]->bufferInit();
}
}
*/
}
Map drawing--
The map only draws from 2 to 4 inclusive in every direction by the means of for loops.
When drawing the chunks it also first checks if they exist if they dont it doesnt draw them.
oid world::draw()
{
wait--;
glPushMatrix();
glTranslatef(-HALFCLIPDIST*16,-HALFCLIPDIST*16,-HALFCLIPDIST*16);
if (drawSkyBox)
{
drawSkydome();
}
//checkChunks();
//Draw Opaque
for (int iChunkY=2;iChunkY<CLIPDIST-2;iChunkY++)
{
for (int iChunkX=2;iChunkX<CLIPDIST-2;iChunkX++)
{
for (int iChunkZ=2;iChunkZ<CLIPDIST-2;iChunkZ++)
{
/*if (!chunkExists[xCur][yCur])
{
Chunk[xCur][yCur] = new chunk();
chunkExists[xCur][yCur]=true;s
printf("/!\\ MISSING CHUNK (%d,%d)\n",xOffset,yOffset);
}
else*/
{
if (chunkVisible(iChunkX,iChunkY,iChunkZ)==true && chunkExists[iChunkX][iChunkY][iChunkZ]==true)
{
Chunk[iChunkX][iChunkY][iChunkZ]->drawOpaque(iChunkX*16,iChunkY*16,iChunkZ*16); //iChunkY-0
}
if (wait==0 && chunkExists[iChunkX][iChunkY][iChunkZ]==true)
{
Chunk[iChunkX][iChunkY][iChunkZ]->update();
}
}
}
}
}
//Draw Transparent
for (int iChunkY=0;iChunkY<CLIPDIST;iChunkY++)
{
for (int iChunkX=0;iChunkX<CLIPDIST;iChunkX++)
{
for (int iChunkZ=0;iChunkZ<CLIPDIST;iChunkZ++)
{
if (chunkVisible(iChunkX,iChunkY,iChunkZ)==true && chunkExists[iChunkX][iChunkY][iChunkZ]==true)
{
Chunk[iChunkX][iChunkY][iChunkZ]->drawTransparent(iChunkX*16,iChunkY*16,iChunkZ*16); //iChunkY-0
}
}
}
}
/*
//Draw Translucent
for (int iChunkY=0;iChunkY<CLIPDIST;iChunkY++)
{
for (int iChunkX=0;iChunkX<CLIPDIST;iChunkX++)
{
for (int iChunkZ=0;iChunkZ<CLIPDIST;iChunkZ++)
{
if (chunkVisible(iChunkX,iChunkY,iChunkZ)==true)
{
Chunk[iChunkX][iChunkY][iChunkZ]->drawTranslucent(iChunkX*16,iChunkY*16,iChunkZ*16); //iChunkY-0
}
}
}
}*/
glPopMatrix();
if (wait==0)
{
wait=WAITTIME;
time+=timeAdd;
if (time>=1.0f || time <= 0.0f)
{
timeAdd=-timeAdd;
}
GLfloat global_ambient[] = { time,time,time, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
}
}
For some reason my game just crashes at random and i don't know why.
It's throwing a segmentation fault.
I think the game is trying to access a chunk that doesn't exist.
I just can't find out where.
Anyone have any ideas?
Am I using threads properly?
I know this is not a simple problem but, someone please spot the problem.
Thanks, because today has been a really upsetting day.