Created
November 4, 2014 05:44
-
-
Save GeirGrusom/347f30e981f33972c934 to your computer and use it in GitHub Desktop.
OpenTK colored triangle example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Drawing; | |
using System.Runtime.InteropServices; | |
using System.Windows.Forms; | |
using OpenTK; | |
using OpenTK.Graphics; | |
using OpenTK.Graphics.OpenGL; | |
namespace OpenTKExample | |
{ | |
class Program | |
{ | |
static void Main() | |
{ | |
var display = new Form { Text = "OpenTK loop example", Size = new Size(640, 480)}; | |
display.Show(); | |
// Create window info and context | |
var windowInfo = OpenTK.Platform.Utilities.CreateWindowsWindowInfo(display.Handle); | |
IGraphicsContext context = new GraphicsContext(GraphicsMode.Default, windowInfo); | |
// Make the new context current | |
context.MakeCurrent(windowInfo); | |
var isRunning = true; | |
display.FormClosing += (sender, e) => isRunning = false; | |
// Load all function pointers | |
context.LoadAll(); | |
// Set clear color | |
GL.ClearColor(Color4.Black); | |
var vertexBuffer = CreateVertexBuffer(); | |
var vertexArray = CreateVertexArray(vertexBuffer); | |
// The most basic of verrtex shaders. | |
const string vertexShaderCode = | |
"uniform mat4 Mvp; in vec4 color; in vec3 position; out vec4 fragcolor; void main() { gl_Position = Mvp * vec4(position, 1); fragcolor = color; }"; | |
// The most basic of fragment shaders. | |
const string fragmentShaderCode = "in vec4 fragcolor; out vec4 FragColor; void main() { FragColor = fragcolor; }"; | |
var vertexShader = CreateVertexShader(vertexShaderCode); | |
var fragmentShader = CreateFragmentShader(fragmentShaderCode); | |
// Create the shader program | |
int program = GL.CreateProgram(); | |
// Attach the shaders to the program | |
GL.AttachShader(program, vertexShader); | |
GL.AttachShader(program, fragmentShader); | |
// Set FragColor as output fragment variable | |
GL.BindFragDataLocation(program, 0, "FragColor"); | |
GL.BindAttribLocation(program, 0, "position"); | |
GL.BindAttribLocation(program, 1, "color"); | |
GL.LinkProgram(program); | |
GL.ValidateProgram(program); | |
GL.UseProgram(program); | |
// Get the uniform location of mvp which we will use to set the value with later on. | |
int mvp = GL.GetUniformLocation(program, "Mvp"); | |
Matrix4 view = Matrix4.LookAt(new Vector3(0, 2, 2), new Vector3(), Vector3.UnitY); | |
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(((float)Math.PI / 180) * 80, 640.0f/480.0f, 0.1f, 10f); | |
float angle = 0; | |
var lastTimestamp = Stopwatch.GetTimestamp(); | |
var freq = Stopwatch.Frequency; | |
do | |
{ | |
var timeStamp = Stopwatch.GetTimestamp(); | |
angle += (float)((timeStamp - lastTimestamp) / (double)freq); | |
lastTimestamp = timeStamp; | |
// Clear color and depth buffers | |
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); | |
// Create a rotation matrix | |
var model = Matrix4.CreateFromAxisAngle(Vector3.UnitY, angle); | |
Matrix4 modelViewProjection = model * view * projection; | |
GL.UniformMatrix4(mvp, false, ref modelViewProjection); | |
GL.BindVertexArray(vertexArray); | |
GL.DrawArrays(PrimitiveType.Triangles, 0, 3); | |
// Present result | |
context.SwapBuffers(); | |
// Process windows events (this may invoke the FormClosing event if the user closed the form) | |
Application.DoEvents(); | |
} while (isRunning); // If the user closed the form then FormClosing should have changed isRunning variable to false | |
context.Dispose(); | |
} | |
private static int CreateVertexShader(string code) | |
{ | |
var shader = GL.CreateShader(ShaderType.VertexShader); | |
GL.ShaderSource(shader, code); | |
GL.CompileShader(shader); | |
return shader; | |
} | |
private static int CreateFragmentShader(string code) | |
{ | |
var shader = GL.CreateShader(ShaderType.FragmentShader); | |
GL.ShaderSource(shader, code); | |
GL.CompileShader(shader); | |
return shader; | |
} | |
private static int CreateVertexArray(int vertexBuffer) | |
{ | |
int array = GL.GenVertexArray(); | |
GL.BindVertexArray(array); | |
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); | |
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 28, IntPtr.Zero); | |
GL.EnableVertexAttribArray(0); | |
GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 28, new IntPtr(12)); | |
GL.EnableVertexAttribArray(1); | |
GL.BindVertexArray(0); | |
return array; | |
} | |
private static int CreateVertexBuffer() | |
{ | |
var vertexBuffer = GL.GenBuffer(); | |
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); | |
var vertices = new Vertex[] | |
{ | |
new Vertex { Color = Color4.Red, Position = new Vector3(-0.5f, 0, 0)}, | |
new Vertex { Color = Color4.Green, Position = new Vector3(0.5f, 0.5f, 0)}, | |
new Vertex { Color = Color4.Blue, Position = new Vector3(-0.5f, 1, 0)} | |
}; | |
var handle = GCHandle.Alloc(vertices, GCHandleType.Pinned); | |
try | |
{ | |
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(28*vertices.Length), handle.AddrOfPinnedObject(), | |
BufferUsageHint.StaticDraw); | |
} | |
finally | |
{ | |
handle.Free(); | |
} | |
GL.BindBuffer(BufferTarget.ArrayBuffer, 0); | |
return vertexBuffer; | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 4)] | |
struct Vertex | |
{ | |
public Vector3 Position; | |
public Color4 Color; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment