OpenTK:在 VBO 中使用不同的颜色

发布于 2024-12-12 04:48:59 字数 1782 浏览 0 评论 0原文

情况:我正在使用 OpenTK 库在 C# 中使用 OpenGL 进行绘图。

问题:我无法选择要绘制的缓冲区/顶点集。

设置功能:

var vertices = new Vertex[..];

创建顶点

foreach( .. ) 
{
 Byte4 color = new Byte4();
 color.R     = 255;
 color.G     = 0;
 color.B     = 0;
 color.A     = 100;

 Vertex vertex;
 vertex.Position = new Vector3(.....);
 vertex.Color    = color;

 vertices[index] = vertex;
}

生成/绑定缓冲区。

vbo_size = vertices.Length;
GL.GenBuffers(1, out vbo_id);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(vbo_size * Vertex.SizeInBytes), vertices, BufferUsageHint.StaticDraw);
GL.InterleavedArrays(InterleavedArrayFormat.C4ubV3f, 0, IntPtr.Zero);

* 如果这很重要的话,Vertex.SizeInBytes 是 16。

渲染代码:

GL.Enable(EnableCap.DepthTest);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
..
GL.Enable(EnableCap.ColorArray);
GL.DrawArrays(BeginMode.Points, 0, vbo_size);
GL.Disable(EnableCap.ColorArray);
..
glControl1.SwapBuffers();

.

我喜欢做什么:

在设置代码中,我创建我的顶点(顶点包括位置和颜色)。我现在创建了一组,但我想再创建一组(只是具有不同颜色值的相同代码)。我这样做了,当然创建它并将其绑定到辅助缓冲区(vbo_id/vbo_secondary_id)就可以了。但我该如何画它呢?

我正在寻找这样的东西:

RenderNormalColors()
{
  GL.UseVboId(vbo_id);
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
}

RenderAlternativeColors()
{
  GL.UseVboId(vbo_id_secondary);
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
}

GL.DrawArrays 似乎可以获取所有内容,而无需控制要绘制的内容。

除了颜色之外,顶点/数组中的所有内容都将/是相同的。我只需要使用另一个“颜色方案”渲染相同的对象 - 数千个点。

任何帮助将不胜感激。

Situation: I am drawing with OpenGL in C# with the library OpenTK.

.

Problem: I cannot choose which one of my buffers/sets of vertices to draw.

.

Setup-Function:

var vertices = new Vertex[..];

Create the vertices

foreach( .. ) 
{
 Byte4 color = new Byte4();
 color.R     = 255;
 color.G     = 0;
 color.B     = 0;
 color.A     = 100;

 Vertex vertex;
 vertex.Position = new Vector3(.....);
 vertex.Color    = color;

 vertices[index] = vertex;
}

Generate / bind buffers.

vbo_size = vertices.Length;
GL.GenBuffers(1, out vbo_id);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(vbo_size * Vertex.SizeInBytes), vertices, BufferUsageHint.StaticDraw);
GL.InterleavedArrays(InterleavedArrayFormat.C4ubV3f, 0, IntPtr.Zero);

* Vertex.SizeInBytes is 16 if this matters.

.

Render-code:

GL.Enable(EnableCap.DepthTest);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
..
GL.Enable(EnableCap.ColorArray);
GL.DrawArrays(BeginMode.Points, 0, vbo_size);
GL.Disable(EnableCap.ColorArray);
..
glControl1.SwapBuffers();

.

What id like to do:

In the setup-code i create my vertices (Vertex include position and color). I create one set right now, but i would like to create one more (just the same code with different color-values). I did this, and of course it is fine to create it and bind it to a secondary buffer (vbo_id/vbo_secondary_id). But how do I draw it?

Something like this is what I am looking for:

RenderNormalColors()
{
  GL.UseVboId(vbo_id);
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
}

RenderAlternativeColors()
{
  GL.UseVboId(vbo_id_secondary);
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
}

The GL.DrawArrays seems to take everything without control of what to draw.

Everything in the vertices/arrays will/is be identical apart from the colors. I just need to render the same objects - thousands of points - with another "colorscheme".

Any help would be appriciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟雨扶苏 2024-12-19 04:48:59

所以我修好了它。这就是我最初认为的解决方案。

我为顶点(位置)创建了一个数组,并为两个带有颜色的单独数组(C#“颜色”)创建了一个数组。

  vertices  = new Vector3[evaluations.Count];
  colors    = new int[evaluations.Count];
  altcolors = new int[evaluations.Count];

然后我将它们绑定到不同的缓冲区。

  vbo_size = vertices.Length; // Necessary for rendering later on
  GL.GenBuffers(1, out vbo_id);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(vertices.Length * BlittableValueType.StrideOf(vertices)), // strideof means what?
                vertices, BufferUsageHint.StaticDraw);

  GL.GenBuffers(1, out vbo_color_id);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(colors.Length * BlittableValueType.StrideOf(vertices)),
                colors, BufferUsageHint.StaticDraw);

  GL.GenBuffers(1, out vbo_color_id_alt);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id_alt);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(altcolors.Length * BlittableValueType.StrideOf(vertices)),
                altcolors, BufferUsageHint.StaticDraw);

注意“vbo_color_id”和“vbo_color_id_alt”。这些在 Render() 中使用

selected_vbo = color_id_altcolor_id

  GL.BindBuffer(BufferTarget.ArrayBuffer, selected_vbo);
  GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
  GL.EnableClientState(ArrayCap.ColorArray);

  GL.EnableClientState(ArrayCap.VertexArray);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);

So I fixed it. Kind of how I originally thought the solution would be.

I created one array for the vertices (positions) and two separate arrays with colors (C# "Color").

  vertices  = new Vector3[evaluations.Count];
  colors    = new int[evaluations.Count];
  altcolors = new int[evaluations.Count];

Then I bound them to different buffers.

  vbo_size = vertices.Length; // Necessary for rendering later on
  GL.GenBuffers(1, out vbo_id);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(vertices.Length * BlittableValueType.StrideOf(vertices)), // strideof means what?
                vertices, BufferUsageHint.StaticDraw);

  GL.GenBuffers(1, out vbo_color_id);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(colors.Length * BlittableValueType.StrideOf(vertices)),
                colors, BufferUsageHint.StaticDraw);

  GL.GenBuffers(1, out vbo_color_id_alt);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id_alt);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(altcolors.Length * BlittableValueType.StrideOf(vertices)),
                altcolors, BufferUsageHint.StaticDraw);

Notice the "vbo_color_id" and "vbo_color_id_alt". These are used in the Render()

selected_vbo = either color_id_alt or color_id

  GL.BindBuffer(BufferTarget.ArrayBuffer, selected_vbo);
  GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
  GL.EnableClientState(ArrayCap.ColorArray);

  GL.EnableClientState(ArrayCap.VertexArray);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
一片旧的回忆 2024-12-19 04:48:59

我用它来选择点云中的点。在替代颜色方案中,每个点都会获得唯一的颜色(存储在指向点 id(索引)的字典中)。

当我单击鼠标时,它会检索当前像素并检查列表。如果它找到颜色集中存在的颜色,它将知道单击了哪个点。

这非常好,因为我不必使用光线投射或八叉树或类似的检查。但值得注意的是,这将导致无法找到当前屏幕上显示的点后面的任何内容。

我渲染替代颜色,选择鼠标下的像素颜色,但我不使用“swapbuffer()”,因此它永远不会显示在屏幕上。然后我用正确的颜色再次渲染它。

非常漂亮。

public void RenderAlternativeColorsAndPick(int x, int y)
{
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id_alt);
  GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
  GL.EnableClientState(ArrayCap.ColorArray);

  GL.EnableClientState(ArrayCap.VertexArray);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);

  // Psuedo code sorry
  GL.GetPixelColor(x,y)
  SelectedPoint    = dictionary<color,int>.findValuebyKey(thePixelsColor)
}

希望这对将来的人有帮助。

I used this to be able to select points in a point cloud. Every point gets, in the alternative colorscheme, an unique color (stored in a dictionary which points to the points id (index)).

When I click the mouse it retreives the current pixel and checks the list. If it finds a color that are present in the set it will know what point was clicked.

This is pretty good since I did not have to use raycasting or octtrees or similar checks. Worth noticing though is that this will make it impossible to find anything behind the points that are currently showed on the screen.

I render the alternative colors, pick the pixel-under-mouse-color but I do not use "swapbuffer()" so it will never show on the screen. Then I render it again with the corerct colors.

Pretty nifty.

public void RenderAlternativeColorsAndPick(int x, int y)
{
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id_alt);
  GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
  GL.EnableClientState(ArrayCap.ColorArray);

  GL.EnableClientState(ArrayCap.VertexArray);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);

  // Psuedo code sorry
  GL.GetPixelColor(x,y)
  SelectedPoint    = dictionary<color,int>.findValuebyKey(thePixelsColor)
}

Hope this helps someone in the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文