Jump to content
  • Advertisement
Sign in to follow this  
Spa8nky

[XNA] [HLSL] Drawing a single triangle in a mesh part with a different texture?

This topic is 3076 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 currently drawing a model by mesh part using the current code:


foreach (ModelMesh mesh in model.Meshes)
{
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
graphics_Device.VertexDeclaration = meshPart.VertexDeclaration;
graphics_Device.Vertices[0].SetSource(mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride);
graphics_Device.Indices = mesh.IndexBuffer;

graphics_Device.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
meshPart.BaseVertex,
0,
meshPart.NumVertices,
meshPart.StartIndex,
meshPart.PrimitiveCount
);
}
}



How would it be possible to tell HLSL to draw one random triangle in the mesh part with a different texture?

I understand that I could send HLSL a boolean value but how can I make sure that a random triangle is affected? Is there anyway of counting the number of triangles drawn in the HLSL file itself, or is there another way someone can suggest?

Share this post


Link to post
Share on other sites
Advertisement
Before drawing you could pick a random triangle from your index buffer (i.e. 3 consecutive indices starting from a random point that is a multiple of 3) and set a float value in those vertices to 1 (Make sure all other vertices have it set to 0) so then when you come to the pixel shader you can check that float value and if it's 1 then use your random texture otherwise use the normal mesh part texture.

Share this post


Link to post
Share on other sites
I'm not that familiar with XNA, but can you add another variable to your vertex structure, say to hold the vertex index, and set an index in a shader constant? Or stream the indexbuffer in a second stream?

Share this post


Link to post
Share on other sites
How would I draw a model with a custom vertex format?

I don't think it is possible to overwrite the mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride and meshPart.VertexDeclaration, unless someone else knows a way?

I can only think of storing all the triangles from the model in a custom vertex format when loading the model.

Share this post


Link to post
Share on other sites
I think the suggestion for adding a triangle index into your vertex structure is probably the best idea, and its not difficult in XNA. Since you aren't sharing vertices across triangles (TriangleList instead of TriangleStrip or Fan) it should be simple to set the triangle index for each vertex when you initialize your vertices.

Then you can track which of the triangles you want to highlight in your C# code and simply pass that index along as a shader constant.

EDIT: since you aren't generating the vertices yourself, it will be more difficult to extend the vertex format to do what you want, though you probably could by creating a custom content processor and massaging the vertex data at build time.

Share this post


Link to post
Share on other sites
Quote:
Original post by dadooGames
I think the suggestion for adding a triangle index into your vertex structure is probably the best idea, and its not difficult in XNA. Since you aren't sharing vertices across triangles (TriangleList instead of TriangleStrip or Fan) it should be simple to set the triangle index for each vertex when you initialize your vertices.


I completely agree that this method would be best but how would you approach the custom vertex format?

Would you be inclined to use the method I mentioned above and assign the triangles to the new format when loading the model or something else entirely?

Share this post


Link to post
Share on other sites
The Shatter sample on the XNA creators club site has a custom model processor that adds data into the vertex format of an existing model at compile time Writing a custom processor is not terribly simple thing to do, but it is possible.

Note that you may run into issues where the texture coordinates are wrong between your selected and non-selected triangle even if you do get the processor to work.

Share this post


Link to post
Share on other sites
Thank you very much, I'll look into that.

If it gets too complicated, and is prone to errors, then I'll go with my plan of storing all the triangles in a custom vertex format when loading the model.

If that seems illogical then now is the time to warn me away from the idea :)

Share this post


Link to post
Share on other sites
My first question would be, what are you trying to achieve by doing this? What is the purpose? There may be a better solution to your problem.

Share this post


Link to post
Share on other sites
I've extracted the data from the mesh in a custom content pipeline:


private void ProcessMesh(NodeContent node)
{
MeshContent mesh = node as MeshContent;

if (mesh != null)
{
Matrix absTransform = mesh.AbsoluteTransform;

for (int i = 0; i < mesh.Geometry.Count; ++i)
{
GeometryContent geometry = mesh.Geometry;

// Vertex position
IndirectPositionCollection meshPositions = geometry.Vertices.Positions;

// Vertex normals
VertexChannel<Vector3> meshNormals = geometry.Vertices.Channels.Get<Vector3>(VertexChannelNames.Normal());

// Vertex texture coordinates
VertexChannel<Vector2> meshTexCoords = geometry.Vertices.Channels.Get<Vector2>(VertexChannelNames.TextureCoordinate(0));

for (int ii = 0; ii < geometry.Indices.Count; ++ii)
{
normals.Add(meshNormals[ii]);
texCoords.Add(meshTexCoords[ii]);

Vector3 transformedVertex = Vector3.Transform(meshPositions[ii], absTransform);
vertices.Add(transformedVertex);
}
}
}

for (int i = 0; i < node.Children.Count; ++i)
{
ProcessMesh(node.Children);
}
}



Now I can create my own vertex format using the extracted data :)

Quote:

My first question would be, what are you trying to achieve by doing this? What is the purpose? There may be a better solution to your problem.


I wish to animate random triangles with different textures that belong to one mesh part of the whole model.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!