Lors de ma session aux TechDays 2008, j'ai animé une session sur DirectX10 et .Net.

Or, lors d'une démo j'ai écris le code nécessaire à l'affichage d'un triangle 2D rouge sur un fond bleu.

Sauf que la démo a surtout affiché le fond bleu :).

La raison était toute simple : j'avais oublié de définir le viewport!!!

Les pixels étaient envoyés à l'écran entre (-1.0, -1.0) et (1.0, 1.0). Voila tout!!

Grâce au viewport, ils seront envoyés entre (0, 0) et (1024, 768).

Le code final donne donc ça (le projet complet est dispo ici) :

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SlimDX.Direct3D10;
using SlimDX;
using SlimDX.Direct3D;
using System.IO;

public partial class Form1 : Form
{
    Device device;
    SwapChain swapChain;
    RenderTargetView view;
    SlimDX.Direct3D10.Buffer vertexBuffer;
    Effect effect;
    EffectTechnique technique;
    EffectPass pass;
    InputLayout layout;
    Viewport viewport = new Viewport();
    RasterizerState state;


    public Form1()
    {
        InitializeComponent();
    }

    private void cmdInitDevice_Click(object sender, EventArgs e)
    {
        // Device
        device = new Device(DriverType.Hardware, DeviceCreationFlags.Debug);

        CreateSwapChain();

        // Effect
        string err;
        effect = Effect.FromFile(device, "MyEffect.fx", "fx_4_0", out err);
        technique = effect.GetTechniqueByIndex(0);
        pass = technique.GetPassByIndex(0);


        InputElement[] elements = new InputElement[]
        {
            new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, 
                InputClassification.PerVertexData, 0),
        };

        layout = new InputLayout(device, elements, pass.Signature);
    }

    private void CreateSwapChain()
    {
        if (swapChain != null)
        {
            swapChain.Dispose();
            swapChain = null;
        }

        // Swap chain
        SwapChainDescription description = new SwapChainDescription();

        description.BufferCount = 1;
        description.Flags = SwapChainFlags.None;
        description.Format = Format.R8G8B8A8_UNorm;
        description.Height = panel1.Height;
        description.Width = panel1.Width;
        description.Windowed = true;
        description.RefreshRate = new Rational(60, 1);
        description.SampleCount = 1;
        description.SampleQuality = 0;
        description.Scaling = DisplayModeScaling.Unspecified;
        description.ScanlineOrdering = DisplayModeScanlineOrdering.Unspecified;
        description.Usage = SurfaceUsage.RenderTargetOutput;
        description.SwapEffect = SwapEffect.Discard;
        description.OutputHandle = panel1.Handle;

        swapChain = new SwapChain(device, description);

        using (Texture2D backBuffer = swapChain.GetBuffer(0))
        {
            view = new RenderTargetView(device, backBuffer);
            device.OutputMerger.SetTargets(view);
        }

        // Viewport
        viewport.X = panel1.ClientRectangle.Left;
        viewport.Y = panel1.ClientRectangle.Top;
        viewport.Width = panel1.ClientSize.Width;
        viewport.Height = panel1.ClientSize.Height;
        viewport.MinZ = 0.0f;
        viewport.MaxZ = 1.0f;

        device.Rasterizer.SetViewports(viewport);

        // States
        RasterizerStateDescription desc = new RasterizerStateDescription();
        desc.CullMode = CullMode.None;
        state = new RasterizerState(device, desc);
    }

    internal void Render()
    {
        if (view != null)
        {
            view.Clear(new SlimDX.Direct3D.ColorValue(0, 0, 1.0f));

            if (vertexBuffer != null)
            {
                device.InputAssembler.SetInputLayout(layout);
                device.InputAssembler.SetPrimitiveTopology(
PrimitiveTopology.TriangleList); device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, 3 * sizeof(float), 0)); // States device.Rasterizer.State = state; // Render for (int index = 0; index < technique.PassCount; index++) { technique.GetPassByIndex(index).Apply(); device.Draw(3, 0); } } swapChain.Present(0, 0); } } private void cmdCreateGeometry_Click(object sender, EventArgs e) { // Vertex Buffer DataStream data = new DataStream(sizeof(float) * 9, false, true); data.Write(-1.0f); data.Write(0.0f); data.Write(0); data.Write(0.0f); data.Write(1.0f); data.Write(0); data.Write(1.0f); data.Write(0.0f); data.Write(0); data.Seek(0, System.IO.SeekOrigin.Begin); vertexBuffer = new SlimDX.Direct3D10.Buffer(device, sizeof(float) * 9 , data, ResourceUsage.Immutable, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None); } private void panel1_Resize(object sender, EventArgs e) { CreateSwapChain(); } }