2013-05-29 23 views
1

我看着從一個例子,我從谷歌發現並實現它變成我的遊戲的一些代碼,但問題是,我得到一個錯誤:當前頂點聲明並沒有包括所有由所需的元素當前頂點着色器。位置0缺失。我看過MSDN文檔,我看不到我在做什麼錯繪製索引數據錯誤

class Cube 
{ 
    public GraphicsDevice device; 

    const int number_of_vertices = 8; 
    const int number_of_indices = 36; 

    private VertexBuffer vertices; 
    private IndexBuffer indices; 

    public Cube(GraphicsDevice graphicsDevice) 
    { 
     device = graphicsDevice; 
    } 

    void CreateCubeVertexBuffer() 
    { 
     VertexPositionColor[]cubeVertices = new VertexPositionColor[number_of_vertices]; 

     cubeVertices[0].Position = new Vector3(-1, -1, -1); 
     cubeVertices[1].Position = new Vector3(-1, -1, 1); 
     cubeVertices[2].Position = new Vector3(1, -1, 1); 
     cubeVertices[3].Position = new Vector3(1, -1, -1); 
     cubeVertices[4].Position = new Vector3(-1, 1, -1); 
     cubeVertices[5].Position = new Vector3(-1, 1, 1); 
     cubeVertices[6].Position = new Vector3(1, 1, 1); 
     cubeVertices[7].Position = new Vector3(1, 1, -1); 

     cubeVertices[0].Color = Color.Black; 
     cubeVertices[1].Color = Color.Red; 
     cubeVertices[2].Color = Color.Yellow; 
     cubeVertices[3].Color = Color.Green; 
     cubeVertices[4].Color = Color.Blue; 
     cubeVertices[5].Color = Color.Magenta; 
     cubeVertices[6].Color = Color.White; 
     cubeVertices[7].Color = Color.Cyan; 

     vertices = new VertexBuffer(device, VertexPositionColor.VertexDeclaration, number_of_vertices, BufferUsage.WriteOnly); 
     vertices.SetData <VertexPositionColor> (cubeVertices); 
    } 

    void CreateCubeIndexBuffer() { 
    UInt16[]cubeIndices = new UInt16[number_of_indices]; 

    //bottom face 
    cubeIndices[0] = 0; 
    cubeIndices[1] = 2; 
    cubeIndices[2] = 3; 
    cubeIndices[3] = 0; 
    cubeIndices[4] = 1; 
    cubeIndices[5] = 2; 

    //top face 
    cubeIndices[6] = 4; 
    cubeIndices[7] = 6; 
    cubeIndices[8] = 5; 
    cubeIndices[9] = 4; 
    cubeIndices[10] = 7; 
    cubeIndices[11] = 6; 

    //front face 
    cubeIndices[12] = 5; 
    cubeIndices[13] = 2; 
    cubeIndices[14] = 1; 
    cubeIndices[15] = 5; 
    cubeIndices[16] = 6; 
    cubeIndices[17] = 2; 

    //back face 
    cubeIndices[18] = 0; 
    cubeIndices[19] = 7; 
    cubeIndices[20] = 4; 
    cubeIndices[21] = 0; 
    cubeIndices[22] = 3; 
    cubeIndices[23] = 7; 

    //left face 
    cubeIndices[24] = 0; 
    cubeIndices[25] = 4; 
    cubeIndices[26] = 1; 
    cubeIndices[27] = 1; 
    cubeIndices[28] = 4; 
    cubeIndices[29] = 5; 

    //right face 
    cubeIndices[30] = 2; 
    cubeIndices[31] = 6; 
    cubeIndices[32] = 3; 
    cubeIndices[33] = 3; 
    cubeIndices[34] = 6; 
    cubeIndices[35] = 7; 

    indices = new IndexBuffer(device, IndexElementSize.SixteenBits, number_of_indices, BufferUsage.WriteOnly); 
    indices.SetData <UInt16> (cubeIndices); 

    } 

    public void Draw(BasicEffect effect) 
    { 
     device.SetVertexBuffer(vertices); 
     device.Indices = indices; 

     foreach(EffectPass pass in effect.CurrentTechnique.Passes) 
     { 
      pass.Apply(); 
      device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, number_of_vertices, 0, number_of_indices/3); 
     } 
    } 
} 

編輯:

public override void Draw(GameTime gameTime) 
{ 
    cube.CreateCubeIndexBuffer(); 
    cube.CreateCubeVertexBuffer(); 

    foreach (var item in entities) 
    { 
     effect.VertexColorEnabled = false; 
     effect.TextureEnabled = true; 
     effect.Texture = item.Texture; 

     Matrix center = Matrix.CreateTranslation(new Vector3(-0.5f, -0.5f, -0.5f)); 
     Matrix scale = Matrix.CreateScale(1f); 
     Matrix translate = Matrix.CreateTranslation(item.Position); 

     effect.World = center * scale * translate; 
     effect.View = camera.View; 
     effect.Projection = camera.Projection; 

     cube.Draw(effect); 
    } 

    base.Draw(gameTime); 
} 

這工作,但慢FPS。

構造:

public Cube(GraphicsDevice graphicsDevice) 
{ 
    device = graphicsDevice; 
    CreateCubeIndexBuffer(); 
    CreateCubeVertexBuffer(); 
} 

protected override void LoadContent() 
{ 
    // Create a new SpriteBatch, which can be used to draw textures. 
    spriteBatch = new SpriteBatch(GraphicsDevice); 
    font = Content.Load<SpriteFont>("font"); 
    grass = Content.Load<Texture2D>("grass"); 

    // TODO: use this.Content to load your game content here 
    Components.Add(cubes); 
    cube.CreateCubeIndexBuffer(); 
    cube.CreateCubeVertexBuffer(); 

    for (int x = 0; x < 50; x++) 
    { 
     for (int z = 0; z < 50; z++) 
     { 
      cubes.Add(new Vector3(mapX[x], 0f, mapZ[z]), Matrix.Identity, grass); 
     } 
    } 
} 

這是我主要的遊戲類。這不工作,給了我沒有設置爲指向我的立方體類線的對象錯誤的實例的對象引用:

indices = new IndexBuffer(device, IndexElementSize.SixteenBits, number_of_indices, BufferUsage.WriteOnly); 
+0

另外請注意,我從另一個類調用這個方法抽籤,然後調用的類在我的主遊戲類繪製方法 –

+0

當前的頂點聲明並沒有包括所有當前頂點着色器所需的元素。這是着色器錯誤。編寫自己的着色器是最簡單的。但是,如果您使用BasicEffect並使用顏色繪製,則需要設置基本效果以禁用Texture並啓用VertexColor。 effect.TextureEnabled = false; effect.VertexColorEnabled = true;此外,您可以在傳遞效果後嘗試使用DrawIndexPrimitives,如果這樣做。 – Deukalion

+0

的BasicEffect方法調用另一個類繪製方法這是問題... –

回答

1

這裏是代碼爲我渲染對象立方添加作爲它的一個對象和我自己的立方體的實現。

XNA RenderObject with 2 types of Cubes

這是我測試的遊戲本作的執行情況。

你可以簡單的改變defaultCube =假,嘗試用你的。但是你應該把它調整到0.5,因爲它應該是x start = -0.5f,x end = 0.5f,它的大小等於1。您可以輕鬆地改變世界範圍。

Test game for XNA RenderObject

由於沒有上述工程的,或者因爲它可能是別的東西在你的代碼是阻礙性能我做了,我已經用於早期發動機的例子。

要minimalize每個對象我簡單地創建一個抽象類,可以處理幾乎任何類型的頂點的數據量,這樣你就可以創建一個顏色立方體,立方體正常,紋理立方體等。

首先我有所有由一個對象所需的字段存儲要渲染的渲染對象; VertexBuffer,IndexBuffer,世界矩陣,BoundingBox。

然後我創建處理每種類型,普通,顏色,紋理特定的類。在這種情況下,我只包含了一個PrimitiveColor的版本,它創建了一個Color渲染對象。

您甚至可以進一步擴展它來代替PrimitiveColor類,它可以是隻接受類型(Color/Normal/Texture)的Cube類,並且可以最小化用於創建不同類型多維數據集的代碼,因爲在這種情況下,立方體將始終是具有36個頂點和6個面的立方體。它是靜態的。

無論如何,這不是必需的。但是,像任何遊戲編程或面向對象編程一樣,一個好的結構很重要,並且會增加工作流程。重新創建100個類的相同屬性並不是那麼有趣。這使得調試和查找錯誤變得更加容易。

因此,要簡化:渲染對象 - > PrimitiveColor/PrimitiveNormal - > ColorCube/ColorNormal,然後你可以與多維數據集,而不是其他的工作。

我不知道,如果您呈現「一」多維數據集或一千立方體。但在我的情況下,我提供了50 * 50的立方體,並且我必須使用平截頭體來在相機視野內剔除立方體才能降低性能。如果你這樣做,但它仍然無法正常工作,那麼錯誤可能在於另一個代碼。

我認爲這是處理這個最佳的方式。因爲每個渲染對象都共享一個緩衝區,一個矩陣和一個渲染方法(並不總是必需的),這樣你只能處理重要的代碼 - 創建多維數據集。它不會重新創建任何效果,它在初始化後不會重新創建任何緩衝區(儘管它們可以在更新方法中相當快地進行更改 - 我已經使用地形來完成此操作,只記得在更改之前更改舊的vertexbuffer說,在頂點的顏色,然後重新創建緩衝區)

我的魔方,正確縮放。添加白色,黑色,白色,黑色立方體以查看它們的開始和結束位置。 enter image description here

你的立方體,按比例不正確。添加您的默認顏色。 enter image description here

但重要的是,在跳過截錐體剔除立方體之前,幀率不會出錯。如果你不這樣做,它會導致framedrop。但是如果你只畫一個立方體,這不應該發生。

+0

我認爲它可能只是我的電腦,因爲我正在剔除40fps左右。否則,它工作正常 –

+0

您還可以爲每個頂點緩衝區添加一百個立方體,這也會增加拉制速度。但這可能是爲了渲染遠離立方體。只需將一個多維數據集添加到具有IVertexType且位置爲關鍵字的Dictionary中,如果在創建新多維數據集時Position退出,則將其添加到索引中。如果你只是想繪製立方體並與最近的相互作用,這可能是一個好主意,並在稍後繪製它們。如果他們有質感,可能會更困難。 – Deukalion

+0

正如我前面所說,如果它發生在剔除或您只是繪製一個立方體,它不是您的計算機,它可能是您的代碼中的其他東西。繪製一個立方體不需要任何東西,因此任何計算機都應該能夠繪製出一個沒有任何問題或framedrop。因此,請檢查您的代碼或使用某種工具來檢查大部分工作的完成情況,以便能夠確定framedrop的來源。 – Deukalion