Jump to content

  • Log In with Google      Sign In   
  • Create Account

Need a Little Help Drawing Triangle


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 zee_ola05   Members   -  Reputation: 325

Like
0Likes
Like

Posted 25 February 2011 - 10:57 AM

Hi everyone. I'm a little behind the tutorial and I'm having trouble drawing my first triangle.
Here is my code:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace FirstTriangle
{
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class Game1 : Microsoft.Xna.Framework.Game
	{
    	GraphicsDeviceManager graphics;
    	SpriteBatch spriteBatch;

    	//camera
    	Matrix projection;
    	Matrix view;

    	VertexPositionNormalTexture[] vertices;
    	BasicEffect effect;
    	public Game1()
    	{
        	graphics = new GraphicsDeviceManager(this);
        	Content.RootDirectory = "Content";
    	}

    	/// <summary>
    	/// Allows the game to perform any initialization it needs to before starting to run.
    	/// This is where it can query for any required services and load any non-graphic
    	/// related content.  Calling base.Initialize will enumerate through any components
    	/// and initialize them as well.
    	/// </summary>
    	protected override void Initialize()
    	{
        	// TODO: Add your initialization logic here
        	InitializeCamera();
        	InitializeVertices();

        	effect = new BasicEffect(graphics.GraphicsDevice);
        	base.Initialize();
    	}

    	/// <summary>
    	/// LoadContent will be called once per game and is the place to load
    	/// all of your content.
    	/// </summary>
    	protected override void LoadContent()
    	{
        	// Create a new SpriteBatch, which can be used to draw textures.
        	spriteBatch = new SpriteBatch(GraphicsDevice);

        	// TODO: use this.Content to load your game content here
    	}

    	/// <summary>
    	/// UnloadContent will be called once per game and is the place to unload
    	/// all content.
    	/// </summary>
    	protected override void UnloadContent()
    	{
        	// TODO: Unload any non ContentManager content here
    	}

    	/// <summary>
    	/// Allows the game to run logic such as updating the world,
    	/// checking for collisions, gathering input, and playing audio.
    	/// </summary>
    	/// <param name="gameTime">Provides a snapshot of timing values.</param>
    	protected override void Update(GameTime gameTime)
    	{
        	// Allows the game to exit
        	if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            	this.Exit();

        	// TODO: Add your update logic here

        	base.Update(gameTime);
    	}

    	/// <summary>
    	/// This is called when the game should draw itself.
    	/// </summary>
    	/// <param name="gameTime">Provides a snapshot of timing values.</param>
    	protected override void Draw(GameTime gameTime)
    	{
        	GraphicsDevice.Clear(Color.CornflowerBlue);

        	// TODO: Add your drawing code here
        	effect.View = view;
        	effect.Projection = projection;

        	Matrix world = Matrix.Identity;
        	effect.World = world;
        	effect.EnableDefaultLighting();

        	foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        	{
            	pass.Apply();
            	graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 1,
                	VertexPositionNormalTexture.VertexDeclaration);
        	}

        	base.Draw(gameTime);
    	}

    	private void InitializeCamera()
    	{
        	Vector3 cameraPosition = new Vector3(0,0,3);
        	Vector3 cameraTarget = new Vector3(0,0,0);
        	projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, graphics.GraphicsDevice.Viewport.AspectRatio,
            	0.0001f, 1000.0f);

        	view = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
    	}

    	private void InitializeVertices()
    	{
        	Vector3 position;
        	Vector2 textureCoordinate;
        	vertices = new VertexPositionNormalTexture[3];
        	//top left
        	position = new Vector3(-1, 1, 0);
        	textureCoordinate = new Vector2(0, 0);
        	vertices[0] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinate);
        	//bottom left
        	position = new Vector3(-1, -1, 0);
        	textureCoordinate = new Vector2(0, 1);
        	vertices[1] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinate);
        	//bottom right
        	position = new Vector3(1, -1, 0);
        	textureCoordinate = new Vector2(1, 1);
        	vertices[2] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinate);
    	}
	}
}


Can anyone tell me why the triangle isn't being drawn? Thanks! :)

Sponsor:

#2 JWalsh   Moderators   -  Reputation: 463

Like
0Likes
Like

Posted 26 February 2011 - 04:28 PM

Hi Zee,

Whenever you're working with 3D you have to be aware of which side of a triangle you're looking at. The graphics pipeline determines which side of a triangle you're looking at based on the normal vector to the surface, which is computed using the winding order of the triangle. As an optimization, the rendering pipeline does not draw any triangles which are facing away from the camera.

In this case, The GraphiveDevice's Rasterizer State is set by default to cull out (not draw) counter clockwise triangles. As you indicated in your InitializeVertices(), your triangle go from top left, to bottom left, to bottom right - which is counter clockwise! So the renderer thinks you're looking at the backside of the triangle and doesn't draw it.

There are two possible remedies.

#1. Switch the CullMode property to CullClockwiseFace ie:

GraphicsDevice.RasterizerState = new RasterizerState { CullMode = Microsoft.Xna.Framework.Graphics.CullMode.CullClockwiseFace };

#2. Change the winding order of your triangle via ....


//bottom left
position = new Vector3(-1, -1, 0);
textureCoordinate = new Vector2(0, 1);
vertices[1] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinate);


//top left
position = new Vector3(-1, 1, 0);
textureCoordinate = new Vector2(0, 0);
vertices[0] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinate);


//bottom right
position = new Vector3(1, -1, 0);
textureCoordinate = new Vector2(1, 1);
vertices[2] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinate);

The first solution tells the API to treat triangles facing the other direction as back facing, while the second solution actually changes the orientation of the triangle so that it is forward facing. Making sure your triangles are wound correctly can be tricky at first, but once you've got the idea down it's easy enough.

Cheers and Good Luck!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints

#3 zee_ola05   Members   -  Reputation: 325

Like
0Likes
Like

Posted 27 February 2011 - 01:11 AM

Thanks! :)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS