这应该是一个简单的问题。所以我终于想出了如何在OpenTK中用3D渲染东西。大!唯一的问题是,它看起来并不像我期待的那样。我使用Polar方法绘制球体,并使用PrimitiveType.Polygon绘图。
这里是计算坐标的算法。我正在做的是逐步通过球体中的每个phi然后theta,逐步添加更多相邻的四边形到我的最终点列表:
第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;
}
所以我的Sphere类看起来像这样:
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)
{
}
}
我还应该提一下,这个球体的颜色不是恒定的。我有2个维度,我有这个代码非常适合渐变。在3D ......不是那么多。这就是我的球体有多种颜色的原因。 2d渐变代码的工作方式是,有一个颜色列表来自我创建的类GeometryColor。渲染多边形时,每个顶点都会根据GeometryColor中的颜色列表进行着色。因此,如果用户希望在3种颜色之间进行渐变,并且有6个顶点(六边形),则代码将分配前2个顶点颜色1,第2个颜色2,然后是最后2个颜色3.以下代码显示如何计算顶点的颜色。
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];
}
无论如何,这是我得到的输出......希望有人能看到我的错误...
感谢。
编辑:如果我只使用一个顶点颜色(我,而不是我的4种不同颜色的数组),那么我得到一个完全光滑的球体......虽然没有光线和东西很难说它除了一个圆圈之外的任何东西笑)
编辑....所以我的球体稍微透视......即使我的所有alpha都设置为1.0f并且我正在进行深度测试..
GL.DepthMask(true);
GL.Enable(EnableCap.DepthTest);
GL.ClearDepth(1.0f);
GL.DepthFunc(DepthFunction.Lequal);
最终编辑:好的,它有一些与我的顶点有关的猜测,因为当我使用PrimitiveType.Quads时它完美地工作....