Opentk/Source/Examples/OpenGL/3.0/HelloGL3.cs

223 lines
7.8 KiB
C#

#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;
using OpenTK.Graphics.OpenGL;
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)
{ }
protected 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<Vector3>(BufferTarget.ArrayBuffer,
new IntPtr(positionVboData.Length * Vector3.SizeInBytes),
positionVboData, BufferUsageHint.StaticDraw);
GL.GenBuffers(1, out normalVboHandle);
GL.BindBuffer(BufferTarget.ArrayBuffer, normalVboHandle);
GL.BufferData<Vector3>(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.CreateRotationY((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);
}
}
}
}