none
Толщина линий direct3d RRS feed

  • Вопрос

  • Можно ли изменить толщину линий при выводе на direct3d устройство (код формы см. ниже)?

    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 Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    
    namespace LineStrip3D
    {
        public partial class Form1 : Form
        {
            float ar = 4f / 3f, cpx = 0, cpy = 0, cpz = 10;
            Color bc = Color.LightGray;
            Random rn = new Random();
            CustomVertex.PositionColored[] v = new CustomVertex.PositionColored[1000];
            Device dr = null;
            VertexBuffer vbf = null;
            PresentParameters ppr = new PresentParameters();
    
            public Form1()
            {
                InitializeComponent();
                this.ClientSize = new Size(800, 600);
                test();
                InitializeGraphics();
            }
    
            //инициализация 3D устройства
            public void InitializeGraphics()
            {
                ppr.Windowed = true;
                ppr.SwapEffect = SwapEffect.Discard;
                ppr.EnableAutoDepthStencil = true;
                ppr.AutoDepthStencilFormat = DepthFormat.D16;
                try
                {
                    dr = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, ppr);
                }
                catch
                {
                    dr = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, ppr);
                }
                dr.DeviceReset += new System.EventHandler(this.OnResetDevice);
                this.OnCreateDevice(dr, null);
                this.OnResetDevice(dr, null);
            }
    
            public void OnCreateDevice(object sender, EventArgs e)
            {
                vbf = new VertexBuffer(typeof(CustomVertex.PositionColored), 1000, dr, Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
                vbf.Created += new System.EventHandler(this.OnCreateVertexBuffer);
                this.OnCreateVertexBuffer(vbf, null);
            }
    
            public void OnResetDevice(object sender, EventArgs e)
            {
                dr.RenderState.CullMode = Cull.None;
                dr.RenderState.ZBufferEnable = true;
                dr.RenderState.Lighting = false;
            }
    
            //Заполнение буфера вершин
            public void OnCreateVertexBuffer(object sender, EventArgs e)
            {
                VertexBuffer vbf = (VertexBuffer)sender;
                CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[])vbf.Lock(0, 0);
                for (int i = 0; i < 1000; i++)
                {
                    verts[i] = v[i];
                }
                vbf.Unlock();
            }
    
            //Визуализация
            public void Render()
            {
                dr.Clear(ClearFlags.ZBuffer | ClearFlags.Target, bc, 1f, 0);
                dr.BeginScene();
                dr.Transform.View = Matrix.LookAtRH(new Vector3(cpx, cpy, cpz), new Vector3(cpx, cpy, 0f), new Vector3(0f, 1f, 0f));
                dr.Transform.Projection = Matrix.OrthoRH(800f, 800f * ar, 1f, 100f);
                dr.SetStreamSource(0, vbf, 0);
                dr.VertexFormat = CustomVertex.PositionColored.Format;
    
                //199 линий
                dr.DrawPrimitives(PrimitiveType.LineStrip, 0, 199);
    
                //100 точек размером 5
                dr.RenderState.PointSize = 5f;
                dr.DrawPrimitives(PrimitiveType.PointList, 200, 100);
    
                //100 точек размером 10
                dr.RenderState.PointSize = 10f;
                dr.DrawPrimitives(PrimitiveType.PointList, 300, 100);
    
                dr.EndScene();
                dr.Present();
            }
    
            //Тест
            private void test()
            {
                for (int i = 0; i < 1000; i++)
                {
                    v[i].X = (float)rn.Next(-300, 301);
                    v[i].Y = (float)rn.Next(-200, 201);
                    v[i].Z = 0;
                    v[i].Color = Color.Red.ToArgb();
                }
            }
    
            //Удаление следов
            private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
            {
                Render();
            }
    
            //Изменение размеров окна
            private void Form1_Resize(object sender, EventArgs e)
            {
                ar = (float)this.ClientSize.Height / (float)this.ClientSize.Width;
                if (this.Created) Render();
            }
        }
    }

    Размер точек меняется очень просто (см. код).

    А как изменить толщину линий не нашел.

    Лепить толстые линии из треугольников не хочется.

    • Перемещено Tagore Bandlamudi 1 октября 2010 г. 22:05 MSDN Forums consolidation (От:Visual C#)
    12 апреля 2010 г. 15:18

Ответы

  • Direct3D does not support lines of varying thickness, all line primitives are rendered as single pixel lines regardless of distance from viewer. To generate lines of differing thickness requires converting them to screen aligned quads. Take a cross product of the linedirection and the forward vector from your view matrix (viewMat._13,viewMat._23,viewMat._33), providing a vector perpendicular to the line and parallel to the screen. Then scale this to your line width and use it to offset the ends of your line in either direction to form a quad.

     

    http://www.mvps.org/directx/faq.php

    • Помечено в качестве ответа hellokol 13 апреля 2010 г. 5:17
    12 апреля 2010 г. 20:51