This project is read-only.

DualTextureEffect for DrawableSurface

Sep 5, 2011 at 12:00 PM

I was wondering if you think of adding the possibility to use the DualTextureEffect for rendering the DrawableSurface?

Cheers

Sep 5, 2011 at 12:25 PM
Edited Sep 5, 2011 at 12:29 PM

Though I haven't test it, it is absolutely possible to render the DrawableSurface using any Effect/Material including DualTextureEffect.

The tricky part is that DualTextureEffect requires 2 set of texture coordinates, but the default DrawableSurface has only 1 set of texture coordinate. So you have to explicitly call the DrawableSurface.ConvertVertexType<VertexPositionNormalDualTexture>() method to fill the appropriate vertex data.

Also take a look at the MaterialsGame sample, it contains the code to add tangent and binormal data to the DrawableSurface to support normal mapping, maybe that can help you out.

Thank.

Sep 5, 2011 at 1:25 PM

Thanks for a quick reply.

I've just tried your suggestion. I've also used some sample code from you methods in vertextConverter method.

 

        public override void LoadContent()
        {

            terrain = new DrawableSurface(BaseGame.Singleton.GraphicsDevice,
                BaseGame.Singleton.Content.Load<Heightmap>("height" ), 16);
            terrain.ConvertVertexType<VertexPositionNormalDualTexture>(new DrawSurfaceVertexConverter<VertexPositionNormalDualTexture>(vertexConverter));
            // Center the terrain to the camera
            terrain.Position = -terrain.BoundingBox.GetCenter();
            terrain.TextureTransform = TextureTransform.CreateScale(32, 32);
            terrain.Invalidate();

            ...
        }

        private void vertexConverter(int x, int y, ref VertexPositionColorNormalTexture input, ref VertexPositionNormalDualTexture vertex)
        {
            Vector2 uv = new Vector2();
            // Texture will map to the whole surface by default.
            uv.X = 1.0f * x / 512;
            uv.Y = 1.0f * y / 512;

            vertex.Position = terrain.Heightmap.GetPosition(x, y);
            vertex.Normal = terrain.Heightmap.Normals[terrain.Heightmap.GetIndex(x, y)];
            vertex.TextureCoordinate0 = TextureTransform.Transform(terrain.TextureTransform, uv);
            vertex.TextureCoordinate0 = TextureTransform.Transform(terrain.TextureTransform, uv);
        }

 

However, i get a strange results, for sure not the one expected.

Am i doing something wrong?

 

Thanks

 

Sep 5, 2011 at 1:41 PM

You forgot to set TextureCoordinate1:

            vertex.TextureCoordinate0 = TextureTransform.Transform(terrain.TextureTransform, uv);
            vertex.TextureCoordinate1 = TextureTransform.Transform(terrain.TextureTransform, uv);

or you can try the following code to ingore the texture transform:

terrain.ConvertVertexType<VertexPositionNormalDualTexture>(new DrawSurfaceVertexConverter<VertexPositionNormalDualTexture>(vertexConverter)); 
terrain.Position = -terrain.BoundingBox.GetCenter(); 
private void vertexConverter(int x, int y, ref VertexPositionColorNormalTexture input, ref VertexPositionNormalDualTexture vertex) 
{
    vertex.Position = input.Position; 
    vertex.Normal = input.Normal; 
    vertex.TextureCoordinate0 = vertex.TextureCoordinate1 = input.TextureCoordinate; 
}
Sep 5, 2011 at 1:51 PM

Lol, stupid copy paste. My bad.

Works like a charm now.

Thanks

Sep 5, 2011 at 1:58 PM
Edited Sep 5, 2011 at 3:17 PM

Why did you decide to make the DrawableSurface to use just one texture? Was this decision made because WP7 does not support multitexturing and in order to implement it, you would require an Effect instance for each DrawableSurfacePatch?

Sep 6, 2011 at 4:15 AM

It was because I have no idea what uv data to set in the second texture coordinate channel. Most of the time, DualTextureEffect is used when the 2 texture coordinate channels contains different uv data, so you can apply a prebaked lightmap or shadowmap to the underlying mesh. But if the texture coordinates are idential, it is better to bake the 2 textures into a single texture and render it using BasicEffect.

And on Windows and Xbox, texture coordinates can be computed in the shader, so terrain splatting, detailed textures won't require a second uv channel either.

Sep 6, 2011 at 8:41 AM

I agree, there is no need to use 2 textures if the coordinates are identical.

What i mean, is there a way to implement terrain splatting on WP7?

Sep 6, 2011 at 9:53 AM

I think DualTextureEffect can be used to implement terrain splatting, but the method might be too slow to be practicle. The basic idea is to draw the base layer first, then draw each layer above with alpha blending turned on. The first texture is set to be the diffuse texture, and the second texture is the layer alpha map with each pixel multiplied by 0.5. It is quite different from my implementation on Windows and Xbox so I didn't make it available to Windows Phone.