/*
* Created by SharpDevelop.
* User: OgreVorbis
* Date: 1/1/2022
* Time: 9:19 PM
*
* This will render a cube(s) with OpenTK at a specific world positions and create an FPS style camera.
* The OpenTK FPS camera sample has some bugs and isn't written in a straightforward way.
* This will start you on a path of a Minecraft type game or anything else based on rendering lots of cubes.
* You need OpenTK 3.3.1 and a reference to system drawing.
*/
using System;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
namespace OpenTKTest
{
class Game : GameWindow
{
const float speed = 0.12f;
const float sensitivity = 0.16f;
float pitch = 0.0f;
float yaw = -90.0f;
bool firstMove = true;
Vector2 lastPos;
Vector3 position = new Vector3(0.0f, 0.0f, 5.0f);
Vector3 front = new Vector3(0.0f, 0.0f, -2.0f);
Vector3 up = new Vector3(0.0f, 2.0f, 0.0f);
public Game() : base(800, 600, GraphicsMode.Default, "OpenTK Cube and Camera")
{
VSync = VSyncMode.On;
}
void drawCube(float x, float y, float z)
{
const float sizex = 0.5f;
const float sizey = 0.5f;
const float sizez = 0.5f;
GL.Translate(-x, -y, -z);
GL.Begin(PrimitiveType.Quads);
GL.Color3(1.0, 1.0, 0.0);
// FRONT
GL.Vertex3(-sizex, -sizey, sizez);
GL.Vertex3(sizex, -sizey, sizez);
GL.Vertex3(sizex, sizey, sizez);
GL.Vertex3(-sizex, sizey, sizez);
// BACK
GL.Vertex3(-sizex, -sizey, -sizez);
GL.Vertex3(-sizex, sizey, -sizez);
GL.Vertex3(sizex, sizey, -sizez);
GL.Vertex3(sizex, -sizey, -sizez);
GL.Color3(0.0, 1.0, 0.0);
// LEFT
GL.Vertex3(-sizex, -sizey, sizez);
GL.Vertex3(-sizex, sizey, sizez);
GL.Vertex3(-sizex, sizey, -sizez);
GL.Vertex3(-sizex, -sizey, -sizez);
// RIGHT
GL.Vertex3(sizex, -sizey, -sizez);
GL.Vertex3(sizex, sizey, -sizez);
GL.Vertex3(sizex, sizey, sizez);
GL.Vertex3(sizex, -sizey, sizez);
//GL.Color3(1.0, 0.0, 1.0);
// we test if we can use bytes here for later - yes we can
GL.Color3((byte)255, (byte)0, (byte)255);
// TOP
GL.Vertex3(-sizex, sizey, sizez);
GL.Vertex3(sizex, sizey, sizez);
GL.Vertex3(sizex, sizey, -sizez);
GL.Vertex3(-sizex, sizey, -sizez);
// BOTTOM
GL.Vertex3(-sizex, -sizey, sizez);
GL.Vertex3(-sizex, -sizey, -sizez);
GL.Vertex3(sizex, -sizey, -sizez);
GL.Vertex3(sizex, -sizey, sizez);
GL.End();
GL.Translate(x, y, z);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
GL.Enable(EnableCap.DepthTest);
CursorGrabbed = true;
CursorVisible = false;
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref projection);
}
// MIGHT NOT NEED THIS FUNCTION
protected override void OnMouseMove(MouseMoveEventArgs e)
{
if (Focused) // check to see if the window is focused
{
Mouse.SetPosition(X + Width / 2f, Y + Height / 2f);
}
base.OnMouseMove(e);
}
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
if (!Focused) // check to see if the window is focused
{
return;
}
KeyboardState input = Keyboard.GetState();
MouseState mouse = Mouse.GetState();
// KEYBOARD MOVEMENT SECTION
if (input.IsKeyDown(Key.W))
position += front * speed; //Forward
if (input.IsKeyDown(Key.S))
position -= front * speed; //Backwards
if (input.IsKeyDown(Key.A))
position -= Vector3.Normalize(Vector3.Cross(front, up)) * speed; //Left
if (input.IsKeyDown(Key.D))
position += Vector3.Normalize(Vector3.Cross(front, up)) * speed; //Right
if (input.IsKeyDown(Key.Space))
position += up * speed; //Up
if (input.IsKeyDown(Key.LShift))
position -= up * speed; //Down
if (input.IsKeyDown(Key.Escape))
{
CursorGrabbed = false;
CursorVisible = true;
}
// MOUSE MOVEMENT SECTION
if (firstMove)
{
lastPos = new Vector2(mouse.X, mouse.Y);
firstMove = false;
}
else
{
float deltaX = mouse.X - lastPos.X;
float deltaY = mouse.Y - lastPos.Y;
lastPos = new Vector2(mouse.X, mouse.Y);
yaw += deltaX * sensitivity;
pitch -= deltaY * sensitivity;
if(pitch > 89.0f)
pitch = 89.0f;
else if(pitch < -89.0f)
pitch = -89.0f;
}
front.X = (float)Math.Cos(MathHelper.DegreesToRadians(pitch)) * (float)Math.Cos(MathHelper.DegreesToRadians(yaw));
front.Y = (float)Math.Sin(MathHelper.DegreesToRadians(pitch));
front.Z = (float)Math.Cos(MathHelper.DegreesToRadians(pitch)) * (float)Math.Sin(MathHelper.DegreesToRadians(yaw));
front = Vector3.Normalize(front);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
Matrix4 modelview = Matrix4.LookAt(position, position + front, up);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref modelview);
drawCube(0.0f, 0.0f, -2.0f);
SwapBuffers();
}
[STAThread]
public static void Main(string[] args)
{
using (Game game = new Game())
{
game.Run(60.0);
}
}
}
}