Cómo: Crear una malla
Actualización: noviembre 2007
Básicamente, existen cuatro maneras de crear una malla:
Cargar los datos de la malla procedentes de un archivo.
Clonar u optimizar una malla existente.
Utilizar una función de creación de formas y especificar el tamaño y el número de triángulos que se utilizarán para crear la forma.
Utilizar el constructor Mesh.
Nota: |
---|
Las aplicaciones móviles Direct3D administradas requieren el software de Windows Mobile versión 5.0 para dispositivos Pocket PC y Smartphone. Vea Recursos externos de .NET Compact Framework para obtener información sobre el software de Windows Mobile y los SDK. |
Para crear una malla desde un archivo
- Cargue los datos de la malla desde un archivo y, a continuación, rellene una malla con ellos. .NET Compact Framework no admite la carga directa de mallas desde un archivo, pero en el se define una clase para cargarlas.
Para crear una malla a partir de una malla existente
Utilice el método Optimize para crear una nueva malla con datos optimizados.
O bien
Utilice el método OptimizeInPlace para optimizar la malla actual.
El principal uso de la clonación es convertir la malla de formato de punto flotante a formato de punto fijo. El principal uso de la optimización es crear una malla que se dibuje más rápidamente. La optimización de la malla reorganiza los triángulos para que las llamadas de dibujo en la malla se realicen más rápidamente. La optimización de la malla también genera una tabla de atributos, que se utiliza para identificar áreas de la malla que deben dibujarse con texturas, estados de representación y materiales diferentes.
Para crear una malla mediante el uso de una función de creación de formas
Utilice uno de los métodos estáticos siguientes de la clase Mesh para crear una malla con la posición y los valores normales especificados en operaciones matemáticas de punto flotante:
Para crear una malla mediante el uso del constructor Mesh
Llame al constructor Mesh con los argumentos deseados.
Establezca los búferes del índice y de los vértices, así como los datos de la tabla de atributos. Los datos, en este caso, se suelen generar en tiempo de ejecución. El ejemplo siguiente muestra los pasos para crear una malla de esta forma.
Ejemplo
En el ejemplo de código siguiente se crea una malla heightfield en el plano x-y; la coordenada z representa la dimensión vertical. La malla determinada creó ejecuciones de (0, 0) a (1, 1) y tiene un alto especificado por el método GetHeight. A esta malla también se le aplica textura con una textura única en toda la malla. El parámetro tessellation, definido por el ejemplo, se utiliza para controlar el número de puntos que se usan en el borde de la malla.
Class Form1
Private Sub New()
MyBase.New()
' In this example, initialize the mesh with
' 4 tessellations
Me.InitializeMesh(4)
End Sub
Private Sub InitializeMesh(ByVal tessellation As Integer)
Dim mesh1 As Mesh = CreateHeightfieldMesh(tessellation)
End Sub
Private Function GetHeight(ByVal x As Single, ByVal y As Single) As Single
Return 0
End Function
Private Function CreateHeightfieldMesh(ByVal tessellation As Integer) As Mesh
Dim mesh As Mesh
Dim device As Device = Nothing
Dim arrayIndices((tessellation - 1) * (tessellation - 1) * 6) As Short
Dim arrayVertices(tessellation * tessellation) As CustomVertex.PositionTextured
Dim attributeRange As New AttributeRange()
' Create mesh with desired vertex format and desired size.
mesh = New Mesh(arrayIndices.Length / 3, arrayVertices.Length, MeshFlags.SystemMemory, CustomVertex.PositionTextured.Format, device)
' For each point in the height field calculate the x, y, z and
' texture coordinates.
Dim y As Integer
For y = 0 To tessellation
Dim x As Integer
For x = 0 To tessellation
Dim arrayIndex As Integer = y * tessellation + x
Dim xCoordinate As Single = System.Convert.ToSingle(x) / System.Convert.ToSingle(tessellation - 1)
Dim yCoordinate As Single = System.Convert.ToSingle(y) / System.Convert.ToSingle(tessellation - 1)
Dim vertex As New CustomVertex.PositionTextured(xCoordinate, yCoordinate, GetHeight(xCoordinate, yCoordinate), xCoordinate, yCoordinate)
arrayVertices(arrayIndex) = vertex
Next x
Next y
' Calculate the index buffer.
Dim z As Integer
For z = 0 To (tessellation - 1)
Dim x As Integer
For x = 0 To (tessellation - 1)
Dim arrayIndex As Integer = (z * (tessellation - 1) + x) * 6
Dim vertexIndex As Integer = z * tessellation + x
arrayIndices(arrayIndex) = Fix(vertexIndex)
arrayIndices((arrayIndex + 1)) = Fix(vertexIndex + 1)
arrayIndices((arrayIndex + 2)) = Fix(vertexIndex + tessellation)
arrayIndices((arrayIndex + 3)) = Fix(vertexIndex + tessellation)
arrayIndices((arrayIndex + 4)) = Fix(vertexIndex + 1)
arrayIndices((arrayIndex + 5)) = Fix(vertexIndex + tessellation + 1)
Next x
Next z
' There is only one attribute value for this mesh.
' By specifying an attribute range the DrawSubset function
' does not have to scan the entire mesh for all faces that are
' are marked with a particular attribute ID.
attributeRange.AttributeId = 0
attributeRange.FaceStart = 0
attributeRange.FaceCount = arrayIndices.Length / 3
attributeRange.VertexStart = 0
attributeRange.VertexCount = arrayVertices.Length
mesh.VertexBuffer.SetData(arrayVertices, 0, LockFlags.None)
mesh.IndexBuffer.SetData(arrayIndices, 0, LockFlags.None)
mesh.SetAttributeTable(New AttributeRange() {attributeRange})
Return mesh
End Function
Public Shared Sub Main()
Try
Dim Form1 As New Form()
Application.Run(Form1)
Catch e As NotSupportedException
MsgBox("Your device does not have the " + _
"needed 3d support to run this sample")
Catch e As DriverUnsupportedException
MsgBox("Your device does not have the " + _
"needed 3d driver support to run this sample")
Catch e As Exception
MsgBox("The sample has run into an error and " + _
"needs to close: " + e.Message)
End Try
End Sub
End Class
class Form1
{
Form1()
{
// In this example, initialize the Mesh object
// with 4 tessellations
this.InitializeMesh(4);
}
private void InitializeMesh(int tessellation)
{
Mesh mesh1 = CreateHeightfieldMesh(tessellation);
}
private float GetHeight(float x, float y)
{
return 0;
//TODO: fill in this function
}
private Mesh CreateHeightfieldMesh(int tessellation)
{
Mesh mesh;
Device device = null; // TODO: initialize this
short[] arrayIndices = new short[(tessellation - 1) * (tessellation - 1) * 6];
CustomVertex.PositionTextured[] arrayVertices =
new CustomVertex.PositionTextured[tessellation * tessellation];
AttributeRange attributeRange = new AttributeRange();
// Create mesh with desired vertex format and desired size
mesh = new Mesh(arrayIndices.Length / 3, arrayVertices.Length, MeshFlags.SystemMemory,
CustomVertex.PositionTextured.Format, device);
// For each point in the height field calculate the x, y, z and
// texture coordinates.
for (int y = 0; y < tessellation; y++)
{
for (int x = 0; x < tessellation; x++)
{
int arrayIndex = y * tessellation + x;
float xCoordinate = (float)x / (float)(tessellation - 1);
float yCoordinate = (float)y / (float)(tessellation - 1);
CustomVertex.PositionTextured vertex = new CustomVertex.PositionTextured
(xCoordinate, yCoordinate, GetHeight(xCoordinate, yCoordinate), xCoordinate, yCoordinate);
arrayVertices[arrayIndex] = vertex;
}
}
// Calculate the index buffer.
for (int y = 0; y < (tessellation - 1); y++)
{
for (int x = 0; x < (tessellation - 1); x++)
{
int arrayIndex = (y * (tessellation - 1) + x) * 6;
int vertexIndex = y * tessellation + x;
arrayIndices[arrayIndex] = (short)vertexIndex;
arrayIndices[arrayIndex + 1] = (short)(vertexIndex + 1);
arrayIndices[arrayIndex + 2] = (short)(vertexIndex + tessellation);
arrayIndices[arrayIndex + 3] = (short)(vertexIndex + tessellation);
arrayIndices[arrayIndex + 4] = (short)(vertexIndex + 1);
arrayIndices[arrayIndex + 5] = (short)(vertexIndex + tessellation + 1);
}
}
// There is only one attribute value for this mesh.
// By specifying an attribute range the DrawSubset function
// does not have to scan the entire mesh for all faces that are
// are marked with a particular attribute id.
attributeRange.AttributeId = 0;
attributeRange.FaceStart = 0;
attributeRange.FaceCount = arrayIndices.Length / 3;
attributeRange.VertexStart = 0;
attributeRange.VertexCount = arrayVertices.Length;
mesh.VertexBuffer.SetData(arrayVertices, 0, LockFlags.None);
mesh.IndexBuffer.SetData(arrayIndices, 0, LockFlags.None);
mesh.SetAttributeTable(new AttributeRange[] { attributeRange });
return (mesh);
}
public static void Main()
{
try
{
Form Form1 = new Form();
Application.Run(Form1);
}
catch (NotSupportedException)
{
MessageBox.Show("Your device does not have the needed 3d " +
"support to run this sample");
}
catch (DriverUnsupportedException)
{
MessageBox.Show("Your device does not have the needed 3d " +
"driver support to run this sample");
}
catch (Exception e)
{
MessageBox.Show("The sample has run into an error and " +
"needs to close: " + e.Message);
}
}
}
Compilar el código
Para este ejemplo se requieren referencias a los siguientes espacios de nombres:
Vea también
Conceptos
.Temas "Cómo..." de .NET Compact Framework