Search code examples
openglcolorsvboopentk

OpenTK: Using different colors with a VBO


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.


Solution

  • 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);