• Advertisement
Sign in to follow this  

Terrain Texturing using Position, Color, Normal, and TEXTURE???

This topic is 3860 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am stumped. I am using Managed DirectX 9 - C#. I have a heightmap terrain and have had some success applying color and texture to it using the CustomVertex.PostionColorTextured. However, is there any way to add a Normal attribute as well? I would like lighting to be applied to the terrain as well. It doesn't appear that DirectX supports a CustomVertex.PositionColorNormalTextured. I have tried to create my own VertexDeclaration to support this functionality - however I either get the texture or the color - but never both to appear properly. Thank you.

Share this post


Link to post
Share on other sites
Advertisement
MDX offers such ready to use structures only for some common vertex formats. A vertex declaration is the right way to create your own custom vertex structure. There are some samples in the SDK (HDRFormats, HDRCubeMap or HLSLwithoutEffects) that show how it works.

Share this post


Link to post
Share on other sites
I think I already know the answer to this, but...

When I create my own vertex declaration it is up to me to ensure that it is populated properly through a vertex shader? DirectX will not handle this?



Share this post


Link to post
Share on other sites
The vertex declaration is responsible to transfer the values from your vertex buffer to the vertex shader input registers.
The Binding is done with the DeclarationUsage and UsageIndex on the vertex element side and with the Semantic on the shader side. I assume you use HLSL.

Example
VS_OUTPUT main( in float3 vPosition : POSITION,
in float2 tex: TEXCOORD )

The vertex declaration elements need to use the following Declaration Usage to bind these two inputs.
DeclarationUsage.Position
DeclarationUsage.TextureCoordinate
The UsageIndex would be 0 in both cases.

The UsageIndex is used if you want to bind multiple inputs with thze same usage
in float2 tex1: TEXCOORD1,
in float2 tex2: TEXCOORD2

You are still responsible to fill the vertex buffer in a way that matches to the vertex declaration. But you can create an own structure (not a class) for this purpose that work like the predefined.

Share this post


Link to post
Share on other sites
I guess I was being a little naive in thinking DirectX "might" be able to interpret my vertex declaration. I was hoping to postpone learning HLSL - but I guess now is a good a time as any.

Thank you very much Demirug.

Share this post


Link to post
Share on other sites
Well you don’t necessary need a vertex shader when you use a vertex declaration.

The declaration usages work with the fixed pipeline too. An element with the usage Position will be transformed by your matrices like it works with the predefined struts. The same is true for texture coordinates, colors, normals, etc. Therefore the fixed function pipeline will “interpret” your vertex declaration depending on the usage you set.

But learning HLSL is a good idea anyway. The MDX successor XNA Framework supports only the shader based model and with Direct3D 10 the ficed functions are removed even from the native API.

Share this post


Link to post
Share on other sites
Well, I am defining the usages in the vertex declaration but DirectX is not interpreting it as I would have expected. Using the following I get a textured terrain without color.

I have tried changing the ordering of the VertextElements and all that seems to do is produce a colored terrain without texture.



public static readonly VertexElement[] Declarator = new VertexElement[]
{
new VertexElement(0, 0, DeclarationType.Float3,
DeclarationMethod.Default,
DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Color,
DeclarationMethod.Default,
DeclarationUsage.Color, 0),
new VertexElement(0, 16, DeclarationType.Float3,
DeclarationMethod.Default,
DeclarationUsage.Normal, 0),
new VertexElement(0, 28, DeclarationType.Float2,
DeclarationMethod.Default,
DeclarationUsage.TextureCoordinate, 0),


VertexElement.VertexDeclarationEnd
};


Share this post


Link to post
Share on other sites
Your vertex declaration looks fine for me.

Maybe your vertex stride is not correct and therefore you lost some parts of the vertex.

You should try to enable the Direct3D debug runtime. Can be done with the DirectX Control Panel. As you use managed DirectX you will need an external debug monitor or enable unmanaged debugging in your C# project to see the messages. This can give you often at least a hint what’s going wrong.

Share this post


Link to post
Share on other sites
The Stride Size is built off of the vertex Declaration - so I don't think that is the problem.

I ran it in Debug Mode and the only thing returned were a bunch of D3D warnings about redundant render states.

HLSL is looking better and better to me. It sounds like I should learn it anyway...



/// <summary>
/// The vertex stride size.
/// </summary>
public static readonly int StrideSize = VertexInformation.GetDeclarationVertexSize(Declarator, 0);




Share this post


Link to post
Share on other sites
Quote:
Original post by AtomicWedgie
I am stumped. I am using Managed DirectX 9 - C#. I have a heightmap terrain and have had some success applying color and texture to it using the CustomVertex.PostionColorTextured.

However, is there any way to add a Normal attribute as well? I would like lighting to be applied to the terrain as well.

It doesn't appear that DirectX supports a CustomVertex.PositionColorNormalTextured. I have tried to create my own VertexDeclaration to support this functionality - however I either get the texture or the color - but never both to appear properly.

Thank you.

You wouldn't normally use both colour and normal attributes. When a normal is used, the lighting (either fixed function or shader based) calculates a colour based on the light colour and object colour. This results in a diffuse (and potentially specular) colour, which is a direct replacement to specifying the colour in the vertex.

If you do want to use the per-vertex colour as the object colour, you'd have to write a shader that calculates the resulting colour from that.

Share this post


Link to post
Share on other sites
Quote:
Original post by ET3D
You wouldn't normally use both colour and normal attributes. When a normal is used, the lighting (either fixed function or shader based) calculates a colour based on the light colour and object colour. This results in a diffuse (and potentially specular) colour, which is a direct replacement to specifying the colour in the vertex.


If you do want to use the per-vertex colour as the object colour, you'd have to write a shader that calculates the resulting colour from that.[/quote]

The fixed function pipeline can replace material colors with vertex colors too. You are right that this is not the default configuration and I had should remember this.

@AtomicWedgie: If your colors are all the same you should set the Device.Material property. If this is not the case you have to set RenderStateManager.DiffuseMaterialSource to ColorSource.Color1.


Share this post


Link to post
Share on other sites
The terrain vertex colors can vary depending on height. I tried the following, but all that I am seeing is the texture - still no color.

I am curious if anyone has had any luck with the fixed function pipeline with a custom vertex declaration? It seems like support is extremely limited? I guess that is the reason for HLSL?


this.Game.DisplayDevice.RenderState.ColorVertex = true;
this.Game.DisplayDevice.RenderState.DiffuseMaterialSource = ColorSource.Color1;

Share this post


Link to post
Share on other sites
Does lighting work for you without a per-vertex colour? If you haven't tried that, I think that'd be an easier place to start.

If lighting does work for you, and only lighting with per-vertex colour doesn't, you might want to try reordering the vertex components in a way compatible with FVFs: position, normal, colour, texture coords.

Share this post


Link to post
Share on other sites
Lighting works as expected with a texture and without a per-vertex color. I have tried tweaking the ordering of the vertex declaration and have not had much luck.

I found a good tutorial on Terrain texturing using HLSL here. I am going to give a try.

Share this post


Link to post
Share on other sites
Hello there,

i'm new to this forum but i hope i can help you with what u're asking. I'm working with managed direct X and just managed to do this a week ago. I'm using VB.net but i guess u can easily interpret it to C#.

1. First i declare a structure:


Public Structure PositionNormalTexVertex
Public Position As Vector3
Public Normal As Vector3
Public Diffuse As Integer
Public Tu0, Tv0 As Single
Public Shared ReadOnly FVF As VertexFormats = VertexFormats.Position Or VertexFormats.Normal Or VertexFormats.Diffuse Or VertexFormats.Texture1
End Structure


you can play with the FVF to set the combination of vertex format you wish.


2. then i make another structure called primitive, which holds the vertex and index buffer of the geometry i want to build:

Public Structure PRIMITIVE
Dim numVerts As Integer
Dim numInds As Integer
Dim VertexBuffer As VertexBuffer
Dim IndexBuffer As IndexBuffer
End Structure


3. Declaring an instance of a primitive...:


Public PRIMITIVE(0) As PRIMITIVE


4. and set the vertex buffer of the instance as the FVF structure format

PRIMITIVE(0).VertexBuffer = New VertexBuffer(GetType(PositionNormalTexVertex), PRIMITIVE(0).numVerts, d3deng.device, 0, VertexFormats.Position, Pool.Managed)

5. after filling the vertex buffer with the data u wish, u can render it (my texture here uses alpha channel for transparency too):


device.SetTexture(0, TEXTURE)
device.RenderState.SourceBlend = Blend.SourceAlpha
device.RenderState.DestinationBlend = Blend.InvSourceAlpha

device.SetStreamSource(0, main.PRIMITIVE(0).VertexBuffer, 0)
device.Indices = main.PRIMITIVE(0).IndexBuffer
device.VertexFormat = PositionNormalTexVertex.FVF
device.DrawIndexedPrimitives(PrimitiveType.TriangleStrip, 0, 0, main.PRIMITIVE(0).numVerts, 0, main.PRIMITIVE(0).numInds - 2)



i hope this helps!!!

vangelis

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement