internal static void UniformMatrix(GraphicsLibrary gl, int uniform, Matrix4x4 matrix) { unsafe { var t = stackalloc float[16]; t[0] = matrix.M11; t[1] = matrix.M12; t[2] = matrix.M13; t[3] = matrix.M14; t[4] = matrix.M21; t[5] = matrix.M22; t[6] = matrix.M23; t[7] = matrix.M24; t[8] = matrix.M31; t[9] = matrix.M32; t[10] = matrix.M33; t[11] = matrix.M34; t[12] = matrix.M41; t[13] = matrix.M42; t[14] = matrix.M43; t[15] = matrix.M44; gl.UniformMatrix4fv(uniform, 1, Boolean.False, t); } }
private static unsafe string GetShaderHeader(GraphicsLibrary gl) { if (shaderHeader == null) { string?s = Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.ShadingLanguageVersion))); if (s != null && s.StartsWith("4.")) { shaderHeader = "#version 4" + s.Substring(2, 2) + " core\n"; } else { shaderHeader = "#version 300 es\nprecision mediump float;\n"; } } return(shaderHeader); }
internal static unsafe uint LoadShader(GraphicsLibrary gl, ShaderType type, string source) { var shader = gl.CreateShader(type); var header = GetShaderHeader(gl); var byteCount = Encoding.UTF8.GetMaxByteCount(header.Length); byteCount += Encoding.UTF8.GetMaxByteCount(source.Length); if (byteCount + 1 > byteBuffer.Length) { byteBuffer = new byte[byteCount + 1]; } byteCount = Encoding.UTF8.GetBytes(header, 0, header.Length, byteBuffer, 0); byteCount += Encoding.UTF8.GetBytes(source, 0, source.Length, byteBuffer, byteCount); byteBuffer[byteCount] = 0; fixed(byte *p = byteBuffer) { byte *t = p; gl.ShaderSource(shader, 1, &t, null); } gl.CompileShader(shader); int len; gl.GetShaderiv(shader, ShaderParameter.InfoLogLength, &len); if (len > 1) { var buffer = new byte[len]; fixed(byte *p = buffer) { gl.GetShaderInfoLog(shader, len, &len, p); Console.WriteLine("Shader Compiler message: " + Marshal.PtrToStringAnsi(new IntPtr(p))); } } int cs; gl.GetShaderiv(shader, ShaderParameter.CompileStatus, &cs); if (cs == 0) { gl.DeleteShader(shader); throw new Exception("Shader compilation error"); } return(shader); }
internal static unsafe void LinkProgram(GraphicsLibrary gl, uint program) { gl.LinkProgram(program); int ls; gl.GetProgramiv(program, ProgramParameter.LinkStatus, &ls); if (ls == 0) { int len; gl.GetProgramiv(program, ProgramParameter.InfoLogLength, &len); if (len > 1) { var buffer = new byte[len]; fixed(byte *p = buffer) { gl.GetProgramInfoLog(program, len, &len, p); Console.WriteLine("Shader link message: " + Marshal.PtrToStringAnsi(new IntPtr(p))); } } gl.DeleteProgram(program); throw new Exception("Link error"); } }
internal static void TexImage2D(GraphicsLibrary gl, RasterImage image, TextureTarget2D target, int level) { TexturePixelFormat textureFormat; PixelFormat format; if (image.Format == RasterImageFormat.TrueColor) { textureFormat = TexturePixelFormat.Rgb8; format = PixelFormat.Rgb; } else { textureFormat = TexturePixelFormat.Rgba8; format = PixelFormat.Rgba; } unsafe { fixed(byte *p = image.Data) { var(width, height) = image.Size; gl.TexImage2D(target, level, textureFormat, width, height, 0, format, PixelType.UnsignedByte, new IntPtr(p)); } } }
internal unsafe void Launch() { Console.WriteLine("Draw Texture..."); var image = new RasterImage(); var namePrefix = typeof(DrawTextureLauncher).Namespace + ".Resources."; using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "kitten.bmp")) { image.LoadBmp(stream ?? throw new InvalidOperationException()); } using var windowServer = new WindowServer(); using var renderingContext = new RenderingContext(); using var window = windowServer.CreateWindow(renderingContext); window.BorderStyle = WindowBorderStyle.Sizable; renderingContext.CurrentWindow = window; window.MinimumSize = (400, 300); window.MaximumSize = (600, 500); window.Size = (450, 350); window.Opacity = 0.8; var gl = new GraphicsLibrary(renderingContext); gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); var program = gl.CreateProgram(); var vertexShader = OpenGLHelper.LoadShader(gl, ShaderType.Vertex, @" in vec2 position; in vec3 color; in vec2 texCoord; out vec3 fColor; out vec2 fTexCoord; void main() { gl_Position = vec4(position, 0.0, 1.0); fColor = color; fTexCoord = texCoord; } "); gl.AttachShader(program, vertexShader); var fragmentShader = OpenGLHelper.LoadShader(gl, ShaderType.Fragment, @" in vec3 fColor; in vec2 fTexCoord; out vec4 outColor; uniform sampler2D tex; void main() { outColor = texture(tex, fTexCoord) * vec4(fColor, 1.0); } "); gl.AttachShader(program, fragmentShader); var position = 0u; OpenGLHelper.BindAttribLocation(gl, program, position, "position"); var color = 1u; OpenGLHelper.BindAttribLocation(gl, program, color, "color"); var texCoord = 2u; OpenGLHelper.BindAttribLocation(gl, program, texCoord, "texCoord"); OpenGLHelper.LinkProgram(gl, program); uint h; gl.GenVertexArrays(1, &h); uint vertexArray = h; gl.BindVertexArray(vertexArray); float[] vertices = new float[] { -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left }; gl.GenBuffers(1, &h); uint vertexBuffer = h; gl.BindBuffer(BufferTarget.Array, vertexBuffer); OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw); var elements = new ushort[] { 0, 1, 2, 2, 3, 0 }; gl.GenBuffers(1, &h); uint elementBuffer = h; gl.BindBuffer(BufferTarget.ElementArray, elementBuffer); OpenGLHelper.BufferData(gl, BufferTarget.ElementArray, elements, BufferUsage.StaticDraw); gl.UseProgram(program); var stride = sizeof(float) * 7; gl.EnableVertexAttribArray(position); gl.VertexAttribPointer(position, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero); gl.EnableVertexAttribArray(color); gl.VertexAttribPointer(color, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 2 * sizeof(float)); gl.EnableVertexAttribArray(texCoord); gl.VertexAttribPointer(texCoord, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 5 * sizeof(float)); gl.GenTextures(1, &h); var texture = h; gl.ActiveTexture(TextureUnit.Texture0); gl.BindTexture(TextureTarget.Texture2d, texture); OpenGLHelper.TexImage2D(gl, image, TextureTarget2D.Texture2d, 0); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapS, (int)TextureParameterValue.ClampToEdge); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapT, (int)TextureParameterValue.ClampToEdge); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMinFilter, (int)TextureParameterValue.Linear); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMagFilter, (int)TextureParameterValue.Linear); var tex = OpenGLHelper.GetUniformLocation(gl, program, "tex"); gl.Uniform1i(tex, 0); window.Closed += (sender, e) => { uint t = texture; gl.DeleteTextures(1, &t); gl.DeleteProgram(program); gl.DeleteShader(vertexShader); gl.DeleteShader(fragmentShader); t = vertexBuffer; gl.DeleteBuffers(1, &t); t = elementBuffer; gl.DeleteBuffers(1, &t); t = vertexArray; gl.DeleteVertexArrays(1, &t); }; void draw() { var(width, height) = window.ViewportSize; gl.Viewport(0, 0, (int)width, (int)height); gl.Clear(Buffers.Color); gl.DrawElements(DrawMode.Triangles, 6, DrawIndexType.UnsignedShort, IntPtr.Zero); renderingContext.SwapBuffers(window); } window.Resize += (sender, e) => draw(); window.Visible = true; while (windowServer.Windows.Count > 0) { draw(); windowServer.ProcessEvents(0.02); } Console.WriteLine("Draw Texture done."); }
internal void Launch() { Console.WriteLine("Terrain..."); Console.WriteLine(" Press Esc to exit."); Console.WriteLine(" Press W, Q, S, D, Space to move."); using var windowServer = new WindowServer(); using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 4 } }; using var window = windowServer.CreateWindow(renderingContext); window.Title = "Terrain"; window.BorderStyle = WindowBorderStyle.Sizable; const double WindowWidth = 1024; const double WindowHeight = 768; window.Size = (WindowWidth, WindowHeight); renderingContext.CurrentWindow = window; var gl = new GraphicsLibrary(renderingContext); gl.ClearColor(0, 0, 0, 1); using (var scene = new Scene(gl)) { var imageLength = 16 * 16 * 3; var buffer = new byte[imageLength * 3]; var image = new RasterImage(); var namePrefix = typeof(TerrainLauncher).Namespace + ".Resources."; using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "grass.png")) { image.LoadPng(stream ?? throw new InvalidOperationException()); } Array.Copy(image.Data, 0, buffer, 0, imageLength); using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "grass_side.png")) { image.LoadPng(stream ?? throw new InvalidOperationException()); } Array.Copy(image.Data, 0, buffer, imageLength, imageLength); using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "dirt.png")) { image.LoadPng(stream ?? throw new InvalidOperationException()); } Array.Copy(image.Data, 0, buffer, imageLength * 2, imageLength); scene.AddTextureMap(buffer, 3); var viewportSize = window.ViewportSize; scene.SetViewport(0, 0, (int)viewportSize.width, (int)viewportSize.height); (double x, double y)previousPoint = (-1d, -1d); window.MouseMove += (sender, e) => { if (previousPoint.x != -1d || previousPoint.y != -1d) { scene.Rotate((float)(e.Position.x - previousPoint.x), (float)(e.Position.y - previousPoint.y)); } previousPoint = e.Position; }; void draw() { scene.Render(); renderingContext.SwapBuffers(window); } window.Resize += (sender, e) => { var(width, height) = window.ViewportSize; scene.SetViewport(0, 0, (int)width, (int)height); draw(); }; window.FramebufferResize += (sender, e) => { var(width, height) = window.ViewportSize; scene.SetViewport(0, 0, (int)width, (int)height); }; window.Closed += (sender, e) => { scene.Dispose(); }; var stopWatch = new Stopwatch(); stopWatch.Start(); var lastTime = stopWatch.ElapsedMilliseconds / 1e3f; var deltaTime = 0.0f; window.FreeLookMouse = true; //renderingContext.SyncWithVerticalBlank(window, false); Console.WriteLine("Press 'Esc' to quit."); window.Visible = true; while (windowServer.Windows.Count > 0) { var currentTime = stopWatch.ElapsedMilliseconds / 1e3f; deltaTime = currentTime - lastTime; lastTime = currentTime; if (window.IsKeyPressed(Keycode.W)) { scene.MoveForward(deltaTime); } if (window.IsKeyPressed(Keycode.S)) { scene.MoveBackward(deltaTime); } if (window.IsKeyPressed(Keycode.A)) { scene.MoveLeft(deltaTime); } if (window.IsKeyPressed(Keycode.D)) { scene.MoveRight(deltaTime); } if (window.IsKeyPressed(Keycode.Space)) { scene.MoveUp(deltaTime); } if (window.IsKeyPressed(Keycode.Escape)) { window.Close(); windowServer.ProcessEvents(0.0); break; } draw(); windowServer.ProcessEvents(0.0); } stopWatch.Stop(); } Console.WriteLine("Terrain done."); }
internal unsafe void Launch() { Console.WriteLine("Rotate Cube..."); var image = new RasterImage(); var namePrefix = typeof(DrawTextureLauncher).Namespace + ".Resources."; using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "kitten.png")) { image.LoadPng(stream ?? throw new InvalidOperationException()); } using var windowServer = new WindowServer(); using var renderingContext = new RenderingContext(); using var window = windowServer.CreateWindow(renderingContext); window.BorderStyle = WindowBorderStyle.Sizable; window.Title = "Rotate Cube..."; renderingContext.CurrentWindow = window; var gl = new GraphicsLibrary(renderingContext); gl.ClearColor(0, 0, 0, 1); var program = gl.CreateProgram(); var vertexShader = OpenGLHelper.LoadShader(gl, ShaderType.Vertex, @" in vec3 position; in vec3 color; in vec2 texCoord; out vec3 fColor; out vec2 fTexCoord; uniform mat4 model; uniform mat4 view; uniform mat4 proj; void main() { gl_Position = proj * view * model * vec4(position, 1.0); fColor = color; fTexCoord = texCoord; } "); gl.AttachShader(program, vertexShader); var fragmentShader = OpenGLHelper.LoadShader(gl, ShaderType.Fragment, @" in vec3 fColor; in vec2 fTexCoord; out vec4 outColor; uniform sampler2D tex; void main() { outColor = texture(tex, fTexCoord) * vec4(fColor, 1.0); } "); gl.AttachShader(program, fragmentShader); var position = 0u; OpenGLHelper.BindAttribLocation(gl, program, position, "position"); var color = 1u; OpenGLHelper.BindAttribLocation(gl, program, color, "color"); var texCoord = 2u; OpenGLHelper.BindAttribLocation(gl, program, texCoord, "texCoord"); OpenGLHelper.LinkProgram(gl, program); uint h; gl.GenVertexArrays(1, &h); uint vertexArray = h; gl.BindVertexArray(vertexArray); var vertices = new float[] { -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; gl.GenBuffers(1, &h); uint vertexBuffer = h; gl.BindBuffer(BufferTarget.Array, vertexBuffer); OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw); var stride = sizeof(float) * 8; gl.EnableVertexAttribArray(position); gl.VertexAttribPointer(position, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero); gl.EnableVertexAttribArray(color); gl.VertexAttribPointer(color, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 3 * sizeof(float)); gl.EnableVertexAttribArray(texCoord); gl.VertexAttribPointer(texCoord, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 6 * sizeof(float)); gl.GenTextures(1, &h); var texture = h; gl.ActiveTexture(TextureUnit.Texture0); gl.BindTexture(TextureTarget.Texture2d, texture); OpenGLHelper.TexImage2D(gl, image, TextureTarget2D.Texture2d, 0); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapS, (int)TextureParameterValue.ClampToEdge); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapT, (int)TextureParameterValue.ClampToEdge); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMinFilter, (int)TextureParameterValue.Linear); gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMagFilter, (int)TextureParameterValue.Linear); gl.UseProgram(program); var tex = OpenGLHelper.GetUniformLocation(gl, program, "tex"); gl.Uniform1i(tex, 0); var view = OpenGLHelper.GetUniformLocation(gl, program, "view"); var proj = OpenGLHelper.GetUniformLocation(gl, program, "proj"); var model = OpenGLHelper.GetUniformLocation(gl, program, "model"); var mat = Matrix4x4.CreateLookAt(new Vector3(1.5f, 1.5f, 1.5f), new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 1f)); OpenGLHelper.UniformMatrix(gl, view, mat); mat = Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), 1.3f, 1f, 10f); OpenGLHelper.UniformMatrix(gl, proj, mat); var viewportSize = window.ViewportSize; var windowSize = window.Size; renderingContext.CurrentWindow = null; bool done = false; float angle = 0f; var drawLock = new object(); void draw() { var stopWatch = new Stopwatch(); stopWatch.Start(); var lastTime = stopWatch.ElapsedMilliseconds / 1e3f; var deltaTime = 0.0f; //renderingContext.SyncWithVerticalBlank(window, false); renderingContext.CurrentWindow = window; while (!done) { var currentTime = stopWatch.ElapsedMilliseconds / 1e3f; deltaTime = currentTime - lastTime; lastTime = currentTime; gl.Viewport(0, 0, (int)viewportSize.width, (int)viewportSize.height); gl.UseProgram(program); angle += deltaTime; mat = Matrix4x4.CreateFromAxisAngle(new Vector3(0f, 0f, 1f), angle); OpenGLHelper.UniformMatrix(gl, model, mat); gl.Enable(Capability.DepthTest); gl.Clear(Buffers.Color | Buffers.Depth); gl.BindVertexArray(vertexArray); gl.BindBuffer(BufferTarget.Array, vertexBuffer); gl.ActiveTexture(TextureUnit.Texture0); gl.BindTexture(TextureTarget.Texture2d, texture); gl.DrawArrays(DrawMode.Triangles, 0, 36); gl.Disable(Capability.DepthTest); renderingContext.SwapBuffers(window); lock (drawLock) { Monitor.Wait(drawLock, 15); } } renderingContext.CurrentWindow = null; } var drawThread = new Thread(draw); window.Closed += (sender, e) => { done = true; drawThread.Join(); renderingContext.CurrentWindow = window; uint t = texture; gl.DeleteTextures(1, &t); gl.DeleteProgram(program); gl.DeleteShader(vertexShader); gl.DeleteShader(fragmentShader); t = vertexBuffer; gl.DeleteBuffers(1, &t); t = vertexArray; gl.DeleteVertexArrays(1, &t); }; window.Resize += (sender, e) => { viewportSize = window.ViewportSize; windowSize = window.Size; lock (drawLock) { Monitor.Pulse(drawLock); } }; window.FramebufferResize += (sender, e) => { viewportSize = window.ViewportSize; lock (drawLock) { Monitor.Pulse(drawLock); } }; drawThread.Start(); window.Visible = true; while (windowServer.Windows.Count > 0) { windowServer.ProcessEvents(-1); } Console.WriteLine("Rotate Cube done."); }
internal unsafe void Launch() { Console.WriteLine("Draw Polygon..."); using var windowServer = new WindowServer(); using var renderingContext = new RenderingContext(); using var window = windowServer.CreateWindow(renderingContext); renderingContext.CurrentWindow = window; var gl = new GraphicsLibrary(renderingContext); gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); Console.WriteLine(" GL VERSION: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.Version)))); Console.WriteLine("GLSL VERSION: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.ShadingLanguageVersion)))); Console.WriteLine(" GL VENDOR: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.Vendor)))); Console.WriteLine(" GL RENDERER: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.Renderer)))); var program = gl.CreateProgram(); var vertexShader = OpenGLHelper.LoadShader(gl, ShaderType.Vertex, @" layout(location = 0) in vec2 vPosition; layout(location = 1) in vec3 vColor; out vec3 fColor; void main() { gl_Position = vec4(vPosition, 0.0, 1.0); fColor = vColor; } "); gl.AttachShader(program, vertexShader); var fragmentShader = OpenGLHelper.LoadShader(gl, ShaderType.Fragment, @" in vec3 fColor; out vec4 outColor; void main() { outColor = vec4(fColor, 1.0); } "); gl.AttachShader(program, fragmentShader); const uint position = 0u; const uint color = 1u; OpenGLHelper.LinkProgram(gl, program); uint h; gl.GenVertexArrays(1, &h); uint vertexArray = h; gl.BindVertexArray(vertexArray); gl.EnableVertexAttribArray(color); gl.EnableVertexAttribArray(position); var vertices = new float[] { -0.5f, 0.5f, // Top-left 0.5f, 0.5f, // Top-right 0.5f, -0.5f, // Bottom-right -0.5f, -0.5f, // Bottom-left }; gl.GenBuffers(1, &h); uint vertexBuffer1 = h; gl.BindBuffer(BufferTarget.Array, vertexBuffer1); OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw); var stride = sizeof(float) * 2; gl.VertexAttribPointer(position, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero); vertices = new float[] { 1.0f, 0.0f, 0.0f, // Top-left 0.0f, 1.0f, 0.0f, // Top-right 0.0f, 0.0f, 1.0f, // Bottom-right 1.0f, 1.0f, 1.0f, // Bottom-left }; gl.GenBuffers(1, &h); uint vertexBuffer2 = h; gl.BindBuffer(BufferTarget.Array, vertexBuffer2); OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw); stride = sizeof(float) * 3; gl.VertexAttribPointer(color, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero); var elements = new byte[] { 0, 1, 2, 2, 3, 0 }; gl.GenBuffers(1, &h); uint elementBuffer = h; gl.BindBuffer(BufferTarget.ElementArray, elementBuffer); OpenGLHelper.BufferData(gl, BufferTarget.ElementArray, elements, BufferUsage.StaticDraw); gl.UseProgram(program); window.Closed += (sender, e) => { gl.DeleteProgram(program); gl.DeleteShader(vertexShader); gl.DeleteShader(fragmentShader); uint t = vertexBuffer1; gl.DeleteBuffers(1, &t); t = vertexBuffer2; gl.DeleteBuffers(1, &t); t = elementBuffer; gl.DeleteBuffers(1, &t); t = vertexArray; gl.DeleteVertexArrays(1, &t); }; window.Visible = true; while (windowServer.Windows.Count > 0) { gl.Clear(Buffers.Color); gl.DrawElements(DrawMode.Triangles, 6, DrawIndexType.UnsignedByte, IntPtr.Zero); renderingContext.SwapBuffers(window); windowServer.ProcessEvents(0.02); } Console.WriteLine("Draw Polygon done."); }