Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Need a Little Help Drawing Triangle

Started by zee_ola05 Feb 25, 2011 at 4:57 PM 1 replies 4.3k views
Original Post
zee_ola05
zee_ola05
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!
JWalsh
JWalsh
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!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.