正确渲染重叠的三角形?

时间:2013-02-06 11:06:30

标签: c# direct3d directx-9 directdraw

我开始在C#中学习DirectX 9。我想渲染两个三角形并围绕Y轴旋转它们。

在这部分中,我初始化设备:

public bool InitializeDevice()
{
    try
    {
        meshList = new List<Sphere>();

        // Erstellt die PresentParameters für weitere Einstellungen des Device
        PresentParameters presParams = new PresentParameters() {
            Windowed = true,                // Device nur innerhalbe des Fensterhandels benutzen
            SwapEffect = SwapEffect.Discard, // Grafikkarte entscheidet selbst wie sie den Backbuffer zur anzeige bringt
        };

        // Erzeugt eine Instanz von dem Device
        device = new Device(0,                                      // Nummer fuer den Grafikadapter der verwendet wird                  
                            DeviceType.Hardware,                    // Parameter über die Garfikkarte oder CPU ausführen
                            Panel_3D,                               // Fensterhadel für das Device 
                            CreateFlags.SoftwareVertexProcessing,   // Einstellung des Device. Gibt an, dass die Vertices nur per Software verarbeitet werden 
                            presParams);                            // Gibt die weiteren Einstellungen mit

        // Wenn das Device neupositioniert wird
        device.DeviceReset += new System.EventHandler(this.OnResetDevice);
        // Führt das Reset aus
        OnResetDevice(device, null);

        // Definiert keine Vor und Rückseite
        device.RenderState.CullMode = Cull.Clockwise;
        // Direct3D-Beleuchtung deaktivieren
        device.RenderState.Lighting = false;
        // Beschreibt einen festen Füllmodus
        device.RenderState.FillMode = FillMode.Solid;

        // Erstellt den Buffer für die Vertices (Lab Koordinatensystem)
        vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored),   // Typ der Vertices
                                        18,                                     // Anzahl der Vertices
                                        device,                                 // Gerätekontext unser device
                                        0,                                      // Anzahl der Flags zur Verarbeitung der Vertice
                                        CustomVertex.PositionColored.Format,    // Typ der Vertices (Weil man auch eigene Strukturen definieren kann)
                                        Pool.Default);                          // Speicherung der Vertices

        // Event welches aufgerufen wird wenn der Vertexbuffer erstellt wurde
        vertexBuffer.Created += new System.EventHandler(this.OnCreateVertexBuffer);
        // Event wird von Hand aufgerufen
        this.OnCreateVertexBuffer(vertexBuffer, null);

        return true;    // Device wurde erstellt
    }
    catch { return false; } // Device konnte nicht erstellt werden 
} 

对于VertexBuffer,我使用CustomVertex.PositionColored[]

在这部分中,我设置矩阵并渲染基元:

/// <summary>
/// Berechnen und Darstellen des Bildes
/// </summary>
public void Render()
{
    // Fragt ob das Device erstellt wurde und noch gültig ist
    if (device == null)
        return;

    // Inhalt des Backbuffers löschen und das ganze mit einer Farbe einfärben
    device.Clear(ClearFlags.Target,         // Die entsprechende Oberfläche
                    System.Drawing.Color.Black,// Die Farbe 
                    1.0f,                      // Abstand vom Betrachter, an dem die Oberfläche gelöscht wird und einen Wert, ...
                    0);                        // ...der in jedem Stencil-Buffer-Eintrag gespeichert wird.

    // Anfang der Szene
    device.BeginScene();
    // Matrizen aufsetzen
    SetupMatrices();

    // Bindet den Buffer an das Device
    device.SetStreamSource(0,           // Nummer des Streams
                            vertexBuffer,// Der Buffer
                            0);          // StartOffset in dem Buffer

    // Teilt dem Device das Format der Vertices mit
    device.VertexFormat = CustomVertex.PositionColored.Format;
    // Zeichnet die Dreiecke
    device.DrawPrimitives(PrimitiveType.LineList,   // Typ der Primitive
                            0,                        // Eintrag des ersten Vertex
                            3);                       // Anzahl der Primetive

    // Zeichnet das Rechteck
    device.DrawPrimitives(PrimitiveType.TriangleList,   // Typ der Primitive
                            6,                            // Eintrag des ersten Vertex
                            4);                           // Anzahl der Primetive

    // Ende der Szene
    device.EndScene();
    // Bringt die Zeichnung auf das Fensterhandle
    device.Present();
}

/// <summary>
/// Setzt die Matrizen auf
/// </summary>
private void SetupMatrices()
{
    Matrix MX = Matrix.RotationX(impValue.ObjektRotationY);
    impValue.ObjektRotationY = 0;
    Matrix MY = Matrix.RotationY(impValue.ObjektRotationX);
    impValue.ObjektRotationX = 0;

    Matrix Rotation = device.Transform.World;
    Rotation *= MY;
    Rotation *= MX;

    // Rotiert das device entlag der X und Y Achse
    device.Transform.World = Rotation;

    // Setzt den Benutzerblickwinkel auf
    device.Transform.View = Matrix.LookAtLH(new Vector3(impValue.KameraPosX, impValue.KameraPosY, impValue.KameraPosZ), // Kameraposition
                            new Vector3(impValue.SchauPosX, impValue.SchauPosY, impValue.SchauPosZ),                    // Punkt, auf den geschaut wird
                            new Vector3(impValue.OberstePosX, impValue.OberstePosY, impValue.OberstePosZ));             // Vektor der angibt, wo oben ist

    // Setzt die Ansichtsmatrix auf (Linke-Hand-orientiertes System)
    device.Transform.Projection = Matrix.PerspectiveFovLH(impValue.BlickWinkel, // Sichtbereich (Blickwinkel)
                                    impValue.SeitenVerhaeltnis,                   // Seitenverhältnis
                                    impValue.NaheEbene,                           // Abstand zum nächsten sichtbaren Punkt (nahe Ebene)
                                    impValue.FerneEbene);                         // Abstand zum letzten sichtbaren Punkt (ferne Ebene)
}

开始位置

Two triangles, red in front of white http://s1.directupload.net/images/130206/q3gu27ol.png

轮换后

Same triangles, but rotated; red still in front of white http://s7.directupload.net/images/130206/753b42to.png

在第二张图片中,您可以看到我的问题。红色三角形位于白色三角形的前面。如何在白色三角形后面绘制红色三角形?

1 个答案:

答案 0 :(得分:1)

在3D应用程序中处理重叠面有不同的方法:

深度缓冲区(或Z缓冲区)是一种非常常见的解决方案,因为它为不透明几何体提供了完美的结果。

深度缓冲区是存储渲染像素的深度信息的纹理。如果像素到相机的距离大于深度缓冲器中该像素的值,则丢弃该像素。如果距离相机较近,则会将颜色写入渲染目标并更新深度。