Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

i'm having a spot of trouble trying to get my voxels textures in the right place.

I am using a very simple mechanism that assumes all sides of any given block are always individually specified (i'll improve it later). The idea being that the method below gets me the UV coordinates for the block faces.

Given a block type (the Y index) and a face (the X index) i am trying to pull the (textureSize X textureSize) portion of the atlas on to the block face. But it isn't doing what I expect.

So I figured I'd start by confirming that this code is logically correct then look at my vertices to confirm that i'm putting the mappings on the right ones.

        /// <summary>
        /// Gets the UV mappings for the given face on the given block type
        /// where the textures in the atlas have the given size and the atlas contains 
        /// textures for the given number of block types.
        /// </summary>
        /// <param name="blockType">Type of the block.</param>
        /// <param name="face">The face.</param>
        /// <param name="textureSize">Size of the textures within the atlas.</param>
        /// <param name="atlasSize">Size of the atlas.</param>
        /// <returns></returns>
        public static Vector2[] GetUVMappingsFor(int blockType, int face, int textureSize, int atlasSizeInBlocks)
        {
            Vector2[] result;
            // knowing a little about the engine design means I can make an assumption (or 4) here ...
            //    1. all textures in the mapped atlas are to be the same size
            //    2. all atlas's are laid out in the same way (vertically for each block, horizontally for each face on the block)
            //    3. the blocktype is a number, we don't care what the block is just that it's texture will be in the calculated position
            //    4. all blocks are a perfect cube so no odd shaped textures in the atlas


                // used when dealing with an atlas
                float atlasWidth = textureSize * 6;                    // total width of the atlas
                float atlasHeight = textureSize * atlasSizeInBlocks;   // total height of the atlas
                float tWidth = (1 / atlasWidth) * textureSize;         // width of 1 texture face in the atlas
                float tHeight = (1 / atlasHeight) * textureSize;       // height of 1 texture face in the atlas
                float y = blockType * tHeight;                         // Y to top left of block texture info
                float x = (float)face * tWidth;                        // X to top left of block texture info

                result = new Vector2[]
                {
                    new Vector2(x, y),                   // top left
                    new Vector2(x + tWidth, y),          // top right
                    new Vector2(x, y + tHeight),         // bottom left
                    new Vector2(x + tWidth, y + tHeight) // bottom right
                };
         }

Building the vertex array im doing this ...

 /// <summary>
        /// Gets the vertices that make up this block.
        /// </summary>
        /// <param name="position">The block position.</param>
        /// <param name="block">The block.</param>
        /// <param name="visibleFaces">The visible faces.</param>
        /// <returns></returns>
        public static VertexPositionNormalTexture[] GetTexturedVertices(Vector3 position, Block block, bool[] visibleFaces, float blockSize, int textureSize, int blocksInAtlas)
        {
            if (block.IsActive)
            {
                List<VertexPositionNormalTexture> _vertices = new List<VertexPositionNormalTexture>(36);

                // Calculate the position of the vertices on the top face.
                Vector3 topLeftFront = position + new Vector3(-blockSize, blockSize, -blockSize);
                Vector3 topLeftBack = position + new Vector3(-blockSize, blockSize, blockSize);
                Vector3 topRightFront = position + new Vector3(blockSize, blockSize, -blockSize);
                Vector3 topRightBack = position + new Vector3(blockSize, blockSize, blockSize);

                // Calculate the position of the vertices on the bottom face.
                Vector3 btmLeftFront = position + new Vector3(-blockSize, -blockSize, -blockSize);
                Vector3 btmLeftBack = position + new Vector3(-blockSize, -blockSize, blockSize);
                Vector3 btmRightFront = position + new Vector3(blockSize, -blockSize, -blockSize);
                Vector3 btmRightBack = position + new Vector3(blockSize, -blockSize, blockSize);

                // Normal vectors for each face (needed for lighting / display)
                Vector3 normalFront = new Vector3(0.0f, 0.0f, 1f);
                Vector3 normalBack = new Vector3(0.0f, 0.0f, -1f);
                Vector3 normalTop = new Vector3(0.0f, 1f, 0.0f);
                Vector3 normalBottom = new Vector3(0.0f, -1f, 0.0f);
                Vector3 normalLeft = new Vector3(-1f, 0.0f, 0.0f);
                Vector3 normalRight = new Vector3(1f, 0.0f, 0.0f);

                if (visibleFaces[0])
                {
                    // Add the vertices for the FRONT face.
                    Vector2[] uvMappings = GetUVMappingsFor(block.Type, 0, textureSize, blocksInAtlas);
                    _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalFront, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalFront, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightFront, normalFront, uvMappings[1]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalFront, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalFront, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightFront, normalFront, uvMappings[1]));
                }

                if (visibleFaces[1])
                {
                    // Add the vertices for the BACK face.
                    Vector2[] uvMappings = GetUVMappingsFor(block.Type, 1, textureSize, blocksInAtlas);
                    _vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalBack, uvMappings[1]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalBack, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBack, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBack, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalBack, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBack, uvMappings[2]));
                }

                if (visibleFaces[2])
                {
                    // Add the vertices for the TOP face.
                    Vector2[] uvMappings = GetUVMappingsFor(block.Type, 2, textureSize, blocksInAtlas);
                    _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalTop, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightFront, normalTop, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uvMappings[1]));
                }

                if (visibleFaces[3])
                {
                    // Add the vertices for the BOTTOM face. 
                    Vector2[] uvMappings = GetUVMappingsFor(block.Type, 3, textureSize, blocksInAtlas);
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalBottom, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalBottom, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBottom, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalBottom, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalBottom, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalBottom, uvMappings[1]));
                }

                if (visibleFaces[4])
                {
                    // Add the vertices for the LEFT face.
                    Vector2[] uvMappings = GetUVMappingsFor(block.Type, 4, textureSize, blocksInAtlas);
                    _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalLeft, uvMappings[1]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalLeft, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftFront, normalLeft, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalLeft, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmLeftBack, normalLeft, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalLeft, uvMappings[1]));
                }

                if (visibleFaces[5])
                {
                    // Add the vertices for the RIGHT face. 
                    Vector2[] uvMappings = GetUVMappingsFor(block.Type, 5, textureSize, blocksInAtlas);
                    _vertices.Add(new VertexPositionNormalTexture(topRightFront, normalRight, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightFront, normalRight, uvMappings[2]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalRight, uvMappings[3]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalRight, uvMappings[1]));
                    _vertices.Add(new VertexPositionNormalTexture(topRightFront, normalRight, uvMappings[0]));
                    _vertices.Add(new VertexPositionNormalTexture(btmRightBack, normalRight, uvMappings[3]));
                }

                return _vertices.ToArray();
            }

            return new VertexPositionNormalTexture[0];
        }

Screenshot of the problem: http://www.ccoder.co.uk/textures.png texture issue

share|improve this question

closed as too localized by Byte56, bummzack, Roy T., Jimmy Shelter, Sean Middleditch Mar 20 '13 at 1:23

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

    
I need you to be a bit more specific on what you meant on the "But it isn't doing what I expect" part. If you can provide a screenshot showing the rendering not going correctly, it will become much easier for us to spot what might be wrong with your code. –  UBSophung Mar 19 '13 at 13:53
    
fair enough (my bad ... let me grab a screenshot) –  Wardy Mar 19 '13 at 13:54
    
hmmm ok odd ... my printscreen key isn't letting me capture the screen at the moment. It's basically putting streaks of other textures (from the block above / below in the block face. –  Wardy Mar 19 '13 at 14:01
    
I can paste the vector2s i've used in TechCraft for uvMappings for comparison if it helps. –  Jason Coombes Mar 19 '13 at 14:11
    
Hi Jason ... i looked at your logic in techcraft but couldn't fully understand it, I basically wrote (see above) what I thought was a simpler version of it ... thinking i missed something key though. But looking at it closer im not convinced its even a UV coord problem. –  Wardy Mar 19 '13 at 14:13
show 10 more comments

1 Answer 1

up vote 0 down vote accepted

Ok i cracked it the problem was in the vertex generation method in several places ...

Firstly ...

// Calculate the position of the vertices on the top face.
                Vector3 topLeftFront = position + new Vector3(-blockSize, blockSize, -blockSize);
                Vector3 topLeftBack = position + new Vector3(-blockSize, blockSize, blockSize);
                Vector3 topRightFront = position + new Vector3(blockSize, blockSize, -blockSize);
                Vector3 topRightBack = position + new Vector3(blockSize, blockSize, blockSize);

                // Calculate the position of the vertices on the bottom face.
                Vector3 btmLeftFront = position + new Vector3(-blockSize, -blockSize, -blockSize);
                Vector3 btmLeftBack = position + new Vector3(-blockSize, -blockSize, blockSize);
                Vector3 btmRightFront = position + new Vector3(blockSize, -blockSize, -blockSize);
                Vector3 btmRightBack = position + new Vector3(blockSize, -blockSize, blockSize);

lets assume a block size of 1 ... this code generated an actual set of verts that resulted in a block being 2 in size in all dimensions so my odd looking scene was the result of overlapping blocks which in turn caused a sort of "tearing" to occur between blocks with different textures result in each block having a line of screen real estate (ugly to say the least).

I then noticed something was still not right so I Took Jason Coombes advice (given on skype - thanks Jason) and added another set of textures to my atlas which had numbers on them.

Most of the sides looked ok but the top face seemed messed up ... the uv coordinates were setup wrong in here ...

       if (visibleFaces[2])
        {
            // Add the vertices for the TOP face.
            Vector2[] uvMappings = GetUVMappingsFor(block.Type, 2, textureSize, blocksInAtlas);
            _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uvMappings[2]));
            _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uvMappings[3]));
            _vertices.Add(new VertexPositionNormalTexture(topLeftBack, normalTop, uvMappings[0]));
            _vertices.Add(new VertexPositionNormalTexture(topLeftFront, normalTop, uvMappings[2]));
            _vertices.Add(new VertexPositionNormalTexture(topRightFront, normalTop, uvMappings[3]));
            _vertices.Add(new VertexPositionNormalTexture(topRightBack, normalTop, uvMappings[1]));
        }

This resulted in the texture being "twisted" in the middle. It was hard to explain exactly what I was seeing because there were more than 1 problems with it however taking the time to check through all the steps got me there in the end :)

Thanks everyone. Sometimes it's just good to talk about it.

share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.