Ciao a tutti.
Ho creato un game 3D che disegna un cubo (vedi figura) in cui ogni faccia è costruita con 2 primitive (triangoli)
Questo è il mio shader:codice:using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace Modello3D { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; Matrix view, projection; Effect shader; VertexPositionColor[] vertices = new VertexPositionColor[8]; int[] indices = new int[36]; Vector3 view_pos = new Vector3(10, 10, 100); Vector3 view_pun = Vector3.Zero; Vector3 view_up = Vector3.Up; KeyboardState k; MouseState m, pre; VertexBuffer vBuf; IndexBuffer iBuf; public void KeybInput() { k = Keyboard.GetState(); if (k.IsKeyDown(Keys.Escape)) { }//Exit else if (k.IsKeyDown(Keys.Right)) { } //Freccia a destra else if (k.IsKeyDown(Keys.Left)) { } //Freccia a sinistra else if (k.IsKeyDown(Keys.Up)) view_pos -= Vector3.UnitZ; else if (k.IsKeyDown(Keys.Down)) view_pos += Vector3.UnitZ; } public void MouseInput() { m = Mouse.GetState(); if (pre.X != m.X) { } // if (pre.Y != m.Y) { } // pre = Mouse.GetState(); } public void Set_Buffers() { vBuf = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly); iBuf = new IndexBuffer(GraphicsDevice, typeof(System.Int32), indices.Length, BufferUsage.WriteOnly); GraphicsDevice.SetVertexBuffer(vBuf); GraphicsDevice.Indices = iBuf; } public void Set_Vertices() { vertices[0] = new VertexPositionColor(new Vector3(0, 0, 0), Color.White); vertices[1] = new VertexPositionColor(new Vector3(5, 0, 0), Color.White); vertices[2] = new VertexPositionColor(new Vector3(5, 0, -5), Color.White); vertices[3] = new VertexPositionColor(new Vector3(0, 0, -5), Color.White); vertices[4] = new VertexPositionColor(new Vector3(0, 5, 0), Color.White); vertices[5] = new VertexPositionColor(new Vector3(5, 5, 0), Color.White); vertices[6] = new VertexPositionColor(new Vector3(5, 5, -5), Color.White); vertices[7] = new VertexPositionColor(new Vector3(0, 5, -5), Color.White); } public void Set_Indices() { indices[0] = 0; indices[1] = 4; indices[2] = 1; indices[3] = 4; indices[4] = 5; indices[5] = 1; indices[6] = 1; indices[7] = 5; indices[8] = 2; indices[9] = 5; indices[10] = 6; indices[11] = 2; indices[12] = 2; indices[13] = 6; indices[14] = 3; indices[15] = 6; indices[16] = 7; indices[17] = 3; indices[18] = 7; indices[19] = 4; indices[20] = 3; indices[21] = 3; indices[22] = 4; indices[23] = 0; indices[24] = 4; indices[25] = 7; indices[26] = 5; indices[27] = 7; indices[28] = 6; indices[29] = 5; indices[30] = 1; indices[31] = 2; indices[32] = 3; indices[33] = 3; indices[34] = 0; indices[35] = 1; } public void Raster_State() { //dobbiamo istanziare questa classe se vogliamo disegnare //primitive senza riempimento di colore RasterizerState rs = new RasterizerState(); rs.FillMode = FillMode.WireFrame; //Alternativa: .Solid rs.CullMode = CullMode.CullCounterClockwiseFace; GraphicsDevice.RasterizerState = rs; } public Game1() { graphics = new GraphicsDeviceManager(this); graphics.PreferredBackBufferWidth = 1000; graphics.PreferredBackBufferHeight = 500; Content.RootDirectory = "Content"; } protected override void Initialize() { Raster_State(); Set_Buffers(); Set_Vertices(); Set_Indices(); base.Initialize(); } protected override void LoadContent() { shader = Content.Load<Effect>("MyShader"); projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.Pi / 3, this.GraphicsDevice.Viewport.AspectRatio, 0.1f, 500); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { KeybInput(); view = Matrix.CreateLookAt(view_pos, view_pun, view_up); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.Black); shader.Parameters["World"].SetValue(Matrix.Identity); shader.Parameters["View"].SetValue(view); shader.Parameters["Projection"].SetValue(projection); shader.CurrentTechnique.Passes[0].Apply(); GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3); //base.Draw(gameTime); } } }
Volevo evitare le diagonali delle facce ed ho pensato di usare come primitive le linee che formano i lati del cubo. Ho sostituito gli indices con questicodice:float4x4 World; float4x4 View; float4x4 Projection; struct VertexShaderInput { float4 Position : POSITION0; float4 Color : COLOR; }; struct VertexShaderOutput { float4 Position : POSITION0; float4 Color : COLOR; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; float4 worldPosition = mul(input.Position, World); float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); output.Color = input.Color; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { return input.Color; } technique Technique1 { pass Pass1 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } }
e al posto di PrimitiveType.TriangleList uso questa rigacodice://Faccia inferiore indices[0] = 0; indices[1] = 1; indices[2] = 1; indices[3] = 2; indices[4] = 2; indices[5] = 3; indices[6] = 3; indices[7] = 0; //Faccia superiore indices[8] = 4; indices[9] = 5; indices[10] = 5; indices[11] = 6; indices[12] = 6; indices[13] = 7; indices[14] = 7; indices[15] = 4; //Facce laterali indices[16] = 0; indices[17] = 4; indices[18] = 1; indices[19] = 5; indices[20] = 2; indices[21] = 6; indices[22] = 3; indices[23] = 7;
Il risultato è che mi disegna TUTTI i lati, anche quelli che dovrebbero essere nascosti! E non c'è CullMode che tenga. D'altra parte non sono ammesse primitive oltre le linee e i triangoli (o si?) Come devo fare?codice:GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, vertices, 0, vertices.Length, indices, 0, indices.Length / 2);
Grazie e scusate per questo mattone.

Rispondi quotando