I "discovered" an easy but silly way to create a sphere programmatically in XNA, it is very simple. The idea came to me when I wanted to create huge planets in XNA to make an endless map. Any way the method is very simple, I don't know If someone knows it or it was used before, but till now it is working and efficient. You can control the resolution or how "round" the sphere is.
The code is written in C# with microsoft's XNA 4.0.
Here is a high resolution sphere in wire frame:
The sphere contains 8100 vertices and 48600 indices.
Code:
public class Sphere { VertexPositionColor[] vertices; //later, I will provide another example with VertexPositionNormalTexture VertexBuffer vbuffer; short[] indices; //my laptop can only afford Reach, no HiDef :( IndexBuffer ibuffer; float radius; int nvertices, nindices; BasicEffect effect; GraphicsDevice graphicd; public Sphere(float Radius, GraphicsDevice graphics) { radius = Radius; graphicd = graphics; effect = new BasicEffect(graphicd); nvertices = 90 * 90; // 90 vertices in a circle, 90 circles in a sphere nindices = 90 * 90 * 6; vbuffer = new VertexBuffer(graphics, typeof(VertexPositionNormalTexture), nvertices, BufferUsage.WriteOnly); ibuffer = new IndexBuffer(graphics, IndexElementSize.SixteenBits, nindices, BufferUsage.WriteOnly); createspherevertices(); createindices(); vbuffer.SetData<VertexPositionColor>(vertices); ibuffer.SetData<short>(indices); effect.VertexColorEnabled = true; } void createspherevertices() { vertices = new VertexPositionColor[nvertices]; Vector3 center = new Vector3(0, 0, 0); Vector3 rad = new Vector3((float)Math.Abs(radius), 0, 0); for (int x = 0; x < 90; x++) //90 circles, difference between each is 4 degrees { float difx = 360.0f / 90.0f; for (int y = 0; y < 90; y++) //90 veritces, difference between each is 4 degrees { float dify = 360.0f / 90.0f; Matrix zrot = Matrix.CreateRotationZ(MathHelper.ToRadians(y * dify)); rotate vertex around z Matrix yrot = Matrix.CreateRotationY(MathHelper.ToRadians(x * difx)); rotate circle around y Vector3 point = Vector3.Transform(Vector3.Transform(rad, zrot), yrot);//transformation vertices[x + y * 90] = new VertexPositionColor(point, Color.Black); } } } void createindices() { indices = new short[nindices]; int i = 0; for (int x = 0; x < 90; x++) { for (int y = 0; y < 90; y++) { int s1 = x == 89 ? 0 : x + 1; int s2 = y == 89 ? 0 : y + 1; short upperLeft = (short)(x * 90 + y); short upperRight = (short)(s1 * 90 + y); short lowerLeft = (short)(x * 90 + s2); short lowerRight = (short)(s1 * 90 + s2); indices[i++] = upperLeft; indices[i++] = upperRight; indices[i++] = lowerLeft; indices[i++] = lowerLeft; indices[i++] = upperRight; indices[i++] = lowerRight; } } } public void Draw(Camera cam) // the camera class contains the View and Projection Matrices { effect.View = cam.View; effect.Projection = cam.Projection; graphicd.RasterizerState = new RasterizerState() { FillMode = FillMode.WireFrame }; // Wireframe as in the picture foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); graphicd.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, nvertices, indices, 0, indices.Length / 3); } } }
Hello,
ReplyDeletethis is interesting. I just tried your class and it works. Though I had to modify the draw()-function... How do you call it in your Game and where? When I call it in the Game Draw() Function and there are more Primitives to draw, I get exceptions...
I also have a suggestion:
I added a static int, to set the number of vertices / circles!
Greetings and thanks for your code!
Interesting, what types of exceptions did you get?
DeleteHi, thanks for posting the code. I implement your code and it works. I just have a problem on the DrawingSurface (i'm using a silverlight project on VS2012). In fact if I don't make it exactly squared, the sphere become an ellipse. Do you have any idea of what could be the problem. Thanks
ReplyDeleteThat's a problem with the View Matrix or the camera not the ellipse. When you stretch the view port you should change the aspect ratio of the camera.
Deletesorry, sphere not ellipse.
Deletethank you very much it works.
ReplyDeleteHello, thanks for posting the example. I tried to run the code but I could not get the draw function. it appears the camera is not known by the setting I have. I added "using System.Windows.Media.Media3D;" but then again it could not recognise the view and the projection parameters of the camera. can you tell me what I am not doing to make it work? or can you kindly share the code with all the namespaces needed? Thank you so much
ReplyDeleteHello,
ReplyDeleteThank you very much, it works fine for me.
Just a question: did anyone try to colour it, rather than having it as a plain sphere?
I tried doing t in different ways, it always ended up as a sort of spiral, and always coloured red and black. Does someone have any ideas?
liobecalza Jennifer Williams https://wakelet.com/wake/S8Qf_c_novX7VkJ_iFEfi
ReplyDeletelinkaeconsdis
hiaceaglob_mo-Huntsville Lori Nance UnHackMe
ReplyDeleteExpress VPN
Reg Organizer
tersdediscse
NgnosniOmenru1993 Carlos Ruiz Download Free
ReplyDeleteAwesome
carnidoma
Thank You and that i have a nifty offer: What Home Renovation Shows Are On Netflix home interior renovation
ReplyDelete