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 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 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."); }