Практическое руководство. Создание сетки
Обновлен: Ноябрь 2007
Сетку можно создать четырьмя способами:
Загрузкой данных сетки из файла.
Копированием или оптимизацией существующей сетки.
С помощью функции создания фигуры и определением размера и числа треугольников, которые будут использоваться для создания фигуры.
С помощью конструктора Mesh.
![]() |
---|
Управляемым мобильным приложениям Direct3D требуется программа Windows Mobile версии 5.0 для карманных ПК и смартфонов. Сведения о программе Windows Mobile и пакетах SDK см. в разделе Внешние ресурсы для платформы .NET Compact Framework. |
Чтобы создать сетку из файла
- Загрузите данные сетки из файла и затем заполните сетку этими данными. Платформа .NET Compact Framework не поддерживает непосредственную загрузку сетки из файла, но в документе Direct3D Mobile Meshes Sample определен класс для загрузки сетки.
Чтобы создать сетку из существующей сетки
Используйте метод Optimize для создания новой сетки с оптимизированными данными.
—или—
Используйте метод OptimizeInPlace для оптимизации текущей сетки.
Копирование в основном используется для преобразования сетки из формата с плавающей запятой в формат с фиксированной запятой. Оптимизация в основном используется для создания сетки, позволяющей более быстро выполнять рисование. Оптимизация переупорядочивает треугольники таким образом, что можно быстрее размещать рисунок в сетке. Оптимизация сетки также создает таблицу атрибутов, которые используются для идентификации областей сетки, которые нужно отобразить с помощью разных текстур, состояний пространства прорисовки и материалов.
Чтобы создать сетку с помощью функции создания фигуры
Используйте один из следующих статических методов класса Mesh для создания сетки с использованием позиций и нормалей, указанных в вычислениях с плавающей запятой:
Чтобы создать сетку с помощью конструктора сетки
Вызовите конструктор Mesh с требуемыми аргументами.
Задайте буфер индексов, Буфер вершин и данные таблицы атрибутов. В этом случае, данные часто генерируются во время выполнения. В следующем примере показаны шаги для создания сетки таким образом.
Пример
В следующем примере кода создается сетка heightfield на x-y плоскости с z-координатой, представляющей измерение по вертикали. Отдельная созданная сетка имеет координаты от (0, 0) до (1, 1) и высоту, указанную методом GetHeight. Эта сетка также вся содержит одну текстуру. Параметр tessellation, определенный в этом примере, управляет количеством используемых точек вдоль края сетки.
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);
}
}
}
Компиляция кода
Для этого примера требуются ссылки на следующие пространства имен:
См. также
Основные понятия
Разделы руководства по платформе .NET Compact Framework
Другие ресурсы
Мобильное программирование Direct3D в .NET Compact Framework