Jump to content
  • Advertisement
Sign in to follow this  
Upinflames

3D Sphere Texturing

This topic is 3651 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am doing a project that makes a 3D Earth that rotates. I have it all completed except the texture rendering differently. I am following ZMans tutorial on Coding4Fun. I am using C# and Managed DirectX. Here is my texturing procedure and my mesh creating procedure:
        private void LoadMesh()
        {
            ExtendedMaterial[] materialarray;
            sphere = Mesh.FromFile(System.Windows.Forms.Application.StartupPath + @"\..\..\bin\Release\Sphere.x", MeshFlags.Managed, device, out materialarray);

            if ((materialarray != null) && (materialarray.Length > 0))
            {
                m_materials = new Material[materialarray.Length];

                for (int i = 0; i < materialarray.Length; i++)
                {
                    m_materials = materialarray.Material3D;
                    m_materials.Ambient = m_materials.Diffuse;
                }
            }


            sphere = sphere.Clone(sphere.Options.Value, CustomVertex.PositionNormalTextured.Format, device);
            sphere = SetSphericalTexture(sphere.Clone(sphere.Options.Value, sphere.VertexFormat | VertexFormats.Texture0, sphere.Device));
            //sphere.ComputeNormals();
            
            VertexBuffer vertices = sphere.VertexBuffer;
            GraphicsStream stream = vertices.Lock(0, 0, LockFlags.None);
            Vector3 meshcenter;
            meshradius = Geometry.ComputeBoundingSphere(stream, sphere.NumberVertices, sphere.VertexFormat, out meshcenter);
            vertices.Unlock();
        }
        private static Mesh SetSphericalTexture(Mesh mesh)
        {
            Vector3 vertexRay;
            Vector3 meshCenter;
            double phi;
            float u;

            Vector3 north = new Vector3(0f, 0f,1f);
            Vector3 equator = new Vector3(0f, 1f, 0f);
            Vector3 northEquatorCross = 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 = Vector3.Normalize(verts.Position - meshCenter);

                        ////Ref:http://www.cs.unc.edu/~rademach/xroads-RT/RTarticle.html and
                        ////Glassner, A. (ed) An Introduction to Ray Tracing. Academic Press New York, N.Y. 1989. 
                        //phi = Math.Acos((double)Vector3.Dot(north, vertexRay));
                        //verts.Tv = (float)(phi / Math.PI);
                        //if (phi == 0.0) //if north and vertex ray are coincident then we can pick an arbitray u since its the entire top/bottom line of the texture
                        //{
                        //    u = 0.5f;
                        //}
                        //else
                        //{
                        //    //Clamp the acos() param to 1.0/-1.0 (rounding errors are sometimes taking it slightly over.
                        //    u = (float)(Math.Acos(Math.Max(Math.Min((double)Vector3.Dot(equator, vertexRay) / Math.Sin(phi), 1.0), -1.0)) / (2.0 * Math.PI));
                        //    if (Vector3.Dot(northEquatorCross, vertexRay) < 0.0)
                        //    {
                        //        verts.Tu = u;
                        //    }
                        //    else
                        //    {
                        //        verts.Tu = 1 - u;
                        //    }
                        //}

                        //Since we know we are using normalised axis we can simplify this somewhat!
                        //Note these simplifcations only apply if the basis vectors are the unit axis
                        //north=(0,0,1)=zaxis, equator=(0,1,0)=yaxis and north x equator=(1,0,0)=xaxis
                        //since (0,0,1)dot(x,y,z)==z and (0,1,0)dot(x,y,z)==y

                        //if north and vertex ray are coincident then we can pick an arbitray u since its the entire top/bottom line of the texture
                        phi = Math.Acos((double)vertexRay.Z);
                        verts.Tv = (float)(phi / Math.PI);

                        if (vertexRay.Z == 1.0f || vertexRay.Z == -1.0f)
                        {
                            verts.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.Tu = (vertexRay.X > 0f) ? u : 1 - u;
                        }

                    }
                }
                finally
                {
                    vb.Unlock();
                }
            }
            return mesh;
        }
        public static float ComputeBoundingSphere(Mesh mesh, out Vector3 center)
        {

            // Lock the vertex buffer
            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 void DrawMesh(Mesh mesh, Material[] meshmaterials)
        {
            for (int i = 0; i < meshmaterials.Length; i++)
            {
                device.Material = meshmaterials;
                mesh.DrawSubset(i);
            }
        }
Here is a picture of what it looks like when it renders: Free Image Hosting at www.ImageShack.us (Ignore the reness of it, I want it to be red.) If someone could help me that would be appreciated because I have been attempting to resolve it with no success. [Edited by - Upinflames on September 20, 2008 12:20:26 PM]

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!