我有一个名为 PointCloud 的类,它是一个 vbo 缓冲区对象,我正在使用不同的数据渲染其中的几个,一个作为球体,一个作为 xyz 数据集,数据集有颜色,球体没有颜色。问题是两者似乎共享相同的颜色,而不是具有单独的颜色集,球体的颜色实际上设置为空,所以我很困惑为什么要对其应用颜色。
我想做的是将球体绘制为“白色”,而另一个点云是它各自的颜色。
如果您看不到图像,请尝试此操作 ( http://s8.postimg.org/q1j0nlkol/pcerror.png )
我的问题是有人可以解释为什么会发生这种情况以及我做错了什么吗?
这是点云类:
using System;
using OpenTK.Graphics.OpenGL;
using OpenTK;
internal class PointCloud : IDisposable
{
protected int[] vbo_id = new int[2];
protected int vbo_size;
public bool HasColor;
public float[] Vertices = null;
public int[] Colors = null;
public float PointSize { get; set; }
public bool Visible { get; set; }
~PointCloud()
{
EmptyBuffer();
}
private void EmptyBuffer()
{
Vertices = (float[])null;
Colors = (int[])null;
}
public void Delete()
{
Dispose();
}
public PointCloud(float[] points)
{
this.vbo_size = points.Length;
GL.GenBuffers(2, this.vbo_id);
GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo_id[0]);
GL.BufferData<float>(BufferTarget.ArrayBuffer, new IntPtr(points.Length * BlittableValueType.StrideOf<float>(points)), points, BufferUsageHint.StaticDraw);
Vertices = points;
}
public void ApplyColorMap(int[] colors)
{
GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo_id[1]);
GL.BufferData<int>(BufferTarget.ArrayBuffer, new IntPtr(colors.Length * BlittableValueType.StrideOf<int>(colors)), colors, BufferUsageHint.StaticDraw);
Colors = colors;
this.HasColor = true;
}
public void Render(FrameEventArgs e)
{
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo_id[0]);
GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
GL.DrawArrays(BeginMode.Points, 0, this.vbo_size);
if (!this.HasColor)
{
return;
}
GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo_id[1]);
GL.ColorPointer(4, ColorPointerType.UnsignedByte, 4, IntPtr.Zero);
GL.EnableClientState(ArrayCap.ColorArray);
}
public void Dispose()
{
EmptyBuffer();
GL.DeleteBuffers(vbo_id.Length, vbo_id);
this.vbo_id = new int[2];
}
}
这是我的渲染代码:
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.MatrixMode(MatrixMode.Modelview);
GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
GL.LoadMatrix(ref this.CameraMatrix);
GL.PushMatrix();
this.pointclouds.ForEach((Action<PointCloud>)(i =>
{
//blend
GL.Enable(EnableCap.Blend);
if (i.Visible)
{
GL.PushMatrix();
GL.PointSize(2.0f);
if (!i.HasColor)
{
GL.Color4(Color.White);
}
i.Render(e);
GL.PopMatrix();
}
}));
GL.PopMatrix();
}
最佳答案
它不起作用的原因是您从未禁用 clientState(ArrayCap.ColorArray)。这将导致OpenGL无休止地重用这些信息。 一个好的方法是在您离开渲染方法之前始终禁用您在函数开始时启用的所有客户端状态。 在您的情况下,您可以通过完全删除颜色 VBO 来简化事情,因为您的点无论如何都只有单一颜色。无论如何,您已经尝试对 !hasColor 案例执行此操作
其次,我不确定这是否是故意的。在渲染函数中,您永远不会设置正确的颜色:当您调用drawArrays时,您将信息发送到GPU,然后加载颜色。这将导致下一个点具有先前的颜色。
类似这样的事情:
public void Render(FrameEventArgs e)
{
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo_id[0]);
GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
if (!this.HasColor) GL.Color4f(0,0,0);
else GL.Color4f(putcolorvalue);
GL.DrawArrays(BeginMode.Points, 0, this.vbo_size);
GL.DisableClientState(ArrayCap.VertexArray);
}
关于c# - opengl-Vbo 颜色在对象之间混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17847765/