[SOLVED] Backface Culling, ON, Vertex Primitives or Rotation - Help

Hello :slight_smile:

So just playing about to get a 3D camera going and I hit a snag, I want to enable err… disable back face culling, but err I don’t think my thing is using two faces anyway… the tutorial I am following is using Vertices so err, new concepts for me… a bit…

Since renderstate is switched to Rasterizer… [XNA used Renderstate, looked up the Docs here to find the changes]

    protected override void Initialize()
    {
        RasterizerState rs = new RasterizerState();
        rs.CullMode = CullMode.None;
        base.Initialize();
    }

Which, does not work, but again this is just me having a quick go and just trying to see two faces on that thing if it is easy… but vertices is not a strong point for me here, I am more used to creating a model and texturing it…

Anyway, if there is a way to draw two faces on this thing with a simple fix, please do let me know :slight_smile:

My Struct:

    // Vertex data
    VertexPositionTexture[] verts;

``

My verts: [LoadContent()]

        // Initialize vertices
        verts = new VertexPositionTexture[4];
        verts[0] = new VertexPositionTexture(
            new Vector3(-1, 1, 0), new Vector2(0, 0));
        verts[1] = new VertexPositionTexture(
            new Vector3(1, 1, 0), new Vector2(1, 0));
        verts[2] = new VertexPositionTexture(
            new Vector3(-1, -1, 0), new Vector2(0, 1));
        verts[3] = new VertexPositionTexture(
            new Vector3(1, -1, 0), new Vector2(1, 1));

        // Set vertex data in VertexBuffer
        vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), verts.Length, BufferUsage.None);
        vertexBuffer.SetData(verts);

        // Initialize the BasicEffect
        effect = new BasicEffect(GraphicsDevice);

        // Load texture
        texture = Content.Load<Texture2D>("Trees");

And my Draw():

    // Set the vertex buffer on the GraphicsDevice
    GraphicsDevice.SetVertexBuffer(vertexBuffer);

    //Set object and camera info
    effect.World = worldRotation * worldTranslation * worldRotation;
    effect.View = camera.view;
    effect.Projection = camera.projection;
    effect.Texture = texture;
    effect.TextureEnabled = true;
    
    // Begin effect and draw for each pass
    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
    {
        pass.Apply();

        GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>
            (PrimitiveType.TriangleStrip, verts, 0, 2);

    }

I should probably add, this is using the GameComponent class… something I am still new to.

I was thinking to just duplicate the verts data and create a mirrored version offset from where the existing one is… but pretty sure I will mess it up, so just seeing if there is a snappy method someone may know.

Thanks.

Before posting this I tried creating another struct called vertsa and essentially:

        vertsa = new VertexPositionTexture[4];
        vertsa[0] = new VertexPositionTexture(
            new Vector3(-2, 2, 1), new Vector2(0, 0));
        vertsa[1] = new VertexPositionTexture(
            new Vector3(2, 2, 1), new Vector2(2, 0));
        vertsa[2] = new VertexPositionTexture(
            new Vector3(-2, -2, 1), new Vector2(0, 1));
        vertsa[3] = new VertexPositionTexture(
            new Vector3(2, -2, 1), new Vector2(1, 1));

But, I am still lost as to how to turn this thing around… note that I intentionally made it twice the size… I just want to rotate it by 180 on the y axis…

I suspect the effect bit to be involved in rotating it but, unsure right now as it is just past 05:00 now

Anyone know how I rotate it?

EDIT

A temporary measure, but yet again I suffer the facing issue…

        vertsa = new VertexPositionTexture[4];
        vertsa[0] = new VertexPositionTexture(
            new Vector3(-1, 1, 1), new Vector2(1, 1));
        vertsa[1] = new VertexPositionTexture(
            new Vector3(1, 1, 1), new Vector2(0, 1));
        vertsa[2] = new VertexPositionTexture(
            new Vector3(-1, 1, -1), new Vector2(1, 0));
        vertsa[3] = new VertexPositionTexture(
            new Vector3(1, 1, -1), new Vector2(0, 0));

Which results in:

When do you use the rs member ? it is only defined in the initialize method.
You have to declare it as a class member.
Then in your update, or as soon as you have access to the GraphicsDevice, use RS to set the culling mode.
If I remembemr well:

GraphicsDevice.RasterizerState = rs;

If you need to go back to default after this draw:

RasterizerState originalState = GraphicsDevice.RasterizerState;
     
RasterizerState rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
     
// Do your wireframe drawing here...
     
GraphicsDevice.RasterizerState = originalState;

But I’m not sure you will get the double sided effect.
A simple manner to achive this is to double your geometry and drow another quad pointing to the opposite of the current one’s normal.

Concerning the problem of textures coordinates, it is more complicated to solve, there is no simple method to solve this.

2 Likes

That’s the thing, I cannot figure out how to point the quad…

EDIT

I basically have:

    // Game camera
    Camera camera;

    // Vertex data
    VertexPositionTexture[] verts;
    VertexPositionTexture[] vertsa;
    VertexBuffer vertexBuffer;

    // Effect
    BasicEffect effect;

    // Movement and rotation stuff
    Matrix worldTranslation = Matrix.Identity;
    Matrix worldRotation = Matrix.Identity;

    // Texture info
    Texture2D texture;

@Alkher you nailed it… Thank you!

I made this field as you said and I set it to what I believe to be the default cull mode of CCW as it was the effect I was getting: [For any beginners, this is declared just before where you find public Game1() in your code in Game1.cs.]

    private RasterizerState rs = RasterizerState.CullCounterClockwise;

And then I modified vertsa to be in a more appropriate position so we can see its back face to see the effects…

        vertsa = new VertexPositionTexture[4];
        vertsa[0] = new VertexPositionTexture(
            new Vector3(-1, -1, 1), new Vector2(1, 1));
        vertsa[1] = new VertexPositionTexture(
            new Vector3(1, -1, 1), new Vector2(0, 1));
        vertsa[2] = new VertexPositionTexture(
            new Vector3(-1, -1, -1), new Vector2(1, 0));
        vertsa[3] = new VertexPositionTexture(
            new Vector3(1, -1, -1), new Vector2(0, 0));

And then as you said inside Update():

        GraphicsDevice.RasterizerState = rs;

And then at the top of Draw() just after the usual placement of CornflowerBlue as per your suggestion:

            // Grab the original state of the rasterozer [previously renderstate if coming from XNA]
            RasterizerState originalState = GraphicsDevice.RasterizerState;
            
            // I guess this is creating a new rasterizer [or renderstate for XNA]
            RasterizerState rasterizerState = new RasterizerState();
            
            // Set the new cull mode
            rasterizerState.CullMode = CullMode.None;

            // I guess this sets the changes
            GraphicsDevice.RasterizerState = rasterizerState;

And now to the test code…

My block: [Inside Draw() after the effect code]

        // Begin effect and draw for each pass
        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Apply();

            GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>
                (PrimitiveType.TriangleStrip, verts, 0, 2);
            
            GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>
                (PrimitiveType.TriangleStrip, vertsa, 0, 2);
        }

Where the verts are drawn, if I place:

        GraphicsDevice.RasterizerState = originalState;

Before vertsa is drawn, you cannot see it, however if it is placed after it, it reappears.

And I made a final video for you all…

Thank you once again.

Thank you for this one, bookmarked your post for future reference!

Please note this code does not include the 3D camera class, you can find it in the book: Learning XNA 4.0: Game Development for the PC, Xbox 360, and Windows Phone 7 - In Chapter 9 :wink: and as you might have noticed, some code changes did occur such as Renderstate now being Rasterizer… this is going to be an interesting adventure.

[Side note, had to write this post twice because it did not automagically save :frowning:]

You can set states directly to the graphics device but xna allowed you to predefine states to save repetitive typing and reinitizing these states.
For the rasterstate you might define a state like myrasterstate_no_cull or rs_wireframe , ccw cw nocull pertains to vertice winding order of triangles clockwise or counterclockwise. To say if vertices a b c is calculated or c b a to find a surface normals direction for
“backface triangle occlusion culling”.
One important thing to note I forgot to say is that all the triangles you build yourself should wind in the same direction either clockwise or counterclockwise.

1 Like