diff --git a/Source/Examples/OpenGL/3.0/HelloGL3.cs b/Source/Examples/OpenGL/3.0/HelloGL3.cs new file mode 100644 index 00000000..3adc8845 --- /dev/null +++ b/Source/Examples/OpenGL/3.0/HelloGL3.cs @@ -0,0 +1,222 @@ +#region License +// +// The Open Toolkit Library License +// +// Copyright (c) 2006 - 2009 the Open Toolkit library. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +#endregion + +using System; +using System.Diagnostics; +using System.IO; + +using OpenTK; +using OpenTK.Graphics; + +namespace Examples.Tutorial +{ + [Example("OpenGL 3.0", ExampleCategory.OpenGL, "3.0", Documentation="HelloGL3")] + public class HelloGL3 : GameWindow + { + string vertexShaderSource = @" +#version 130 + +precision highp float; + +uniform mat4 projection_matrix; +uniform mat4 modelview_matrix; + +in vec3 in_position; +in vec3 in_normal; + +out vec3 normal; + +void main(void) +{ + //works only for orthogonal modelview + normal = (modelview_matrix * vec4(in_normal, 0)).xyz; + + gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1); +}"; + + string fragmentShaderSource = @" +#version 130 + +precision highp float; + +const vec3 ambient = vec3(0.1, 0.1, 0.1); +const vec3 lightVecNormalized = normalize(vec3(0.5, 0.5, 2)); +const vec3 lightColor = vec3(0.9, 0.9, 0.7); + +in vec3 normal; + +out vec4 out_frag_color; + +void main(void) +{ + float diffuse = clamp(dot(lightVecNormalized, normalize(normal)), 0.0, 1.0); + out_frag_color = vec4(ambient + diffuse * lightColor, 1.0); +}"; + + int vertexShaderHandle, + fragmentShaderHandle, + shaderProgramHandle, + modelviewMatrixLocation, + projectionMatrixLocation, + vaoHandle, + positionVboHandle, + normalVboHandle; + + Vector3[] positionVboData = new Vector3[]{ + new Vector3(-1.0f, -1.0f, 1.0f), + new Vector3( 1.0f, -1.0f, 1.0f), + new Vector3( 1.0f, 1.0f, 1.0f), + new Vector3(-1.0f, 1.0f, 1.0f), + new Vector3(-1.0f, -1.0f, -1.0f), + new Vector3( 1.0f, -1.0f, -1.0f), + new Vector3( 1.0f, 1.0f, -1.0f), + new Vector3(-1.0f, 1.0f, -1.0f) }; + + int[] indicesVboData = new int[]{ + // front face + 0, 1, 2, 2, 3, 0, + // top face + 3, 2, 6, 6, 7, 3, + // back face + 7, 6, 5, 5, 4, 7, + // left face + 4, 0, 3, 3, 7, 4, + // bottom face + 0, 1, 5, 5, 4, 0, + // right face + 1, 5, 6, 6, 2, 1, }; + + Matrix4 projectionMatrix, modelviewMatrix; + + public HelloGL3() + : base(640, 480, + new GraphicsMode(), "OpenGL 3 Example", 0, + DisplayDevice.Default, 3, 0, + GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug) + { } + + public override void OnLoad (System.EventArgs e) + { + // Create shaders + vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader); + fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader); + + GL.ShaderSource(vertexShaderHandle, vertexShaderSource); + GL.ShaderSource(fragmentShaderHandle, fragmentShaderSource); + + GL.CompileShader(vertexShaderHandle); + GL.CompileShader(fragmentShaderHandle); + + Debug.WriteLine(GL.GetShaderInfoLog(vertexShaderHandle)); + Debug.WriteLine(GL.GetShaderInfoLog(fragmentShaderHandle)); + + // Create program + shaderProgramHandle = GL.CreateProgram(); + + GL.AttachShader(shaderProgramHandle, vertexShaderHandle); + GL.AttachShader(shaderProgramHandle, fragmentShaderHandle); + + GL.LinkProgram(shaderProgramHandle); + + Debug.WriteLine(GL.GetProgramInfoLog(shaderProgramHandle)); + + GL.UseProgram(shaderProgramHandle); + + // Set uniforms + projectionMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "projection_matrix"); + modelviewMatrixLocation = GL.GetUniformLocation(shaderProgramHandle, "modelview_matrix"); + + float aspectRatio = ClientSize.Width / (float)(ClientSize.Height); + Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, aspectRatio, 1, 100, out projectionMatrix); + modelviewMatrix = Matrix4.LookAt(new Vector3(0, 3, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); + + GL.UniformMatrix4(projectionMatrixLocation, false, ref projectionMatrix); + GL.UniformMatrix4(modelviewMatrixLocation, false, ref modelviewMatrix); + + // Create vertex buffer + GL.GenVertexArrays(1, out vaoHandle); + GL.BindVertexArray(vaoHandle); + + GL.GenBuffers(1, out positionVboHandle); + GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); + GL.BufferData(BufferTarget.ArrayBuffer, + new IntPtr(positionVboData.Length * Vector3.SizeInBytes), + positionVboData, BufferUsageHint.StaticDraw); + + GL.GenBuffers(1, out normalVboHandle); + GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle); + GL.BufferData(BufferTarget.ArrayBuffer, + new IntPtr(positionVboData.Length * Vector3.SizeInBytes), + positionVboData, BufferUsageHint.StaticDraw); + + GL.EnableVertexAttribArray(0); + GL.EnableVertexAttribArray(1); + + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0); + GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0); + + GL.BindAttribLocation(shaderProgramHandle, 0, "in_position"); + GL.BindAttribLocation(shaderProgramHandle, 1, "in_normal"); + + // Other state + GL.Enable(EnableCap.DepthTest); + GL.ClearColor(System.Drawing.Color.MidnightBlue); + } + + protected override void OnUpdateFrame(FrameEventArgs e) + { + Matrix4 rotation = Matrix4.RotateY((float)e.Time); + Matrix4.Mult(ref rotation, ref modelviewMatrix, out modelviewMatrix); + GL.UniformMatrix4(modelviewMatrixLocation, false, ref modelviewMatrix); + + if (Keyboard[OpenTK.Input.Key.Escape]) + Exit(); + } + + protected override void OnRenderFrame(FrameEventArgs e) + { + GL.Viewport(0, 0, Width, Height); + + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + + GL.DrawElements(BeginMode.Triangles, indicesVboData.Length, + DrawElementsType.UnsignedInt, indicesVboData); + + SwapBuffers(); + } + + [STAThread] + public static void Main() + { + using (HelloGL3 example = new HelloGL3()) + { + Utilities.SetWindowTitle(example); + example.Run(30); + } + } + } +} \ No newline at end of file