2

vbo バッファー オブジェクトである PointCloud というクラスがあり、これらのいくつかを異なるデータでレンダリングしています。1 つは球体、もう 1 つは xyz のデータセットです。データセットには色があり、球体には色がありません。問題は、両方の色が同じ色を共有しているように見えることです。個々の色のセットではなく、実際には球の色が null に設定されているため、色が適用される理由について混乱しています。

私がやろうとしているのは、球体を「白」で描画し、他の点群はそれぞれの色です。

ここに画像の説明を入力

画像が表示されない場合は、これを試してください ( http://s8.postimg.org/q1j0nlkol/pcerror.png )

http://pastebin.com/3fM9K87A

私の質問は、なぜこれが起こっているのか、私が間違っていることを説明できる人はいますか?

ポイントクラウドクラスは次のとおりです。

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();
}
4

2 に答える 2

2

機能しない理由は、clientState(ArrayCap.ColorArray) を無効にしないためです。これにより、OpenGL はこの情報を際限なく再利用します。適切なアプローチは、render メソッドを終了する前に、関数の開始時に有効にしたすべてのクライアント状態を常に無効にすることです。あなたの場合、ポイントにはとにかく単一の色しかないため、カラー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);
}
于 2013-07-25T03:31:07.237 に答える
0

最新の適用されたカラー配列が使用されない場合は、ArrayCap.ColorArray 状態を無効にする必要があると思います。

GL.DisableClientState(ArrayCap.ColorArray);
于 2013-07-25T03:26:37.453 に答える