flopoloco's picture

The OpenTK Framework

I would be interested to start working on an application framework called OpenTK Framework that will allow users to create games/simulations/graphics extremely fast and easy. This OpenTK Framework will wrap common functionality in order to provide a layer of abstractness to the user when programming 3D. Because it will be easy to use, thus it will enhance creativity and productivity.

By using the OpenTK Framework each developer can focus in the field he is really interested in:
* A physics developer can simulate his fluid dynamics without paying attention to his graphics code at all!!!
* A network developer can visualize the packets and network traffic with remarkable easiness.
* A game developer can focus on the game play mechanics (making even better and enjoyable games) rather focusing on the WOW factor
(NOTE: OpenTK Framework will be WOW-factor compatible, as long as there are good shaders loaded in it)

A use case scenario follows (outdated - a more Object Oriented API will implemented) :

// How to create a romantic moonlight scene with the exact parts (boat, sea, sky, stars and moon)
 
using System;
using OpenTK;
using OpenTK.Input;
using OpenTKFramework;
 
namespace OpenTKFrameworkGameTest
{
	class Game : GameWindow
	{
		Entity camera, moon, ship, skybox, sea;
		Entity [] star = new Entity[100];
 
		public Game()
		{
			// Create a skybox
			Entity skybox = CreateBox();
			EntityScale(skybox , 100, 100, 100);
			EntityFlip(skybox); // Flip normals
			EntityTexture(skybox, "media/textures/nightsky.jpg");
 
			// Create a camera
			Entity camera = CreateCamera();
			EntityParent(camera, skybox, ParentingRelation.Positional); // skybox will be the child node of camera in positional manners.
			EntityPosition(camera, 500, 10, 200);
			EntityRotate(camera, -40, 0, 0); // sky box is not rotated
			EntityColor(camera, 0, 0, 0); // Set the clearing color of screen
			EntityShader(camera, "media/shaders/bloomfilter.glsl");
			EntityShader(camera, "media/shaders/hdrfilter.glsl"); // Post production filters can be combined
 
			// Create the moon
			Entity moon = CreateSphere();
			EntityPosition(moon, 200, 600, 200);
			EntityScale(moon, 10, 10, 10);
			EntityTexture(moon, "media/textures/moon.jpg");
			EntityShader(moon, ShadingStyle.Flat); // Use some of the already existing basic shaders.
 
			// Create a ship
			ship = LoadModel("media/models/ship/ship.x");
			EntityTexture(ship, "media/models/ship/ship.dds");
 
			// Create stars
			for (int i = 0; i <= 99; i++)
			{
				star[i] = CreateSphere();
				EntityPosition(star[i], Random(-500.0, 500.0), 800.0, Random(-500.0, 500.0));
				byte starColor = Random(0, 255);
				EntityColor(star[i], starColor, starColor, starColor);
			}
 
			// Create sea
			sea = CreatePlane();
			EntityRotation(sea, 90, 0, 0);
			EntityScale(sea, 1000, 0, 1000);
			EntityShader(sea , "media/shaders/realistic_water.glsl");
		}
 
		// Give simple movement to the ship
		public override void OnUpdateFrame(UpdateFrameEventArgs e)
		{
			base.OnUpdateFrame(e);
 
			if (Keyboard[Key.Up])
				EntityTranslate(ship, 0, 0, 1);
			if (Keyboard[Key.Down])
				EntityTranslate(ship, 0, 0, -1);
			if (Keyboard[Key.Left])
				EntityRotate(ship, 0, -1, 0);
			if (Keyboard[Key.Right])
				EntityRotate(ship, 0,  1, 0);
 
			if (Keyboard[Key.Escape])
				Exit();
		}
 
		public static void Main(string[] args)
		{
			Game game = new Game();
			game.Run(30.0);
		}
	}
}

That was 100% C# and 100% OpenToolkit!!! Isn't that great?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
flopoloco's picture

I have started working again for a couple of 10 days on the project... Here is a basic part of the Entity class, that will make your game transformations piece of cake!!! :)

public class Entity
	{
		private Vector3 vecPosition;
		private Vector3 vecRotation;
		private Matrix4 positionMatrix;
		private Matrix4 modelMatrix;
 
		public Entity()
		{
			positionMatrix = Matrix4.Identity;
			modelMatrix = Matrix4.Identity;
			SetPosition(0f, 0f, 0f);
		}
 
		public void SetPosition(float x, float y, float z)
		{
			vecPosition.X = x;
			vecPosition.Y = y;
			vecPosition.Z = z;
		}
 
		public void SetRotation(float x, float y, float z)
		{
			vecRotation.X = x;
			vecRotation.Y = y;
			vecRotation.Z = z;
		}
 
		public void Translate(float x, float y, float z)
		{
			Translate(x, y, z, false);
		}
 
		public void Translate(float x, float y, float z, bool localAxis)
		{
			if (localAxis == true)
			{
				Matrix4 m = new Matrix4();		// Create new matrix
				m = Matrix4.Identity;			// Reset it
				m = Matrix4.Translation(x, y, z);// Translate matrix
				// Perform series of rotation operations to matrix
				m = Matrix4.Mult(m, Matrix4.RotateX(vecRotation.X));
				m = Matrix4.Mult(m, Matrix4.RotateY(vecRotation.Y));
				m = Matrix4.Mult(m, Matrix4.RotateZ(vecRotation.Z));
 
				// Save the result of temporary matrix
				vecPosition.X += m.Row3.X;
				vecPosition.Y += m.Row3.Y;
				vecPosition.Z += m.Row3.Z;
			}
 
 
			if (localAxis == false)
			{
				vecPosition.X += x;
				vecPosition.Y += y;
				vecPosition.Z += z;
			}
		}
 
		public void Rotate(float x, float y, float z)
		{
			vecRotation.X += (float)(x * (Math.PI/180));
			vecRotation.Y += (float)(y * (Math.PI/180));
			vecRotation.Z += (float)(z * (Math.PI/180));
		}
 
		public void Update(ref Matrix4 viewMatrix)
		{
			Matrix4 rotationMatrix = Matrix4.RotateX(vecRotation.X);
			rotationMatrix = Matrix4.Mult(rotationMatrix, Matrix4.RotateY(vecRotation.Y));
			rotationMatrix = Matrix4.Mult(rotationMatrix, Matrix4.RotateZ(vecRotation.Z));
			modelMatrix = Matrix4.Mult(rotationMatrix, Matrix4.Translation(vecPosition));
			modelMatrix = Matrix4.Mult(modelMatrix, viewMatrix);
		}
 
		public void Render()
		{
			GL.LoadMatrix(ref modelMatrix);
			GL.Begin(BeginMode.Triangles);
			GL.Color3(System.Drawing.Color.LightYellow); GL.Vertex3(-1.0f, -1.0f, 0.0f);
			GL.Color3(System.Drawing.Color.LightYellow); GL.Vertex3(1.0f, -1.0f, 0.0f);
			GL.Color3(System.Drawing.Color.LightSkyBlue); GL.Vertex3(0.0f, 1.0f, 0.0f);
			GL.End();
		}
	}

Also there's an accompanying standalone example application of the class:

using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using OpenTK.Platform;
using OpenTK.Math;
 
namespace OpenTKNavigationOpenGL
{
	public class OpenTKNavigation3D : GameWindow
	{
		Entity player;
 
		public OpenTKNavigation3D()
		{
			player = new Entity();
		}
 
		public override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			GL.ClearColor(Color.MidnightBlue);
			GL.ShadeModel(ShadingModel.Flat);
			GL.Enable(EnableCap.LineSmooth);
			GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
			GL.Enable(EnableCap.DepthTest);
		}
 
 
		protected override void OnRenderFrame(FrameEventArgs e)
		{
			GL.Clear(ClearBufferMask.ColorBufferBit |
					ClearBufferMask.DepthBufferBit);
 
			Matrix4 modelView = Matrix4.LookAt(new Vector3(20f, 20f, 20f), Vector3.Zero, Vector3.UnitY);
			GL.MatrixMode(MatrixMode.Modelview);
			GL.LoadMatrix(ref modelView);
 
			player.Update(ref modelView);
			player.Render();
 
			this.SwapBuffers();
		}
 
		protected override void OnResize(EventArgs e)
		{
			GL.Viewport(0, 0, Width, Height);
            Matrix4 projection = Matrix4.Perspective(45.0f, Width / (float)Height, 1.0f, 200.0f);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);
		}
 
		protected override void OnUpdateFrame(FrameEventArgs e)
		{
			if (Keyboard[Key.Escape])
				Exit();
 
			float moveSpeed = (float)(25.0 * e.Time);
			float rotateSpeed = (float)(100.0 * e.Time);
 
			// Test global axis transformation
            if (Keyboard[Key.A]) player.Translate(-moveSpeed, 0f, 0f);
            if (Keyboard[Key.D]) player.Translate( moveSpeed, 0f, 0f);
			if (Keyboard[Key.W]) player.Translate( 0f, 0f,-moveSpeed);
			if (Keyboard[Key.S]) player.Translate( 0f, 0f, moveSpeed);
 
			// Test local axis transformation
			if (Keyboard[Key.F]) player.Translate(-moveSpeed, 0f, 0f, true);
            if (Keyboard[Key.H]) player.Translate( moveSpeed, 0f, 0f, true);
			if (Keyboard[Key.T]) player.Translate( 0f, 0f,-moveSpeed, true);
			if (Keyboard[Key.G]) player.Translate( 0f, 0f, moveSpeed, true);
 
			// Test rotations			
			if (Keyboard[Key.Left]) player.Rotate(0f,  rotateSpeed, 0);
			if (Keyboard[Key.Right]) player.Rotate(0f, -rotateSpeed, 0);
			if (Keyboard[Key.Up]) player.Rotate(rotateSpeed, 0f, 0f);
			if (Keyboard[Key.Down]) player.Rotate(-rotateSpeed, 0f, 0f);
 
			// Reset all
			if (Keyboard[Key.Space])
			{
				player.SetPosition(0f, 0f, 0f);
				player.SetRotation(0f, 0f, 0f);
			}
 
			base.OnUpdateFrame(e);
		}
 
		public static void Main()
		{
			using (OpenTKNavigation3D n = new OpenTKNavigation3D())
			{
				n.Run();
			}
		}
	}
}

As for the progress of the OpenTK Framework, I will continue the work in my own pace (that means really slow) and provide source code of the 5 most important classes of it :
- Mesh Loaders (Collada, 3Ds, Obj)
- Camera
- Materials
- Shaders
- Lights

Remember: OpenTK Framework is about higher level access and ease of use...

objarni's picture

Do you have a particular game in mind?

iliak's picture

This would be nicer and more C# than C++ :

public class Entity
 {
        public Vector3 vecPosition
        {
              get;
              set;
        }
        private Vector3 vecRotation
        {
              get;
              set;
        }
       [....]
 }
flopoloco's picture

objarni: No, I have not a specific game in mind. But I would like to experiment on new genres, that means I would like plenty of functionality for start.

iliak: Thanks for your notice. When I get some basic parts working I would pay more attention to C# specifications (also I think of integrating FXCop, StyleCop and Test Driven Development into it, any one has experience with these?).