0
\$\begingroup\$

Image of the problem:

image of the problem

I used Microsoft's BasicEffect tutorial here and the code sample here and got everything to work fine. Next, I changed everything to use vertexPositionNormalTexture, added a few small methods to help with the texture, and was able to render a textured cube just fine. I also made the cube spin a bit. Next, I wanted to try using vertexPositionNormalTexture. Unfortunately, I got this image instead of a cube. Here are some pieces of my code that contain major modifications.

Draw method

 protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.SteelBlue);

            RasterizerState rasterizerState1 = new RasterizerState();
            //backface culling
            rasterizerState1.CullMode = CullMode.None;
            //turn off texture blurring
            graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;


            graphics.GraphicsDevice.RasterizerState = rasterizerState1;
            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                graphics.GraphicsDevice.DrawPrimitives(
                    PrimitiveType.TriangleList, 
                    0, 
                    12
                );
            } 

            base.Draw(gameTime);
        }

Part of the method that sets up vertices

private void InitializeCube()
    {

        Vector3 topLeftFront = new Vector3(-1.0f, 1.0f, 1.0f);
        Vector3 bottomLeftFront = new Vector3(-1.0f, -1.0f, 1.0f);
        Vector3 topRightFront = new Vector3(1.0f, 1.0f, 1.0f);
        Vector3 bottomRightFront = new Vector3(1.0f, -1.0f, 1.0f);
        Vector3 topLeftBack = new Vector3(-1.0f, 1.0f, -1.0f);
        Vector3 topRightBack = new Vector3(1.0f, 1.0f, -1.0f);
        Vector3 bottomLeftBack = new Vector3(-1.0f, -1.0f, -1.0f);
        Vector3 bottomRightBack = new Vector3(1.0f, -1.0f, -1.0f);

        Vector2 textureTopLeft = new Vector2(0.0f, 0.0f);
        Vector2 textureTopRight = new Vector2(.25f, 0.0f);
        Vector2 textureBottomLeft = new Vector2(0.0f, .25f);
        Vector2 textureBottomRight = new Vector2(.25f, .25f);

        Color frontColor = new Color(255, 255, 255);
        Color backColor = new Color(255, 0, 0);
        Color topColor = new Color(0, 255, 0);
        Color bottomColor = new Color(0, 0, 255);
        Color leftColor = new Color(0, 255, 255);
        Color rightColor = new Color(0, 0, 0);

        // Front face.
        cubeVertices[0] =
            new VertexPositionColorTexture(
            topLeftFront, frontColor, GetTexPos(2));
        cubeVertices[1] =
            new VertexPositionColorTexture(
            bottomLeftFront, frontColor, GetTexPos(2) + textureBottomLeft);
        cubeVertices[2] =
            new VertexPositionColorTexture(
            topRightFront, frontColor, GetTexPos(2) + textureTopRight);
        cubeVertices[3] =
            new VertexPositionColorTexture(
            bottomLeftFront, frontColor, GetTexPos(2) + textureBottomLeft);
        cubeVertices[4] =
            new VertexPositionColorTexture(
            bottomRightFront, frontColor, GetTexPos(2) + textureBottomRight);
        cubeVertices[5] =
            new VertexPositionColorTexture(
            topRightFront, frontColor, GetTexPos(2) + textureTopRight);

Initializing basicEffect

private void InitializeEffect()
    {
        basicEffect = new BasicEffect(graphics.GraphicsDevice);


        basicEffect.World = worldMatrix;
        basicEffect.View = viewMatrix;
        basicEffect.Projection = projectionMatrix;

        //basicEffect.EnableDefaultLighting
    }

LoadContent

protected override void LoadContent()
    {
        canyonTexture = Content.Load<Texture2D>("CanyonTexture");
        textureSheetWidth = canyonTexture.Width / 16;
        InitializeTransform();
        InitializeEffect();
        basicEffect.TextureEnabled = true;
        basicEffect.VertexColorEnabled = true;
        basicEffect.Texture = canyonTexture;

        InitializeCube();

    }

Setting up the VertexBuffer

private void CreateVertexBuffer()
    {
        vertexDeclaration = new VertexDeclaration(new VertexElement[]
            {
                new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
                new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
            });

        vertexBuffer = new VertexBuffer(
            graphics.GraphicsDevice,
            vertexDeclaration,
            number_of_vertices,
            BufferUsage.None
            );


        cubeVertices = new VertexPositionColorTexture[number_of_vertices];
        InitializeCube();


        vertexBuffer.SetData<VertexPositionColorTexture>(cubeVertices);

        graphics.GraphicsDevice.SetVertexBuffer(vertexBuffer);
    }


    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        CreateVertexBuffer();

        base.Initialize();
    }
\$\endgroup\$
1
\$\begingroup\$

Basically your vertex declaration is wrong.

A Color is only four bytes wide. So the offset of the texture-coordinate element that follows should be 16, not 24.

However you don't even need to create a vertex declaration for this in XNA 4.0. Simply pass VertexPositionColorTexture.VertexDeclaration or typeof(VertexPositionColorTexture) to the constructor of your VertexBuffer.

There is a blog post here that explains how this all works.

\$\endgroup\$
  • \$\begingroup\$ Thanks . (My post on two sites gets the same great answer from same great person :D) \$\endgroup\$ – BluShine May 1 '11 at 2:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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