public void ShaderProgram_SaveBinary() { if (!_Context.IsProgramBinarySupported) { Assert.Inconclusive(); } byte[] programBinary = null; int programBinaryFormat = 0; // Save program to binary format using (ShaderProgram shaderProgram = new ShaderProgram("OpenGL.Objects.Test.ShaderProgram.Link")) using (Shader vertexShader = new Shader(ShaderType.VertexShader)) using (Shader fragmentShader = new Shader(ShaderType.FragmentShader)) { vertexShader.LoadSource(new[] { "#version 150", "in vec4 vPosition;", "void main() {", " gl_Position = vPosition;", "}", }); fragmentShader.LoadSource(new[] { "#version 150", "out vec4 test_Output;", "void main() {", " test_Output = vec4(0.0, 0.0, 0.0, 1.0);", "}", }); shaderProgram.Attach(vertexShader); shaderProgram.Attach(fragmentShader); shaderProgram.Create(_Context); Assert.IsTrue(shaderProgram.IsLinked); Assert.AreEqual("vPosition", shaderProgram.ActiveAttributes.First()); Assert.DoesNotThrow(() => { using (MemoryStream memoryStream = new MemoryStream()) { shaderProgram.GetBinary(_Context, memoryStream, out programBinaryFormat); programBinary = memoryStream.ToArray(); } }); } // Save program to binary format using (ShaderProgram shaderProgram = new ShaderProgram("OpenGL.Objects.Test.ShaderProgram.Link")) { shaderProgram.Create(_Context, programBinary, programBinaryFormat); Assert.IsTrue(shaderProgram.IsLinked); Assert.AreEqual("vPosition", shaderProgram.ActiveAttributes.First()); } }
public void ExampleCreateShaderProgram(GraphicsContext ctx, IEnumerable <Shader> shaderObjects) { ShaderProgram shaderProgram = new ShaderProgram("SampleProgram"); foreach (Shader shader in shaderObjects) { shaderProgram.Attach(shader); } shaderProgram.Create(ctx); }
public void ShaderProgram_CreateSimple() { using (ShaderProgram shaderProgram = new ShaderProgram("OpenGL.Objects.Test.ShaderProgram.Link")) using (Shader vertexShader = new Shader(ShaderType.VertexShader)) using (Shader fragmentShader = new Shader(ShaderType.FragmentShader)) { // Create shaders vertexShader.LoadSource(new[] { "#version 150", "void main() {", " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);", "}", }); Assert.IsFalse(vertexShader.Exists(_Context)); fragmentShader.LoadSource(new[] { "#version 150", "out vec4 test_Output;", "void main() {", " test_Output = vec4(0.0, 0.0, 0.0, 1.0);", "}", }); // Attach shaders Assert.DoesNotThrow(() => { shaderProgram.Attach(vertexShader); }); Assert.DoesNotThrow(() => { shaderProgram.Attach(fragmentShader); }); // Attachment does not create resources Assert.IsFalse(vertexShader.Exists(_Context)); Assert.IsFalse(fragmentShader.Exists(_Context)); // Compile and link Assert.IsFalse(shaderProgram.IsLinked); shaderProgram.Create(_Context); Assert.IsTrue(shaderProgram.IsLinked); Assert.IsTrue(vertexShader.Exists(_Context)); Assert.IsTrue(fragmentShader.Exists(_Context)); } }
public void ShaderStorageBuffer_TestShaderProgram() { if (!_Context.Extensions.ComputeShader_ARB) { Assert.Inconclusive("GL_ARB_compute_shader not supported"); } if (!_Context.Extensions.ShaderStorageBufferObject_ARB) { Assert.Inconclusive("GL_ARB_shader_storage_buffer_object not supported"); } const uint Size = 1024; using (ShaderProgram program = new ShaderProgram("")) using (Shader computeShader = new Shader(ShaderType.ComputeShader)) using (ShaderStorageBuffer storageBuffer = new ShaderStorageBuffer(MapBufferUsageMask.MapReadBit)) { computeShader.LoadSource(new[] { "#version 430", "layout(local_size_x = 1, local_size_y = 1) in;", "layout(std430, binding = 3) buffer glo_Buffer {", " uint data[];", "};", "", "void main() {", " data[gl_WorkGroupID.x * gl_WorkGroupID.y] = uint(gl_WorkGroupID.x * gl_WorkGroupID.y);", "}" }); program.Attach(computeShader); program.Create(_Context); storageBuffer.Create(_Context, Size * Size * 4); program.SetStorageBuffer(_Context, "glo_Buffer", storageBuffer); program.Compute(_Context, Size, Size); program.MemoryBarrier(MemoryBarrierMask.ShaderStorageBarrierBit); uint[] storage = new uint[Size * Size]; storageBuffer.Load(_Context, storage, Size * Size * 4); for (uint x = 0; x < Size; x++) { for (uint y = 0; y < Size; y++) { Assert.AreEqual(x * y, storage[x * y]); } } } }
public static Shaders.ShaderProgram CreateShaderProgram(params Shaders.Shader[] shaders) { var result = new ShaderProgram(); foreach (var shader in shaders) { result.Attach(shader); } BindVertexAttributeLocations(result); result.Link(); return(result); }
public void ComputeProgram_SetUniformImage() { const uint Size = 1024; using (ShaderProgram computeProgram = new ShaderProgram("OpenGL.Objects.Test.ComputeProgram")) using (Shader computeShader = new Shader(ShaderType.ComputeShader)) using (Texture2D texture0 = new Texture2D()) using (Texture2D texture1 = new Texture2D(Size / 2, Size / 2, PixelLayout.R8)) { computeShader.LoadSource(new[] { "#version 430", "layout(local_size_x = 1, local_size_y = 1) in;", "layout(r8) uniform image2D glo_ImageInput;", "layout(r8) uniform image2D glo_ImageOutput;", "", "void main() {", " ivec2 glo_ImageOutputCoords = ivec2(gl_GlobalInvocationID.xy);", " vec2 ndc = glo_ImageOutputCoords / imageSize(glo_ImageOutput).xy;", " ivec2 glo_ImageInputCoords = ivec2(ndc * imageSize(glo_ImageInput).xy);", "", " vec4 v00 = imageLoad(glo_ImageInput, glo_ImageInputCoords + ivec2(0, 0));", " vec4 v01 = imageLoad(glo_ImageInput, glo_ImageInputCoords + ivec2(0, 1));", " vec4 v10 = imageLoad(glo_ImageInput, glo_ImageInputCoords + ivec2(1, 0));", " vec4 v11 = imageLoad(glo_ImageInput, glo_ImageInputCoords + ivec2(1, 1));", " vec4 max = max(max(v00, v01), max(v10, v11));", "", " imageStore(glo_ImageOutput, glo_ImageOutputCoords, max);", "}" }); computeProgram.Attach(computeShader); computeProgram.Create(_Context); using (Image image = new Image(PixelLayout.R8, Size, Size)) { for (uint y = 0; y < image.Height; y++) { for (uint x = 0; x < image.Width; x++) { if ((x % 2) == 0 && (y % 2) == 0) { image.SetPixel(x, y, (byte)254); } else { image.SetPixel(x, y, (byte)0); } } } texture0.Create(_Context, image); } texture1.Create(_Context); // SetUniformImage requires the program bound // TODO: evaluate to call bind implicitly in SetUniformImage _Context.Bind(computeProgram); computeProgram.SetUniformImage(_Context, "glo_ImageInput", texture0, BufferAccess.ReadOnly); computeProgram.SetUniformImage(_Context, "glo_ImageOutput", texture1, BufferAccess.WriteOnly); computeProgram.Compute(_Context, texture1.Width, texture1.Height); computeProgram.MemoryBarrier(MemoryBarrierMask.BufferUpdateBarrierBit); using (Image result = texture1.Get(_Context, PixelLayout.R8, 0)) { for (uint y = 0; y < result.Height; y++) { for (uint x = 0; x < result.Width; x++) { byte pixel = result.GetPixel <byte>(x, y); Assert.AreEqual(pixel, 254); } } } } }