Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


MarlboroKing

Member Since 16 Nov 2010
Offline Last Active Today, 02:03 PM

Posts I've Made

In Topic: Chunk-based random world generation à la Minecraft

19 May 2015 - 10:45 PM

You won't be able to generate the array for your world, create the lighting and vbs ibs in one pass. Sure, you could, but don't. Nasty results. Generate and create obvious lighting first (eg --y and set sunlight to 0 if block is overhead)
Then loop and run your lighting. Then throw away useless faces while creating your buffers. Create an initial section (eg 68 chunks) then light/create as you gain closer and remove as further.

Ditch the heightmap if you want cliffs and overhangs. Slightly modify perlin as needed. This is the most difficult part of these games. Don't get discouraged, read and test.

Split your world into 'chunks'. 1 draw call consisting of 300 16x128x16 chunk blocks is deadly. 300 * (16x128x16) draw calls is idiotic.

Sorry, phone sucks for typing.

In Topic: How to time bomb a beta?

07 April 2014 - 10:13 PM

Hidden RDTSC instruction - Awaits if a debugger is present. Basically is just a hidden windows timer, akin to GetTickCount, but screwed up in the byte code.

 

 

Runtime functions - Use VirtualProtect (or similar for your OS) and implement it. Is a lot of fun and you'll learn a lot.

 

Implement a random obfuscation virtualization environment. Hard, but not as hard as one would perceive. You'll just need to dive into the PE format (agian, for your OS, mine is Windows..), it's honestly quite intriguing.


In Topic: Exactly what's the point of 'int32_t', etc.

17 March 2014 - 12:25 PM

Alright, I see. If you're expecting your plain int has at least 32 bits of storage, however, the platform it's being deployed on creates only 16 bits of storage.

So if you are performing a bit shift operation to take the last 16 bits out of the supposed 32 bits, bam.

 

Thanks!


In Topic: Voxels Theory

11 February 2014 - 10:32 AM

TGrey, I wouldn't advise relying on frustrum culling. Every frame you would be doing that. So instead, take those faces out before hand instead of "taking those out every frame for 40,000 blocks".

@kaptein, wonderful! Never thought of that!

In Topic: Voxels Theory

10 February 2014 - 11:52 AM

I'm trying to stay away from octrees and similar, so I will semi-explain how my voxel game works:

We have a block class (nType, nSun, color)
This will be the main blocks such as grass or dirt. Obviously the best way to render and deal with this blocks is to split them up into "Chunks".

Now we have a chunk class (vecIndex, vecPosition, nState)
Did you notice we don't use blocks in this chunk class? Because constant allocation and deallocation is a big no. Instead of searching each chunk, create/destroy, etc., we see what our maximum cache distance is as for our BlockManager class

And our BlockManager class (Block* pBlocks)
I know, a single pointer-array. With this, we can index and grab quicker than an 3D array, and we won't have the overhead of new'ing or delete'ing a 16*128*16 array every time we go into a new chunk.

I will post some code in a minute when my wonderful Pentium 4 finally boots up.

 

Edit: Here we go. This is just a sample that I ripped apart from several sources inside my game. Could be error prone, and defiantly needs some tidying up.

#define CHUNK_WIDTH 16
#define CHUNK_HEIGHT 128
#define CHUNK_DEPTH 16

#define CHUNK_CACHE_RANGE 5
#define CHUNK_CACHE_VIEWRANGE 3

#define CHUNK_CACHESIZE_WIDTH ((CHUNK_CACHE_RANGE * 2) + 1) * CHUNK_WIDTH
#define CHUNK_CACHESIZE_DEPTH ((CHUNK_CACHE_RANGE * 2) + 1) * CHUNK_DEPTH

int MOD( int a, int b )
{
	return (a % b + b) % b;
}

int OFFSET( int x, int z )
{
	int nWrapX = MOD( x, CHUNK_CACHESIZE_WIDTH );
	int nWrapZ = MOD( z, CHUNK_CACHESIZE_DEPTH );

	if( nWrapX < 0 )
		nWrapX += CHUNK_CACHESIZE_WIDTH;
	if( nWrapZ < 0 )
		nWrapZ += CHUNK_CACHESIZE_DEPTH;

	return nWrapX * (CHUNK_CACHESIZE_WIDTH * CHUNK_HEIGHT) + nWrapZ * CHUNK_HEIGHT;
}

int OFFSET( int x, int y, int z )
{
	int nWrapX = MOD( x, CHUNK_CACHESIZE_WIDTH );
	int nWrapZ = MOD( z, CHUNK_CACHESIZE_DEPTH );

	if( nWrapX < 0 )
		nWrapX += CHUNK_CACHESIZE_WIDTH;
	if( nWrapZ < 0 )
		nWrapZ += CHUNK_CACHESIZE_DEPTH;

	return nWrapX * (CHUNK_CACHESIZE_WIDTH * CHUNK_HEIGHT) + nWrapZ * CHUNK_HEIGHT + y;
}

class BlockManager
{
public:
    Block* m_pBlocks;

    BlockManager()
    {
        int nSize = CHUNK_CACHESIZE_WIDTH * CHUNK_CACHESIZE_DEPTH * CHUNK_HEIGHT + 1;
        m_Blocks = new Block[nSize];

        for( int i = 0; i < nSize; i++ )
            m_Blocks[i] = Block();
    }

    Block BlockAt( int x, int y, int z )
    {
	if( !ChunkCache::IsInBounds( x, y, z ) )
		return Block();

	int nWrapX = MOD( x, CHUNK_CACHESIZE_WIDTH );
	int nWrapZ = MOD( z, CHUNK_CACHESIZE_DEPTH );
	if( nWrapX < 0 )
		nWrapX += CHUNK_CACHESIZE_WIDTH;
	if( nWrapZ < 0 )
		nWrapZ += CHUNK_CACHESIZE_DEPTH;

        int nOffset = nWrapX * (CHUNK_CACHESIZE_WIDTH * CHUNK_HEIGHT) + nWrapZ * CHUNK_HEIGHT;

	return m_Blocks[nOffset];
    }
};

 

 

Alright, now we can use a TerrainChunkGenerator, go from x = 0, y = 127, z = 0 and x++, y--, z++

Generate our chunks, and move to the LightingChunkGenerator. Perform some nasty recursive functions to spread out our light source from 16, and continue.

 

Now we are at VertexChunkGenerator. When creating the vertices, we check the current block's neighbors. So, if a block is above us, we don't create the top face. If a block is to its left but not to its right, don't create the left face and generate the right face.

Now we have this chunk that will only have visible blocks vertices and indicies. We just gave our performance steroids.


PARTNERS