PDA

View Full Version : "Voxel" Problems [SOLVED]



g0bl1n
08-20-2011, 11:20 PM
So I've been working on a Minecraft style system (Oh noes!!! Not another one!!!). I know there is a stigma with Minecraft clones, but whenever I play a game I always try to figure out how it was programmed, and it kind of eats away at me until I figure it out...

But anyways I figure Minecraft draws the faces of all blocks near "air". So I created a simple class called Chunk, which contains a three dimensional array of unsigned ints. 0 being empty, anything greater being a block (dirt, grass, etc...). Then to draw this chunk I use three nested for loops, I find a block that is empty (0) then draw the faces of the blocks around it.

Chunks is a vector of Chunk*, and the get function returns a block (unsigned int) in that chunk.

Here is the bulk of the code:

for(unsigned int ii=0;ii<Chunks.size();ii++)
{
for(unsigned int xx=0;xx<chunkSize;xx++)
{
for(unsigned int yy=0;yy<chunkSize;yy++)
{
for(unsigned int zz=0;zz<chunkSize;zz++)
{
if(Chunks[ii]->get(xx,yy,zz)==0)
{
if(xx+1<chunkSize&amp;&amp;Chunks[ii]->get(xx+1,yy,zz)>0)
{
//Draw Left Facing Face of Block on Right
}

if(static_cast<int>(xx)-1>0&amp;&amp;Chunks[ii]->get(xx-1,yy,zz)>0)
{
//Draw Right Facing Face of Block on Left
}

if(yy+1<chunkSize&amp;&amp;Chunks[ii]->get(xx,yy+1,zz)>0)
{
//Draw Top Facing Face of Block Below
}

if(static_cast<int>(yy)-1>0&amp;&amp;Chunks[ii]->get(xx,yy-1,zz)>0)
{
//Draw Bottom Facing Face of Block Above
}

if(zz+1<chunkSize&amp;&amp;Chunks[ii]->get(xx,yy,zz+1)>0)
{
//Draw Front Facing Face of Block Behind
}

if(static_cast<int>(zz)-1>0&amp;&amp;Chunks[ii]->get(xx,yy,zz+1)>0)
{
//Draw Back Facing Face of Block in Front
}
}
}
}
}
}

Of course it does have the quad stuff in there, it gets quite huge.

Anyways, the problem is that it draws the blocks wrong (I mean they look right in terms of orientation, but they are wrong because if the front face of a block is dirt then the top of it can't be sand...common sense...).

I'm not sure what I'm doing wrong. Here is the code with the faces put in:

for(unsigned int ii=0;ii<Chunks.size();ii++)
{
for(unsigned int xx=0;xx<chunkSize;xx++)
{
for(unsigned int yy=0;yy<chunkSize;yy++)
{
for(unsigned int zz=0;zz<chunkSize;zz++)
{
if(Chunks[ii]->get(xx,yy,zz)==0)
{
if(xx+1<chunkSize&amp;&amp;Chunks[ii]->get(xx+1,yy,zz)>0)
{
//Draw Left Facing Face of Block on Right
double texcoord=static_cast<double>(Chunks[ii]->get(xx+1,yy,zz)-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
}

if(static_cast<int>(xx)-1>0&amp;&amp;Chunks[ii]->get(xx-1,yy,zz)>0)
{
//Draw Right Facing Face of Block on Left
double texcoord=static_cast<double>(Chunks[ii]->get(xx-1,yy,zz)-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
}

if(yy+1<chunkSize&amp;&amp;Chunks[ii]->get(xx,yy+1,zz)>0)
{
//Draw Top Facing Face of Block Below
double texcoord=static_cast<double>(Chunks[ii]->get(xx,yy+1,zz)-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
}

if(static_cast<int>(yy)-1>0&amp;&amp;Chunks[ii]->get(xx,yy-1,zz)>0)
{
//Draw Bottom Facing Face of Block Above
double texcoord=static_cast<double>(Chunks[ii]->get(xx,yy-1,zz)-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
}

if(zz+1<chunkSize&amp;&amp;Chunks[ii]->get(xx,yy,zz+1)>0)
{
//Draw Front Facing Face of Block Behind
double texcoord=static_cast<double>(Chunks[ii]->get(xx,yy,zz+1)-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
}

if(static_cast<int>(zz)-1>0&amp;&amp;Chunks[ii]->get(xx,yy,zz+1)>0)
{
//Draw Back Facing Face of Block in Front
double texcoord=static_cast<double>(Chunks[ii]->get(xx,yy,zz+1)-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
}
}
}
}
}
}

So some more info:
The texcoords variable is based on a 1x4 grid of images on a bitmap file, I learned through some experimentation that the x coordinates for each sub image is as follows: 0-0.249, 0.25-0.499, 0.5-0.749, 0.75-0.999. So each block is either 0, 1, 2, 3, or 4, and since 0 is blank subtract 1, and I'll let ya'll do the math...

The variable blockSize is 32.0, and blockHalf is blockSize/2.0.

I haven't implemented the coordinates of the chunk yet, but that's in the near future (it's just the blockSize*chunkSize*position added to the draw sequence, just figured I'd get the hard part done first).

I haven't got it to where it renders blocks on the sides, again that's a completely different thing and I was hoping to get this part done first!

Thanks for any help!
Goblin

P.S.
Man that's a long post... Sorry!

EDIT:
Well it seems I figured it out, I started from scratch with just a single int array, then moving on to the y and z planes and got it done with some doing. Here's the final code, it's a little different at the moment, since I only used a three dimensional array in this instead of using the chunk class.


for(int xx=0;xx<3;xx++)
{
for(int yy=0;yy<3;yy++)
{
for(int zz=0;zz<3;zz++)
{
if(TEST[xx][yy][zz]==0)
{
if(xx-1>=0&amp;&amp;TEST[xx-1][yy][zz]>0)
{
double texcoord=(TEST[xx-1][yy][zz]-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
}

if(xx+1<3&amp;&amp;TEST[xx+1][yy][zz]>0)
{
double texcoord=(TEST[xx+1][yy][zz]-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
}

if(yy-1>=0&amp;&amp;TEST[xx][yy-1][zz]>0)
{
double texcoord=(TEST[xx][yy-1][zz]-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
}

if(yy+1<3&amp;&amp;TEST[xx][yy+1][zz]>0)
{
double texcoord=(TEST[xx][yy+1][zz]-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
}

if(zz-1>=0&amp;&amp;TEST[xx][yy][zz-1]>0)
{
double texcoord=(TEST[xx][yy][zz-1]-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()-blockHalf);
}

if(zz+1<3&amp;&amp;TEST[xx][yy][zz+1]>0)
{
double texcoord=(TEST[xx][yy][zz+1]-1)*0.25;
glTexCoord2f(texcoord,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,0.0);
glVertex3f((xx*blockSize)+camera.X()+blockHalf,(yy *blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord+0.249,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()-blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
glTexCoord2f(texcoord,1.0);
glVertex3f((xx*blockSize)+camera.X()-blockHalf,(yy*blockSize)+camera.Y()+blockHalf,
(zz*blockSize)+camera.Z()+blockHalf);
}
}
}
}
}