title: Binding OpenGL vertex buffers per frame for multiple meshes
body: <p>I'm making and OpenGL application that has <strong><em>MULTIPLE</em></strong> meshes that are described as lists of positions, normals, and uvs. I am binding these data to a vertex buffer but I was wondering how I would draw these meshes per frame without re-binding the vertex buffer. Correct me if I'm wrong, but isn't copying ~100KB of data to the vertex buffer slowish? How would I draw each mesh with separate transforms (position, rotation, scale). Thanks :) Here is my Mesh code:</p>
  
  <pre><code>using System;
  using System.IO;
  using OpenTK;
  using OpenTK.Graphics.OpenGL;
  
  public class Mesh
  {
      public Vector3[] positions;
      public Vector3[] normals;
      public Vector2[] uvs;
      public Triangle[] triangles;
      public int buffer;
      public Mesh()
      {
          this.positions = new Vector3[0];
          this.normals = new Vector3[0];
          this.uvs = new Vector2[0];
          this.triangles = new Triangle[0];
          this.buffer = 0;
      }
      public Mesh(Vector3[] positions, Vector3[] normals, Vector2[] uvs, Triangle[] triangles, int buffer)
      {
          this.positions = positions;
          this.normals = normals;
          this.uvs = uvs;
          this.triangles = triangles;
          this.buffer = buffer;
      }
      public static Mesh fromFile(string fileName)
      {
          Mesh mesh = new Mesh();
          BinaryReader binaryReader = new BinaryReader(new FileStream(fileName, FileMode.Open));
          int positionCount = binaryReader.ReadInt32();
          mesh.positions = new Vector3[positionCount];
          for (int i = 0; i &lt; positionCount; i++)
          {
              mesh.positions[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
          }
          int normalCount = binaryReader.ReadInt32();
          mesh.normals = new Vector3[normalCount];
          for (int i = 0; i &lt; normalCount; i++)
          {
              mesh.normals[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
          }
          int uvCount = binaryReader.ReadInt32();
          mesh.uvs = new Vector2[uvCount];
          for (int i = 0; i &lt; uvCount; i++)
          {
              mesh.uvs[i] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
          }
          int triangleCount = binaryReader.ReadInt32();
          mesh.triangles = new Triangle[triangleCount];
          for (int i = 0; i &lt; triangleCount; i++)
          {
              mesh.triangles[i] = new Triangle(binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32());
          }
          binaryReader.Close();
          return mesh;
      }
      public void toFile(string fileName)
      {
          BinaryWriter binaryWriter = new BinaryWriter(new FileStream(fileName, FileMode.OpenOrCreate));
          binaryWriter.Write(positions.Length);
          for (int i = 0; i &lt; positions.Length; i++)
          {
              binaryWriter.Write(positions[i].X);
              binaryWriter.Write(positions[i].Y);
              binaryWriter.Write(positions[i].Z);
          }
          binaryWriter.Write(normals.Length);
          for (int i = 0; i &lt; normals.Length; i++)
          {
              binaryWriter.Write(normals[i].X);
              binaryWriter.Write(normals[i].Y);
              binaryWriter.Write(normals[i].Z);
          }
          binaryWriter.Write(uvs.Length);
          for (int i = 0; i &lt; uvs.Length; i++)
          {
              binaryWriter.Write(uvs[i].X);
              binaryWriter.Write(uvs[i].Y);
          }
          binaryWriter.Write(triangles.Length);
          for (int i = 0; i &lt; triangles.Length; i++)
          {
              binaryWriter.Write(triangles[i].positionIndex0);
              binaryWriter.Write(triangles[i].normalIndex0);
              binaryWriter.Write(triangles[i].uvIndex0);
              binaryWriter.Write(triangles[i].positionIndex1);
              binaryWriter.Write(triangles[i].normalIndex1);
              binaryWriter.Write(triangles[i].uvIndex1);
              binaryWriter.Write(triangles[i].positionIndex2);
              binaryWriter.Write(triangles[i].normalIndex2);
              binaryWriter.Write(triangles[i].uvIndex2);
          }
          binaryWriter.Close();
      }
      public void draw(Transform transform)
      {
          float[] data = new float[triangles.Length * 24];
          for (int i = 0; i &lt; triangles.Length; i++)
          {
              data[(i * 9) + 0] = positions[triangles[i].positionIndex0].X;
              data[(i * 9) + 1] = positions[triangles[i].positionIndex0].Y;
              data[(i * 9) + 2] = positions[triangles[i].positionIndex0].Z;
              data[(i * 9) + 3] = positions[triangles[i].positionIndex1].X;
              data[(i * 9) + 4] = positions[triangles[i].positionIndex1].Y;
              data[(i * 9) + 5] = positions[triangles[i].positionIndex1].Z;
              data[(i * 9) + 6] = positions[triangles[i].positionIndex2].X;
              data[(i * 9) + 7] = positions[triangles[i].positionIndex2].Y;
              data[(i * 9) + 8] = positions[triangles[i].positionIndex2].Z;
              data[(triangles.Length * 9) + (i * 9) + 0] = normals[triangles[i].normalIndex0].X;
              data[(triangles.Length * 9) + (i * 9) + 1] = normals[triangles[i].normalIndex0].Y;
              data[(triangles.Length * 9) + (i * 9) + 2] = normals[triangles[i].normalIndex0].Z;
              data[(triangles.Length * 9) + (i * 9) + 3] = normals[triangles[i].normalIndex1].X;
              data[(triangles.Length * 9) + (i * 9) + 4] = normals[triangles[i].normalIndex1].Y;
              data[(triangles.Length * 9) + (i * 9) + 5] = normals[triangles[i].normalIndex1].Z;
              data[(triangles.Length * 9) + (i * 9) + 6] = normals[triangles[i].normalIndex2].X;
              data[(triangles.Length * 9) + (i * 9) + 7] = normals[triangles[i].normalIndex2].Y;
              data[(triangles.Length * 9) + (i * 9) + 8] = normals[triangles[i].normalIndex2].Z;
              data[(triangles.Length * 18) + (i * 6) + 0] = uvs[triangles[i].uvIndex0].X;
              data[(triangles.Length * 18) + (i * 6) + 1] = uvs[triangles[i].uvIndex0].Y;
              data[(triangles.Length * 18) + (i * 6) + 2] = uvs[triangles[i].uvIndex1].X;
              data[(triangles.Length * 18) + (i * 6) + 3] = uvs[triangles[i].uvIndex1].Y;
              data[(triangles.Length * 18) + (i * 6) + 4] = uvs[triangles[i].uvIndex2].X;
              data[(triangles.Length * 18) + (i * 6) + 5] = uvs[triangles[i].uvIndex2].Y;
          }
          buffer = GL.GenBuffer();
          GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
          GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(triangles.Length * 96), data, BufferUsageHint.StaticDraw);
          //------------------------
          //----------TODO----------
          //------------------------
      }
  }
  </code></pre>
  
  <p>The last function, draw, is the one I'm working on.</p>