public void UpdateVertexArray(int row, int col, SpriteSurface s, int sprite_offset_row, int sprite_offset_col, params float[][] vertex_attributes) { GL.BindBuffer(BufferTarget.ArrayBuffer, s.ArrayBufferID); float tex_start_h = s.SpriteHeight * sprite_offset_row; float tex_start_w = s.SpriteWidth * sprite_offset_col; float tex_end_h = tex_start_h + s.SpriteHeightPadded; float tex_end_w = tex_start_w + s.SpriteWidthPadded; int flipped_row = (s.Rows - 1) - row; float fi = screen_multiplier_h * (((float)flipped_row / s.HeightScale) + s.GLCoordHeightOffset); float fj = screen_multiplier_w * (((float)col / s.WidthScale) + s.GLCoordWidthOffset); float fi_plus1 = screen_multiplier_h * (((float)(flipped_row + 1) / s.HeightScale) + s.GLCoordHeightOffset); float fj_plus1 = screen_multiplier_w * (((float)(col + 1) / s.WidthScale) + s.GLCoordWidthOffset); float[] values = new float[4 * s.TotalVertexAttribSize]; values[0] = fj; values[1] = fi; values[2] = tex_start_w; values[3] = tex_end_h; values[s.TotalVertexAttribSize] = fj; values[1 + s.TotalVertexAttribSize] = fi_plus1; values[2 + s.TotalVertexAttribSize] = tex_start_w; values[3 + s.TotalVertexAttribSize] = tex_start_h; values[s.TotalVertexAttribSize * 2] = fj_plus1; values[1 + s.TotalVertexAttribSize * 2] = fi_plus1; values[2 + s.TotalVertexAttribSize * 2] = tex_end_w; values[3 + s.TotalVertexAttribSize * 2] = tex_start_h; values[s.TotalVertexAttribSize * 3] = fj_plus1; values[1 + s.TotalVertexAttribSize * 3] = fi; values[2 + s.TotalVertexAttribSize * 3] = tex_end_w; values[3 + s.TotalVertexAttribSize * 3] = tex_end_h; int total_of_previous_attribs = 4; for (int j = 2; j < s.VertexAttribSize.Length; ++j) //starting at 2 because vertex position & texcoords are already done { for (int k = 0; k < s.VertexAttribSize[j]; ++k) { float attrib = vertex_attributes[j - 2][k]; values[total_of_previous_attribs + k] = attrib; values[total_of_previous_attribs + k + s.TotalVertexAttribSize] = attrib; values[total_of_previous_attribs + k + (s.TotalVertexAttribSize * 2)] = attrib; values[total_of_previous_attribs + k + (s.TotalVertexAttribSize * 3)] = attrib; } total_of_previous_attribs += s.VertexAttribSize[j]; } int idx = (col + row * s.Cols) * 4 * s.TotalVertexAttribSize; GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * idx), new IntPtr(sizeof(float) * 4 * s.TotalVertexAttribSize), values); }
public static void LoadShaders(SpriteSurface s, string vs, string fs, params string[] attributes) { int vertex_shader = GL.CreateShader(ShaderType.VertexShader); int fragment_shader = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(vertex_shader, vs); GL.ShaderSource(fragment_shader, fs); GL.CompileShader(vertex_shader); GL.CompileShader(fragment_shader); int compiled; GL.GetShader(vertex_shader, ShaderParameter.CompileStatus, out compiled); if (compiled < 1) { Console.Error.WriteLine(GL.GetShaderInfoLog(vertex_shader)); throw new Exception("vertex shader compilation failed"); } GL.GetShader(fragment_shader, ShaderParameter.CompileStatus, out compiled); if (compiled < 1) { Console.Error.WriteLine(GL.GetShaderInfoLog(fragment_shader)); throw new Exception("fragment shader compilation failed"); } int shader_program = GL.CreateProgram(); GL.AttachShader(shader_program, vertex_shader); GL.AttachShader(shader_program, fragment_shader); int attrib_index = 0; foreach (string attr in attributes) { GL.BindAttribLocation(shader_program, attrib_index++, attr); } GL.LinkProgram(shader_program); s.ShaderProgramID = shader_program; GL.UseProgram(shader_program); s.UniformLocation = GL.GetUniformLocation(shader_program, "texture"); GL.Uniform1(s.UniformLocation, s.TextureIndex); }
public void CreateVertexArray(SpriteSurface s, int default_sprite_offset_row, int default_sprite_offset_col, params float[][] default_vertex_attributes) { int count = s.Rows * s.Cols; float[] all_values = new float[count * 4 * s.TotalVertexAttribSize]; //4 vertices for each tile int[] indices = new int[s.NumElements]; float tex_start_h = s.SpriteHeight * default_sprite_offset_row; float tex_start_w = s.SpriteWidth * default_sprite_offset_col; float tex_end_h = tex_start_h + s.SpriteHeightPadded; float tex_end_w = tex_start_w + s.SpriteWidthPadded; for (int i = 0; i < s.Rows; ++i) { for (int j = 0; j < s.Cols; ++j) { int flipped_row = (s.Rows - 1) - i; float fi = screen_multiplier_h * (((float)flipped_row / s.HeightScale) + s.GLCoordHeightOffset); float fj = screen_multiplier_w * (((float)j / s.WidthScale) + s.GLCoordWidthOffset); float fi_plus1 = screen_multiplier_h * (((float)(flipped_row + 1) / s.HeightScale) + s.GLCoordHeightOffset); float fj_plus1 = screen_multiplier_w * (((float)(j + 1) / s.WidthScale) + s.GLCoordWidthOffset); float[] values = new float[4 * s.TotalVertexAttribSize]; values[0] = fj; values[1] = fi; values[2] = tex_start_w; values[3] = tex_end_h; values[s.TotalVertexAttribSize] = fj; values[1 + s.TotalVertexAttribSize] = fi_plus1; values[2 + s.TotalVertexAttribSize] = tex_start_w; values[3 + s.TotalVertexAttribSize] = tex_start_h; values[s.TotalVertexAttribSize * 2] = fj_plus1; values[1 + s.TotalVertexAttribSize * 2] = fi_plus1; values[2 + s.TotalVertexAttribSize * 2] = tex_end_w; values[3 + s.TotalVertexAttribSize * 2] = tex_start_h; values[s.TotalVertexAttribSize * 3] = fj_plus1; values[1 + s.TotalVertexAttribSize * 3] = fi; values[2 + s.TotalVertexAttribSize * 3] = tex_end_w; values[3 + s.TotalVertexAttribSize * 3] = tex_end_h; for (int g = 2; g < s.VertexAttribSize.Length; ++g) //starting at 2 because vertex position & texcoords are already done { for (int k = 0; k < s.VertexAttribSize[g]; ++k) { float attrib = default_vertex_attributes[g - 2][k]; values[4 + k] = attrib; values[4 + k + s.TotalVertexAttribSize] = attrib; values[4 + k + (s.TotalVertexAttribSize * 2)] = attrib; values[4 + k + (s.TotalVertexAttribSize * 3)] = attrib; } } values.CopyTo(all_values, (j + i * s.Cols) * 4 * s.TotalVertexAttribSize); int idx4 = (j + i * s.Cols) * 4; int idx6 = (j + i * s.Cols) * 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; } } int vert_id; int elem_id; GL.GenBuffers(1, out vert_id); GL.GenBuffers(1, out elem_id); s.ArrayBufferID = vert_id; s.ElementArrayBufferID = elem_id; GL.BindBuffer(BufferTarget.ArrayBuffer, vert_id); GL.BindBuffer(BufferTarget.ElementArrayBuffer, elem_id); GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * all_values.Length), all_values, BufferUsageHint.StreamDraw); GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(int) * indices.Length), indices, BufferUsageHint.StaticDraw); //int stride = sizeof(float)*s.TotalVertexAttribSize; //GL.EnableVertexAttribArray(0); //GL.EnableVertexAttribArray(1); //GL.VertexAttribPointer(0,2,VertexAttribPointerType.Float,false,stride,0); //GL.VertexAttribPointer(1,2,VertexAttribPointerType.Float,false,stride,new IntPtr(sizeof(float)*2)); int total_of_previous_attribs = 4; for (int g = 2; g < s.VertexAttribSize.Length; ++g) { //GL.EnableVertexAttribArray(g); //GL.VertexAttribPointer(g,s.VertexAttribSize[g],VertexAttribPointerType.Float,false,stride,new IntPtr(sizeof(float)*total_of_previous_attribs)); total_of_previous_attribs += s.VertexAttribSize[g]; } }