DrawIndexedPrimitives overdraws data in previous buffer if called in loop

Posted by Daniel Excinsky on Game Development See other posts from Game Development or by Daniel Excinsky
Published on 2012-10-02T09:45:01Z Indexed on 2012/10/02 9:50 UTC
Read the original article Hit count: 239

Filed under:
|
|

I doubled the question from stackoverflow here, and will delete the opposite of a question that gave me the answer.

I have the Draw method in one of my renderers, that loops through the dictionary and gets precollected and preinitialized buffers. When dictionary has only one element, everything is just fine. But with more elements what I get on the screen is only the data from the last buffer (I suppose, not sure)

My Draw method:

public void Draw(GameTime gameTime)
{                        
    if (!_areStaticEffectsSet)
    {
//          blockEffect.Parameters["TextureAtlas"].SetValue(textureAtlas);
            blockEffect.Parameters["HorizonColor"].SetValue(World.HORIZONCOLOR);
            blockEffect.Parameters["NightColor"].SetValue(World.NIGHTCOLOR);

            blockEffect.Parameters["MorningTint"].SetValue(World.MORNINGTINT);
            blockEffect.Parameters["EveningTint"].SetValue(World.EVENINGTINT);

            blockEffect.Parameters["SunColor"].SetValue(World.SUNCOLOR);

            _areStaticEffectsSet = true;
        }

        blockEffect.Parameters["World"].SetValue(Matrix.Identity);
        blockEffect.Parameters["View"].SetValue(_player.CameraView);
        blockEffect.Parameters["Projection"].SetValue(_player.CameraProjection);
        blockEffect.Parameters["CameraPosition"].SetValue(_player.CameraPosition);
        blockEffect.Parameters["timeOfDay"].SetValue(_world.TimeOfDay);

        var viewFrustum = new BoundingFrustum(_player.CameraView * _player.CameraProjection);

        _graphicsDevice.BlendState = BlendState.Opaque;
        _graphicsDevice.DepthStencilState = DepthStencilState.Default;            

        foreach (KeyValuePair<int, Texture2D> textureAtlas in textureAtlases)
        {
            blockEffect.Parameters["TextureAtlas"].SetValue(textureAtlas.Value);

            foreach (EffectPass pass in blockEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                //TODO: ?????????? ??????????????? ?? ?????? ?? ??????? ??????? VertexBuffer ? IndexBuffer
                foreach (Chunk chunk in _world.Chunks.Values)
                {
                    if (chunk == null || chunk.IsDisposed)
                    {
                        continue;
                    }

                    if (chunk.BoundingBox.Intersects(viewFrustum) && chunk.GetBlockIndexBuffer(textureAtlas.Key) != null)
                    {
                        lock (chunk)
                        {
                            if (chunk.GetBlockIndexBuffer(textureAtlas.Key).IndexCount > 0)
                            {
                                VertexBuffer vertexBuffer = chunk.GetBlockVertexBuffer(textureAtlas.Key);
                                IndexBuffer indexBuffer = chunk.GetBlockIndexBuffer(textureAtlas.Key);
                                //if (chunk.DrawIndex == new Vector3i(0, 0, 0))
                                //{
                                    //if (textureAtlas.Key == -1)
                                    //{
                                        //var varray = new []
                                        //{
                                            //new VertexPositionTextureLight(new Vector3(0,68,0), new Vector2(0,1),1,new Vector3(0,0,0), new Vector3(1,1,1)), 
                                            //new VertexPositionTextureLight(new Vector3(0,68,1), new Vector2(0,1),1,new Vector3(0,0,0), new Vector3(1,1,1)), 
                                            //new VertexPositionTextureLight(new Vector3(1,68,0), new Vector2(0,1),1,new Vector3(0,0,0), new Vector3(1,1,1)) 
                                        //};

                                        //var iarray = new short[] {0, 1, 2};
                                        //vertexBuffer = new VertexBuffer(_graphicsDevice, typeof(VertexPositionTextureLight), varray.Length, BufferUsage.WriteOnly);
                                        //indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, iarray.Length, BufferUsage.WriteOnly);

                                        //vertexBuffer.SetData(varray);
                                        //indexBuffer.SetData(iarray);
                                    }    
                                }

                                _graphicsDevice.SetVertexBuffer(vertexBuffer);
                                _graphicsDevice.Indices = indexBuffer;
                                _graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexBuffer.VertexCount, 0, indexBuffer.IndexCount / 3);                                    
                            }
                        }
                    }
                }
            }
        }
    }

Noteworthy things about the code:

XNA version is 4.0.

I've commented the debugging code in the loop, but left it for it may bring some insight.

I try not only to change vertices/indices in the loop, but textureAtlas also. Code in the shader about textureAtlas:

Texture TextureAtlas;
sampler TextureAtlasSampler = sampler_state
{
    texture = <TextureAtlas>;
    magfilter = POINT;
    minfilter = POINT;
    mipfilter = POINT;
    AddressU = WRAP;
    AddressV = WRAP;
};

struct VSInput
{
    float4 Position : POSITION0;    
    float2 TexCoords1 : TEXCOORD0;
    float SunLight : COLOR0;
    float3 LocalLight : COLOR1;
    float3 Normal : NORMAL0;
};

VertexPositionTextureLight is my own realization of IVertexType.

So, do anybody know about this problem, or see the wrongness in my code (that's far more likely)?

© Game Development or respective owner

Related posts about XNA

Related posts about c#