Last active
December 13, 2017 21:42
-
-
Save Daomephsta/17d36f84d4ab2452a4975999edeca8a2 to your computer and use it in GitHub Desktop.
OpenGL Testbed
This file contains hidden or 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 OpenGL_Testbed.Lib; | |
using OpenTK; | |
using OpenTK.Graphics; | |
using OpenTK.Graphics.OpenGL; | |
using System; | |
using System.IO; | |
using OpenTK.Input; | |
namespace OpenGL_Testbed | |
{ | |
public class Cameras : GameWindow | |
{ | |
private ShaderProgram shaderProgram; | |
private VertexBuffer vbo; | |
private VertexArray vao; | |
private Texture texture1; | |
private Texture texture2; | |
//Camera variables | |
private Vector3 pos = new Vector3(0, 0, 3); | |
private Vector3 front = new Vector3(0.0f, 0.0f, -1.0f), right, up = new Vector3(0.0F, 1.0F, 0.0F); | |
private double pitch, yaw = -90.0F; | |
private int lastMouseX, lastMouseY; | |
private bool firstMouse = true; | |
private float deltaTime = 0.0F; //Time between the current frame and the last one | |
private float lastFrameTime = 0.0F; //The timestamp of the last frame | |
private readonly float[] vertices = | |
{ | |
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, | |
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, | |
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f | |
}; | |
public Cameras() : base(800, 600, GraphicsMode.Default, "Test Game", GameWindowFlags.FixedWindow, DisplayDevice.Default, 3, 3, GraphicsContextFlags.Default) {} | |
protected override void OnResize(EventArgs e) | |
{ | |
base.OnResize(e); | |
GL.Viewport(0, 0, this.Width, this.Height); | |
} | |
protected override void OnLoad(EventArgs e) | |
{ | |
//Setup the viewport & capture the mouse | |
GL.Viewport(0, 0, this.Width, this.Height); | |
CursorVisible = false; | |
//Load the textures | |
try | |
{ | |
texture1 = new Texture("resources/textures/container.jpg"); | |
texture2 = new Texture("resources/textures/awesomeface.png"); | |
} | |
catch (FileNotFoundException fnf) | |
{ | |
Console.Write(fnf.ToString()); | |
} | |
//Create a vertex shader | |
Shader vertShader = Shader.CreateShaderFromFile(ShaderType.VertexShader, "coordSystemsVertex"); | |
//Create a fragment shader | |
Shader fragShader = Shader.CreateShaderFromFile(ShaderType.FragmentShader, "coordSystemsFragment"); | |
//Create a shader program | |
shaderProgram = new ShaderProgram(); | |
shaderProgram.Attach(vertShader, delete: true); | |
shaderProgram.Attach(fragShader, delete: true); | |
shaderProgram.Link("shaderProgram"); | |
vao = new VertexArray(); | |
vao.Bind(); | |
//Create a VBO(Vertex Buffer Object) | |
vbo = new VertexBuffer(); | |
vbo.Bind(); | |
vbo.SetData(vertices, BufferUsageHint.StaticDraw); | |
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0); | |
GL.EnableVertexAttribArray(0); | |
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); | |
GL.EnableVertexAttribArray(1); | |
vbo.Unbind(); | |
vao.Unbind(); | |
shaderProgram.Use(); | |
shaderProgram.SetUniform("texture1", 0); | |
shaderProgram.SetUniform("texture2", 1); | |
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45.0F), (float)Width / Height, 0.1F, 100.0F); | |
shaderProgram.SetUniform("projection", projection); | |
} | |
protected override void OnRenderFrame(FrameEventArgs e) | |
{ | |
base.OnRenderFrame(e); | |
GL.Enable(EnableCap.DepthTest); | |
GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f); | |
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); | |
float currentFrame = Environment.TickCount / 1000.0F; | |
deltaTime = currentFrame - lastFrameTime; | |
lastFrameTime = currentFrame; | |
GL.ActiveTexture(TextureUnit.Texture0); | |
texture1.Bind(); | |
GL.ActiveTexture(TextureUnit.Texture1); | |
texture2.Bind(); | |
Matrix4 view = Matrix4.LookAt(pos, pos + front, up); | |
shaderProgram.SetUniform("view", view); | |
Vector3[] cubePositions = | |
{ | |
new Vector3( 0.0f, 0.0f, 0.0f), | |
new Vector3( 2.0f, 5.0f, -15.0f), | |
new Vector3(-1.5f, -2.2f, -2.5f), | |
new Vector3(-3.8f, -2.0f, -12.3f), | |
new Vector3( 2.4f, -0.4f, -3.5f), | |
new Vector3(-1.7f, 3.0f, -7.5f), | |
new Vector3( 1.3f, -2.0f, -2.5f), | |
new Vector3( 1.5f, 2.0f, -2.5f), | |
new Vector3( 1.5f, 0.2f, -1.5f), | |
new Vector3(-1.3f, 1.0f, -1.5f) | |
}; | |
vao.Bind(); | |
for(int i = 0; i < 10; i++) | |
{ | |
float angle = i * 20; | |
Matrix4 model = Matrix4.CreateFromAxisAngle(new Vector3(1.0f, 0.3f, 0.5f), MathHelper.DegreesToRadians(angle)) * Matrix4.CreateTranslation(cubePositions[i]); | |
shaderProgram.SetUniform("model", model); | |
GL.DrawArrays(PrimitiveType.Triangles, 0, 36); | |
} | |
vao.Unbind(); | |
SwapBuffers(); | |
} | |
private void RecalculateLocalUnitVectors() | |
{ | |
right = Vector3.Normalize(Vector3.Cross(Vector3.UnitY, front)); | |
up = Vector3.Cross(front, right); | |
} | |
public void MoveCamera(float x = 0.0F, float y = 0.0F, float z = 0.0F) | |
{ | |
MoveCamera(new Vector3(x, y, z)); | |
} | |
public void MoveCamera(Vector3 xyz) | |
{ | |
pos += xyz; | |
} | |
protected override void OnKeyDown(KeyboardKeyEventArgs e) | |
{ | |
float moveSpeed = 2.5F * deltaTime; | |
if (Keyboard.GetState().IsKeyDown(Key.Escape)) CursorVisible = true; | |
if (Keyboard.GetState().IsKeyDown(Key.W)) MoveCamera(moveSpeed * front); | |
if (Keyboard.GetState().IsKeyDown(Key.S)) MoveCamera(-moveSpeed * front); | |
if (Keyboard.GetState().IsKeyDown(Key.A)) MoveCamera(moveSpeed * right); | |
if (Keyboard.GetState().IsKeyDown(Key.D)) MoveCamera(-moveSpeed * right); | |
} | |
protected override void OnMouseDown(MouseButtonEventArgs e) { CursorVisible = false; } | |
protected override void OnMouseMove(MouseMoveEventArgs e) | |
{ | |
if (CursorVisible) return; | |
if(firstMouse) | |
{ | |
lastMouseX = e.X; | |
lastMouseY = e.Y; | |
firstMouse = false; | |
} | |
double xOffset = e.X - lastMouseX; | |
double yOffset = e.Y - lastMouseY; | |
lastMouseX = e.X; | |
lastMouseY = e.Y; | |
double sensitivity = 0.05F; | |
xOffset *= sensitivity; | |
yOffset *= sensitivity; | |
yaw = yaw + xOffset; | |
pitch = pitch + yOffset; | |
pitch = MathHelper.Clamp(pitch, -89.0D, 89.0D); | |
Vector3d tempFront; | |
tempFront.X = Math.Cos(MathHelper.DegreesToRadians(pitch)) * Math.Cos(MathHelper.DegreesToRadians(yaw)); | |
tempFront.Y = Math.Sin(MathHelper.DegreesToRadians(pitch)); | |
tempFront.Z = Math.Cos(MathHelper.DegreesToRadians(pitch)) * Math.Sin(MathHelper.DegreesToRadians(yaw)); | |
front = (Vector3) Vector3d.Normalize(tempFront); | |
RecalculateLocalUnitVectors(); | |
} | |
protected override void OnClosed(EventArgs e) | |
{ | |
base.OnClosed(e); | |
//Cleanup | |
vao.Delete(); | |
vbo.Delete(); | |
} | |
} | |
} |
This file contains hidden or 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
#version 330 core | |
out vec4 fragmentColour; | |
in vec2 uv; | |
uniform sampler2D texture1; | |
uniform sampler2D texture2; | |
void main() | |
{ | |
fragmentColour = mix(texture(texture1, uv), texture(texture2, uv), 0.2); | |
} |
This file contains hidden or 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
#version 330 core | |
layout (location = 0) in vec3 position; | |
layout (location = 1) in vec2 uvIn; | |
out vec2 uv; | |
uniform mat4 model; | |
uniform mat4 view; | |
uniform mat4 projection; | |
void main() | |
{ | |
gl_Position = projection * view * model * vec4(position, 1.0); | |
uv = uvIn; | |
} |
This file contains hidden or 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 OpenTK; | |
using OpenTK.Graphics.OpenGL; | |
using System; | |
using System.Drawing; | |
using System.Drawing.Imaging; | |
using System.IO; | |
using System.Text; | |
using opengl = OpenTK.Graphics.OpenGL; | |
using imaging = System.Drawing.Imaging; | |
namespace OpenGL_Testbed.Lib | |
{ | |
public class Shader | |
{ | |
internal readonly int glID; | |
public Shader(ShaderType type, string shadername, params string[] shaderSource) | |
{ | |
this.glID = GL.CreateShader(type); | |
GL.ShaderSource(this.glID, shaderSource.Length, shaderSource, (int[])null); | |
GL.CompileShader(this.glID); | |
Console.WriteLine("Compiling shader: " + shadername + ".glsl"); | |
//Check the shader compiled successfully | |
int success; | |
GL.GetShader(this.glID, ShaderParameter.CompileStatus, out success); | |
if (success == 0) | |
{ | |
Console.WriteLine("Could not compile shader: " + shadername + ".glsl"); | |
string errors; | |
GL.GetShaderInfoLog(this.glID, out errors); | |
Console.WriteLine(errors); | |
} | |
else | |
{ | |
Console.WriteLine("Shader: " + shadername + ".glsl compiled successfully!"); | |
} | |
} | |
public static Shader CreateShaderFromFile(ShaderType type, String shaderName) | |
{ | |
StringBuilder source = new StringBuilder(); | |
using (StreamReader reader = new StreamReader(Environment.CurrentDirectory + "\\resources\\shaders\\" + shaderName + ".glsl")) | |
{ | |
while (reader.Peek() != -1) | |
{ | |
source.AppendLine(reader.ReadLine()); | |
} | |
} | |
return new Shader(type, shaderName, source.ToString()); | |
} | |
public void Delete() | |
{ | |
GL.DeleteShader(this.glID); | |
} | |
public static void DeleteShaders(Shader[] shaders) | |
{ | |
foreach (Shader shader in shaders) | |
{ | |
GL.DeleteShader(shader.glID); | |
} | |
} | |
} | |
public class ShaderProgram | |
{ | |
internal readonly int glID; | |
public ShaderProgram() | |
{ | |
this.glID = GL.CreateProgram(); | |
} | |
public void Attach(Shader shader, bool delete = false) | |
{ | |
GL.AttachShader(this.glID, shader.glID); | |
if (delete) shader.Delete(); | |
} | |
public void Link(string name) | |
{ | |
GL.LinkProgram(this.glID); | |
Console.WriteLine("Attempting to link shader program: " + name); | |
//Check the link succeeded | |
int success; | |
GL.GetProgram(this.glID, GetProgramParameterName.LinkStatus, out success); | |
if (success == 0) | |
{ | |
Console.WriteLine("Linking of shader program: " + name + " failed"); | |
string errors; | |
GL.GetProgramInfoLog(this.glID, out errors); | |
Console.WriteLine(errors); | |
} | |
else | |
{ | |
Console.WriteLine("Shader program: " + name + " linked successfully!"); | |
} | |
} | |
public void Use() | |
{ | |
GL.UseProgram(this.glID); | |
} | |
public int GetUniformLocation(string uniformName) | |
{ | |
return GL.GetUniformLocation(this.glID, uniformName); | |
} | |
public void SetUniform(string uniformName, int value) | |
{ | |
GL.Uniform1(GL.GetUniformLocation(this.glID, uniformName), value); | |
} | |
public void SetUniform(string uniformName, float value) | |
{ | |
GL.Uniform1(GL.GetUniformLocation(this.glID, uniformName), value); | |
} | |
public void SetUniform(string uniformName, Matrix4 value) | |
{ | |
GL.UniformMatrix4(GL.GetUniformLocation(this.glID, uniformName), false, ref value); | |
} | |
} | |
public class VertexBuffer | |
{ | |
internal readonly int glID; | |
public VertexBuffer() | |
{ | |
this.glID = GL.GenBuffer(); | |
} | |
public void Bind() | |
{ | |
GL.BindBuffer(BufferTarget.ArrayBuffer, this.glID); | |
} | |
public void Unbind() | |
{ | |
GL.BindBuffer(BufferTarget.ArrayBuffer, 0); | |
} | |
public void SetData(float[] vertices, BufferUsageHint usageHint) | |
{ | |
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * vertices.Length, vertices, usageHint); | |
} | |
public void Delete() | |
{ | |
GL.DeleteBuffer(this.glID); | |
} | |
public static void DeleteVBOS(VertexBuffer[] buffers) | |
{ | |
foreach (VertexBuffer buffer in buffers) | |
{ | |
GL.DeleteBuffer(buffer.glID); | |
} | |
} | |
} | |
public class ElementBuffer | |
{ | |
internal readonly int glID; | |
public ElementBuffer() | |
{ | |
this.glID = GL.GenBuffer(); | |
} | |
public void Bind() | |
{ | |
GL.BindBuffer(BufferTarget.ElementArrayBuffer, this.glID); | |
} | |
public void Unbind() | |
{ | |
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); | |
} | |
public void SetData(int[] indices, BufferUsageHint usageHint) | |
{ | |
GL.BufferData(BufferTarget.ElementArrayBuffer, sizeof(int) * indices.Length, indices, usageHint); | |
} | |
public void Delete() | |
{ | |
GL.DeleteBuffer(this.glID); | |
} | |
public static void DeleteEBOS(ElementBuffer[] buffers) | |
{ | |
foreach (ElementBuffer buffer in buffers) | |
{ | |
GL.DeleteBuffer(buffer.glID); | |
} | |
} | |
} | |
public class VertexArray | |
{ | |
internal readonly int glID; | |
public VertexArray() | |
{ | |
this.glID = GL.GenVertexArray(); | |
} | |
public void Bind() | |
{ | |
GL.BindVertexArray(this.glID); | |
} | |
public void Unbind() | |
{ | |
GL.BindVertexArray(0); | |
} | |
public void Delete() | |
{ | |
GL.DeleteVertexArray(this.glID); | |
} | |
public static void DeleteVAOS(VertexArray[] vaos) | |
{ | |
foreach (VertexArray vao in vaos) | |
{ | |
GL.DeleteVertexArray(vao.glID); | |
} | |
} | |
} | |
public struct Texture | |
{ | |
internal readonly int glID; | |
public Texture(String fileName) : this(fileName, imaging::PixelFormat.Format24bppRgb, opengl::PixelFormat.Bgr) {} | |
public Texture(String fileName, imaging::PixelFormat imageFormat, opengl::PixelFormat format) | |
{ | |
glID = GL.GenTexture(); | |
using (Bitmap bitmap = new Bitmap(fileName)) | |
{ | |
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); | |
BitmapData imageData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, imageFormat); | |
GL.BindTexture(TextureTarget.Texture2D, glID); | |
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, bitmap.Width, bitmap.Height, 0, format, PixelType.UnsignedByte, imageData.Scan0); | |
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); | |
//Cleanup | |
GL.BindTexture(TextureTarget.Texture2D, 0); | |
bitmap.UnlockBits(imageData); | |
} | |
} | |
public void Bind() | |
{ | |
GL.BindTexture(TextureTarget.Texture2D, glID); | |
} | |
public void Unbind() | |
{ | |
GL.BindTexture(TextureTarget.Texture2D, glID); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment