2012-04-11 9 views
2

Ich mache gerade eine Methode, um in einer lauten Heightmap zu laden, aber die Dreiecke dazu fehlen. Ich möchte einen Algorithmus machen, der ein Bild, seine Breite und Höhe aufnimmt und daraus einen Geländeknoten konstruiert.Eine Methode zum Indizieren von Dreiecken aus einer geladenen Heightmap?

Hier ist, was ich bisher, pseudo in etwas

Vertex* vertices = new Vertices[image.width * image.height]; 
Index* indices; // How do I judge how many indices I will have? 
float scaleX = 1/image.width; 
float scaleY = 1/image.height; 
float currentYScale = 0; 

for(int y = 0; y < image.height; ++y) { 
    float currentXScale = 0; 
    for (int x = 0; x < image.width; ++x) { 
     Vertex* v = vertices[x * y]; 
     v.x = currentXScale; 
     v.y = currentYScale; 
     v.z = image[x,y]; 
     currentXScale += scaleX; 
    } 
    currentYScale += scaleY; 
} 

Das auf meine Bedürfnisse gut genug funktioniert, mein einziges Problem ist folgendes: Wie würde ich die Anzahl der Indizes und ihre Positionen zum Zeichnen der Dreiecke berechnen ? Ich bin mit Indizes etwas vertraut, aber nicht wie man sie programmatisch berechnet, ich kann das nur statisch machen.

Antwort

4

Soweit Ihr Code oben geht, ist die Verwendung vertices[x * y] nicht richtig - wenn Sie das verwenden, dann z. vert(2,3) == vert(3,2). Was Sie wollen, ist etwas wie vertices[y * image.width + x], aber Sie können es effizienter machen, indem Sie einen Zähler inkrementieren (siehe unten).

Hier ist der entsprechende Code, den ich verwende. Es ist in C# leider, aber hoffentlich sollte es den Punkt illustrieren:

/// <summary> 
/// Constructs the vertex and index buffers for the terrain (for use when rendering the terrain). 
/// </summary> 
private void ConstructBuffers() 
{ 
    int heightmapHeight = Heightmap.GetLength(0); 
    int heightmapWidth = Heightmap.GetLength(1); 
    int gridHeight = heightmapHeight - 1; 
    int gridWidth = heightmapWidth - 1; 

    // Construct the individual vertices for the terrain. 
    var vertices = new VertexPositionTexture[heightmapHeight * heightmapWidth]; 

    int vertIndex = 0; 
    for(int y = 0; y < heightmapHeight; ++y) 
    { 
     for(int x = 0; x < heightmapWidth; ++x) 
     { 
      var position = new Vector3(x, y, Heightmap[y,x]); 
      var texCoords = new Vector2(x * 2f/heightmapWidth, y * 2f/heightmapHeight); 
      vertices[vertIndex++] = new VertexPositionTexture(position, texCoords); 
     } 
    } 

    // Create the vertex buffer and fill it with the constructed vertices. 
    this.VertexBuffer = new VertexBuffer(Renderer.GraphicsDevice, typeof(VertexPositionTexture), vertices.Length, BufferUsage.WriteOnly); 
    this.VertexBuffer.SetData(vertices); 

    // Construct the index array. 
    var indices = new short[gridHeight * gridWidth * 6]; // 2 triangles per grid square x 3 vertices per triangle 

    int indicesIndex = 0; 
    for(int y = 0; y < gridHeight; ++y) 
    { 
     for(int x = 0; x < gridWidth; ++x) 
     { 
      int start = y * heightmapWidth + x; 
      indices[indicesIndex++] = (short)start; 
      indices[indicesIndex++] = (short)(start + 1); 
      indices[indicesIndex++] = (short)(start + heightmapWidth); 
      indices[indicesIndex++] = (short)(start + 1); 
      indices[indicesIndex++] = (short)(start + 1 + heightmapWidth); 
      indices[indicesIndex++] = (short)(start + heightmapWidth); 
     } 
    } 

    // Create the index buffer. 
    this.IndexBuffer = new IndexBuffer(Renderer.GraphicsDevice, typeof(short), indices.Length, BufferUsage.WriteOnly); 
    this.IndexBuffer.SetData(indices); 
} 

ich der entscheidende Punkt erraten ist, dass ein heightmap der Größe gegeben heightmapHeight * heightmapWidth Sie (heightmapHeight - 1) * (heightmapWidth - 1) * 6 Indizes benötigen, da Sie zeichnen:

  • 2 Dreiecken pro Planquadrat
  • 3 Eckpunkte pro Dreieck
  • (heightmapHeight - 1) * (heightmapWidth - 1) Rasterquadrate in Ihrem Gelände.
+1

Mann, ich muss wirklich mein Spiel steigern. Ich hätte nie darüber nachgedacht. Danke Kumpel, das ist was ich brauchte. – DubyaDubyaDubyaDot

+0

Hat jemand versucht, Normale hinzuzufügen? Ich kann nicht scheinen, sie richtig zu machen – TiagoLing

Verwandte Themen