DirectX 10 - Full object flashes, then draws only points

277 views Asked by At

I am using C# and the SharpDX library to do some rendering on a project that I am working on. However, I am only able to get the object to fully draw on the first pass, each subsequent pass it will only draw points. It doesn't matter if I use FillMode.Solid, or FillMode.Wireframe. I've also disabled culling. If I rotate the camera around the object, I still only see points. I have images displaying the issue and key points in my files. Having looked at this code for the past few days, I am completely out of ideas, and perhaps some fresh eyes will be able to figure it out.

Additionally, it only appears to draw the first triangle, not the second one.

Here are the pictures: Imgur Imgur

Here is my code:

Mesh init

        rCom.mesh = new Components.Mesh3D(this.render.Device,
            new Components.VertexStructures.Color[] {
new Components.VertexStructures.Color(
    new SharpDX.Vector3(-1.0f, -1.0f, 0.0f),  new SharpDX.Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new Components.VertexStructures.Color(
    new SharpDX.Vector3(-1.0f, 1.0f, 0.0f),  new SharpDX.Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new Components.VertexStructures.Color(
    new SharpDX.Vector3(1.0f, 1.0f, 0.0f),  new SharpDX.Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new Components.VertexStructures.Color(
    new SharpDX.Vector3(1.0f, -1.0f, 0.0f),  new SharpDX.Vector4(1.0f, 1.0f, 1.0f, 1.0f))
            },
            new[] {
                0, 1, 2, 0, 2, 3
            }
        );

Vertex structure - color

public static class VertexStructures
{
    ...
    public struct Color
    {
        public SharpDX.Vector3 pos;
        public SharpDX.Vector4 col;
        public static int sizeInBytes
        { get { return Vector3.SizeInBytes + Vector4.SizeInBytes; } }
        public Color(SharpDX.Vector3 pos, SharpDX.Vector4 col)
        { this.pos = pos; this.col = col; }
    }
    ...
}

Mesh Class

public class Mesh3D
{
    private D3D10.Device device;
    public D3D10.VertexBufferBinding vertexBuffer;
    public D3D10.Buffer indexBuffer;
    public int numberOfVertices;
    public int numberOfIndices;

    public static D3D10.Buffer CreateBuffer<T>(D3D10.Device device, BindFlags bindFlags, params T[] items)
        where T : struct
    {
        var len = Utilities.SizeOf(items);
        var stream = new DataStream(len, true, true);
        foreach (var item in items)
            stream.Write(item);
        stream.Position = 0;
        var buffer = new D3D10.Buffer(device, stream, len, ResourceUsage.Default,
            bindFlags, CpuAccessFlags.None, ResourceOptionFlags.None);
        return buffer;
    }
    ...
    public Mesh3D(D3D10.Device device, VertexStructures.Color[] vertices, int[] indices = null)
    {
        this.numberOfVertices = vertices.Length;
        this.numberOfIndices = indices.Length;

        this.vertexBuffer = new VertexBufferBinding(
            CreateBuffer<VertexStructures.Color>(device, BindFlags.VertexBuffer, vertices),
            VertexStructures.Color.sizeInBytes, 0);
        if (indices != null)
            this.indexBuffer = CreateBuffer<int>(device, BindFlags.IndexBuffer, indices);
    }
    ...
}

Render Update Code

    public override void Update(double timeDelta = 0.0f)
    {
        // Clear our backbuffer with the rainbow color
        d3d10Device.ClearRenderTargetView(this.renderTargetView, (Color4)SharpDX.Color.CornflowerBlue);

        float time = (float)(timeDelta / 1000.0f); // time in milliseconds?

        // Do actual drawing here
        foreach (RenderComponent com in this._components)
        {
            // Get any required components
            PositionComponent pos = com.entity.GetComponent<PositionComponent>();

            // Set up required buffers
            var inputAssembler = this.d3d10Device.InputAssembler;
            inputAssembler.SetVertexBuffers(0, com.mesh.vertexBuffer);
            if (com.mesh.indexBuffer != null)
                inputAssembler.SetIndexBuffer(com.mesh.indexBuffer, Format.R32_UInt, 0);

            // Set up effect variables
            // These matrices should always be defined in the shader, even if they're not used
            com.shader.shader.GetVariableByIndex(0).AsMatrix().SetMatrix(this.camera.viewMatrix);
            com.shader.shader.GetVariableByIndex(1).AsMatrix().SetMatrix(this.camera.projectionMatrix);
            com.shader.shader.GetVariableByIndex(2).AsMatrix().SetMatrix(pos.rotationXMatrix);
            com.shader.shader.GetVariableByIndex(3).AsMatrix().SetMatrix(pos.rotationYMatrix);
            com.shader.shader.GetVariableByIndex(4).AsMatrix().SetMatrix(pos.rotationZMatrix);
            com.shader.shader.GetVariableByIndex(5).AsMatrix().SetMatrix(pos.scalingMatrix);
            com.shader.shader.GetVariableByIndex(6).AsMatrix().SetMatrix(pos.translationLocalMatrix);
            com.shader.shader.GetVariableByIndex(7).AsMatrix().SetMatrix(pos.translationWorldMatrix);
            foreach (var shaderVars in com.shader.vars)
            {
                // Eventually, we'll use this to set all the required variables needed
            }

            // Run through each technique, pass, draw
            int i = 0, j = 0;
            foreach (var techniqueContainer in com.shader.inputLayouts)
            {
                var technique = com.shader.shader.GetTechniqueByIndex(i);
                foreach (var passContainer in techniqueContainer)
                {
                    var pass = technique.GetPassByIndex(j);
                    inputAssembler.InputLayout = passContainer;

                    pass.Apply();
                    this.d3d10Device.Draw(com.mesh.numberOfVertices, 0);

                    j += 1;
                }
                i += 1;
            }
        }

        // Present our drawn scene waiting for one vertical sync
        this.swapChain.Present(1, PresentFlags.None);
    }

lastly, my shader file

matrix View;
matrix Projection;

matrix rotationXMatrix;
matrix rotationYMatrix;
matrix rotationZMatrix;
matrix scalingMatrix;
matrix translationLocalMatrix;
matrix translationWorldMatrix;

struct VS_IN
{
    float4 pos : POSITION;
    float4 col : COLOR;
};

struct PS_IN
{
    float4 pos : SV_POSITION;
    float4 col : COLOR;
};

PS_IN VS( VS_IN input )
{
    PS_IN output = (PS_IN)0;

    input.pos = mul(input.pos, rotationXMatrix);
    input.pos = mul(input.pos, rotationYMatrix);
    input.pos = mul(input.pos, rotationZMatrix);

    input.pos = mul(input.pos, scalingMatrix);

    input.pos = mul(input.pos, translationLocalMatrix);
    input.pos = mul(input.pos, translationWorldMatrix);

    input.pos = mul(input.pos, View);
    input.pos = mul(input.pos, Projection);

    output.pos = input.pos;
    output.col = float4(1.0f, 1.0f, 1.0f, 1.0f);//input.col;

    return output;
}

float4 PS( PS_IN input ) : SV_Target
{
    return input.col;
}

technique10 Render
{
    pass P0
    {
        SetGeometryShader( 0 );
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Please let me know if any further information or code is needed. I really hope someone can help me with this, I can't figure it out.

2

There are 2 answers

0
NextInLine On BEST ANSWER

In the code above you don't appear to be setting the topology (triangles vs lines vs points). See for instance MSDN documentation on Primitive Toplogies, as well as the SharpDX documentation on InputAssemblyStage.PrimitiveToplogy and the SharpDX documentation on the PrimitiveTopology enum.

In your Update() method you probably want to add

inputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

You should probably put this before your foreach for performance reasons since it doesn't change.

0
Alex Planida On

You didn't organize your points in a triangle block on update() stage.