public void SetVariable(string name, Vector4 x) { if (ProgramId > 0) { GLStates.UseProgram(ProgramId); int location = GetUniformLocation(name); if (location != -1) { GL.Uniform4(location, x); } } }
public void SetVariable(string name, Matrix2 matrix) { if (ProgramId > 0) { GLStates.UseProgram(ProgramId); int location = GetUniformLocation(name); if (location != -1) { GL.UniformMatrix2(location, false, ref matrix); } } }
public TiledTexture(string filename, float tileWidth, float tileHeight) { TileSize = new Vector2(tileWidth, tileHeight); Filename = filename; TextureId = GL.GenTexture(); GLStates.BindTexture(TextureTarget.Texture2D, TextureId); Bitmap bmp = new Bitmap(filename); BitmapData bmpData = bmp.LockBits( new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Stride = bmp.Width / (int)tileWidth; uRatio = 1f / (float)bmp.Width; vRatio = 1f / (float)bmp.Height; uTile = uRatio * (float)TileWidth; vTile = vRatio * (float)TileHeight; //Set Alpha IntPtr ptr = bmpData.Scan0; int bytes = Math.Abs(bmpData.Stride) * bmp.Height; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); int r = rgbValues[0]; int b = rgbValues[1]; int g = rgbValues[2]; Background = new Vector4(rgbValues[0] / 255f, rgbValues[1] / 255f, rgbValues[2] / 255f, rgbValues[3] / 255f); for (int i = 0; i < rgbValues.Length; i += 4) { if (rgbValues[i] == r && rgbValues[i + 1] == b && rgbValues[i + 2] == g) { rgbValues[i + 3] = 0; } } System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); //Create Texture GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmpData.Width, bmpData.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0); bmp.UnlockBits(bmpData); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); }
public void Draw() { if (updated) { UpdateBuffer(); updated = false; } GLStates.ActiveTexture(TextureUnit.Texture0); GLStates.BindTexture(TextureTarget.Texture2D, TiledTexture.TextureId); GLStates.BindBuffer(BufferTarget.ElementArrayBuffer, Quad.IBO); GLStates.UseProgram(program.ProgramId); GLStates.BindBuffer(BufferTarget.ArrayBuffer, Quad.VBO); GLStates.EnableVertexAttribArray(program.GetAttribLocation("vertex_position")); GL.VertexAttribPointer(program.GetAttribLocation("vertex_position"), 2, VertexAttribPointerType.Float, false, 0, 0); if (BackColor) { GLStates.BindBuffer(BufferTarget.ArrayBuffer, tileBO); GLStates.EnableVertexAttribArray(program.GetAttribLocation("tex_position")); GL.VertexAttribPointer(program.GetAttribLocation("tex_position"), 2, VertexAttribPointerType.Float, false, 10 * sizeof(float), 0); GL.VertexAttribDivisor(program.GetAttribLocation("tex_position"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("vx_color")); GL.VertexAttribPointer(program.GetAttribLocation("vx_color"), 4, VertexAttribPointerType.Float, false, 10 * sizeof(float), 2 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("vx_color"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("vx_back_color")); GL.VertexAttribPointer(program.GetAttribLocation("vx_back_color"), 4, VertexAttribPointerType.Float, false, 10 * sizeof(float), 6 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("vx_back_color"), 1); } else { GLStates.BindBuffer(BufferTarget.ArrayBuffer, tileBO); GLStates.EnableVertexAttribArray(program.GetAttribLocation("tex_position")); GL.VertexAttribPointer(program.GetAttribLocation("tex_position"), 2, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); GL.VertexAttribDivisor(program.GetAttribLocation("tex_position"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("vx_color")); GL.VertexAttribPointer(program.GetAttribLocation("vx_color"), 4, VertexAttribPointerType.Float, false, 6 * sizeof(float), 2 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("vx_color"), 1); } GL.DrawElementsInstanced(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedByte, IntPtr.Zero, drawCount); }
static Quad() { VBO = GL.GenBuffer(); float[] vertices = { 1.0f, 0.0f, //Pos 0 0.0f, 0.0f, //Pos 1 0.0f, 1.0f, //Pos 2 1.0f, 1.0f }; //Pos 3 GLStates.BindBuffer(BufferTarget.ArrayBuffer, VBO); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw); IBO = GL.GenBuffer(); byte[] indices = { 0, 1, 2, 2, 3, 0 }; GLStates.BindBuffer(BufferTarget.ElementArrayBuffer, IBO); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(byte)), indices, BufferUsageHint.StaticDraw); }
public void Draw() { UpdateBuffer(); GLStates.Enable(EnableCap.Blend); GLStates.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GLStates.ActiveTexture(TextureUnit.Texture0); GLStates.BindTexture(TextureTarget.Texture2D, TiledTexture.TextureId); GLStates.BindBuffer(BufferTarget.ElementArrayBuffer, Quad.IBO); GLStates.UseProgram(program.ProgramId); GLStates.BindBuffer(BufferTarget.ArrayBuffer, Quad.VBO); GLStates.EnableVertexAttribArray(program.GetAttribLocation("vertex_position")); GL.VertexAttribPointer(program.GetAttribLocation("vertex_position"), 2, VertexAttribPointerType.Float, false, 0, 0); GLStates.BindBuffer(BufferTarget.ArrayBuffer, bufferObject.Id); GLStates.EnableVertexAttribArray(program.GetAttribLocation("sprite_position")); GL.VertexAttribPointer(program.GetAttribLocation("sprite_position"), 2, VertexAttribPointerType.Float, false, 13 * sizeof(float), 0); GL.VertexAttribDivisor(program.GetAttribLocation("sprite_position"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("size")); GL.VertexAttribPointer(program.GetAttribLocation("size"), 2, VertexAttribPointerType.Float, false, 13 * sizeof(float), 2 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("size"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("tex_position")); GL.VertexAttribPointer(program.GetAttribLocation("tex_position"), 2, VertexAttribPointerType.Float, false, 13 * sizeof(float), 4 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("tex_position"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("scale")); GL.VertexAttribPointer(program.GetAttribLocation("scale"), 2, VertexAttribPointerType.Float, false, 13 * sizeof(float), 6 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("scale"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("rotation")); GL.VertexAttribPointer(program.GetAttribLocation("rotation"), 1, VertexAttribPointerType.Float, false, 13 * sizeof(float), 8 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("rotation"), 1); GLStates.EnableVertexAttribArray(program.GetAttribLocation("vx_color")); GL.VertexAttribPointer(program.GetAttribLocation("vx_color"), 4, VertexAttribPointerType.Float, false, 13 * sizeof(float), 9 * sizeof(float)); GL.VertexAttribDivisor(program.GetAttribLocation("vx_color"), 1); GL.DrawElementsInstanced(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedByte, IntPtr.Zero, Sprites.Count); }
private void UpdateBuffer() { if (BackColor) { for (int i = 0; i < drawCount; i++) { Vector2 uv = TiledTexture.GetUV(tiles[i]); int i10 = i * 10; tileVertices[i10] = uv[0]; tileVertices[i10 + 1] = uv[1]; tileVertices[i10 + 2] = colors[i][0]; tileVertices[i10 + 3] = colors[i][1]; tileVertices[i10 + 4] = colors[i][2]; tileVertices[i10 + 5] = colors[i][3]; tileVertices[i10 + 6] = backColors[i][0]; tileVertices[i10 + 7] = backColors[i][1]; tileVertices[i10 + 8] = backColors[i][2]; tileVertices[i10 + 9] = backColors[i][3]; } } else { for (int i = 0; i < drawCount; i++) { Vector2 uv = TiledTexture.GetUV(tiles[i]); int i10 = i * 6; tileVertices[i10] = uv[0]; tileVertices[i10 + 1] = uv[1]; tileVertices[i10 + 2] = colors[i][0]; tileVertices[i10 + 3] = colors[i][1]; tileVertices[i10 + 4] = colors[i][2]; tileVertices[i10 + 5] = colors[i][3]; } } GLStates.BindBuffer(BufferTarget.ArrayBuffer, tileBO); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(tileVertices.Length * sizeof(float)), tileVertices, BufferUsageHint.DynamicDraw); }
private void UpdateBuffer() { for (int i = 0; i < Sprites.Count; i++) { int i2 = i * 13; Vector2 uv = TiledTexture.GetUV(Sprites[i].tile); //sprite_position bufferObject.Data[i2] = Sprites[i].position.X; bufferObject.Data[i2 + 1] = Sprites[i].position.Y; //Size bufferObject.Data[i2 + 2] = Sprites[i].size.X; bufferObject.Data[i2 + 3] = Sprites[i].size.Y; //Texture bufferObject.Data[i2 + 4] = uv.X; bufferObject.Data[i2 + 5] = uv.Y; //Scale bufferObject.Data[i2 + 6] = Sprites[i].scale.X; bufferObject.Data[i2 + 7] = Sprites[i].scale.Y; //Rotation bufferObject.Data[i2 + 8] = Sprites[i].rotation; //Color bufferObject.Data[i2 + 9] = Sprites[i].color[0]; bufferObject.Data[i2 + 10] = Sprites[i].color[1]; bufferObject.Data[i2 + 11] = Sprites[i].color[2]; bufferObject.Data[i2 + 12] = Sprites[i].color[3]; } GLStates.BindBuffer(BufferTarget.ArrayBuffer, bufferObject.Id); GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0, (IntPtr)(Sprites.Count * 13 * sizeof(float)), bufferObject.Data); }
public TileGrid(TiledTexture tiledTexture, int x, int y, int z, int width, int height, float scaleX, float scaleY, bool backColor) { Width = width; Height = height; Scale = new Vector2(scaleX, scaleY); drawCount = width * height; TiledTexture = tiledTexture; BackColor = backColor; X = x; Y = y; Z = z; //Shader program = new Program(); string vertexShader = @" in vec2 vertex_position; in vec2 tex_position; in vec4 vx_color; in vec4 vx_back_color; varying vec4 fg_color; varying vec2 tex_coord; uniform mat4 projection; uniform vec2 offset; uniform float grid_width; uniform vec2 tile_size; uniform mat2 uvTile; {0} void main() { fg_color = vx_color; {1} float a = floor(gl_InstanceID / grid_width); gl_Position = projection * mat4(vec4(tile_size.x, 0.0, 0.0, 0.0), vec4(0.0, tile_size.y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4((gl_InstanceID - (grid_width * a)) * tile_size.x, a * tile_size.y, 0.0, 1.0)) * vec4(vertex_position + offset, 0.0, 1.0); tex_coord = tex_position + (vertex_position * uvTile); } "; string fragShader = @" varying vec2 tex_coord; varying vec4 fg_color; uniform sampler2D tex_sampler; {0} void main() { gl_FragColor = texture2D(tex_sampler, tex_coord).bgra; {1} } "; if (BackColor) { vertexShader = vertexShader.Replace("{0}", "varying vec4 fg_back_color;"); vertexShader = vertexShader.Replace("{1}", "fg_back_color = vx_back_color;"); fragShader = fragShader.Replace("{0}", "varying vec4 fg_back_color; uniform vec4 background;"); fragShader = fragShader.Replace("{1}", "if (gl_FragColor.rgb == background.rgb) gl_FragColor = fg_back_color; else gl_FragColor *= fg_color;"); } else { vertexShader = vertexShader.Replace("{0}", string.Empty); vertexShader = vertexShader.Replace("{1}", string.Empty); fragShader = fragShader.Replace("{0}", string.Empty); fragShader = fragShader.Replace("{1}", "gl_FragColor *= fg_color;"); } program.AddShader(ShaderType.VertexShader, vertexShader); program.AddShader(ShaderType.FragmentShader, fragShader); program.SetVariable("grid_width", (float)width); program.SetVariable("offset", new Vector2(X, Y)); program.SetVariable("tile_size", tiledTexture.TileSize * Scale); program.SetVariable("uvTile", new Matrix2(tiledTexture.uTile, 0, 0, tiledTexture.vTile)); program.SetVariable("projection", Projection.Matrix); program.SetVariable("tex_sampler", 0); if (BackColor) { program.SetVariable("background", tiledTexture.Background); } Projection.ProjectionChangeEvent += Projection_ProjectionChangeEvent; //Tile and Colors tiles = new ushort[drawCount]; colors = new Vector4[drawCount]; backColors = new Vector4[drawCount]; if (BackColor) { tileVertices = new float[drawCount * 10]; } else { tileVertices = new float[drawCount * 6]; } tileBO = GL.GenBuffer(); GLStates.BindBuffer(BufferTarget.ArrayBuffer, tileBO); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(tileVertices.Length * sizeof(float)), IntPtr.Zero, BufferUsageHint.DynamicDraw); }
public void Use() { GLStates.UseProgram(ProgramId); }