This should hopefully be a simple question. So I finally figured out how to render stuff in 3D in OpenTK. Great! Only problem is, it doesn't quite look how I expect. I'm drawing a sphere using the Polar method, and drawing using PrimitiveType.Polygon.
Here's the algorithm for calculating the coordinates. What I'm doing is stepping through each phi then theta in the sphere, incrementally adding more adjacent quads to my final point list:
- Point 1: Theta1, Phi1
- Point 2: Theta1, Phi2
- Point 3: Theta2, Phi2
Point 4: Theta2: Phi1
protected static RegularPolygon3D _create_unit(int n) { List<Vector3> pts = new List<Vector3>(); float theta = 0.0f; float theta2 = 0.0f; float phi = 0.0f; float phi2 = 0.0f; float segments = n; float cosT = 0.0f; float cosT2 = 0.0f; float cosP = 0.0f; float cosP2 = 0.0f; float sinT = 0.0f; float sinT2 = 0.0f; float sinP = 0.0f; float sinP2 = 0.0f; List<Vector3> current = new List<Vector3>(4); for (float lat = 0; lat < segments; lat++) { phi = (float)Math.PI * (lat / segments); phi2 = (float)Math.PI * ((lat + 1.0f) / segments); cosP = (float)Math.Cos(phi); cosP2 = (float)Math.Cos(phi2); sinP = (float)Math.Sin(phi); sinP2 = (float)Math.Sin(phi2); for (float lon = 0; lon < segments; lon++) { current = new List<Vector3>(4); theta = TWO_PI * (lon / segments); theta2 = TWO_PI * ((lon + 1.0f) / segments); cosT = (float)Math.Cos(theta); cosT2 = (float)Math.Cos(theta2); sinT = (float)Math.Sin(theta); sinT2 = (float)Math.Sin(theta2); current.Add(new Vector3( cosT * sinP, sinT * sinP, cosP )); current.Add(new Vector3( cosT * sinP2, sinT * sinP2, cosP2 )); current.Add(new Vector3( cosT2 * sinP2, sinT2 * sinP2, cosP2 )); current.Add(new Vector3( cosT2 * sinP, sinT2 * sinP, cosP )); pts.AddRange(current); } } var rtn = new RegularPolygon3D(pts); rtn.Translation = Vector3.ZERO; rtn.Scale = Vector3.ONE; return rtn; }
And so my Sphere class looks like this:
public class Sphere : RegularPolygon3D
{
public static Sphere Create(Vector3 center, float radius)
{
var rp = RegularPolygon3D.Create(30, center, radius);
return new Sphere(rp);
}
private Sphere(RegularPolygon3D polygon) : base(polygon)
{
}
}
I should also mention, that the color of this sphere is not constant. I 2 dimensions, I have this code that works great for gradients. In 3D...not so much. That's why my sphere has multiple colors. The way the 2d gradient code works, is there is a list of colors coming from a class I created called GeometryColor. When the polygon is rendered, every vertex gets colored based off the list of colors within GeometryColor. So if there are 3 colors the user wished to gradient between, and there were 6 vertices (hexagon), then the code would assign the first 2 vertices color 1, the 2nd two color 2, then the last 2 color 3. The following code shows how the color for the vertex is calculated.
public ColorLibrary.sRGB GetVertexFillColor(int index)
{
var pct = ((float)index + 1.0f) / (float)Vertices.Count;
var colorIdx = (int)Math.Round((FillColor.Colors.Count - 1.0f) * pct);
return FillColor.Colors[colorIdx];
}
Anyway, here's the output I'm getting...hope somebody can see my error...
Thanks.
Edit: If I only use ONE Vertex color (i,e instead of my array of 4 diff colors), then I get a completely smooth sphere...although without lighting and stuff its hard to tell its anything but a circle lol)
Edit....so somehow my sphere is slightly see through...even though all my alphas are set to 1.0f and I'm doing depth testing..
GL.DepthMask(true);
GL.Enable(EnableCap.DepthTest);
GL.ClearDepth(1.0f);
GL.DepthFunc(DepthFunction.Lequal);
Final edit: OK, it has SOMETHING to do with my vertices I'm guessing, because when I use PrimitiveType.Quads it works perfectly....