Как отобразить текстуру на цилиндр в неуправляемом DirectX? - PullRequest
3 голосов
/ 07 апреля 2011

В C # .net у меня есть сетчатый цилиндр с динамическим диаметром и длиной, и я пытаюсь наложить на него текстуру. Я потратил большую часть дня, пытаясь выяснить, как это сделать, но безуспешно нашел какую-либо информацию в Google.

Текстура цилиндров имеет верхнюю область jpg, а сторона - остаток jpg. Мне нужно расположить края изображения jpgs вдоль верхнего края цилиндра. например. Красный сверху и зеленый сбоку, используя одно изображение.

Может кто-нибудь помочь мне сопоставить точки VertexBuffer с текстурой?

C # .Net 2008 DirectX 9 (неуправляемый)

Я разместил свое рабочее решение ниже

Ответы [ 2 ]

1 голос
/ 07 апреля 2011

Хотя это руководство написано на VB, оно четко объясняет процесс.

Расчет координат текстуры может быть довольно трудоемким; именно поэтому обычно это делается с помощью программного обеспечения для 3D-моделирования, поэтому вы можете легко и, что более важно, визуально настроить отображение.

Дайте мне знать, если у вас есть какие-либо вопросы.

EDIT

Для добавления текстурных координат к сгенерированному цилиндру DirecxtX см. Это

0 голосов
/ 08 апреля 2011

Хорошо, я наконец понял это.Ранее у меня был какой-то код, который работал, но не совсем то, что я хотел от http://channel9.msdn.com/coding4fun/articles/Ask-the-ZMan-Applying-Textures-Part-3

В любом случае, я просто сделал несколько модов для этого.

Для справки и для тех, кто прибываетот Google, здесь вы идете.

public static float ComputeBoundingSphere(Mesh mesh, out Microsoft.DirectX.Vector3 center)
    {
        // Lock the vertex buffer
        Microsoft.DirectX.GraphicsStream data = null;
        try
        {
            data = mesh.LockVertexBuffer(LockFlags.ReadOnly);
            // Now compute the bounding sphere
            return Geometry.ComputeBoundingSphere(data, mesh.NumberVertices, 
                mesh.VertexFormat, out center);
        }
        finally
        {
            // Make sure to unlock the vertex buffer
            if (data != null)
                mesh.UnlockVertexBuffer();
        }
    }

    private static Mesh SetSphericalTexture(Mesh mesh)
    {
        Microsoft.DirectX.Vector3 vertexRay;
        Microsoft.DirectX.Vector3 meshCenter;
        double phi;
        float u;


        Microsoft.DirectX.Vector3 north = new Microsoft.DirectX.Vector3(0f, 0f, 1f);
        Microsoft.DirectX.Vector3 equator = new Microsoft.DirectX.Vector3(0f, 1f, 0f);
        Microsoft.DirectX.Vector3 northEquatorCross = Microsoft.DirectX.Vector3.Cross(north, equator);

        ComputeBoundingSphere(mesh, out meshCenter);

        using (VertexBuffer vb = mesh.VertexBuffer)
        {
            CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vb.Lock(0, typeof(CustomVertex.PositionNormalTextured), LockFlags.None, mesh.NumberVertices);
            try
            {
                for (int i = 0; i < verts.Length; i++)
                {
                    //For each vertex take a ray from the centre of the mesh to the vertex and normalize so the dot products work.
                    vertexRay = Microsoft.DirectX.Vector3.Normalize(verts[i].Position - meshCenter);

                    phi = Math.Acos((double)vertexRay.Z);
                    if (vertexRay.Z > -0.9)
                    {
                        verts[i].Tv = 0.121f; //percentage of the image being the top side
                    }
                    else
                        verts[i].Tv = (float)(phi / Math.PI);

                    if (vertexRay.Z == 1.0f || vertexRay.Z == -1.0f)
                    {
                        verts[i].Tu = 0.5f;
                    }
                    else
                    {
                        u = (float)(Math.Acos(Math.Max(Math.Min((double)vertexRay.Y / Math.Sin(phi), 1.0), -1.0)) / (2.0 * Math.PI));
                        //Since the cross product is just giving us (1,0,0) i.e. the xaxis 
                        //and the dot product was giving us a +ve or -ve angle, we can just compare the x value with 0
                        verts[i].Tu = (vertexRay.X > 0f) ? u : 1 - u;
                    }
                }
            }
            finally
            {
                vb.Unlock();
            }
        }
        return mesh;
    }
...