public void UpdatePositionSingleVertex(Surface s, int index, int layout_index = 0) { float[] values = new float[4 * s.vbo.PositionDimensions]; //2 or 3 dimensions for 4 vertices CellLayout layout = s.layouts[layout_index]; float cellx = layout.X(index) + layout.HorizontalOffset; // get cellx+y from layout in world coords, then convert to NDC float celly = layout.Y(index) + layout.VerticalOffset; float x = cellx * worldUnitNdcWidth - 1.0f; float y = celly * worldUnitNdcHeight - 1.0f; float x_plus1 = (cellx + layout.CellWidth) * worldUnitNdcWidth - 1.0f; float y_plus1 = (celly + layout.CellHeight) * worldUnitNdcHeight - 1.0f; int N = s.vbo.PositionDimensions; values[0] = x; //the 4 corners, flipped so it works with the inverted Y axis values[1] = y_plus1; values[N] = x; values[N + 1] = y; values[N * 2] = x_plus1; values[N * 2 + 1] = y; values[N * 3] = x_plus1; values[N * 3 + 1] = y_plus1; if (N == 3) { float z = layout.Z(index); values[2] = z; values[N + 2] = z; values[N * 2 + 2] = z; values[N * 3 + 2] = z; } GL.BindBuffer(BufferTarget.ArrayBuffer, s.vbo.PositionArrayBufferID); GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * 4 * s.vbo.PositionDimensions * index), new IntPtr(sizeof(float) * values.Length), values); }
public void UpdatePositionVertexArray(Surface s, IList <int> index_list, int start_index = -1, int single_layout = 0, IList <int> layout_list = null) { int count = index_list.Count; float[] values = new float[count * 4 * s.vbo.PositionDimensions]; //2 or 3 dimensions for 4 vertices for each tile int[] indices = null; if (start_index < 0 && s.vbo.NumElements != count * 6) { indices = new int[count * 6]; s.vbo.NumElements = count * 6; } else { if (start_index >= 0) { if ((start_index + count) * 6 > s.vbo.NumElements && s.vbo.NumElements > 0) { throw new ArgumentException("Error: start_index + count is bigger than VBO size. To always replace the previous data, set start_index to -1."); } //todo: I could also just ignore the start_index if there's too much data. if ((start_index + count) * 4 * s.vbo.PositionDimensions > s.vbo.PositionDataSize && s.vbo.PositionDataSize > 0) { throw new ArgumentException("Error: (start_index + count) * total_attrib_size is bigger than VBO size. To always replace the previous data, set start_index to -1."); } } } CellLayout layout = layout_list != null? null : s.layouts[single_layout]; for (int i = 0; i < count; ++i) { if (layout_list != null) { layout = s.layouts[layout_list[i]]; } int current_index = index_list[i]; float cellx = layout.X(current_index) + layout.HorizontalOffset; // get cellx+y from layout in world coords, then convert to NDC float celly = layout.Y(current_index) + layout.VerticalOffset; float x = cellx * worldUnitNdcWidth - 1.0f; float y = celly * worldUnitNdcHeight - 1.0f; float x_plus1 = (cellx + layout.CellWidth) * worldUnitNdcWidth - 1.0f; float y_plus1 = (celly + layout.CellHeight) * worldUnitNdcHeight - 1.0f; int N = s.vbo.PositionDimensions; int idxN = i * 4 * N; values[idxN] = x; //the 4 corners, flipped so it works with the inverted Y axis values[idxN + 1] = y_plus1; values[idxN + N] = x; values[idxN + N + 1] = y; values[idxN + N * 2] = x_plus1; values[idxN + N * 2 + 1] = y; values[idxN + N * 3] = x_plus1; values[idxN + N * 3 + 1] = y_plus1; if (N == 3) { float z = layout.Z(current_index); values[idxN + 2] = z; values[idxN + N + 2] = z; values[idxN + N * 2 + 2] = z; values[idxN + N * 3 + 2] = z; } if (indices != null) { int idx4 = i * 4; int idx6 = i * 6; indices[idx6] = idx4; indices[idx6 + 1] = idx4 + 1; indices[idx6 + 2] = idx4 + 2; indices[idx6 + 3] = idx4; indices[idx6 + 4] = idx4 + 2; indices[idx6 + 5] = idx4 + 3; } } GL.BindBuffer(BufferTarget.ArrayBuffer, s.vbo.PositionArrayBufferID); if ((start_index < 0 && s.vbo.PositionDataSize != values.Length) || s.vbo.PositionDataSize == 0) { GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * values.Length), values, BufferUsageHint.StreamDraw); s.vbo.PositionDataSize = values.Length; } else { int offset = start_index; if (offset < 0) { offset = 0; } GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * 4 * s.vbo.PositionDimensions * offset), new IntPtr(sizeof(float) * values.Length), values); } if (indices != null) { GL.BindBuffer(BufferTarget.ElementArrayBuffer, s.vbo.ElementArrayBufferID); GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(int) * indices.Length), indices, BufferUsageHint.StaticDraw); } }